@effect-uai/anthropic 0.17.0 → 0.19.0-dev-20261109183959
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/Anthropic.d.mts +1 -1
- package/dist/Anthropic.mjs +2 -2
- package/dist/Anthropic.mjs.map +1 -1
- package/dist/AnthropicTools.mjs +1 -1
- package/dist/anthropicTools.test.mjs +2 -1
- package/dist/anthropicTools.test.mjs.map +1 -1
- package/dist/codec.d.mts +15 -1
- package/dist/codec.d.mts.map +1 -1
- package/dist/codec.mjs +43 -8
- package/dist/codec.mjs.map +1 -1
- package/dist/codec.test.d.mts +1 -0
- package/dist/codec.test.mjs +101 -0
- package/dist/codec.test.mjs.map +1 -0
- package/dist/dist-DHer1cql.mjs +1533 -0
- package/dist/dist-DHer1cql.mjs.map +1 -0
- package/dist/{test.DNmyFkvJ-N3QqMRwZ.mjs → index.C4tKZ0yW-xEu55bU4.mjs} +8276 -7092
- package/dist/index.C4tKZ0yW-xEu55bU4.mjs.map +1 -0
- package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-EAsCxrDo.mjs} +2 -1
- package/dist/streamEvents.mjs +1 -1
- package/dist/usage.test.mjs +1 -1
- package/package.json +5 -5
- package/src/Anthropic.ts +1 -1
- package/src/anthropicTools.test.ts +1 -0
- package/src/codec.test.ts +78 -0
- package/src/codec.ts +56 -6
- package/dist/magic-string.es-CUAnjKYC.mjs +0 -1014
- package/dist/magic-string.es-CUAnjKYC.mjs.map +0 -1
- package/dist/test.DNmyFkvJ-N3QqMRwZ.mjs.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region \0rolldown/runtime.js
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
3
4
|
var __exportAll = (all, no_symbols) => {
|
|
4
5
|
let target = {};
|
|
5
6
|
for (var name in all) __defProp(target, name, {
|
|
@@ -10,4 +11,4 @@ var __exportAll = (all, no_symbols) => {
|
|
|
10
11
|
return target;
|
|
11
12
|
};
|
|
12
13
|
//#endregion
|
|
13
|
-
export { __exportAll as t };
|
|
14
|
+
export { __exportAll as n, __commonJSMin as t };
|
package/dist/streamEvents.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as __exportAll } from "./rolldown-runtime-EAsCxrDo.mjs";
|
|
2
2
|
import { WireContentBlock, appendInputJsonDelta, appendSignatureDelta, appendTextDelta, appendThinkingDelta, mergeUsage, setStopReason, startBlock } from "./codec.mjs";
|
|
3
3
|
import { Match, Schema } from "effect";
|
|
4
4
|
//#region src/streamEvents.ts
|
package/dist/usage.test.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { emptyAccumulator, mergeUsage } from "./codec.mjs";
|
|
2
2
|
import { applyEvent } from "./streamEvents.mjs";
|
|
3
|
-
import { n as describe, r as it, t as globalExpect } from "./
|
|
3
|
+
import { n as describe, r as it, t as globalExpect } from "./index.C4tKZ0yW-xEu55bU4.mjs";
|
|
4
4
|
//#region src/usage.test.ts
|
|
5
5
|
const wire = {
|
|
6
6
|
input_tokens: 94,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-uai/anthropic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0-dev-20261109183959",
|
|
4
4
|
"description": "Anthropic Messages API provider for @effect-uai/core.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"effect": "4.
|
|
46
|
+
"effect": "4.1.2",
|
|
47
47
|
"typescript": "^7.0.2",
|
|
48
|
-
"@effect-uai/core": "0.
|
|
48
|
+
"@effect-uai/core": "0.19.0-dev-20261109183959"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@effect-uai/core": "
|
|
52
|
-
"effect": ">=4.0.
|
|
51
|
+
"@effect-uai/core": "0.19.0-dev-20261109183959",
|
|
52
|
+
"effect": ">=4.0.1 <5.0.0"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsdown",
|
package/src/Anthropic.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
Stream,
|
|
11
11
|
pipe,
|
|
12
12
|
} from "effect"
|
|
13
|
-
import { HttpClient, HttpClientRequest } from "effect/
|
|
13
|
+
import { HttpClient, HttpClientRequest } from "effect/http"
|
|
14
14
|
import * as AiError from "@effect-uai/core/AiError"
|
|
15
15
|
import * as Capabilities from "@effect-uai/core/Capabilities"
|
|
16
16
|
import {
|
|
@@ -10,6 +10,7 @@ const localTool = Tool.make({
|
|
|
10
10
|
name: "get_weather",
|
|
11
11
|
description: "Look up the weather.",
|
|
12
12
|
inputSchema: Tool.fromEffectSchema(Schema.Struct({ city: Schema.String })),
|
|
13
|
+
outputSchema: Schema.String,
|
|
13
14
|
run: ({ city }) => Effect.succeed(`sunny in ${city}`),
|
|
14
15
|
})
|
|
15
16
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { fileBase64, fileUrl } from "@effect-uai/core/File"
|
|
2
|
+
import { imageBytes } from "@effect-uai/core/Image"
|
|
3
|
+
import * as Items from "@effect-uai/core/Items"
|
|
4
|
+
import { Option, Result } from "effect"
|
|
5
|
+
import { describe, expect, it } from "vitest"
|
|
6
|
+
import { buildRequestBody } from "./codec.js"
|
|
7
|
+
|
|
8
|
+
const toolResultFor = (output: Items.ToolCallOutput) => {
|
|
9
|
+
const body = Result.getOrThrow(
|
|
10
|
+
buildRequestBody({
|
|
11
|
+
model: "claude-sonnet-4-5",
|
|
12
|
+
history: [
|
|
13
|
+
Items.userText("go"),
|
|
14
|
+
{ type: "function_call", call_id: "c1", name: "shot", arguments: "{}" },
|
|
15
|
+
output,
|
|
16
|
+
],
|
|
17
|
+
maxTokens: 1024,
|
|
18
|
+
temperature: Option.none(),
|
|
19
|
+
topP: Option.none(),
|
|
20
|
+
topK: Option.none(),
|
|
21
|
+
stopSequences: Option.none(),
|
|
22
|
+
thinking: Option.none(),
|
|
23
|
+
tools: Option.none(),
|
|
24
|
+
toolChoice: Option.none(),
|
|
25
|
+
userId: Option.none(),
|
|
26
|
+
outputConfig: Option.none(),
|
|
27
|
+
cacheControl: Option.none(),
|
|
28
|
+
}),
|
|
29
|
+
)
|
|
30
|
+
return body.messages.at(-1)?.content
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const outputOf = (output: Items.ToolCallOutput["output"], isError?: boolean) =>
|
|
34
|
+
toolResultFor({
|
|
35
|
+
type: "function_call_output",
|
|
36
|
+
call_id: "c1",
|
|
37
|
+
output,
|
|
38
|
+
...(isError !== undefined && { isError }),
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe("tool_result", () => {
|
|
42
|
+
it("sends text and JSON as one string and flags failures with is_error", () => {
|
|
43
|
+
expect(outputOf([Items.json({ _tag: "CityNotFound", city: "Atlantis" })], true)).toEqual([
|
|
44
|
+
{
|
|
45
|
+
type: "tool_result",
|
|
46
|
+
tool_use_id: "c1",
|
|
47
|
+
content: '{"_tag":"CityNotFound","city":"Atlantis"}',
|
|
48
|
+
is_error: true,
|
|
49
|
+
},
|
|
50
|
+
])
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it("sends media as image and document blocks, the filename as the document title", () => {
|
|
54
|
+
expect(
|
|
55
|
+
outputOf([
|
|
56
|
+
Items.text("Home"),
|
|
57
|
+
Items.image(imageBytes(new Uint8Array([1, 2, 3]), "image/png")),
|
|
58
|
+
Items.file(fileBase64("JVBE", "application/pdf"), "report.pdf"),
|
|
59
|
+
Items.file(fileUrl("https://x/a.pdf")),
|
|
60
|
+
]),
|
|
61
|
+
).toEqual([
|
|
62
|
+
{
|
|
63
|
+
type: "tool_result",
|
|
64
|
+
tool_use_id: "c1",
|
|
65
|
+
content: [
|
|
66
|
+
{ type: "text", text: "Home" },
|
|
67
|
+
{ type: "image", source: { type: "base64", media_type: "image/png", data: "AQID" } },
|
|
68
|
+
{
|
|
69
|
+
type: "document",
|
|
70
|
+
source: { type: "base64", media_type: "application/pdf", data: "JVBE" },
|
|
71
|
+
title: "report.pdf",
|
|
72
|
+
},
|
|
73
|
+
{ type: "document", source: { type: "url", url: "https://x/a.pdf" } },
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
])
|
|
77
|
+
})
|
|
78
|
+
})
|
package/src/codec.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { Array as Arr,
|
|
1
|
+
import { Array as Arr, Match, Option, Order, Result, Schema, pipe } from "effect"
|
|
2
|
+
import { Base64 } from "effect/encoding"
|
|
2
3
|
import * as Items from "@effect-uai/core/Items"
|
|
3
4
|
import { JsonParseError } from "@effect-uai/core/JSONL"
|
|
5
|
+
import * as ToolOutput from "@effect-uai/core/ToolOutput"
|
|
4
6
|
import type { Turn } from "@effect-uai/core/Turn"
|
|
5
7
|
|
|
6
8
|
// ---------------------------------------------------------------------------
|
|
@@ -59,9 +61,20 @@ type RequestTextContent = {
|
|
|
59
61
|
type RequestToolResultContent = {
|
|
60
62
|
readonly type: "tool_result"
|
|
61
63
|
readonly tool_use_id: string
|
|
62
|
-
readonly content: string
|
|
64
|
+
readonly content: string | ReadonlyArray<RequestToolResultBlock>
|
|
65
|
+
readonly is_error?: boolean
|
|
63
66
|
}
|
|
64
67
|
|
|
68
|
+
type RequestDocumentContent = {
|
|
69
|
+
readonly type: "document"
|
|
70
|
+
readonly source:
|
|
71
|
+
| { readonly type: "url"; readonly url: string }
|
|
72
|
+
| { readonly type: "base64"; readonly media_type: string; readonly data: string }
|
|
73
|
+
readonly title?: string
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type RequestToolResultBlock = RequestTextContent | RequestImageContent | RequestDocumentContent
|
|
77
|
+
|
|
65
78
|
type RequestToolUseContent = {
|
|
66
79
|
readonly type: "tool_use"
|
|
67
80
|
readonly id: string
|
|
@@ -129,11 +142,50 @@ const imageSourceToWire = Match.type<Items.InputImage["source"]>().pipe(
|
|
|
129
142
|
Match.tag("bytes", (s): RequestImageContent["source"] => ({
|
|
130
143
|
type: "base64",
|
|
131
144
|
media_type: s.mimeType,
|
|
132
|
-
data:
|
|
145
|
+
data: Base64.encode(s.bytes),
|
|
146
|
+
})),
|
|
147
|
+
Match.exhaustive,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
const fileSourceToWire = Match.type<Items.InputFile["source"]>().pipe(
|
|
151
|
+
Match.tag("url", (s): RequestDocumentContent["source"] => ({ type: "url", url: s.url })),
|
|
152
|
+
Match.tag("base64", (s): RequestDocumentContent["source"] => ({
|
|
153
|
+
type: "base64",
|
|
154
|
+
media_type: s.mimeType,
|
|
155
|
+
data: s.base64,
|
|
156
|
+
})),
|
|
157
|
+
Match.tag("bytes", (s): RequestDocumentContent["source"] => ({
|
|
158
|
+
type: "base64",
|
|
159
|
+
media_type: s.mimeType,
|
|
160
|
+
data: Base64.encode(s.bytes),
|
|
133
161
|
})),
|
|
134
162
|
Match.exhaustive,
|
|
135
163
|
)
|
|
136
164
|
|
|
165
|
+
const toolResultBlock = Match.type<Items.ToolOutputContent>().pipe(
|
|
166
|
+
Match.discriminatorsExhaustive("type")({
|
|
167
|
+
input_text: (p): RequestToolResultBlock => ({ type: "text", text: ToolOutput.partText(p) }),
|
|
168
|
+
input_json: (p): RequestToolResultBlock => ({ type: "text", text: ToolOutput.partText(p) }),
|
|
169
|
+
input_image: (p): RequestToolResultBlock => ({
|
|
170
|
+
type: "image",
|
|
171
|
+
source: imageSourceToWire(p.source),
|
|
172
|
+
}),
|
|
173
|
+
input_file: (p): RequestToolResultBlock => ({
|
|
174
|
+
type: "document",
|
|
175
|
+
source: fileSourceToWire(p.source),
|
|
176
|
+
...(p.filename !== undefined && { title: p.filename }),
|
|
177
|
+
}),
|
|
178
|
+
}),
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// Text and JSON only: one string. With media: image and document blocks.
|
|
182
|
+
const toolResult = (o: Items.ToolCallOutput): RequestToolResultContent => ({
|
|
183
|
+
type: "tool_result",
|
|
184
|
+
tool_use_id: o.call_id,
|
|
185
|
+
content: Option.getOrElse(ToolOutput.text(o.output), () => o.output.map(toolResultBlock)),
|
|
186
|
+
...(o.isError === true && { is_error: true }),
|
|
187
|
+
})
|
|
188
|
+
|
|
137
189
|
const userContentBlock = (
|
|
138
190
|
block: Items.ContentBlock,
|
|
139
191
|
): Result.Result<RequestUserContentBlock, void> =>
|
|
@@ -178,9 +230,7 @@ const itemToUserBlocks = (item: Items.HistoryItem): ReadonlyArray<RequestUserCon
|
|
|
178
230
|
message: (m): ReadonlyArray<RequestUserContentBlock> =>
|
|
179
231
|
m.role === "user" ? pipe(m.content, Arr.filterMap(userContentBlock)) : [],
|
|
180
232
|
function_call: (): ReadonlyArray<RequestUserContentBlock> => [],
|
|
181
|
-
function_call_output: (o): ReadonlyArray<RequestUserContentBlock> => [
|
|
182
|
-
{ type: "tool_result", tool_use_id: o.call_id, content: o.output },
|
|
183
|
-
],
|
|
233
|
+
function_call_output: (o): ReadonlyArray<RequestUserContentBlock> => [toolResult(o)],
|
|
184
234
|
reasoning: (): ReadonlyArray<RequestUserContentBlock> => [],
|
|
185
235
|
}),
|
|
186
236
|
)
|