@effect/ai-anthropic 0.23.0 → 4.0.0-beta.0

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.
Files changed (104) hide show
  1. package/dist/AnthropicClient.d.ts +196 -0
  2. package/dist/AnthropicClient.d.ts.map +1 -0
  3. package/dist/AnthropicClient.js +142 -0
  4. package/dist/AnthropicClient.js.map +1 -0
  5. package/dist/{dts/AnthropicConfig.d.ts → AnthropicConfig.d.ts} +9 -9
  6. package/dist/AnthropicConfig.d.ts.map +1 -0
  7. package/dist/{esm/AnthropicConfig.js → AnthropicConfig.js} +8 -5
  8. package/dist/AnthropicConfig.js.map +1 -0
  9. package/dist/AnthropicError.d.ts +102 -0
  10. package/dist/AnthropicError.d.ts.map +1 -0
  11. package/dist/AnthropicError.js +10 -0
  12. package/dist/AnthropicError.js.map +1 -0
  13. package/dist/AnthropicLanguageModel.d.ts +522 -0
  14. package/dist/AnthropicLanguageModel.d.ts.map +1 -0
  15. package/dist/AnthropicLanguageModel.js +2107 -0
  16. package/dist/AnthropicLanguageModel.js.map +1 -0
  17. package/dist/AnthropicTelemetry.d.ts +101 -0
  18. package/dist/AnthropicTelemetry.d.ts.map +1 -0
  19. package/dist/AnthropicTelemetry.js +35 -0
  20. package/dist/AnthropicTelemetry.js.map +1 -0
  21. package/dist/AnthropicTool.d.ts +2153 -0
  22. package/dist/AnthropicTool.d.ts.map +1 -0
  23. package/dist/AnthropicTool.js +1168 -0
  24. package/dist/AnthropicTool.js.map +1 -0
  25. package/dist/Generated.d.ts +25233 -0
  26. package/dist/Generated.d.ts.map +1 -0
  27. package/dist/Generated.js +7649 -0
  28. package/dist/Generated.js.map +1 -0
  29. package/dist/index.d.ts +53 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +54 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/internal/errors.d.ts +2 -0
  34. package/dist/internal/errors.d.ts.map +1 -0
  35. package/dist/internal/errors.js +344 -0
  36. package/dist/internal/errors.js.map +1 -0
  37. package/dist/{dts/internal → internal}/utilities.d.ts.map +1 -1
  38. package/dist/internal/utilities.js.map +1 -0
  39. package/package.json +45 -81
  40. package/src/AnthropicClient.ts +327 -683
  41. package/src/AnthropicConfig.ts +20 -34
  42. package/src/AnthropicError.ts +111 -0
  43. package/src/AnthropicLanguageModel.ts +2039 -993
  44. package/src/AnthropicTelemetry.ts +138 -0
  45. package/src/AnthropicTool.ts +1500 -475
  46. package/src/Generated.ts +9798 -6359
  47. package/src/index.ts +38 -6
  48. package/src/internal/errors.ts +368 -0
  49. package/src/internal/utilities.ts +1 -1
  50. package/AnthropicClient/package.json +0 -6
  51. package/AnthropicConfig/package.json +0 -6
  52. package/AnthropicLanguageModel/package.json +0 -6
  53. package/AnthropicTokenizer/package.json +0 -6
  54. package/AnthropicTool/package.json +0 -6
  55. package/Generated/package.json +0 -6
  56. package/README.md +0 -5
  57. package/dist/cjs/AnthropicClient.js +0 -344
  58. package/dist/cjs/AnthropicClient.js.map +0 -1
  59. package/dist/cjs/AnthropicConfig.js +0 -30
  60. package/dist/cjs/AnthropicConfig.js.map +0 -1
  61. package/dist/cjs/AnthropicLanguageModel.js +0 -1322
  62. package/dist/cjs/AnthropicLanguageModel.js.map +0 -1
  63. package/dist/cjs/AnthropicTokenizer.js +0 -52
  64. package/dist/cjs/AnthropicTokenizer.js.map +0 -1
  65. package/dist/cjs/AnthropicTool.js +0 -461
  66. package/dist/cjs/AnthropicTool.js.map +0 -1
  67. package/dist/cjs/Generated.js +0 -6578
  68. package/dist/cjs/Generated.js.map +0 -1
  69. package/dist/cjs/index.js +0 -20
  70. package/dist/cjs/index.js.map +0 -1
  71. package/dist/cjs/internal/utilities.js +0 -29
  72. package/dist/cjs/internal/utilities.js.map +0 -1
  73. package/dist/dts/AnthropicClient.d.ts +0 -730
  74. package/dist/dts/AnthropicClient.d.ts.map +0 -1
  75. package/dist/dts/AnthropicConfig.d.ts.map +0 -1
  76. package/dist/dts/AnthropicLanguageModel.d.ts +0 -304
  77. package/dist/dts/AnthropicLanguageModel.d.ts.map +0 -1
  78. package/dist/dts/AnthropicTokenizer.d.ts +0 -13
  79. package/dist/dts/AnthropicTokenizer.d.ts.map +0 -1
  80. package/dist/dts/AnthropicTool.d.ts +0 -548
  81. package/dist/dts/AnthropicTool.d.ts.map +0 -1
  82. package/dist/dts/Generated.d.ts +0 -12504
  83. package/dist/dts/Generated.d.ts.map +0 -1
  84. package/dist/dts/index.d.ts +0 -25
  85. package/dist/dts/index.d.ts.map +0 -1
  86. package/dist/esm/AnthropicClient.js +0 -317
  87. package/dist/esm/AnthropicClient.js.map +0 -1
  88. package/dist/esm/AnthropicConfig.js.map +0 -1
  89. package/dist/esm/AnthropicLanguageModel.js +0 -1309
  90. package/dist/esm/AnthropicLanguageModel.js.map +0 -1
  91. package/dist/esm/AnthropicTokenizer.js +0 -44
  92. package/dist/esm/AnthropicTokenizer.js.map +0 -1
  93. package/dist/esm/AnthropicTool.js +0 -452
  94. package/dist/esm/AnthropicTool.js.map +0 -1
  95. package/dist/esm/Generated.js +0 -6247
  96. package/dist/esm/Generated.js.map +0 -1
  97. package/dist/esm/index.js +0 -25
  98. package/dist/esm/index.js.map +0 -1
  99. package/dist/esm/internal/utilities.js.map +0 -1
  100. package/dist/esm/package.json +0 -4
  101. package/index/package.json +0 -6
  102. package/src/AnthropicTokenizer.ts +0 -59
  103. /package/dist/{dts/internal → internal}/utilities.d.ts +0 -0
  104. /package/dist/{esm/internal → internal}/utilities.js +0 -0
@@ -1,1322 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.withConfigOverride = exports.prepareTools = exports.modelWithTokenizer = exports.model = exports.make = exports.layerWithTokenizer = exports.layer = exports.Config = void 0;
7
- var AiError = _interopRequireWildcard(require("@effect/ai/AiError"));
8
- var IdGenerator = _interopRequireWildcard(require("@effect/ai/IdGenerator"));
9
- var LanguageModel = _interopRequireWildcard(require("@effect/ai/LanguageModel"));
10
- var AiModel = _interopRequireWildcard(require("@effect/ai/Model"));
11
- var _Telemetry = require("@effect/ai/Telemetry");
12
- var Tool = _interopRequireWildcard(require("@effect/ai/Tool"));
13
- var Arr = _interopRequireWildcard(require("effect/Array"));
14
- var Context = _interopRequireWildcard(require("effect/Context"));
15
- var DateTime = _interopRequireWildcard(require("effect/DateTime"));
16
- var Effect = _interopRequireWildcard(require("effect/Effect"));
17
- var Encoding = _interopRequireWildcard(require("effect/Encoding"));
18
- var _Function = require("effect/Function");
19
- var Layer = _interopRequireWildcard(require("effect/Layer"));
20
- var Predicate = _interopRequireWildcard(require("effect/Predicate"));
21
- var Stream = _interopRequireWildcard(require("effect/Stream"));
22
- var _AnthropicClient = require("./AnthropicClient.js");
23
- var AnthropicTokenizer = _interopRequireWildcard(require("./AnthropicTokenizer.js"));
24
- var AnthropicTool = _interopRequireWildcard(require("./AnthropicTool.js"));
25
- var InternalUtilities = _interopRequireWildcard(require("./internal/utilities.js"));
26
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
27
- /**
28
- * @since 1.0.0
29
- */
30
-
31
- // =============================================================================
32
- // Configuration
33
- // =============================================================================
34
- /**
35
- * @since 1.0.0
36
- * @category Context
37
- */
38
- class Config extends /*#__PURE__*/Context.Tag("@effect/ai-anthropic/AnthropicLanguageModel/Config")() {
39
- /**
40
- * @since 1.0.0
41
- */
42
- static getOrUndefined = /*#__PURE__*/Effect.map(/*#__PURE__*/Effect.context(), context => context.unsafeMap.get(Config.key));
43
- }
44
- // =============================================================================
45
- // Anthropic Language Model
46
- // =============================================================================
47
- /**
48
- * @since 1.0.0
49
- * @category Ai Models
50
- */
51
- exports.Config = Config;
52
- const model = (model, config) => AiModel.make("anthropic", layer({
53
- model,
54
- config
55
- }));
56
- /**
57
- * @since 1.0.0
58
- * @category Ai Models
59
- */
60
- exports.model = model;
61
- const modelWithTokenizer = (model, config) => AiModel.make("anthropic", layerWithTokenizer({
62
- model,
63
- config
64
- }));
65
- /**
66
- * @since 1.0.0
67
- * @category Constructors
68
- */
69
- exports.modelWithTokenizer = modelWithTokenizer;
70
- const make = exports.make = /*#__PURE__*/Effect.fnUntraced(function* (options) {
71
- const client = yield* _AnthropicClient.AnthropicClient;
72
- const makeRequest = Effect.fnUntraced(function* (providerOptions) {
73
- const context = yield* Effect.context();
74
- const config = {
75
- model: options.model,
76
- ...options.config,
77
- ...context.unsafeMap.get(Config.key)
78
- };
79
- const {
80
- betas: messageBetas,
81
- messages,
82
- system
83
- } = yield* prepareMessages(providerOptions);
84
- const {
85
- betas: toolBetas,
86
- toolChoice,
87
- tools
88
- } = yield* prepareTools(providerOptions, config);
89
- const responseFormat = providerOptions.responseFormat;
90
- const request = {
91
- max_tokens: 4096,
92
- ...config,
93
- system,
94
- messages,
95
- tools: responseFormat.type === "text" ? tools : [{
96
- name: responseFormat.objectName,
97
- description: Tool.getDescriptionFromSchemaAst(responseFormat.schema.ast) ?? "Respond with a JSON object",
98
- input_schema: Tool.getJsonSchemaFromSchemaAst(responseFormat.schema.ast)
99
- }],
100
- tool_choice: responseFormat.type === "text" ? toolChoice : {
101
- type: "tool",
102
- name: responseFormat.objectName,
103
- disable_parallel_tool_use: true
104
- }
105
- };
106
- return {
107
- betas: new Set([...messageBetas, ...toolBetas]),
108
- request
109
- };
110
- });
111
- return yield* LanguageModel.make({
112
- generateText: Effect.fnUntraced(function* (options) {
113
- const {
114
- betas,
115
- request
116
- } = yield* makeRequest(options);
117
- annotateRequest(options.span, request);
118
- const anthropicBeta = betas.size > 0 ? Array.from(betas).join(",") : undefined;
119
- const rawResponse = yield* client.createMessage({
120
- params: {
121
- "anthropic-beta": anthropicBeta
122
- },
123
- payload: request
124
- });
125
- annotateResponse(options.span, rawResponse);
126
- return yield* makeResponse(rawResponse, options);
127
- }),
128
- streamText: Effect.fnUntraced(function* (options) {
129
- const {
130
- betas,
131
- request
132
- } = yield* makeRequest(options);
133
- annotateRequest(options.span, request);
134
- const anthropicBeta = betas.size > 0 ? Array.from(betas).join(",") : undefined;
135
- return client.createMessageStream({
136
- params: {
137
- "anthropic-beta": anthropicBeta
138
- },
139
- payload: request
140
- });
141
- }, (effect, options) => effect.pipe(Effect.flatMap(stream => makeStreamResponse(stream, options)), Stream.unwrap, Stream.map(response => {
142
- annotateStreamResponse(options.span, response);
143
- return response;
144
- })))
145
- });
146
- });
147
- /**
148
- * @since 1.0.0
149
- * @category Layers
150
- */
151
- const layer = options => Layer.effect(LanguageModel.LanguageModel, make({
152
- model: options.model,
153
- config: options.config
154
- }));
155
- /**
156
- * @since 1.0.0
157
- * @category Layers
158
- */
159
- exports.layer = layer;
160
- const layerWithTokenizer = options => Layer.merge(layer(options), AnthropicTokenizer.layer);
161
- /**
162
- * @since 1.0.0
163
- * @category Configuration
164
- */
165
- exports.layerWithTokenizer = layerWithTokenizer;
166
- const withConfigOverride = exports.withConfigOverride = /*#__PURE__*/(0, _Function.dual)(2, (self, overrides) => Effect.flatMap(Config.getOrUndefined, config => Effect.provideService(self, Config, {
167
- ...config,
168
- ...overrides
169
- })));
170
- // =============================================================================
171
- // Prompt Conversion
172
- // =============================================================================
173
- const prepareMessages = /*#__PURE__*/Effect.fnUntraced(function* (options) {
174
- const betas = new Set();
175
- const groups = groupMessages(options.prompt);
176
- let system = undefined;
177
- const messages = [];
178
- for (let i = 0; i < groups.length; i++) {
179
- const group = groups[i];
180
- const isLastGroup = i === groups.length - 1;
181
- switch (group.type) {
182
- case "system":
183
- {
184
- system = group.messages.map(message => ({
185
- type: "text",
186
- text: message.content,
187
- cache_control: getCacheControl(message)
188
- }));
189
- break;
190
- }
191
- case "user":
192
- {
193
- const content = [];
194
- for (const message of group.messages) {
195
- switch (message.role) {
196
- case "user":
197
- {
198
- for (let j = 0; j < message.content.length; j++) {
199
- const part = message.content[j];
200
- const isLastPart = j === message.content.length - 1;
201
- // Attempt to get the cache control from the part first. If
202
- // the part does not have cache control defined and we are
203
- // evaluating the last part for this message, also check the
204
- // message for cache control.
205
- const cacheControl = getCacheControl(part) ?? (isLastPart ? getCacheControl(message) : undefined);
206
- switch (part.type) {
207
- case "text":
208
- {
209
- content.push({
210
- type: "text",
211
- text: part.text,
212
- cache_control: cacheControl
213
- });
214
- break;
215
- }
216
- case "file":
217
- {
218
- if (part.mediaType.startsWith("image/")) {
219
- const source = part.data instanceof URL ? {
220
- type: "url",
221
- url: part.data.toString()
222
- } : {
223
- type: "base64",
224
- media_type: part.mediaType === "image/*" ? "image/jpeg" : part.mediaType,
225
- data: typeof part.data === "string" ? part.data : Encoding.encodeBase64(part.data)
226
- };
227
- content.push({
228
- type: "image",
229
- source,
230
- cache_control: cacheControl
231
- });
232
- } else if (part.mediaType === "application/pdf" || part.mediaType === "text/plain") {
233
- if (part.mediaType === "application/pdf") {
234
- betas.add("pdfs-2024-09-25");
235
- }
236
- const enableCitations = shouldEnableCitations(part);
237
- const documentOptions = getDocumentMetadata(part);
238
- const source = part.data instanceof URL ? {
239
- type: "url",
240
- url: part.data.toString()
241
- } : part.mediaType === "application/pdf" ? {
242
- type: "base64",
243
- media_type: "application/pdf",
244
- data: typeof part.data === "string" ? part.data : Encoding.encodeBase64(part.data)
245
- } : {
246
- type: "text",
247
- media_type: "text/plain",
248
- data: typeof part.data === "string" ? part.data : Encoding.encodeBase64(part.data)
249
- };
250
- content.push({
251
- type: "document",
252
- source,
253
- title: documentOptions?.title ?? part.fileName,
254
- ...(documentOptions?.context ? {
255
- context: documentOptions.context
256
- } : undefined),
257
- ...(enableCitations ? {
258
- citations: {
259
- enabled: true
260
- }
261
- } : undefined),
262
- cache_control: cacheControl
263
- });
264
- } else {
265
- return yield* new AiError.MalformedInput({
266
- module: "AnthropicLanguageModel",
267
- method: "prepareMessages",
268
- description: `Detected unsupported media type for file: '${part.mediaType}'`
269
- });
270
- }
271
- break;
272
- }
273
- }
274
- }
275
- break;
276
- }
277
- // TODO: advanced tool result content parts
278
- case "tool":
279
- {
280
- for (let j = 0; j < message.content.length; j++) {
281
- const part = message.content[j];
282
- const isLastPart = j === message.content.length - 1;
283
- // Attempt to get the cache control from the part first. If
284
- // the part does not have cache control defined and we are
285
- // evaluating the last part for this message, also check the
286
- // message for cache control.
287
- const cacheControl = getCacheControl(part) ?? (isLastPart ? getCacheControl(message) : undefined);
288
- content.push({
289
- type: "tool_result",
290
- tool_use_id: part.id,
291
- content: JSON.stringify(part.result),
292
- is_error: part.isFailure,
293
- cache_control: cacheControl
294
- });
295
- }
296
- break;
297
- }
298
- }
299
- }
300
- messages.push({
301
- role: "user",
302
- content
303
- });
304
- break;
305
- }
306
- case "assistant":
307
- {
308
- const content = [];
309
- for (let j = 0; j < group.messages.length; j++) {
310
- const message = group.messages[j];
311
- const isLastMessage = j === group.messages.length - 1;
312
- for (let k = 0; k < message.content.length; k++) {
313
- const part = message.content[k];
314
- const isLastPart = k === message.content.length - 1;
315
- // Attempt to get the cache control from the part first. If
316
- // the part does not have cache control defined and we are
317
- // evaluating the last part for this message, also check the
318
- // message for cache control.
319
- const cacheControl = getCacheControl(part) ?? (isLastPart ? getCacheControl(message) : undefined);
320
- switch (part.type) {
321
- case "text":
322
- {
323
- content.push({
324
- type: "text",
325
- // Anthropic does not allow trailing whitespace in assistant
326
- // content blocks
327
- text: isLastGroup && isLastMessage && isLastPart ? part.text.trim() : part.text
328
- });
329
- break;
330
- }
331
- case "reasoning":
332
- {
333
- const options = part.options.anthropic;
334
- if (Predicate.isNotUndefined(options)) {
335
- if (options.type === "thinking") {
336
- content.push({
337
- type: "thinking",
338
- thinking: part.text,
339
- signature: options.signature
340
- });
341
- } else {
342
- content.push({
343
- type: "redacted_thinking",
344
- data: options.redactedData
345
- });
346
- }
347
- }
348
- break;
349
- }
350
- case "tool-call":
351
- {
352
- if (part.providerExecuted) {
353
- if (part.name === "AnthropicCodeExecution") {
354
- content.push({
355
- type: "server_tool_use",
356
- id: part.id,
357
- name: "code_execution",
358
- input: part.params,
359
- cache_control: cacheControl
360
- });
361
- }
362
- if (part.name === "AnthropicWebSearch") {
363
- content.push({
364
- type: "server_tool_use",
365
- id: part.id,
366
- name: "web_search",
367
- input: part.params,
368
- cache_control: cacheControl
369
- });
370
- }
371
- } else {
372
- content.push({
373
- type: "tool_use",
374
- id: part.id,
375
- name: part.name,
376
- input: part.params,
377
- cache_control: cacheControl
378
- });
379
- }
380
- break;
381
- }
382
- case "tool-result":
383
- {
384
- if (part.name === "AnthropicCodeExecution") {
385
- content.push({
386
- type: "code_execution_tool_result",
387
- tool_use_id: part.id,
388
- content: part.result,
389
- cache_control: cacheControl
390
- });
391
- } else if (part.name === "AnthropicWebSearch") {
392
- content.push({
393
- type: "web_search_tool_result",
394
- tool_use_id: part.id,
395
- content: part.result,
396
- cache_control: cacheControl
397
- });
398
- } else {
399
- return yield* new AiError.MalformedInput({
400
- module: "AnthropicLanguageModel",
401
- method: "prepareMessages",
402
- description: `Provider executed tool result for tool ${part.name} is not supported in prompt`
403
- });
404
- }
405
- }
406
- }
407
- }
408
- }
409
- messages.push({
410
- role: "assistant",
411
- content
412
- });
413
- break;
414
- }
415
- }
416
- }
417
- return {
418
- system,
419
- messages,
420
- betas
421
- };
422
- });
423
- // =============================================================================
424
- // Response Conversion
425
- // =============================================================================
426
- const makeResponse = /*#__PURE__*/Effect.fnUntraced(function* (response, options) {
427
- const idGenerator = yield* IdGenerator.IdGenerator;
428
- const parts = [];
429
- const citableDocuments = extractCitableDocuments(options.prompt);
430
- parts.push({
431
- type: "response-metadata",
432
- id: response.id,
433
- modelId: response.model,
434
- timestamp: DateTime.formatIso(yield* DateTime.now)
435
- });
436
- for (const part of response.content) {
437
- switch (part.type) {
438
- case "text":
439
- {
440
- // The text parts should only be added to the response here if the
441
- // response format is `"text"`. If the response format is `"json"`,
442
- // then the text parts must instead be added to the response when a
443
- // tool call is received.
444
- if (options.responseFormat.type === "text") {
445
- parts.push({
446
- type: "text",
447
- text: part.text
448
- });
449
- if (Predicate.isNotNullable(part.citations)) {
450
- for (const citation of part.citations) {
451
- const source = yield* processCitation(citation, citableDocuments, idGenerator);
452
- if (Predicate.isNotUndefined(source)) {
453
- parts.push(source);
454
- }
455
- }
456
- }
457
- }
458
- break;
459
- }
460
- case "thinking":
461
- {
462
- parts.push({
463
- type: "reasoning",
464
- text: part.thinking,
465
- metadata: {
466
- anthropic: {
467
- type: "thinking",
468
- signature: part.signature
469
- }
470
- }
471
- });
472
- break;
473
- }
474
- case "redacted_thinking":
475
- {
476
- parts.push({
477
- type: "reasoning",
478
- text: "",
479
- metadata: {
480
- anthropic: {
481
- type: "redacted_thinking",
482
- redactedData: part.data
483
- }
484
- }
485
- });
486
- break;
487
- }
488
- case "tool_use":
489
- {
490
- // When a `"json"` response format is requested, the JSON that we need
491
- // will be returned by the tool call injected into the request
492
- if (options.responseFormat.type === "json") {
493
- parts.push({
494
- type: "text",
495
- text: JSON.stringify(part.input)
496
- });
497
- } else {
498
- const providerTool = AnthropicTool.getProviderDefinedToolName(part.name);
499
- const name = Predicate.isNotUndefined(providerTool) ? providerTool : part.name;
500
- const providerName = Predicate.isNotUndefined(providerTool) ? part.name : undefined;
501
- parts.push({
502
- type: "tool-call",
503
- id: part.id,
504
- name,
505
- params: part.input,
506
- providerName,
507
- providerExecuted: false
508
- });
509
- }
510
- break;
511
- }
512
- case "server_tool_use":
513
- {
514
- const providerTool = AnthropicTool.getProviderDefinedToolName(part.name);
515
- if (Predicate.isNotUndefined(providerTool)) {
516
- parts.push({
517
- type: "tool-call",
518
- id: part.id,
519
- name: providerTool,
520
- params: part.input,
521
- providerName: part.name,
522
- providerExecuted: true
523
- });
524
- }
525
- break;
526
- }
527
- case "bash_code_execution_tool_result":
528
- {
529
- const isFailure = part.content.type === "bash_code_execution_tool_result_error";
530
- parts.push({
531
- type: "tool-result",
532
- id: part.tool_use_id,
533
- name: "AnthropicCodeExecution",
534
- isFailure,
535
- result: part.content,
536
- providerName: "code_execution",
537
- providerExecuted: true
538
- });
539
- break;
540
- }
541
- case "code_execution_tool_result":
542
- {
543
- const isFailure = part.content.type === "code_execution_tool_result_error";
544
- parts.push({
545
- type: "tool-result",
546
- id: part.tool_use_id,
547
- name: "AnthropicCodeExecution",
548
- isFailure,
549
- result: part.content,
550
- providerName: "code_execution",
551
- providerExecuted: true
552
- });
553
- break;
554
- }
555
- case "text_editor_code_execution_tool_result":
556
- {
557
- const isFailure = part.content.type === "text_editor_code_execution_tool_result_error";
558
- parts.push({
559
- type: "tool-result",
560
- id: part.tool_use_id,
561
- name: "AnthropicCodeExecution",
562
- isFailure,
563
- result: part.content,
564
- providerName: "code_execution",
565
- providerExecuted: true
566
- });
567
- break;
568
- }
569
- case "web_search_tool_result":
570
- {
571
- const isFailure = !Array.isArray(part.content);
572
- parts.push({
573
- type: "tool-result",
574
- id: part.tool_use_id,
575
- name: "AnthropicWebSearch",
576
- isFailure,
577
- result: part.content,
578
- providerName: "web_search",
579
- providerExecuted: true
580
- });
581
- break;
582
- }
583
- }
584
- }
585
- // Anthropic always returns a non-null `stop_reason` for non-streaming responses
586
- const finishReason = InternalUtilities.resolveFinishReason(response.stop_reason, options.responseFormat.type === "json");
587
- parts.push({
588
- type: "finish",
589
- reason: finishReason,
590
- usage: {
591
- inputTokens: response.usage.input_tokens,
592
- outputTokens: response.usage.output_tokens,
593
- totalTokens: response.usage.input_tokens + response.usage.output_tokens,
594
- cachedInputTokens: response.usage.cache_read_input_tokens ?? undefined
595
- },
596
- metadata: {
597
- anthropic: {
598
- usage: response.usage,
599
- stopSequence: response.stop_sequence ?? undefined
600
- }
601
- }
602
- });
603
- return parts;
604
- });
605
- const makeStreamResponse = /*#__PURE__*/Effect.fnUntraced(function* (stream, options) {
606
- const idGenerator = yield* IdGenerator.IdGenerator;
607
- const citableDocuments = extractCitableDocuments(options.prompt);
608
- // Setup all requisite state for the streaming response
609
- let finishReason = "unknown";
610
- const contentBlocks = {};
611
- let blockType = undefined;
612
- const usage = {
613
- inputTokens: undefined,
614
- outputTokens: undefined,
615
- totalTokens: undefined
616
- };
617
- let metaUsage = undefined;
618
- let stopSequence = undefined;
619
- return stream.pipe(Stream.mapEffect(Effect.fnUntraced(function* (event) {
620
- const parts = [];
621
- switch (event.type) {
622
- case "ping":
623
- {
624
- break;
625
- }
626
- case "message_start":
627
- {
628
- // Track usage metadata
629
- usage.inputTokens = event.message.usage.input_tokens;
630
- metaUsage = event.message.usage;
631
- // Track response metadata
632
- parts.push({
633
- type: "response-metadata",
634
- id: event.message.id,
635
- modelId: event.message.model,
636
- timestamp: DateTime.formatIso(yield* DateTime.now)
637
- });
638
- break;
639
- }
640
- case "message_delta":
641
- {
642
- // Track usage metadata
643
- if (Predicate.isNotNullable(event.usage.output_tokens)) {
644
- usage.outputTokens = event.usage.output_tokens;
645
- }
646
- usage.totalTokens = (usage.inputTokens ?? 0) + (event.usage.output_tokens ?? 0);
647
- // Track stop sequence metadata
648
- if (Predicate.isNotNullable(event.delta.stop_sequence)) {
649
- stopSequence = event.delta.stop_sequence;
650
- }
651
- // Track the response finish reason
652
- if (Predicate.isNotNullable(event.delta.stop_reason)) {
653
- finishReason = InternalUtilities.resolveFinishReason(event.delta.stop_reason);
654
- }
655
- break;
656
- }
657
- case "message_stop":
658
- {
659
- parts.push({
660
- type: "finish",
661
- reason: finishReason,
662
- usage,
663
- metadata: {
664
- anthropic: {
665
- usage: metaUsage,
666
- stopSequence
667
- }
668
- }
669
- });
670
- break;
671
- }
672
- case "content_block_start":
673
- {
674
- blockType = event.content_block.type;
675
- switch (event.content_block.type) {
676
- case "text":
677
- {
678
- contentBlocks[event.index] = {
679
- type: "text"
680
- };
681
- parts.push({
682
- type: "text-start",
683
- id: event.index.toString()
684
- });
685
- break;
686
- }
687
- case "thinking":
688
- {
689
- contentBlocks[event.index] = {
690
- type: "reasoning"
691
- };
692
- parts.push({
693
- type: "reasoning-start",
694
- id: event.index.toString()
695
- });
696
- break;
697
- }
698
- case "redacted_thinking":
699
- {
700
- contentBlocks[event.index] = {
701
- type: "reasoning"
702
- };
703
- parts.push({
704
- type: "reasoning-start",
705
- id: event.index.toString(),
706
- metadata: {
707
- anthropic: {
708
- type: "redacted_thinking",
709
- redactedData: event.content_block.data
710
- }
711
- }
712
- });
713
- break;
714
- }
715
- case "tool_use":
716
- {
717
- const toolName = event.content_block.name;
718
- const providerTool = AnthropicTool.getProviderDefinedToolName(toolName);
719
- const name = Predicate.isNotUndefined(providerTool) ? providerTool : toolName;
720
- const providerName = Predicate.isNotUndefined(providerTool) ? toolName : undefined;
721
- contentBlocks[event.index] = {
722
- type: "tool-call",
723
- id: event.content_block.id,
724
- name,
725
- params: "",
726
- providerName,
727
- providerExecuted: false
728
- };
729
- parts.push({
730
- type: "tool-params-start",
731
- id: event.content_block.id,
732
- name: toolName,
733
- providerName,
734
- providerExecuted: false
735
- });
736
- break;
737
- }
738
- case "server_tool_use":
739
- {
740
- const toolName = event.content_block.name;
741
- const providerTool = AnthropicTool.getProviderDefinedToolName(toolName);
742
- if (Predicate.isNotUndefined(providerTool)) {
743
- contentBlocks[event.index] = {
744
- type: "tool-call",
745
- id: event.content_block.id,
746
- name: providerTool,
747
- params: "",
748
- providerName: toolName,
749
- providerExecuted: true
750
- };
751
- parts.push({
752
- type: "tool-params-start",
753
- id: event.content_block.id,
754
- name: providerTool,
755
- providerName: toolName,
756
- providerExecuted: true
757
- });
758
- }
759
- break;
760
- }
761
- case "bash_code_execution_tool_result":
762
- {
763
- const toolUseId = event.content_block.tool_use_id;
764
- const content = event.content_block.content;
765
- const isFailure = content.type === "bash_code_execution_tool_result_error";
766
- parts.push({
767
- type: "tool-result",
768
- id: toolUseId,
769
- name: "AnthropicCodeExecution",
770
- isFailure,
771
- result: content,
772
- providerName: "code_execution",
773
- providerExecuted: true
774
- });
775
- break;
776
- }
777
- case "code_execution_tool_result":
778
- {
779
- const toolUseId = event.content_block.tool_use_id;
780
- const content = event.content_block.content;
781
- const isFailure = content.type === "code_execution_tool_result_error";
782
- parts.push({
783
- type: "tool-result",
784
- id: toolUseId,
785
- name: "AnthropicCodeExecution",
786
- isFailure,
787
- result: content,
788
- providerName: "code_execution",
789
- providerExecuted: true
790
- });
791
- break;
792
- }
793
- case "text_editor_code_execution_tool_result":
794
- {
795
- const toolUseId = event.content_block.tool_use_id;
796
- const content = event.content_block.content;
797
- const isFailure = content.type === "text_editor_code_execution_tool_result_error";
798
- parts.push({
799
- type: "tool-result",
800
- id: toolUseId,
801
- name: "AnthropicCodeExecution",
802
- isFailure,
803
- result: content,
804
- providerName: "code_execution",
805
- providerExecuted: true
806
- });
807
- break;
808
- }
809
- case "web_search_tool_result":
810
- {
811
- const toolUseId = event.content_block.tool_use_id;
812
- const content = event.content_block.content;
813
- const isFailure = !Array.isArray(content);
814
- parts.push({
815
- type: "tool-result",
816
- id: toolUseId,
817
- name: "AnthropicWebSearch",
818
- isFailure,
819
- result: content,
820
- providerName: "web_search",
821
- providerExecuted: true
822
- });
823
- break;
824
- }
825
- }
826
- break;
827
- }
828
- case "content_block_delta":
829
- {
830
- switch (event.delta.type) {
831
- case "text_delta":
832
- {
833
- parts.push({
834
- type: "text-delta",
835
- id: event.index.toString(),
836
- delta: event.delta.text
837
- });
838
- break;
839
- }
840
- case "thinking_delta":
841
- {
842
- parts.push({
843
- type: "reasoning-delta",
844
- id: event.index.toString(),
845
- delta: event.delta.thinking
846
- });
847
- break;
848
- }
849
- case "signature_delta":
850
- {
851
- if (blockType === "thinking") {
852
- parts.push({
853
- type: "reasoning-delta",
854
- id: event.index.toString(),
855
- delta: "",
856
- metadata: {
857
- anthropic: {
858
- type: "thinking",
859
- signature: event.delta.signature
860
- }
861
- }
862
- });
863
- }
864
- break;
865
- }
866
- case "input_json_delta":
867
- {
868
- const contentBlock = contentBlocks[event.index];
869
- const delta = event.delta.partial_json;
870
- if (contentBlock.type === "tool-call") {
871
- parts.push({
872
- type: "tool-params-delta",
873
- id: contentBlock.id,
874
- delta
875
- });
876
- contentBlock.params += delta;
877
- }
878
- break;
879
- }
880
- case "citations_delta":
881
- {
882
- const citation = event.delta.citation;
883
- const source = yield* processCitation(citation, citableDocuments, idGenerator);
884
- if (Predicate.isNotUndefined(source)) {
885
- parts.push(source);
886
- }
887
- }
888
- }
889
- break;
890
- }
891
- case "content_block_stop":
892
- {
893
- if (Predicate.isNotNullable(contentBlocks[event.index])) {
894
- const contentBlock = contentBlocks[event.index];
895
- switch (contentBlock.type) {
896
- case "text":
897
- {
898
- parts.push({
899
- type: "text-end",
900
- id: event.index.toString()
901
- });
902
- break;
903
- }
904
- case "reasoning":
905
- {
906
- parts.push({
907
- type: "reasoning-end",
908
- id: event.index.toString()
909
- });
910
- break;
911
- }
912
- case "tool-call":
913
- {
914
- parts.push({
915
- type: "tool-params-end",
916
- id: contentBlock.id
917
- });
918
- const toolName = contentBlock.name;
919
- // If the tool call has no parameters, an empty string is returned
920
- const toolParams = contentBlock.params.length === 0 ? "{}" : contentBlock.params;
921
- const parsedParams = yield* Effect.try({
922
- try: () => Tool.unsafeSecureJsonParse(toolParams),
923
- catch: cause => new AiError.MalformedOutput({
924
- module: "AnthropicLanguageModel",
925
- method: "makeStreamResponse",
926
- description: "Failed to securely parse tool call parameters " + `for tool '${toolName}':\nParameters: ${toolParams}`,
927
- cause
928
- })
929
- });
930
- parts.push({
931
- type: "tool-call",
932
- id: contentBlock.id,
933
- name: toolName,
934
- params: parsedParams,
935
- providerName: contentBlock.providerName,
936
- providerExecuted: contentBlock.providerExecuted
937
- });
938
- break;
939
- }
940
- }
941
- delete contentBlocks[event.index];
942
- }
943
- blockType = undefined;
944
- break;
945
- }
946
- case "error":
947
- {
948
- parts.push({
949
- type: "error",
950
- error: event.error
951
- });
952
- break;
953
- }
954
- }
955
- return parts;
956
- })), Stream.flattenIterables);
957
- });
958
- // =============================================================================
959
- // Telemetry
960
- // =============================================================================
961
- const annotateRequest = (span, request) => {
962
- (0, _Telemetry.addGenAIAnnotations)(span, {
963
- system: "anthropic",
964
- operation: {
965
- name: "chat"
966
- },
967
- request: {
968
- model: request.model,
969
- temperature: request.temperature,
970
- topK: request.top_k,
971
- topP: request.top_p,
972
- maxTokens: request.max_tokens,
973
- stopSequences: Arr.ensure(request.stop_sequences).filter(Predicate.isNotNullable)
974
- }
975
- });
976
- };
977
- const annotateResponse = (span, response) => {
978
- (0, _Telemetry.addGenAIAnnotations)(span, {
979
- response: {
980
- id: response.id,
981
- model: response.model,
982
- finishReasons: response.stop_reason ? [response.stop_reason] : undefined
983
- },
984
- usage: {
985
- inputTokens: response.usage.input_tokens,
986
- outputTokens: response.usage.output_tokens
987
- }
988
- });
989
- };
990
- const annotateStreamResponse = (span, part) => {
991
- if (part.type === "response-metadata") {
992
- (0, _Telemetry.addGenAIAnnotations)(span, {
993
- response: {
994
- id: part.id,
995
- model: part.modelId
996
- }
997
- });
998
- }
999
- if (part.type === "finish") {
1000
- (0, _Telemetry.addGenAIAnnotations)(span, {
1001
- response: {
1002
- finishReasons: [part.reason]
1003
- },
1004
- usage: {
1005
- inputTokens: part.usage.inputTokens,
1006
- outputTokens: part.usage.outputTokens
1007
- }
1008
- });
1009
- }
1010
- };
1011
- /**
1012
- * A helper method which takes in large language model provider options from
1013
- * the base Effect AI SDK as well as Anthropic request configuration options
1014
- * and returns the prepared tools, tool choice, and Anthropic betas to include
1015
- * in a request.
1016
- *
1017
- * This method is primarily exposed for use by other Effect provider
1018
- * integrations which can utilize Anthropic models (i.e. Amazon Bedrock).
1019
- *
1020
- * @since 1.0.0
1021
- * @category Tool Calling
1022
- */
1023
- const prepareTools = exports.prepareTools = /*#__PURE__*/Effect.fnUntraced(function* (options, config) {
1024
- // Return immediately if no tools are in the toolkit or a tool choice of
1025
- // "none" was specified
1026
- if (options.tools.length === 0 || options.toolChoice === "none") {
1027
- return {
1028
- betas: new Set(),
1029
- tools: undefined,
1030
- toolChoice: undefined
1031
- };
1032
- }
1033
- const betas = new Set();
1034
- let tools = [];
1035
- let toolChoice = undefined;
1036
- // Convert the tools in the toolkit to the provider-defined format
1037
- for (const tool of options.tools) {
1038
- if (Tool.isUserDefined(tool)) {
1039
- tools.push({
1040
- name: tool.name,
1041
- description: Tool.getDescription(tool),
1042
- input_schema: Tool.getJsonSchema(tool)
1043
- });
1044
- }
1045
- if (Tool.isProviderDefined(tool)) {
1046
- switch (tool.id) {
1047
- case "anthropic.bash_20241022":
1048
- {
1049
- betas.add("computer-use-2024-10-22");
1050
- tools.push({
1051
- name: "bash",
1052
- type: "bash_20241022"
1053
- });
1054
- break;
1055
- }
1056
- case "anthropic.bash_20250124":
1057
- {
1058
- betas.add("computer-use-2025-01-24");
1059
- tools.push({
1060
- name: "bash",
1061
- type: "bash_20250124"
1062
- });
1063
- break;
1064
- }
1065
- case "anthropic.code_execution_20250522":
1066
- {
1067
- betas.add("code-execution-2025-05-22");
1068
- tools.push({
1069
- ...tool.args,
1070
- name: "code_execution",
1071
- type: "code_execution_2025522"
1072
- });
1073
- break;
1074
- }
1075
- case "anthropic.code_execution_20250825":
1076
- {
1077
- betas.add("code-execution-2025-08-25");
1078
- tools.push({
1079
- ...tool.args,
1080
- name: "code_execution",
1081
- type: "code_execution_20250825"
1082
- });
1083
- break;
1084
- }
1085
- case "anthropic.computer_use_20241022":
1086
- {
1087
- betas.add("computer-use-2025-10-22");
1088
- tools.push({
1089
- ...tool.args,
1090
- name: "computer",
1091
- type: "computer_20241022"
1092
- });
1093
- break;
1094
- }
1095
- case "anthropic.computer_use_20250124":
1096
- {
1097
- betas.add("computer-use-2025-01-24");
1098
- tools.push({
1099
- ...tool.args,
1100
- name: "computer",
1101
- type: "computer_20250124"
1102
- });
1103
- break;
1104
- }
1105
- case "anthropic.text_editor_20241022":
1106
- {
1107
- betas.add("computer-use-2024-10-22");
1108
- tools.push({
1109
- name: "str_replace_editor",
1110
- type: "text_editor_20241022"
1111
- });
1112
- break;
1113
- }
1114
- case "anthropic.text_editor_20250124":
1115
- {
1116
- betas.add("computer-use-2025-01-24");
1117
- tools.push({
1118
- name: "str_replace_editor",
1119
- type: "text_editor_20250124"
1120
- });
1121
- break;
1122
- }
1123
- case "anthropic.text_editor_20250429":
1124
- {
1125
- betas.add("computer-use-2025-01-24");
1126
- tools.push({
1127
- name: "str_replace_based_edit_tool",
1128
- type: "text_editor_20250429"
1129
- });
1130
- break;
1131
- }
1132
- case "anthropic.text_editor_20250728":
1133
- {
1134
- tools.push({
1135
- name: "str_replace_based_edit_tool",
1136
- type: "text_editor_20250728"
1137
- });
1138
- break;
1139
- }
1140
- case "anthropic.web_search_20250305":
1141
- {
1142
- tools.push({
1143
- ...tool.args,
1144
- name: "web_search",
1145
- type: "web_search_20250305"
1146
- });
1147
- break;
1148
- }
1149
- default:
1150
- {
1151
- return yield* new AiError.MalformedInput({
1152
- module: "AnthropicLanguageModel",
1153
- method: "prepareTools",
1154
- description: `Received request to call unknown provider-defined tool '${tool.name}'`
1155
- });
1156
- }
1157
- }
1158
- }
1159
- }
1160
- // Convert the tool choice to the provider-defined format
1161
- if (options.toolChoice === "auto") {
1162
- toolChoice = {
1163
- type: "auto",
1164
- disable_parallel_tool_use: config.disableParallelToolCalls
1165
- };
1166
- } else if (options.toolChoice === "required") {
1167
- toolChoice = {
1168
- type: "any",
1169
- disable_parallel_tool_use: config.disableParallelToolCalls
1170
- };
1171
- } else if ("tool" in options.toolChoice) {
1172
- toolChoice = {
1173
- type: "tool",
1174
- name: options.toolChoice.tool,
1175
- disable_parallel_tool_use: config.disableParallelToolCalls
1176
- };
1177
- } else {
1178
- const allowedTools = new Set(options.toolChoice.oneOf);
1179
- tools = tools.filter(tool => allowedTools.has(tool.name));
1180
- toolChoice = {
1181
- type: options.toolChoice.mode === "required" ? "any" : "auto",
1182
- disable_parallel_tool_use: config.disableParallelToolCalls
1183
- };
1184
- }
1185
- return {
1186
- betas,
1187
- tools,
1188
- toolChoice
1189
- };
1190
- });
1191
- const groupMessages = prompt => {
1192
- const messages = [];
1193
- let current = undefined;
1194
- for (const message of prompt.content) {
1195
- switch (message.role) {
1196
- case "system":
1197
- {
1198
- if (current?.type !== "system") {
1199
- current = {
1200
- type: "system",
1201
- messages: []
1202
- };
1203
- messages.push(current);
1204
- }
1205
- current.messages.push(message);
1206
- break;
1207
- }
1208
- case "assistant":
1209
- {
1210
- if (current?.type !== "assistant") {
1211
- current = {
1212
- type: "assistant",
1213
- messages: []
1214
- };
1215
- messages.push(current);
1216
- }
1217
- current.messages.push(message);
1218
- break;
1219
- }
1220
- case "tool":
1221
- case "user":
1222
- {
1223
- if (current?.type !== "user") {
1224
- current = {
1225
- type: "user",
1226
- messages: []
1227
- };
1228
- messages.push(current);
1229
- }
1230
- current.messages.push(message);
1231
- break;
1232
- }
1233
- }
1234
- }
1235
- return messages;
1236
- };
1237
- const isCitationPart = part => {
1238
- if (part.type === "file" && (part.mediaType === "application/pdf" || part.mediaType === "text/plain")) {
1239
- return part.options.anthropic?.citations?.enabled ?? false;
1240
- }
1241
- return false;
1242
- };
1243
- const extractCitableDocuments = prompt => {
1244
- const citableDocuments = [];
1245
- for (const message of prompt.content) {
1246
- if (message.role === "user") {
1247
- for (const part of message.content) {
1248
- if (isCitationPart(part)) {
1249
- citableDocuments.push({
1250
- title: part.fileName ?? "Untitled Document",
1251
- fileName: part.fileName,
1252
- mediaType: part.mediaType
1253
- });
1254
- }
1255
- }
1256
- }
1257
- }
1258
- return citableDocuments;
1259
- };
1260
- const getCacheControl = part => part.options.anthropic?.cacheControl;
1261
- const getDocumentMetadata = part => {
1262
- const options = part.options.anthropic;
1263
- if (Predicate.isNotUndefined(options)) {
1264
- return {
1265
- title: options.documentTitle,
1266
- context: options.documentContext
1267
- };
1268
- }
1269
- return undefined;
1270
- };
1271
- const shouldEnableCitations = part => part.options.anthropic?.citations?.enabled ?? false;
1272
- const processCitation = /*#__PURE__*/Effect.fnUntraced(function* (citation, citableDocuments, idGenerator) {
1273
- if (citation.type === "page_location" || citation.type === "char_location") {
1274
- const citedDocument = citableDocuments[citation.document_index];
1275
- if (Predicate.isNotUndefined(citedDocument)) {
1276
- const id = yield* idGenerator.generateId();
1277
- const metadata = citation.type === "char_location" ? {
1278
- source: "document",
1279
- type: citation.type,
1280
- citedText: citation.cited_text,
1281
- startCharIndex: citation.start_char_index,
1282
- endCharIndex: citation.end_char_index
1283
- } : {
1284
- source: "document",
1285
- type: citation.type,
1286
- citedText: citation.cited_text,
1287
- startPageNumber: citation.start_page_number,
1288
- endPageNumber: citation.end_page_number
1289
- };
1290
- return {
1291
- type: "source",
1292
- sourceType: "document",
1293
- id,
1294
- mediaType: citedDocument.mediaType,
1295
- title: citation.document_title ?? citedDocument.title,
1296
- fileName: citedDocument.fileName,
1297
- metadata: {
1298
- anthropic: metadata
1299
- }
1300
- };
1301
- }
1302
- }
1303
- if (citation.type === "web_search_result_location") {
1304
- const id = yield* idGenerator.generateId();
1305
- const metadata = {
1306
- source: "url",
1307
- citedText: citation.cited_text,
1308
- encryptedIndex: citation.encrypted_index
1309
- };
1310
- return {
1311
- type: "source",
1312
- sourceType: "url",
1313
- id,
1314
- url: citation.url,
1315
- title: citation.title ?? "Untitled",
1316
- metadata: {
1317
- anthropic: metadata
1318
- }
1319
- };
1320
- }
1321
- });
1322
- //# sourceMappingURL=AnthropicLanguageModel.js.map