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