Skip to content

Commit 9375c28

Browse files
authored
Add initial anthropic ai provider integration package (#4446)
1 parent b56a211 commit 9375c28

33 files changed

+4787
-1111
lines changed

.changeset/thin-hounds-dance.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@effect/ai-anthropic": patch
3+
"@effect/ai-openai": patch
4+
"@effect/ai": patch
5+
---
6+
7+
Add Anthropic AI provider integration

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ The Effect monorepo is organized into multiple packages, each extending the core
1717
| `effect` | Core package | [README](https://github.com/Effect-TS/effect/blob/main/packages/effect/README.md) |
1818
| `@effect/ai` | AI utilities | [README](https://github.com/Effect-TS/effect/blob/main/packages/ai/ai/README.md) |
1919
| `@effect/ai-openai` | OpenAI utilities | [README](https://github.com/Effect-TS/effect/blob/main/packages/ai/openai/README.md) |
20+
| `@effect/ai-anthropic` | Anthropic utilities | [README](https://github.com/Effect-TS/effect/blob/main/packages/ai/anthropic/README.md) |
2021
| `@effect/cli` | CLI utilities | [README](https://github.com/Effect-TS/effect/blob/main/packages/cli/README.md) |
2122
| `@effect/cluster` | Distributed computing tools | [README](https://github.com/Effect-TS/effect/blob/main/packages/cluster/README.md) |
2223
| `@effect/cluster-browser` | Cluster utilities for the browser | [README](https://github.com/Effect-TS/effect/blob/main/packages/cluster-browser/README.md) |

flake.nix

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,28 @@
22
inputs = {
33
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
44
};
5-
outputs = {nixpkgs, ...}: let
6-
forAllSystems = function:
7-
nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed
8-
(system: function nixpkgs.legacyPackages.${system});
9-
in {
10-
formatter = forAllSystems (pkgs: pkgs.alejandra);
11-
devShells = forAllSystems (pkgs: {
12-
default = pkgs.mkShell {
13-
packages = with pkgs; [
14-
bun
15-
corepack
16-
deno
17-
nodejs
18-
python3
19-
];
20-
};
21-
});
22-
};
5+
outputs =
6+
{ nixpkgs, ... }:
7+
let
8+
forAllSystems =
9+
function:
10+
nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed (
11+
system: function nixpkgs.legacyPackages.${system}
12+
);
13+
in
14+
{
15+
formatter = forAllSystems (pkgs: pkgs.alejandra);
16+
devShells = forAllSystems (pkgs: {
17+
default = pkgs.mkShell {
18+
packages = with pkgs; [
19+
bun
20+
corepack
21+
deno
22+
nodejs
23+
python3
24+
yq-go
25+
];
26+
};
27+
});
28+
};
2329
}

packages/ai/ai/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
# `@effect/ai`
2+
3+
## Documentation
4+
5+
- **API Reference**: [View the full documentation](https://effect-ts.github.io/effect/docs/ai/ai).

packages/ai/ai/src/AiInput.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,12 @@ export class ImagePart extends Schema_.TaggedClass<ImagePart>("@effect/ai/AiInpu
205205
)
206206
}
207207

208+
get asBase64(): string {
209+
return Encoding.encodeBase64(this.image.data)
210+
}
211+
208212
get asDataUri(): string {
209-
const base64 = Encoding.encodeBase64(this.image.data)
210-
return `data:${this.image.contentType};base64,${base64}`
213+
return `data:${this.image.contentType};base64,${this.asBase64}`
211214
}
212215
}
213216

packages/ai/ai/src/Completions.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as Effect from "effect/Effect"
77
import * as HashMap from "effect/HashMap"
88
import * as JsonSchema from "effect/JSONSchema"
99
import * as Option from "effect/Option"
10+
import * as Predicate from "effect/Predicate"
1011
import * as Schema from "effect/Schema"
1112
import * as AST from "effect/SchemaAST"
1213
import * as Stream from "effect/Stream"
@@ -377,7 +378,7 @@ const resolveParts = (
377378
const handler = HashMap.unsafeGet(options.tools.handlers, part.name)
378379
const decodeParams = Schema.decodeUnknown(tool as any)
379380
const encodeSuccess = Schema.encode(tool.success)
380-
return decodeParams(part.params).pipe(
381+
return decodeParams(injectTag(part.params, part.name)).pipe(
381382
Effect.mapError((cause) =>
382383
new AiError({
383384
module: "Completions",
@@ -410,3 +411,24 @@ const resolveParts = (
410411
Effect.as(new WithResolved({ response: options.response, resolved, encoded }))
411412
)
412413
}
414+
415+
/**
416+
* Certain providers (i.e. Anthropic) do not do a great job returning the
417+
* `_tag` enum with the parameters for a tool call. This method ensures that
418+
* the `_tag` is injected into the tool call parameters to avoid issues when
419+
* decoding.
420+
*/
421+
function injectTag(params: unknown, tag: string) {
422+
// If for some reason we do not receive an object back for the tool call
423+
// input parameters, just return them unchanged
424+
if (!Predicate.isObject(params)) {
425+
return params
426+
}
427+
// If the tool's `_tag` is already present in input parameters, return them
428+
// unchanged
429+
if (Predicate.hasProperty(params, "_tag")) {
430+
return params
431+
}
432+
// Otherwise inject the tool's `_tag` into the input parameters
433+
return { ...params, _tag: tag }
434+
}

packages/ai/anthropic/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Effectful Technologies Inc
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/ai/anthropic/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# `@effect/ai-anthropic`
2+
3+
## Documentation
4+
5+
- **API Reference**: [View the full documentation](https://effect-ts.github.io/effect/docs/ai/ai-anthropic).

packages/ai/anthropic/docgen.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"$schema": "../../../node_modules/@effect/docgen/schema.json",
3+
"exclude": ["src/Generated.ts", "src/internal/**/*.ts"],
4+
"examplesCompilerOptions": {
5+
"noEmit": true,
6+
"strict": true,
7+
"skipLibCheck": true,
8+
"moduleResolution": "Bundler",
9+
"module": "ES2022",
10+
"target": "ES2022",
11+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
12+
"paths": {
13+
"effect": ["../../../../effect/src/index.js"],
14+
"effect/*": ["../../../../effect/src/*.js"],
15+
"@effect/experimental": ["../../../../experimental/src/index.js"],
16+
"@effect/experimental/*": ["../../../../experimental/src/*.js"],
17+
"@effect/platform": ["../../../../platform/src/index.js"],
18+
"@effect/platform/*": ["../../../../platform/src/*.js"],
19+
"@effect/ai": ["../../../ai/src/index.js"],
20+
"@effect/ai/*": ["../../../ai/src/*.js"],
21+
"@effect/ai-anthropic": ["../../../ai-anthropic/src/index.js"],
22+
"@effect/ai-anthropic/*": ["../../../ai-anthropic/src/*.js"]
23+
}
24+
}
25+
}

packages/ai/anthropic/package.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"name": "@effect/ai-anthropic",
3+
"type": "module",
4+
"version": "0.0.0",
5+
"license": "MIT",
6+
"description": "Effect modules for working with AI apis",
7+
"homepage": "https://effect.website",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/Effect-TS/effect.git",
11+
"directory": "packages/ai/anthropic"
12+
},
13+
"bugs": {
14+
"url": "https://github.com/Effect-TS/effect/issues"
15+
},
16+
"tags": [
17+
"typescript",
18+
"algebraic-data-types",
19+
"functional-programming"
20+
],
21+
"keywords": [
22+
"typescript",
23+
"algebraic-data-types",
24+
"functional-programming"
25+
],
26+
"publishConfig": {
27+
"access": "public",
28+
"directory": "dist",
29+
"provenance": true
30+
},
31+
"scripts": {
32+
"codegen": "build-utils prepare-v2",
33+
"build": "pnpm build-esm && pnpm build-annotate && pnpm build-cjs && build-utils pack-v2",
34+
"build-esm": "tsc -b tsconfig.build.json",
35+
"build-cjs": "babel build/esm --plugins @babel/transform-export-namespace-from --plugins @babel/transform-modules-commonjs --out-dir build/cjs --source-maps",
36+
"build-annotate": "babel build/esm --plugins annotate-pure-calls --out-dir build/esm --source-maps",
37+
"check": "tsc -b tsconfig.json",
38+
"test": "vitest",
39+
"coverage": "vitest --coverage"
40+
},
41+
"peerDependencies": {
42+
"@effect/ai": "workspace:^",
43+
"@effect/experimental": "workspace:^",
44+
"@effect/platform": "workspace:^",
45+
"effect": "workspace:^"
46+
},
47+
"devDependencies": {
48+
"@effect/ai": "workspace:^",
49+
"@effect/experimental": "workspace:^",
50+
"@effect/platform": "workspace:^",
51+
"@effect/platform-node": "workspace:^",
52+
"@tim-smart/openapi-gen": "^0.3.6",
53+
"effect": "workspace:^"
54+
},
55+
"dependencies": {
56+
"@anthropic-ai/tokenizer": "^0.0.4"
57+
}
58+
}

0 commit comments

Comments
 (0)