@yourgpt/llm-sdk 2.6.0-beta.2 → 2.6.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.
- package/LICENSE +21 -0
- package/README.md +87 -17
- package/dist/adapters/index.d.mts +11 -13
- package/dist/adapters/index.d.ts +11 -13
- package/dist/adapters/index.js +406 -114
- package/dist/adapters/index.mjs +406 -114
- package/dist/audio-K-Z3-Bce.d.mts +191 -0
- package/dist/audio-K-Z3-Bce.d.ts +191 -0
- package/dist/{base-BICaQaRS.d.mts → base-6LzczuCg.d.ts} +8 -1
- package/dist/{base-CpRPB8u8.d.ts → base-DySbTP8C.d.mts} +8 -1
- package/dist/decisions-CJzOt87t.d.mts +137 -0
- package/dist/decisions-CJzOt87t.d.ts +137 -0
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/http-BQxUT5A9.d.mts +9 -0
- package/dist/http-BQxUT5A9.d.ts +9 -0
- package/dist/index.d.mts +17 -9
- package/dist/index.d.ts +17 -9
- package/dist/index.js +698 -205
- package/dist/index.mjs +695 -206
- package/dist/providers/anthropic/index.d.mts +7 -4
- package/dist/providers/anthropic/index.d.ts +7 -4
- package/dist/providers/anthropic/index.js +389 -115
- package/dist/providers/anthropic/index.mjs +389 -115
- package/dist/providers/azure/index.d.mts +3 -3
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/cloudflare/index.d.mts +11 -0
- package/dist/providers/cloudflare/index.d.ts +11 -0
- package/dist/providers/cloudflare/index.js +743 -0
- package/dist/providers/cloudflare/index.mjs +741 -0
- package/dist/providers/fireworks/index.d.mts +3 -3
- package/dist/providers/fireworks/index.d.ts +3 -3
- package/dist/providers/fireworks/index.js +181 -60
- package/dist/providers/fireworks/index.mjs +181 -60
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +181 -60
- package/dist/providers/google/index.mjs +181 -60
- package/dist/providers/ollama/index.d.mts +4 -4
- package/dist/providers/ollama/index.d.ts +4 -4
- package/dist/providers/openai/index.d.mts +38 -6
- package/dist/providers/openai/index.d.ts +38 -6
- package/dist/providers/openai/index.js +1451 -85
- package/dist/providers/openai/index.mjs +1449 -86
- package/dist/providers/openrouter/index.d.mts +21 -4
- package/dist/providers/openrouter/index.d.ts +21 -4
- package/dist/providers/openrouter/index.js +1040 -131
- package/dist/providers/openrouter/index.mjs +1040 -132
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +181 -60
- package/dist/providers/togetherai/index.mjs +181 -60
- package/dist/providers/typesafe/index.d.mts +8 -0
- package/dist/providers/typesafe/index.d.ts +8 -0
- package/dist/providers/typesafe/index.js +735 -0
- package/dist/providers/typesafe/index.mjs +733 -0
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +181 -60
- package/dist/providers/xai/index.mjs +181 -60
- package/dist/{types-DCFqkJAy.d.ts → types-B0y6VZSQ.d.ts} +1 -1
- package/dist/{types-DHQEMFHA.d.mts → types-BXQMtaCX.d.ts} +17 -3
- package/dist/{types-C3RgRbEC.d.mts → types-BY6BVhFg.d.mts} +1 -1
- package/dist/{types-Dikj3En4.d.ts → types-C7_qVSSd.d.mts} +17 -3
- package/dist/{types-Dg1Bcg1k.d.mts → types-D7lzMMLu.d.mts} +13 -1
- package/dist/{types-Dg1Bcg1k.d.ts → types-D7lzMMLu.d.ts} +13 -1
- package/dist/yourgpt/index.d.mts +1 -1
- package/dist/yourgpt/index.d.ts +1 -1
- package/docs/decisions.md +174 -0
- package/docs/media.md +201 -0
- package/docs/multimodal-and-audio.md +9 -2
- package/package.json +34 -12
- package/dist/audio-BBSwnjo8.d.mts +0 -92
- package/dist/audio-BBSwnjo8.d.ts +0 -92
package/dist/adapters/index.mjs
CHANGED
|
@@ -101,6 +101,63 @@ function textToolOutput(value, fallback) {
|
|
|
101
101
|
return toolOutputForProvider(value, "unsupported").map((part) => part.text).join("\n");
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
// src/core/anthropic-replay.ts
|
|
105
|
+
function anthropicReplay(content) {
|
|
106
|
+
if (!Array.isArray(content) || !content.some(
|
|
107
|
+
(b) => b?.type === "thinking" || b?.type === "redacted_thinking"
|
|
108
|
+
))
|
|
109
|
+
return void 0;
|
|
110
|
+
const blocks = content.flatMap((block) => {
|
|
111
|
+
if (block?.type === "thinking" && typeof block.thinking === "string" && typeof block.signature === "string")
|
|
112
|
+
return [
|
|
113
|
+
{
|
|
114
|
+
type: "thinking",
|
|
115
|
+
thinking: block.thinking,
|
|
116
|
+
signature: block.signature
|
|
117
|
+
}
|
|
118
|
+
];
|
|
119
|
+
if (block?.type === "redacted_thinking" && typeof block.data === "string")
|
|
120
|
+
return [{ type: "redacted_thinking", data: block.data }];
|
|
121
|
+
if (block?.type === "text" && typeof block.text === "string")
|
|
122
|
+
return [{ type: "text", text: block.text }];
|
|
123
|
+
if (block?.type === "tool_use" && typeof block.id === "string" && typeof block.name === "string")
|
|
124
|
+
return [
|
|
125
|
+
{
|
|
126
|
+
type: "tool_use",
|
|
127
|
+
id: block.id,
|
|
128
|
+
name: block.name,
|
|
129
|
+
input: block.input
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
return [];
|
|
133
|
+
});
|
|
134
|
+
return { anthropic: { content: blocks } };
|
|
135
|
+
}
|
|
136
|
+
function anthropicReplayContent(metadata) {
|
|
137
|
+
const state = metadata?.anthropic;
|
|
138
|
+
return anthropicReplay(state?.content)?.anthropic?.content;
|
|
139
|
+
}
|
|
140
|
+
function collectAnthropicContent(blocks, event) {
|
|
141
|
+
if (event.type === "content_block_start")
|
|
142
|
+
blocks[event.index] = { ...event.content_block };
|
|
143
|
+
const block = blocks[event.index];
|
|
144
|
+
if (event.type !== "content_block_delta" || !block) return;
|
|
145
|
+
const delta = event.delta;
|
|
146
|
+
if (delta.type === "thinking_delta")
|
|
147
|
+
block.thinking = (block.thinking ?? "") + delta.thinking;
|
|
148
|
+
else if (delta.type === "signature_delta")
|
|
149
|
+
block.signature = (block.signature ?? "") + delta.signature;
|
|
150
|
+
else if (delta.type === "text_delta")
|
|
151
|
+
block.text = (block.text ?? "") + delta.text;
|
|
152
|
+
else if (delta.type === "input_json_delta") {
|
|
153
|
+
block.partialInput = (block.partialInput ?? "") + delta.partial_json;
|
|
154
|
+
try {
|
|
155
|
+
block.input = JSON.parse(block.partialInput);
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
104
161
|
// src/core/openai-parameters.ts
|
|
105
162
|
function capabilities(model) {
|
|
106
163
|
const gpt = /^gpt-(\d+)(?:\.(\d+))?(?:-(.+))?$/i.exec(model);
|
|
@@ -111,6 +168,19 @@ function capabilities(model) {
|
|
|
111
168
|
const supportsNone = major === 5 && minor >= 1 && !chat || /^gpt-6-(?:sol|luna)(?:-\d{4}-\d{2}-\d{2})?$/i.test(model);
|
|
112
169
|
return { major, minor, reasoning, supportsNone };
|
|
113
170
|
}
|
|
171
|
+
function filterOpenAIResponseInclude(model, include, options = {}) {
|
|
172
|
+
const c = capabilities(model);
|
|
173
|
+
let result = include;
|
|
174
|
+
if (options.parameterPolicy !== "passthrough" && c.reasoning && !(options.reasoningEffort === "none" && c.supportsNone) && include.includes("message.output_text.logprobs")) {
|
|
175
|
+
result = include.filter(
|
|
176
|
+
(value) => value !== "message.output_text.logprobs"
|
|
177
|
+
);
|
|
178
|
+
(options.onWarning ?? console.warn)(
|
|
179
|
+
`[llm-sdk] ${model}: omitted message.output_text.logprobs because reasoning is enabled.`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
return result.length ? result : void 0;
|
|
183
|
+
}
|
|
114
184
|
function requiresOpenAIResponses(model, baseUrl, options = {}) {
|
|
115
185
|
if (options.parameterPolicy === "passthrough") return false;
|
|
116
186
|
const c = capabilities(model);
|
|
@@ -282,7 +352,22 @@ function stripSchemaKeys(schema, keysToDrop, options = {}) {
|
|
|
282
352
|
)) {
|
|
283
353
|
if (keysToDrop.has(key)) continue;
|
|
284
354
|
const renamed = options.renameKeys?.[key] ?? key;
|
|
285
|
-
|
|
355
|
+
if ([
|
|
356
|
+
"properties",
|
|
357
|
+
"$defs",
|
|
358
|
+
"definitions",
|
|
359
|
+
"patternProperties",
|
|
360
|
+
"dependentSchemas"
|
|
361
|
+
].includes(key) && value && typeof value === "object" && !Array.isArray(value)) {
|
|
362
|
+
out[renamed] = Object.fromEntries(
|
|
363
|
+
Object.entries(value).map(([name, child]) => [
|
|
364
|
+
name,
|
|
365
|
+
stripSchemaKeys(child, keysToDrop, options)
|
|
366
|
+
])
|
|
367
|
+
);
|
|
368
|
+
} else if (["enum", "const", "default", "examples"].includes(key)) {
|
|
369
|
+
out[renamed] = value;
|
|
370
|
+
} else out[renamed] = stripSchemaKeys(value, keysToDrop, options);
|
|
286
371
|
}
|
|
287
372
|
if (options.forceAdditionalPropertiesFalse && out.type === "object") {
|
|
288
373
|
out.additionalProperties = false;
|
|
@@ -303,6 +388,7 @@ function toOpenAIResponseFormat(rf) {
|
|
|
303
388
|
};
|
|
304
389
|
}
|
|
305
390
|
function toOpenAIResponsesTextFormat(rf) {
|
|
391
|
+
if (rf?.type === "json_object") return { type: "json_object" };
|
|
306
392
|
if (!rf || rf.type !== "json_schema") return void 0;
|
|
307
393
|
return {
|
|
308
394
|
type: "json_schema",
|
|
@@ -524,21 +610,14 @@ function messageToOpenAIContent(message) {
|
|
|
524
610
|
return blocks;
|
|
525
611
|
}
|
|
526
612
|
function extractAnthropicSystemPrompt(messages, systemPrompt) {
|
|
527
|
-
const
|
|
613
|
+
const explicit = typeof systemPrompt === "string" ? systemPrompt : "";
|
|
614
|
+
const parts = explicit ? [explicit] : [];
|
|
528
615
|
for (const message of messages) {
|
|
529
616
|
if (message.role !== "system") continue;
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
if (block?.type !== "text" || typeof block.text !== "string") {
|
|
535
|
-
throw new TypeError("Anthropic system messages must contain text.");
|
|
536
|
-
}
|
|
537
|
-
if (block.text) parts.push(block.text);
|
|
538
|
-
}
|
|
539
|
-
} else {
|
|
540
|
-
throw new TypeError("Anthropic system messages must contain text.");
|
|
541
|
-
}
|
|
617
|
+
const text = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content.filter(
|
|
618
|
+
(block) => block?.type === "text" && typeof block.text === "string"
|
|
619
|
+
).map((block) => block.text).filter(Boolean).join("\n") : "";
|
|
620
|
+
if (text && text !== explicit) parts.push(text);
|
|
542
621
|
}
|
|
543
622
|
return parts.join("\n");
|
|
544
623
|
}
|
|
@@ -549,6 +628,14 @@ function formatMessagesForAnthropic(messages, systemPrompt) {
|
|
|
549
628
|
const msg = messages[i];
|
|
550
629
|
if (msg.role === "system") continue;
|
|
551
630
|
if (msg.role === "assistant") {
|
|
631
|
+
const replay = anthropicReplayContent(msg.providerMetadata);
|
|
632
|
+
if (replay) {
|
|
633
|
+
formatted.push({
|
|
634
|
+
role: "assistant",
|
|
635
|
+
content: replay
|
|
636
|
+
});
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
552
639
|
const content = [];
|
|
553
640
|
if (msg.content) {
|
|
554
641
|
content.push({ type: "text", text: msg.content });
|
|
@@ -639,6 +726,63 @@ function formatMessagesForOpenAI(messages, systemPrompt, preserveProviderMetadat
|
|
|
639
726
|
return formatted;
|
|
640
727
|
}
|
|
641
728
|
|
|
729
|
+
// src/core/provider-error.ts
|
|
730
|
+
function invalidProviderResponse(message) {
|
|
731
|
+
return Object.assign(new Error(message), {
|
|
732
|
+
name: "InvalidProviderResponseError",
|
|
733
|
+
status: 502,
|
|
734
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
function providerErrorEvent(error, code) {
|
|
738
|
+
const details = error ?? {};
|
|
739
|
+
const event = {
|
|
740
|
+
type: "error",
|
|
741
|
+
message: error instanceof Error ? error.message : String(error),
|
|
742
|
+
code,
|
|
743
|
+
...typeof details.status === "number" ? { status: details.status } : {},
|
|
744
|
+
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
745
|
+
...typeof details.param === "string" ? { param: details.param } : {},
|
|
746
|
+
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
747
|
+
};
|
|
748
|
+
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
749
|
+
return event;
|
|
750
|
+
}
|
|
751
|
+
function throwIfAborted(signal) {
|
|
752
|
+
if (!signal?.aborted) return;
|
|
753
|
+
const error = new Error("The operation was aborted");
|
|
754
|
+
error.name = "AbortError";
|
|
755
|
+
throw error;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// src/core/tool-validation.ts
|
|
759
|
+
function parseToolArguments(value) {
|
|
760
|
+
let args = value;
|
|
761
|
+
if (typeof value === "string") {
|
|
762
|
+
try {
|
|
763
|
+
args = JSON.parse(value || "{}");
|
|
764
|
+
} catch {
|
|
765
|
+
throw invalidProviderResponse("Tool arguments are not valid JSON");
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
if (args === null || typeof args !== "object" || Array.isArray(args))
|
|
769
|
+
throw invalidProviderResponse("Tool arguments must be a JSON object");
|
|
770
|
+
return args;
|
|
771
|
+
}
|
|
772
|
+
function validateToolCalls(calls) {
|
|
773
|
+
const ids = /* @__PURE__ */ new Set();
|
|
774
|
+
for (const call of calls) {
|
|
775
|
+
if (!call || typeof call.id !== "string" || !call.id || typeof call.name !== "string" || !call.name || ids.has(call.id))
|
|
776
|
+
throw invalidProviderResponse(
|
|
777
|
+
"Tool calls have missing or duplicate identities"
|
|
778
|
+
);
|
|
779
|
+
ids.add(call.id);
|
|
780
|
+
if (typeof call.args === "string")
|
|
781
|
+
throw invalidProviderResponse("Parsed tool arguments must be an object");
|
|
782
|
+
parseToolArguments(call.args);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
642
786
|
// src/core/openai-responses.ts
|
|
643
787
|
function resolveOpenAITransport(defaults, overrides) {
|
|
644
788
|
return {
|
|
@@ -686,6 +830,54 @@ function responseMetadata(response) {
|
|
|
686
830
|
}
|
|
687
831
|
};
|
|
688
832
|
}
|
|
833
|
+
function responseReplayMetadata(metadata) {
|
|
834
|
+
const response = metadata?.openai?.response;
|
|
835
|
+
if (!response) return metadata;
|
|
836
|
+
const output = response.output.map((item) => {
|
|
837
|
+
const fields = ["type", "id", "status"];
|
|
838
|
+
switch (item.type) {
|
|
839
|
+
case "reasoning":
|
|
840
|
+
fields.push("encrypted_content");
|
|
841
|
+
break;
|
|
842
|
+
case "message":
|
|
843
|
+
fields.push("role", "phase");
|
|
844
|
+
break;
|
|
845
|
+
case "function_call":
|
|
846
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
847
|
+
break;
|
|
848
|
+
case "tool_search_call":
|
|
849
|
+
fields.push("call_id", "execution", "arguments");
|
|
850
|
+
break;
|
|
851
|
+
case "tool_search_output":
|
|
852
|
+
fields.push("call_id", "tools");
|
|
853
|
+
break;
|
|
854
|
+
case "web_search_call":
|
|
855
|
+
fields.push("action");
|
|
856
|
+
break;
|
|
857
|
+
default:
|
|
858
|
+
return stripItemDiagnostics(item);
|
|
859
|
+
}
|
|
860
|
+
const replay = Object.fromEntries(
|
|
861
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
862
|
+
);
|
|
863
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
864
|
+
if (item.type === "message")
|
|
865
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
866
|
+
(part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
|
|
867
|
+
) : [];
|
|
868
|
+
return stripItemDiagnostics(replay);
|
|
869
|
+
});
|
|
870
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
871
|
+
}
|
|
872
|
+
function stripItemDiagnostics(item) {
|
|
873
|
+
const {
|
|
874
|
+
usage: _usage,
|
|
875
|
+
logprobs: _logprobs,
|
|
876
|
+
metadata: _metadata,
|
|
877
|
+
...state
|
|
878
|
+
} = item;
|
|
879
|
+
return state;
|
|
880
|
+
}
|
|
689
881
|
function getResponseReplay(metadata) {
|
|
690
882
|
const response = metadata?.openai?.response;
|
|
691
883
|
if (response === void 0) return void 0;
|
|
@@ -694,29 +886,7 @@ function getResponseReplay(metadata) {
|
|
|
694
886
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
695
887
|
);
|
|
696
888
|
}
|
|
697
|
-
return response
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// src/core/provider-error.ts
|
|
701
|
-
function providerErrorEvent(error, code) {
|
|
702
|
-
const details = error ?? {};
|
|
703
|
-
const event = {
|
|
704
|
-
type: "error",
|
|
705
|
-
message: error instanceof Error ? error.message : String(error),
|
|
706
|
-
code,
|
|
707
|
-
...typeof details.status === "number" ? { status: details.status } : {},
|
|
708
|
-
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
709
|
-
...typeof details.param === "string" ? { param: details.param } : {},
|
|
710
|
-
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
711
|
-
};
|
|
712
|
-
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
713
|
-
return event;
|
|
714
|
-
}
|
|
715
|
-
function throwIfAborted(signal) {
|
|
716
|
-
if (!signal?.aborted) return;
|
|
717
|
-
const error = new Error("The operation was aborted");
|
|
718
|
-
error.name = "AbortError";
|
|
719
|
-
throw error;
|
|
889
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
720
890
|
}
|
|
721
891
|
|
|
722
892
|
// src/core/utils.ts
|
|
@@ -752,6 +922,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
752
922
|
apiKey: this.config.apiKey,
|
|
753
923
|
baseURL: this.config.baseUrl,
|
|
754
924
|
organization: this.config.organization,
|
|
925
|
+
project: this.config.project,
|
|
926
|
+
timeout: this.config.timeout,
|
|
755
927
|
defaultHeaders: this.config.headers
|
|
756
928
|
});
|
|
757
929
|
}
|
|
@@ -874,7 +1046,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
874
1046
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
875
1047
|
return messages.map((message) => {
|
|
876
1048
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
877
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
1049
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
878
1050
|
if (preserveProviderMetadata && modelOutput)
|
|
879
1051
|
rest.modelOutput = modelOutput;
|
|
880
1052
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -977,17 +1149,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
977
1149
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
978
1150
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
979
1151
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
980
|
-
throw
|
|
1152
|
+
throw invalidProviderResponse(
|
|
1153
|
+
"Responses contains an incomplete function call"
|
|
1154
|
+
);
|
|
981
1155
|
}
|
|
982
1156
|
if (seenCallIds.has(item.call_id))
|
|
983
|
-
throw
|
|
1157
|
+
throw invalidProviderResponse(
|
|
1158
|
+
"Responses contains duplicate function call IDs"
|
|
1159
|
+
);
|
|
984
1160
|
seenCallIds.add(item.call_id);
|
|
985
|
-
|
|
1161
|
+
let args;
|
|
1162
|
+
try {
|
|
1163
|
+
args = JSON.parse(item.arguments);
|
|
1164
|
+
} catch {
|
|
1165
|
+
throw invalidProviderResponse(
|
|
1166
|
+
"Responses function arguments must be valid JSON"
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
986
1169
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
987
|
-
throw
|
|
1170
|
+
throw invalidProviderResponse(
|
|
988
1171
|
"Responses function arguments must be a JSON object"
|
|
989
1172
|
);
|
|
990
|
-
return {
|
|
1173
|
+
return {
|
|
1174
|
+
id: item.call_id,
|
|
1175
|
+
name: item.name,
|
|
1176
|
+
args
|
|
1177
|
+
};
|
|
991
1178
|
}) : [];
|
|
992
1179
|
return {
|
|
993
1180
|
content,
|
|
@@ -1018,6 +1205,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1018
1205
|
request.config?.responseFormat
|
|
1019
1206
|
);
|
|
1020
1207
|
const modelIdForPayload = request.config?.model || this.model;
|
|
1208
|
+
const include = filterOpenAIResponseInclude(
|
|
1209
|
+
modelIdForPayload,
|
|
1210
|
+
[
|
|
1211
|
+
.../* @__PURE__ */ new Set([
|
|
1212
|
+
...options?.include ?? [],
|
|
1213
|
+
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
1214
|
+
])
|
|
1215
|
+
],
|
|
1216
|
+
this.parameterOptions(request)
|
|
1217
|
+
);
|
|
1021
1218
|
const payload = {
|
|
1022
1219
|
model: modelIdForPayload,
|
|
1023
1220
|
instructions: request.systemPrompt,
|
|
@@ -1041,14 +1238,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1041
1238
|
...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
|
|
1042
1239
|
...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
|
|
1043
1240
|
...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
|
|
1044
|
-
...
|
|
1045
|
-
include: [
|
|
1046
|
-
.../* @__PURE__ */ new Set([
|
|
1047
|
-
...options?.include ?? [],
|
|
1048
|
-
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
1049
|
-
])
|
|
1050
|
-
]
|
|
1051
|
-
} : {},
|
|
1241
|
+
...include ? { include } : {},
|
|
1052
1242
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
1053
1243
|
stream
|
|
1054
1244
|
};
|
|
@@ -1230,7 +1420,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1230
1420
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1231
1421
|
for (const call of toolCalls.values()) {
|
|
1232
1422
|
if (!call.id || !call.name)
|
|
1233
|
-
throw
|
|
1423
|
+
throw invalidProviderResponse(
|
|
1424
|
+
"Responses stream contains an incomplete tool call"
|
|
1425
|
+
);
|
|
1234
1426
|
uniqueCalls.set(call.id, call);
|
|
1235
1427
|
}
|
|
1236
1428
|
toolCalls.clear();
|
|
@@ -1417,15 +1609,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1417
1609
|
}
|
|
1418
1610
|
throwIfAborted(request.signal);
|
|
1419
1611
|
if (!finishReason)
|
|
1420
|
-
throw
|
|
1612
|
+
throw invalidProviderResponse(
|
|
1613
|
+
"OpenAI stream ended without a finish reason"
|
|
1614
|
+
);
|
|
1421
1615
|
if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
|
|
1422
|
-
throw
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
if (!call.id || !call.name)
|
|
1426
|
-
throw new Error("OpenAI stream contains an incomplete tool call");
|
|
1427
|
-
JSON.parse(call.arguments || "{}");
|
|
1616
|
+
throw invalidProviderResponse(
|
|
1617
|
+
"OpenAI stream ended with incomplete tool calls"
|
|
1618
|
+
);
|
|
1428
1619
|
}
|
|
1620
|
+
validateToolCalls(
|
|
1621
|
+
[...toolCalls.values()].map((call) => ({
|
|
1622
|
+
...call,
|
|
1623
|
+
args: parseToolArguments(call.arguments)
|
|
1624
|
+
}))
|
|
1625
|
+
);
|
|
1429
1626
|
for (const call of toolCalls.values()) {
|
|
1430
1627
|
yield {
|
|
1431
1628
|
type: "action:start",
|
|
@@ -1509,20 +1706,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1509
1706
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
1510
1707
|
const choice = response.choices?.[0];
|
|
1511
1708
|
const message = choice?.message;
|
|
1709
|
+
const toolCalls = (message?.tool_calls ?? []).map((toolCall) => ({
|
|
1710
|
+
id: toolCall.id,
|
|
1711
|
+
name: toolCall.function?.name,
|
|
1712
|
+
args: parseToolArguments(toolCall.function?.arguments ?? "{}"),
|
|
1713
|
+
...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
|
|
1714
|
+
}));
|
|
1715
|
+
validateToolCalls(toolCalls);
|
|
1716
|
+
if (toolCalls.length && choice?.finish_reason && !["tool_calls", "function_call"].includes(choice.finish_reason))
|
|
1717
|
+
throw invalidProviderResponse(
|
|
1718
|
+
"OpenAI response ended with incomplete tool calls"
|
|
1719
|
+
);
|
|
1512
1720
|
return {
|
|
1513
1721
|
content: message?.content ?? "",
|
|
1514
|
-
toolCalls
|
|
1515
|
-
id: toolCall.id ?? generateToolCallId(),
|
|
1516
|
-
name: toolCall.function?.name ?? "",
|
|
1517
|
-
args: (() => {
|
|
1518
|
-
try {
|
|
1519
|
-
return JSON.parse(toolCall.function?.arguments ?? "{}");
|
|
1520
|
-
} catch {
|
|
1521
|
-
return {};
|
|
1522
|
-
}
|
|
1523
|
-
})(),
|
|
1524
|
-
...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
|
|
1525
|
-
})) ?? [],
|
|
1722
|
+
toolCalls,
|
|
1526
1723
|
usage: response.usage ? {
|
|
1527
1724
|
promptTokens: response.usage.prompt_tokens,
|
|
1528
1725
|
completionTokens: response.usage.completion_tokens,
|
|
@@ -1555,6 +1752,52 @@ function createOpenAIAdapter(config) {
|
|
|
1555
1752
|
return new OpenAIAdapter(config);
|
|
1556
1753
|
}
|
|
1557
1754
|
|
|
1755
|
+
// src/core/anthropic-parameters.ts
|
|
1756
|
+
function anthropicMaxTokens(maxTokens, thinking) {
|
|
1757
|
+
return maxTokens ?? Math.max(4096, Number(thinking?.budget_tokens ?? 0) + 1);
|
|
1758
|
+
}
|
|
1759
|
+
function anthropicModelRules(model) {
|
|
1760
|
+
const match = /^claude-(opus|sonnet|haiku)-(\d+)(?:-(\d{1,2})(?=-|$))?(?:-|$)/i.exec(
|
|
1761
|
+
model
|
|
1762
|
+
);
|
|
1763
|
+
const family = match?.[1]?.toLowerCase();
|
|
1764
|
+
const major = Number(match?.[2] ?? 0);
|
|
1765
|
+
const minor = Number(match?.[3] ?? 0);
|
|
1766
|
+
const adaptive = major >= 5 || major === 4 && minor >= 6;
|
|
1767
|
+
return {
|
|
1768
|
+
structured: major >= 5 || major === 4 && minor >= 5,
|
|
1769
|
+
thinking: major >= 4 || /^claude-3-7-/.test(model),
|
|
1770
|
+
adaptive,
|
|
1771
|
+
rejectsSampling: major >= 5 || family === "opus" && major === 4 && minor >= 7
|
|
1772
|
+
};
|
|
1773
|
+
}
|
|
1774
|
+
function anthropicInputTokens(usage) {
|
|
1775
|
+
return (usage?.input_tokens ?? 0) + (usage?.cache_creation_input_tokens ?? 0) + (usage?.cache_read_input_tokens ?? 0);
|
|
1776
|
+
}
|
|
1777
|
+
function anthropicThinking(model, thinking) {
|
|
1778
|
+
if (!thinking) return void 0;
|
|
1779
|
+
if (thinking.type === "enabled") {
|
|
1780
|
+
if (anthropicModelRules(model).adaptive) {
|
|
1781
|
+
console.warn(
|
|
1782
|
+
`[llm-sdk] ${model}: using adaptive thinking instead of a legacy token budget.`
|
|
1783
|
+
);
|
|
1784
|
+
return { type: "adaptive" };
|
|
1785
|
+
}
|
|
1786
|
+
return { type: "enabled", budget_tokens: thinking.budgetTokens ?? 1e4 };
|
|
1787
|
+
}
|
|
1788
|
+
return { ...thinking };
|
|
1789
|
+
}
|
|
1790
|
+
function anthropicTemperature(model, temperature, thinking = false) {
|
|
1791
|
+
if (temperature === void 0) return {};
|
|
1792
|
+
if (thinking || anthropicModelRules(model).rejectsSampling) {
|
|
1793
|
+
console.warn(
|
|
1794
|
+
`[llm-sdk] ${model}: omitted temperature because this model or thinking mode does not support it.`
|
|
1795
|
+
);
|
|
1796
|
+
return {};
|
|
1797
|
+
}
|
|
1798
|
+
return { temperature };
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1558
1801
|
// src/adapters/anthropic.ts
|
|
1559
1802
|
var AnthropicAdapter = class {
|
|
1560
1803
|
constructor(config) {
|
|
@@ -1566,7 +1809,10 @@ var AnthropicAdapter = class {
|
|
|
1566
1809
|
if (!this.client) {
|
|
1567
1810
|
const { default: Anthropic } = await import('@anthropic-ai/sdk');
|
|
1568
1811
|
this.client = new Anthropic({
|
|
1569
|
-
apiKey: this.config.apiKey
|
|
1812
|
+
apiKey: this.config.apiKey,
|
|
1813
|
+
baseURL: this.config.baseUrl,
|
|
1814
|
+
timeout: this.config.timeout,
|
|
1815
|
+
defaultHeaders: this.config.headers
|
|
1570
1816
|
});
|
|
1571
1817
|
}
|
|
1572
1818
|
return this.client;
|
|
@@ -1603,6 +1849,15 @@ var AnthropicAdapter = class {
|
|
|
1603
1849
|
lastToolCallIds = [];
|
|
1604
1850
|
toolResultIndex = 0;
|
|
1605
1851
|
}
|
|
1852
|
+
const replay = anthropicReplayContent(
|
|
1853
|
+
msg.providerMetadata
|
|
1854
|
+
);
|
|
1855
|
+
if (replay) {
|
|
1856
|
+
messages.push({ role: "assistant", content: replay });
|
|
1857
|
+
lastToolCallIds = replay.filter((b) => b.type === "tool_use").map((b) => b.id);
|
|
1858
|
+
toolResultIndex = 0;
|
|
1859
|
+
continue;
|
|
1860
|
+
}
|
|
1606
1861
|
const content = [];
|
|
1607
1862
|
if (msg.content && typeof msg.content === "string" && msg.content.trim()) {
|
|
1608
1863
|
content.push({ type: "text", text: msg.content });
|
|
@@ -1778,7 +2033,7 @@ var AnthropicAdapter = class {
|
|
|
1778
2033
|
*/
|
|
1779
2034
|
buildRequestOptions(request) {
|
|
1780
2035
|
const responseFormat = request.config?.responseFormat;
|
|
1781
|
-
const jsonObjectSuffix = responseFormat?.type === "json_object" ? "\n\nRespond with a single JSON object and no other text." : "";
|
|
2036
|
+
const jsonObjectSuffix = responseFormat?.type === "json_object" ? "\n\nRespond with a single JSON object and no other text. Do not include Markdown code fences." : "";
|
|
1782
2037
|
let systemMessage;
|
|
1783
2038
|
let messages;
|
|
1784
2039
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
@@ -1800,7 +2055,17 @@ var AnthropicAdapter = class {
|
|
|
1800
2055
|
const tools = anthropicNativeSearch?.enabled ? this.buildNativeSearchTools(
|
|
1801
2056
|
request.toolDefinitions ?? [],
|
|
1802
2057
|
anthropicNativeSearch.variant
|
|
1803
|
-
) : request.
|
|
2058
|
+
) : request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
2059
|
+
name: tool.name,
|
|
2060
|
+
description: tool.description,
|
|
2061
|
+
// Keep the original schema. Legacy ActionParameter conversion
|
|
2062
|
+
// cannot represent unions, null, or nested required constraints.
|
|
2063
|
+
input_schema: tool.inputSchema ?? {
|
|
2064
|
+
type: "object",
|
|
2065
|
+
properties: {},
|
|
2066
|
+
required: []
|
|
2067
|
+
}
|
|
2068
|
+
})) : request.actions?.map((action) => ({
|
|
1804
2069
|
name: action.name,
|
|
1805
2070
|
description: action.description,
|
|
1806
2071
|
input_schema: {
|
|
@@ -1842,12 +2107,25 @@ var AnthropicAdapter = class {
|
|
|
1842
2107
|
};
|
|
1843
2108
|
}
|
|
1844
2109
|
}
|
|
2110
|
+
const thinking = anthropicThinking(
|
|
2111
|
+
request.config?.model || this.model,
|
|
2112
|
+
this.config.thinking
|
|
2113
|
+
);
|
|
1845
2114
|
const options = {
|
|
1846
2115
|
model: request.config?.model || this.model,
|
|
1847
|
-
max_tokens:
|
|
2116
|
+
max_tokens: anthropicMaxTokens(
|
|
2117
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
2118
|
+
thinking
|
|
2119
|
+
),
|
|
1848
2120
|
system: systemMessage,
|
|
1849
2121
|
messages,
|
|
1850
|
-
tools: tools.length ? tools : void 0
|
|
2122
|
+
tools: tools.length ? tools : void 0,
|
|
2123
|
+
...this.config.cacheControl ? { cache_control: { type: "ephemeral" } } : {},
|
|
2124
|
+
...anthropicTemperature(
|
|
2125
|
+
request.config?.model || this.model,
|
|
2126
|
+
request.config?.temperature ?? this.config.temperature,
|
|
2127
|
+
!!this.config.thinking && this.config.thinking.type !== "disabled"
|
|
2128
|
+
)
|
|
1851
2129
|
};
|
|
1852
2130
|
const anthropicToolOptions = request.providerToolOptions?.anthropic;
|
|
1853
2131
|
if (tools.length > 0 && anthropicToolOptions) {
|
|
@@ -1866,15 +2144,13 @@ var AnthropicAdapter = class {
|
|
|
1866
2144
|
options.server_tool_configuration = serverToolConfiguration;
|
|
1867
2145
|
}
|
|
1868
2146
|
const outputConfig = toAnthropicOutputConfig(responseFormat);
|
|
1869
|
-
if (outputConfig) {
|
|
1870
|
-
options.output_config =
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
options.thinking = {
|
|
1874
|
-
type: "enabled",
|
|
1875
|
-
budget_tokens: this.config.thinking.budgetTokens || 1e4
|
|
2147
|
+
if (outputConfig || this.config.effort) {
|
|
2148
|
+
options.output_config = {
|
|
2149
|
+
...outputConfig,
|
|
2150
|
+
...this.config.effort ? { effort: this.config.effort } : {}
|
|
1876
2151
|
};
|
|
1877
2152
|
}
|
|
2153
|
+
if (thinking) options.thinking = thinking;
|
|
1878
2154
|
return { options, messages };
|
|
1879
2155
|
}
|
|
1880
2156
|
/**
|
|
@@ -1894,7 +2170,9 @@ var AnthropicAdapter = class {
|
|
|
1894
2170
|
nonStreamingOptions,
|
|
1895
2171
|
request.debug
|
|
1896
2172
|
);
|
|
1897
|
-
const response = await client.messages.create(nonStreamingOptions
|
|
2173
|
+
const response = await client.messages.create(nonStreamingOptions, {
|
|
2174
|
+
signal: request.signal
|
|
2175
|
+
});
|
|
1898
2176
|
logProviderPayload(
|
|
1899
2177
|
"anthropic",
|
|
1900
2178
|
"response payload",
|
|
@@ -1917,14 +2195,20 @@ var AnthropicAdapter = class {
|
|
|
1917
2195
|
});
|
|
1918
2196
|
}
|
|
1919
2197
|
}
|
|
2198
|
+
validateToolCalls(toolCalls);
|
|
2199
|
+
if (toolCalls.length && response.stop_reason !== "tool_use")
|
|
2200
|
+
throw invalidProviderResponse(
|
|
2201
|
+
"Anthropic response ended with incomplete tool calls"
|
|
2202
|
+
);
|
|
1920
2203
|
return {
|
|
1921
2204
|
content,
|
|
2205
|
+
providerMetadata: anthropicReplay(response.content),
|
|
1922
2206
|
toolCalls,
|
|
1923
2207
|
thinking: thinking || void 0,
|
|
1924
2208
|
usage: response.usage ? {
|
|
1925
|
-
promptTokens: response.usage
|
|
2209
|
+
promptTokens: anthropicInputTokens(response.usage),
|
|
1926
2210
|
completionTokens: response.usage.output_tokens ?? 0,
|
|
1927
|
-
totalTokens: (response.usage
|
|
2211
|
+
totalTokens: anthropicInputTokens(response.usage) + (response.usage.output_tokens ?? 0)
|
|
1928
2212
|
} : void 0,
|
|
1929
2213
|
rawResponse: response
|
|
1930
2214
|
};
|
|
@@ -1944,28 +2228,33 @@ var AnthropicAdapter = class {
|
|
|
1944
2228
|
options,
|
|
1945
2229
|
request.debug
|
|
1946
2230
|
);
|
|
1947
|
-
const stream = await client.messages.stream(options
|
|
2231
|
+
const stream = await client.messages.stream(options, {
|
|
2232
|
+
signal: request.signal
|
|
2233
|
+
});
|
|
1948
2234
|
let currentToolUse = null;
|
|
1949
2235
|
let isInThinkingBlock = false;
|
|
2236
|
+
const content = [];
|
|
2237
|
+
const toolCalls = [];
|
|
2238
|
+
let stopReason;
|
|
1950
2239
|
const collectedCitations = [];
|
|
1951
2240
|
let citationIndex = 0;
|
|
1952
2241
|
let usage;
|
|
1953
2242
|
for await (const event of stream) {
|
|
2243
|
+
collectAnthropicContent(content, event);
|
|
1954
2244
|
logProviderPayload("anthropic", "stream event", event, request.debug);
|
|
1955
|
-
|
|
1956
|
-
break;
|
|
1957
|
-
}
|
|
2245
|
+
throwIfAborted(request.signal);
|
|
1958
2246
|
switch (event.type) {
|
|
1959
2247
|
case "message_start":
|
|
1960
2248
|
if (event.message?.usage) {
|
|
1961
2249
|
usage = {
|
|
1962
|
-
prompt_tokens: event.message.usage
|
|
2250
|
+
prompt_tokens: anthropicInputTokens(event.message.usage),
|
|
1963
2251
|
completion_tokens: 0,
|
|
1964
|
-
total_tokens: event.message.usage
|
|
2252
|
+
total_tokens: anthropicInputTokens(event.message.usage)
|
|
1965
2253
|
};
|
|
1966
2254
|
}
|
|
1967
2255
|
break;
|
|
1968
2256
|
case "message_delta":
|
|
2257
|
+
if (event.delta?.stop_reason) stopReason = event.delta.stop_reason;
|
|
1969
2258
|
if (event.usage && usage) {
|
|
1970
2259
|
usage.completion_tokens = event.usage.output_tokens;
|
|
1971
2260
|
usage.total_tokens = usage.prompt_tokens + event.usage.output_tokens;
|
|
@@ -1978,13 +2267,6 @@ var AnthropicAdapter = class {
|
|
|
1978
2267
|
name: event.content_block.name,
|
|
1979
2268
|
input: ""
|
|
1980
2269
|
};
|
|
1981
|
-
if (currentToolUse.name !== "web_search") {
|
|
1982
|
-
yield {
|
|
1983
|
-
type: "action:start",
|
|
1984
|
-
id: currentToolUse.id,
|
|
1985
|
-
name: currentToolUse.name
|
|
1986
|
-
};
|
|
1987
|
-
}
|
|
1988
2270
|
} else if (event.content_block.type === "web_search_tool_result") {
|
|
1989
2271
|
const webSearchResult = event.content_block;
|
|
1990
2272
|
if (webSearchResult.content && Array.isArray(webSearchResult.content)) {
|
|
@@ -2033,16 +2315,11 @@ var AnthropicAdapter = class {
|
|
|
2033
2315
|
case "content_block_stop":
|
|
2034
2316
|
if (currentToolUse) {
|
|
2035
2317
|
if (currentToolUse.name !== "web_search") {
|
|
2036
|
-
|
|
2037
|
-
type: "action:args",
|
|
2038
|
-
id: currentToolUse.id,
|
|
2039
|
-
args: currentToolUse.input
|
|
2040
|
-
};
|
|
2041
|
-
yield {
|
|
2042
|
-
type: "action:end",
|
|
2318
|
+
toolCalls.push({
|
|
2043
2319
|
id: currentToolUse.id,
|
|
2044
|
-
name: currentToolUse.name
|
|
2045
|
-
|
|
2320
|
+
name: currentToolUse.name,
|
|
2321
|
+
args: parseToolArguments(currentToolUse.input)
|
|
2322
|
+
});
|
|
2046
2323
|
}
|
|
2047
2324
|
currentToolUse = null;
|
|
2048
2325
|
}
|
|
@@ -2055,18 +2332,33 @@ var AnthropicAdapter = class {
|
|
|
2055
2332
|
break;
|
|
2056
2333
|
}
|
|
2057
2334
|
}
|
|
2335
|
+
throwIfAborted(request.signal);
|
|
2336
|
+
if (!stopReason || currentToolUse)
|
|
2337
|
+
throw invalidProviderResponse(
|
|
2338
|
+
"Anthropic stream ended before its turn completed"
|
|
2339
|
+
);
|
|
2340
|
+
validateToolCalls(toolCalls);
|
|
2341
|
+
if (toolCalls.length && stopReason !== "tool_use")
|
|
2342
|
+
throw invalidProviderResponse(
|
|
2343
|
+
"Anthropic stream ended with incomplete tool calls"
|
|
2344
|
+
);
|
|
2345
|
+
for (const call of toolCalls) {
|
|
2346
|
+
yield { type: "action:start", id: call.id, name: call.name };
|
|
2347
|
+
yield {
|
|
2348
|
+
type: "action:args",
|
|
2349
|
+
id: call.id,
|
|
2350
|
+
args: JSON.stringify(call.args)
|
|
2351
|
+
};
|
|
2352
|
+
yield { type: "action:end", id: call.id, name: call.name };
|
|
2353
|
+
}
|
|
2058
2354
|
if (collectedCitations.length > 0) {
|
|
2059
2355
|
const uniqueCitations = deduplicateCitations2(collectedCitations);
|
|
2060
2356
|
yield { type: "citation", citations: uniqueCitations };
|
|
2061
2357
|
}
|
|
2062
2358
|
yield { type: "message:end" };
|
|
2063
|
-
yield { type: "done", usage };
|
|
2359
|
+
yield { type: "done", usage, providerMetadata: anthropicReplay(content) };
|
|
2064
2360
|
} catch (error) {
|
|
2065
|
-
yield
|
|
2066
|
-
type: "error",
|
|
2067
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
2068
|
-
code: "ANTHROPIC_ERROR"
|
|
2069
|
-
};
|
|
2361
|
+
yield providerErrorEvent(error, "ANTHROPIC_ERROR");
|
|
2070
2362
|
}
|
|
2071
2363
|
}
|
|
2072
2364
|
};
|