@code-yeongyu/senpi-ai 2026.9.7 → 2026.9.9-2
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/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +70 -183
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/anthropic-tool-references.d.ts +3 -0
- package/dist/api/anthropic-tool-references.d.ts.map +1 -0
- package/dist/api/anthropic-tool-references.js +260 -0
- package/dist/api/anthropic-tool-references.js.map +1 -0
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +1 -0
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-images-edit.d.ts +4 -0
- package/dist/api/openai-images-edit.d.ts.map +1 -0
- package/dist/api/openai-images-edit.js +11 -0
- package/dist/api/openai-images-edit.js.map +1 -0
- package/dist/api/openai-images-params.d.ts +25 -0
- package/dist/api/openai-images-params.d.ts.map +1 -0
- package/dist/api/openai-images-params.js +58 -0
- package/dist/api/openai-images-params.js.map +1 -0
- package/dist/api/openai-images.d.ts +3 -6
- package/dist/api/openai-images.d.ts.map +1 -1
- package/dist/api/openai-images.js +15 -33
- package/dist/api/openai-images.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +1 -0
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/auth/oauth/anthropic-callback-listener.d.ts +40 -0
- package/dist/auth/oauth/anthropic-callback-listener.d.ts.map +1 -0
- package/dist/auth/oauth/anthropic-callback-listener.js +138 -0
- package/dist/auth/oauth/anthropic-callback-listener.js.map +1 -0
- package/dist/auth/oauth/anthropic.d.ts +2 -3
- package/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/dist/auth/oauth/anthropic.js +42 -139
- package/dist/auth/oauth/anthropic.js.map +1 -1
- package/dist/auth/oauth/authorization-input.d.ts +6 -0
- package/dist/auth/oauth/authorization-input.d.ts.map +1 -0
- package/dist/auth/oauth/authorization-input.js +29 -0
- package/dist/auth/oauth/authorization-input.js.map +1 -0
- package/dist/auth/oauth/error-details.d.ts +3 -0
- package/dist/auth/oauth/error-details.d.ts.map +1 -0
- package/dist/auth/oauth/error-details.js +20 -0
- package/dist/auth/oauth/error-details.js.map +1 -0
- package/dist/image-models.generated.d.ts +61 -1
- package/dist/image-models.generated.d.ts.map +1 -1
- package/dist/image-models.generated.js +61 -1
- package/dist/image-models.generated.js.map +1 -1
- package/dist/images.d.ts +1 -0
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +1 -0
- package/dist/images.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/azure-openai-responses.json +1 -1
- package/dist/providers/data/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/nvidia.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/opengateway.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/tool-call-middleware/recovery-stream-terminal.d.ts.map +1 -1
- package/dist/tool-call-middleware/recovery-stream-terminal.js +16 -1
- package/dist/tool-call-middleware/recovery-stream-terminal.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/overflow.d.ts +1 -1
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +14 -3
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/server-fallback-receipt.d.ts +2 -1
- package/dist/utils/server-fallback-receipt.d.ts.map +1 -1
- package/dist/utils/server-fallback-receipt.js +16 -0
- package/dist/utils/server-fallback-receipt.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAMX,+BAA+B,EAK/B,MAAM,uDAAuD,CAAC;AAG/D,OAAO,KAAK,EACX,wBAAwB,EAKxB,OAAO,EAGP,KAAK,EAGL,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAMX,+BAA+B,EAK/B,MAAM,uDAAuD,CAAC;AAG/D,OAAO,KAAK,EACX,wBAAwB,EAKxB,OAAO,EAGP,KAAK,EAGL,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;AAsCrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AA6JlE,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AA+FhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IAC5C;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AAmvBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CAudzE,CAAC;AAyFF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CA+ClF,CAAC;AA6IF,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACxB,+BAA+B,CAkBjC"}
|
|
@@ -15,12 +15,12 @@ import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
|
15
15
|
import { appendRetryAfterMsMarker, extract429RetryAfterMs } from "../utils/retry-hint.js";
|
|
16
16
|
import { normalizeAnthropicRetryFailure } from "../utils/retry-profile/failure.js";
|
|
17
17
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
18
|
-
import { applyServerFallbackAbort, parseServerFallbackReceipt, parseStickyFallbackReceipt, } from "../utils/server-fallback-receipt.js";
|
|
18
|
+
import { applyServerFallbackAbort, applyServerFallbackContinuation, parseServerFallbackReceipt, parseStickyFallbackReceipt, } from "../utils/server-fallback-receipt.js";
|
|
19
19
|
import { normalizeToolCallId } from "../utils/tool-call-id.js";
|
|
20
20
|
import { isForcedToolChoiceUnsupportedError, omitToolChoiceParam } from "../utils/tool-choice-fallback.js";
|
|
21
21
|
import { resolveRootObjectSchema } from "../utils/tool-schema-compat.js";
|
|
22
|
-
import { demotedToolCallText, demotedToolResultText } from "../utils/unavailable-tool-text.js";
|
|
23
22
|
import { sanitizeAnthropicToolPairs } from "./anthropic-tool-pairs.js";
|
|
23
|
+
import { demoteUnavailableToolReferences } from "./anthropic-tool-references.js";
|
|
24
24
|
import { resolveCloudflareBaseUrl } from "./cloudflare.js";
|
|
25
25
|
import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
|
|
26
26
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
@@ -571,157 +571,12 @@ function sanitizeUnsupportedNativeTools(model, params) {
|
|
|
571
571
|
}
|
|
572
572
|
return changed ? sanitized : params;
|
|
573
573
|
}
|
|
574
|
-
/**
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
* stop registering a tool, or a payload hook can strip a definition while the
|
|
581
|
-
* history still carries the call. Demote those references to plain text so
|
|
582
|
-
* the turn can proceed; the matching tool_result is demoted in lockstep so no
|
|
583
|
-
* orphan pairing error replaces the original one.
|
|
584
|
-
*/
|
|
585
|
-
function demoteUnavailableToolReferences(params) {
|
|
586
|
-
const messages = params.messages;
|
|
587
|
-
if (!Array.isArray(messages) || messages.length === 0)
|
|
588
|
-
return params;
|
|
589
|
-
const definedNames = new Set();
|
|
590
|
-
if (Array.isArray(params.tools)) {
|
|
591
|
-
for (const tool of params.tools) {
|
|
592
|
-
if (isRecord(tool) && typeof tool.name === "string")
|
|
593
|
-
definedNames.add(tool.name);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
// `tool_reference` blocks — emitted for deferred tools or replayed from a
|
|
597
|
-
// server-side tool search — make their targets available without a
|
|
598
|
-
// non-deferred definition.
|
|
599
|
-
const discoveredNames = new Set();
|
|
600
|
-
collectToolReferenceNames(messages, discoveredNames);
|
|
601
|
-
const demotedCallNames = new Map();
|
|
602
|
-
for (const message of messages) {
|
|
603
|
-
if (message.role !== "assistant" || !Array.isArray(message.content))
|
|
604
|
-
continue;
|
|
605
|
-
for (const block of message.content) {
|
|
606
|
-
if (isRecord(block) &&
|
|
607
|
-
block.type === "tool_use" &&
|
|
608
|
-
typeof block.name === "string" &&
|
|
609
|
-
!definedNames.has(block.name) &&
|
|
610
|
-
!discoveredNames.has(block.name)) {
|
|
611
|
-
demotedCallNames.set(block.id, block.name);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
// A `tool_reference` without its definition 400s the same way.
|
|
616
|
-
const danglingReferenceNames = new Set();
|
|
617
|
-
for (const name of discoveredNames) {
|
|
618
|
-
if (!definedNames.has(name))
|
|
619
|
-
danglingReferenceNames.add(name);
|
|
620
|
-
}
|
|
621
|
-
if (demotedCallNames.size === 0 && danglingReferenceNames.size === 0)
|
|
622
|
-
return params;
|
|
623
|
-
let changed = false;
|
|
624
|
-
const availableToolNames = [...definedNames];
|
|
625
|
-
const seenDemotedCallNames = new Set();
|
|
626
|
-
const rewrittenMessages = [];
|
|
627
|
-
for (const message of messages) {
|
|
628
|
-
if (!Array.isArray(message.content)) {
|
|
629
|
-
rewrittenMessages.push(message);
|
|
630
|
-
continue;
|
|
631
|
-
}
|
|
632
|
-
let messageChanged = false;
|
|
633
|
-
const content = [];
|
|
634
|
-
for (const block of message.content) {
|
|
635
|
-
if (message.role === "assistant" && isRecord(block) && block.type === "tool_use") {
|
|
636
|
-
const demotedName = demotedCallNames.get(block.id);
|
|
637
|
-
if (demotedName !== undefined) {
|
|
638
|
-
messageChanged = true;
|
|
639
|
-
const firstOccurrence = !seenDemotedCallNames.has(demotedName);
|
|
640
|
-
seenDemotedCallNames.add(demotedName);
|
|
641
|
-
content.push({
|
|
642
|
-
type: "text",
|
|
643
|
-
text: demotedToolCallText(demotedName, availableToolNames, firstOccurrence),
|
|
644
|
-
});
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
if (isRecord(block) && block.type === "tool_result") {
|
|
649
|
-
const demotedName = demotedCallNames.get(block.tool_use_id);
|
|
650
|
-
if (demotedName !== undefined) {
|
|
651
|
-
messageChanged = true;
|
|
652
|
-
content.push({ type: "text", text: demotedToolResultText(demotedName, toolResultText(block.content)) });
|
|
653
|
-
continue;
|
|
654
|
-
}
|
|
655
|
-
if (danglingReferenceNames.size > 0 && Array.isArray(block.content)) {
|
|
656
|
-
const kept = [];
|
|
657
|
-
const omitted = [];
|
|
658
|
-
for (const item of block.content) {
|
|
659
|
-
if (isRecord(item) &&
|
|
660
|
-
item.type === "tool_reference" &&
|
|
661
|
-
typeof item.tool_name === "string" &&
|
|
662
|
-
danglingReferenceNames.has(item.tool_name)) {
|
|
663
|
-
omitted.push(item.tool_name);
|
|
664
|
-
continue;
|
|
665
|
-
}
|
|
666
|
-
kept.push(item);
|
|
667
|
-
}
|
|
668
|
-
if (omitted.length > 0) {
|
|
669
|
-
messageChanged = true;
|
|
670
|
-
const nextContent = kept.length > 0
|
|
671
|
-
? kept
|
|
672
|
-
: [{ type: "text", text: `Tool reference unavailable: ${[...new Set(omitted)].join(", ")}` }];
|
|
673
|
-
content.push({ ...block, content: nextContent });
|
|
674
|
-
continue;
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
content.push(block);
|
|
679
|
-
}
|
|
680
|
-
if (content.length === 0) {
|
|
681
|
-
changed = true;
|
|
682
|
-
continue;
|
|
683
|
-
}
|
|
684
|
-
if (messageChanged) {
|
|
685
|
-
changed = true;
|
|
686
|
-
rewrittenMessages.push({ ...message, content });
|
|
687
|
-
continue;
|
|
688
|
-
}
|
|
689
|
-
rewrittenMessages.push(message);
|
|
690
|
-
}
|
|
691
|
-
if (!changed)
|
|
692
|
-
return params;
|
|
693
|
-
return { ...params, messages: rewrittenMessages };
|
|
694
|
-
}
|
|
695
|
-
function collectToolReferenceNames(value, names) {
|
|
696
|
-
if (Array.isArray(value)) {
|
|
697
|
-
for (const item of value)
|
|
698
|
-
collectToolReferenceNames(item, names);
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
if (!isRecord(value))
|
|
702
|
-
return;
|
|
703
|
-
if (value.type === "tool_reference" && typeof value.tool_name === "string")
|
|
704
|
-
names.add(value.tool_name);
|
|
705
|
-
for (const nested of Object.values(value))
|
|
706
|
-
collectToolReferenceNames(nested, names);
|
|
707
|
-
}
|
|
708
|
-
function toolResultText(content) {
|
|
709
|
-
if (typeof content === "string")
|
|
710
|
-
return content;
|
|
711
|
-
if (Array.isArray(content)) {
|
|
712
|
-
const parts = [];
|
|
713
|
-
for (const item of content) {
|
|
714
|
-
if (!isRecord(item))
|
|
715
|
-
continue;
|
|
716
|
-
if (item.type === "text" && typeof item.text === "string")
|
|
717
|
-
parts.push(item.text);
|
|
718
|
-
else if (typeof item.type === "string")
|
|
719
|
-
parts.push(`[${item.type}]`);
|
|
720
|
-
}
|
|
721
|
-
if (parts.length > 0)
|
|
722
|
-
return parts.join("\n");
|
|
723
|
-
}
|
|
724
|
-
return "Tool output unavailable.";
|
|
574
|
+
/** Numeric HTTP status carried by an SDK error (Anthropic APIError.status), if any. */
|
|
575
|
+
function httpStatusOfError(error) {
|
|
576
|
+
if (!isRecord(error))
|
|
577
|
+
return undefined;
|
|
578
|
+
const status = error.status;
|
|
579
|
+
return typeof status === "number" && Number.isInteger(status) && status >= 100 && status < 600 ? status : undefined;
|
|
725
580
|
}
|
|
726
581
|
function sanitizeAdaptiveThinkingPayload(model, params, options) {
|
|
727
582
|
if (!supportsAdaptiveThinking(model)) {
|
|
@@ -1046,24 +901,40 @@ export const stream = (model, context, options) => {
|
|
|
1046
901
|
throw error;
|
|
1047
902
|
}
|
|
1048
903
|
};
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
if (unsignedThinkingReplay !== "text" && isInvalidUnsignedThinkingSignatureError(error)) {
|
|
1055
|
-
unsignedThinkingReplay = "text";
|
|
1056
|
-
if (fallbackKey)
|
|
1057
|
-
unsignedThinkingTextReplayFallbacks.add(fallbackKey);
|
|
1058
|
-
return createRequest();
|
|
904
|
+
let requestOutcome;
|
|
905
|
+
try {
|
|
906
|
+
requestOutcome = await retryProviderRequest(async () => {
|
|
907
|
+
try {
|
|
908
|
+
return await createRequest();
|
|
1059
909
|
}
|
|
1060
|
-
|
|
910
|
+
catch (error) {
|
|
911
|
+
if (unsignedThinkingReplay !== "text" && isInvalidUnsignedThinkingSignatureError(error)) {
|
|
912
|
+
unsignedThinkingReplay = "text";
|
|
913
|
+
if (fallbackKey)
|
|
914
|
+
unsignedThinkingTextReplayFallbacks.add(fallbackKey);
|
|
915
|
+
return createRequest();
|
|
916
|
+
}
|
|
917
|
+
throw error;
|
|
918
|
+
}
|
|
919
|
+
}, {
|
|
920
|
+
maxRetries: options?.maxRetries,
|
|
921
|
+
maxRetryDelayMs: options?.maxRetryDelayMs,
|
|
922
|
+
signal: requestSignal,
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
catch (error) {
|
|
926
|
+
// The SDK rejects HTTP failures instead of returning a Response, so a
|
|
927
|
+
// rejected request never reached onResponse. Deliver the numeric status
|
|
928
|
+
// once, after every internal retry, before the caller handles the error;
|
|
929
|
+
// errors without a status (network, aborts) report nothing rather than
|
|
930
|
+
// a fabricated code.
|
|
931
|
+
const status = httpStatusOfError(error);
|
|
932
|
+
if (status !== undefined) {
|
|
933
|
+
await options?.onResponse?.({ status, headers: {} }, model);
|
|
1061
934
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
signal: requestSignal,
|
|
1066
|
-
});
|
|
935
|
+
throw error;
|
|
936
|
+
}
|
|
937
|
+
const { params: sentParams, response } = requestOutcome;
|
|
1067
938
|
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
|
|
1068
939
|
stream.push({ type: "start", partial: output });
|
|
1069
940
|
const blocks = output.content;
|
|
@@ -1102,16 +973,14 @@ export const stream = (model, context, options) => {
|
|
|
1102
973
|
}
|
|
1103
974
|
}
|
|
1104
975
|
else if (event.type === "content_block_start") {
|
|
1105
|
-
|
|
1106
|
-
throw new Error("Anthropic performed an unsupported mid-output model fallback");
|
|
1107
|
-
}
|
|
1108
|
-
const receipt = options?.abortServerSideFallback === true
|
|
1109
|
-
? parseServerFallbackReceipt(event.content_block)
|
|
1110
|
-
: undefined;
|
|
976
|
+
const receipt = parseServerFallbackReceipt(event.content_block);
|
|
1111
977
|
if (receipt !== undefined) {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
978
|
+
if (options?.abortServerSideFallback === true) {
|
|
979
|
+
serverFallbackReceipt = receipt;
|
|
980
|
+
serverFallbackAbort.abort();
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
983
|
+
usageModel = applyServerFallbackContinuation(output, model, receipt);
|
|
1115
984
|
}
|
|
1116
985
|
if (event.content_block.type === "text") {
|
|
1117
986
|
const block = {
|
|
@@ -1749,11 +1618,19 @@ function buildParams(model, context, isOAuthToken, options, unsignedThinkingRepl
|
|
|
1749
1618
|
disableThinkingForRequest(params, model, compat);
|
|
1750
1619
|
}
|
|
1751
1620
|
}
|
|
1752
|
-
//
|
|
1753
|
-
//
|
|
1754
|
-
//
|
|
1755
|
-
//
|
|
1756
|
-
|
|
1621
|
+
// A budget-thinking request whose final assistant turn came from another API
|
|
1622
|
+
// and starts with tool_use (its thinking demoted to text or dropped) is the
|
|
1623
|
+
// history shape Anthropic has rejected with "final assistant message must
|
|
1624
|
+
// start with a thinking block", so that request degrades thinking instead of
|
|
1625
|
+
// failing every turn. Nothing else degrades: adaptive families accept a
|
|
1626
|
+
// tool_use-first final turn (verified live 2026-09-09 on claude-opus-5,
|
|
1627
|
+
// claude-opus-4-6 and claude-fable-5), the model itself skips thinking before
|
|
1628
|
+
// trivial tool calls, and every change to `thinking` re-keys the prompt
|
|
1629
|
+
// cache - degrading here re-wrote the whole cached prefix on each tool
|
|
1630
|
+
// continuation (the "cache misses every second prompt" report).
|
|
1631
|
+
if (params.thinking?.type === "enabled" &&
|
|
1632
|
+
finalAssistantTurnIsForeign(context.messages) &&
|
|
1633
|
+
finalAssistantTurnStartsWithToolUse(params.messages))
|
|
1757
1634
|
disableThinkingForRequest(params, model, compat);
|
|
1758
1635
|
if (options?.metadata) {
|
|
1759
1636
|
const userId = options.metadata.user_id;
|
|
@@ -1794,6 +1671,16 @@ function applyExtraBodyToAnthropicParams(params, extraBody) {
|
|
|
1794
1671
|
* thinking/redacted_thinking block. Anthropic requires thinking-enabled
|
|
1795
1672
|
* requests to start that turn with a thinking block.
|
|
1796
1673
|
*/
|
|
1674
|
+
/** True when the last assistant message was produced through a different wire API. */
|
|
1675
|
+
function finalAssistantTurnIsForeign(messages) {
|
|
1676
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
1677
|
+
const message = messages[index];
|
|
1678
|
+
if (message.role !== "assistant")
|
|
1679
|
+
continue;
|
|
1680
|
+
return message.api !== "anthropic-messages";
|
|
1681
|
+
}
|
|
1682
|
+
return false;
|
|
1683
|
+
}
|
|
1797
1684
|
function finalAssistantTurnStartsWithToolUse(messages) {
|
|
1798
1685
|
for (let index = messages.length - 1; index >= 0; index--) {
|
|
1799
1686
|
const message = messages[index];
|