@kenkaiiii/gg-ai 5.68.1 → 5.70.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/dist/index.cjs +306 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -1
- package/dist/index.d.ts +67 -1
- package/dist/index.js +301 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -594,6 +594,11 @@ type JsonSchema = Record<string, unknown>;
|
|
|
594
594
|
/**
|
|
595
595
|
* Resolve a tool's JSON Schema for provider tool definitions: prefer the
|
|
596
596
|
* tool's pre-built `rawInputSchema`, otherwise convert its Zod `parameters`.
|
|
597
|
+
*
|
|
598
|
+
* A no-argument tool may declare a bare `{ "type": "object" }` root (common
|
|
599
|
+
* for MCP servers). OpenAI rejects that root with HTTP 400 "object schema
|
|
600
|
+
* missing properties", failing the whole request, so an object root without
|
|
601
|
+
* `properties` gets an explicit empty one. JSON Schema meaning is unchanged.
|
|
597
602
|
*/
|
|
598
603
|
declare function resolveToolSchema(tool: Tool): JsonSchema;
|
|
599
604
|
|
|
@@ -604,9 +609,70 @@ declare function resolveToolSchema(tool: Tool): JsonSchema;
|
|
|
604
609
|
* tool results are cloned for the outgoing request.
|
|
605
610
|
*/
|
|
606
611
|
declare function clampProviderContextImages(messages: Message[], provider: Provider, supportsImages: boolean | undefined): Message[];
|
|
612
|
+
/**
|
|
613
|
+
* What a provider accepts as a replayed tool-call name. `pattern` already
|
|
614
|
+
* encodes the length limit where the provider documents one; `maxLength` is
|
|
615
|
+
* checked separately so the generic rule can cap length without a charset.
|
|
616
|
+
*/
|
|
617
|
+
interface ToolCallNameRule {
|
|
618
|
+
/** Short identifier, for diagnostics and tests. */
|
|
619
|
+
id: "anthropic" | "openai-chat" | "openai-responses" | "gemini" | "generic";
|
|
620
|
+
maxLength: number;
|
|
621
|
+
pattern?: RegExp;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Per-transport tool-name rules. A legitimate call always carries the name of a
|
|
625
|
+
* tool we declared, and tool declarations are validated against these same
|
|
626
|
+
* rules, so only model-invented names (blank, invocation text stuffed into the
|
|
627
|
+
* name slot, …) can fail them.
|
|
628
|
+
*/
|
|
629
|
+
declare const TOOL_CALL_NAME_RULES: Record<ToolCallNameRule["id"], ToolCallNameRule>;
|
|
630
|
+
/** True when `name` is a tool-call name the provider described by `rule` will accept. */
|
|
631
|
+
declare function isValidToolCallName(name: unknown, rule: ToolCallNameRule): boolean;
|
|
632
|
+
/**
|
|
633
|
+
* Pick the tool-name rule for the transport a request will actually use. Mirrors
|
|
634
|
+
* the routing in `stream.ts`: `openai` with an `accountId` is the Codex
|
|
635
|
+
* (Responses) endpoint, MiniMax rides the Anthropic transport but is a third
|
|
636
|
+
* party, and an `openai` pointed at a custom baseUrl is an unknown compatible
|
|
637
|
+
* server.
|
|
638
|
+
*/
|
|
639
|
+
declare function toolCallNameRuleFor(provider: Provider | string, options?: {
|
|
640
|
+
accountId?: string;
|
|
641
|
+
baseUrl?: string;
|
|
642
|
+
}): ToolCallNameRule;
|
|
643
|
+
/**
|
|
644
|
+
* Drop assistant tool calls whose name (or id) the target provider rejects,
|
|
645
|
+
* together with the tool results that answer them.
|
|
646
|
+
*
|
|
647
|
+
* One malformed call — a blank name, a whole invocation string written into the
|
|
648
|
+
* name slot, a name over the provider's length limit — would otherwise sit in
|
|
649
|
+
* history and 400 every later request (`tool_use.name: String should match
|
|
650
|
+
* pattern`, `string_above_max_length`, …), wedging the session.
|
|
651
|
+
*
|
|
652
|
+
* Pairing is positional per window: each assistant turn opens a window, and its
|
|
653
|
+
* results (role `tool`) are matched FIFO per id until the next assistant or user
|
|
654
|
+
* message, so a reused id never consumes another turn's result. Valid sibling
|
|
655
|
+
* calls, text and thinking are kept in place. An assistant turn left with
|
|
656
|
+
* nothing replayable is removed whole, as is a tool message left empty — every
|
|
657
|
+
* transport accepts the resulting adjacent user turns (the Anthropic API
|
|
658
|
+
* combines consecutive same-role turns). A Codex reasoning item orphaned by the
|
|
659
|
+
* drop is removed too. If the drop would leave the request ENDING on that
|
|
660
|
+
* pruned assistant turn (its only call was the bad one, so no results follow),
|
|
661
|
+
* the turn is removed as well: a trailing assistant message is an assistant
|
|
662
|
+
* prefill, which current Claude models reject and other APIs treat as a
|
|
663
|
+
* continuation rather than a fresh turn.
|
|
664
|
+
*
|
|
665
|
+
* Returns the input array untouched when nothing is malformed.
|
|
666
|
+
*/
|
|
667
|
+
declare function dropInvalidToolCalls(messages: Message[], rule: ToolCallNameRule): Message[];
|
|
607
668
|
declare function toAnthropicMessages(messages: Message[], cacheControl?: {
|
|
608
669
|
type: "ephemeral";
|
|
609
670
|
ttl?: "1h";
|
|
671
|
+
}, options?: {
|
|
672
|
+
/** Replay server-side refusal `fallback` blocks in place. Only set when the
|
|
673
|
+
* request carries the server-side-fallback beta; otherwise they are
|
|
674
|
+
* stripped (after applying the replay rules). Default false. */
|
|
675
|
+
fallbackBlocks?: boolean;
|
|
610
676
|
}): {
|
|
611
677
|
system: Anthropic.TextBlockParam[] | undefined;
|
|
612
678
|
messages: Anthropic.MessageParam[];
|
|
@@ -710,4 +776,4 @@ interface PalsuProviderConfig {
|
|
|
710
776
|
*/
|
|
711
777
|
declare function registerPalsuProvider(config?: PalsuProviderConfig): PalsuProviderHandle;
|
|
712
778
|
|
|
713
|
-
export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, GGAIError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type PreparedContext, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, resolveToolSchema, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText };
|
|
779
|
+
export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, GGAIError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type PreparedContext, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, TOOL_CALL_NAME_RULES, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolCallNameRule, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, dropInvalidToolCalls, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, isValidToolCallName, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, resolveToolSchema, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText, toolCallNameRuleFor };
|
package/dist/index.d.ts
CHANGED
|
@@ -594,6 +594,11 @@ type JsonSchema = Record<string, unknown>;
|
|
|
594
594
|
/**
|
|
595
595
|
* Resolve a tool's JSON Schema for provider tool definitions: prefer the
|
|
596
596
|
* tool's pre-built `rawInputSchema`, otherwise convert its Zod `parameters`.
|
|
597
|
+
*
|
|
598
|
+
* A no-argument tool may declare a bare `{ "type": "object" }` root (common
|
|
599
|
+
* for MCP servers). OpenAI rejects that root with HTTP 400 "object schema
|
|
600
|
+
* missing properties", failing the whole request, so an object root without
|
|
601
|
+
* `properties` gets an explicit empty one. JSON Schema meaning is unchanged.
|
|
597
602
|
*/
|
|
598
603
|
declare function resolveToolSchema(tool: Tool): JsonSchema;
|
|
599
604
|
|
|
@@ -604,9 +609,70 @@ declare function resolveToolSchema(tool: Tool): JsonSchema;
|
|
|
604
609
|
* tool results are cloned for the outgoing request.
|
|
605
610
|
*/
|
|
606
611
|
declare function clampProviderContextImages(messages: Message[], provider: Provider, supportsImages: boolean | undefined): Message[];
|
|
612
|
+
/**
|
|
613
|
+
* What a provider accepts as a replayed tool-call name. `pattern` already
|
|
614
|
+
* encodes the length limit where the provider documents one; `maxLength` is
|
|
615
|
+
* checked separately so the generic rule can cap length without a charset.
|
|
616
|
+
*/
|
|
617
|
+
interface ToolCallNameRule {
|
|
618
|
+
/** Short identifier, for diagnostics and tests. */
|
|
619
|
+
id: "anthropic" | "openai-chat" | "openai-responses" | "gemini" | "generic";
|
|
620
|
+
maxLength: number;
|
|
621
|
+
pattern?: RegExp;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Per-transport tool-name rules. A legitimate call always carries the name of a
|
|
625
|
+
* tool we declared, and tool declarations are validated against these same
|
|
626
|
+
* rules, so only model-invented names (blank, invocation text stuffed into the
|
|
627
|
+
* name slot, …) can fail them.
|
|
628
|
+
*/
|
|
629
|
+
declare const TOOL_CALL_NAME_RULES: Record<ToolCallNameRule["id"], ToolCallNameRule>;
|
|
630
|
+
/** True when `name` is a tool-call name the provider described by `rule` will accept. */
|
|
631
|
+
declare function isValidToolCallName(name: unknown, rule: ToolCallNameRule): boolean;
|
|
632
|
+
/**
|
|
633
|
+
* Pick the tool-name rule for the transport a request will actually use. Mirrors
|
|
634
|
+
* the routing in `stream.ts`: `openai` with an `accountId` is the Codex
|
|
635
|
+
* (Responses) endpoint, MiniMax rides the Anthropic transport but is a third
|
|
636
|
+
* party, and an `openai` pointed at a custom baseUrl is an unknown compatible
|
|
637
|
+
* server.
|
|
638
|
+
*/
|
|
639
|
+
declare function toolCallNameRuleFor(provider: Provider | string, options?: {
|
|
640
|
+
accountId?: string;
|
|
641
|
+
baseUrl?: string;
|
|
642
|
+
}): ToolCallNameRule;
|
|
643
|
+
/**
|
|
644
|
+
* Drop assistant tool calls whose name (or id) the target provider rejects,
|
|
645
|
+
* together with the tool results that answer them.
|
|
646
|
+
*
|
|
647
|
+
* One malformed call — a blank name, a whole invocation string written into the
|
|
648
|
+
* name slot, a name over the provider's length limit — would otherwise sit in
|
|
649
|
+
* history and 400 every later request (`tool_use.name: String should match
|
|
650
|
+
* pattern`, `string_above_max_length`, …), wedging the session.
|
|
651
|
+
*
|
|
652
|
+
* Pairing is positional per window: each assistant turn opens a window, and its
|
|
653
|
+
* results (role `tool`) are matched FIFO per id until the next assistant or user
|
|
654
|
+
* message, so a reused id never consumes another turn's result. Valid sibling
|
|
655
|
+
* calls, text and thinking are kept in place. An assistant turn left with
|
|
656
|
+
* nothing replayable is removed whole, as is a tool message left empty — every
|
|
657
|
+
* transport accepts the resulting adjacent user turns (the Anthropic API
|
|
658
|
+
* combines consecutive same-role turns). A Codex reasoning item orphaned by the
|
|
659
|
+
* drop is removed too. If the drop would leave the request ENDING on that
|
|
660
|
+
* pruned assistant turn (its only call was the bad one, so no results follow),
|
|
661
|
+
* the turn is removed as well: a trailing assistant message is an assistant
|
|
662
|
+
* prefill, which current Claude models reject and other APIs treat as a
|
|
663
|
+
* continuation rather than a fresh turn.
|
|
664
|
+
*
|
|
665
|
+
* Returns the input array untouched when nothing is malformed.
|
|
666
|
+
*/
|
|
667
|
+
declare function dropInvalidToolCalls(messages: Message[], rule: ToolCallNameRule): Message[];
|
|
607
668
|
declare function toAnthropicMessages(messages: Message[], cacheControl?: {
|
|
608
669
|
type: "ephemeral";
|
|
609
670
|
ttl?: "1h";
|
|
671
|
+
}, options?: {
|
|
672
|
+
/** Replay server-side refusal `fallback` blocks in place. Only set when the
|
|
673
|
+
* request carries the server-side-fallback beta; otherwise they are
|
|
674
|
+
* stripped (after applying the replay rules). Default false. */
|
|
675
|
+
fallbackBlocks?: boolean;
|
|
610
676
|
}): {
|
|
611
677
|
system: Anthropic.TextBlockParam[] | undefined;
|
|
612
678
|
messages: Anthropic.MessageParam[];
|
|
@@ -710,4 +776,4 @@ interface PalsuProviderConfig {
|
|
|
710
776
|
*/
|
|
711
777
|
declare function registerPalsuProvider(config?: PalsuProviderConfig): PalsuProviderHandle;
|
|
712
778
|
|
|
713
|
-
export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, GGAIError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type PreparedContext, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, resolveToolSchema, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText };
|
|
779
|
+
export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, GGAIError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type PreparedContext, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, TOOL_CALL_NAME_RULES, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolCallNameRule, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, dropInvalidToolCalls, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, isValidToolCallName, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, resolveToolSchema, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText, toolCallNameRuleFor };
|
package/dist/index.js
CHANGED
|
@@ -448,7 +448,11 @@ function zodToJsonSchema(schema) {
|
|
|
448
448
|
return normalized;
|
|
449
449
|
}
|
|
450
450
|
function resolveToolSchema(tool) {
|
|
451
|
-
|
|
451
|
+
const schema = tool.rawInputSchema ?? zodToJsonSchema(tool.parameters);
|
|
452
|
+
if (schema.type === "object" && schema.properties === void 0) {
|
|
453
|
+
return { ...schema, properties: {} };
|
|
454
|
+
}
|
|
455
|
+
return schema;
|
|
452
456
|
}
|
|
453
457
|
function normalizeRootForAnthropic(schema) {
|
|
454
458
|
const branches = schema.oneOf ?? schema.anyOf;
|
|
@@ -655,6 +659,10 @@ var ANTHROPIC_INPUT_BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
|
655
659
|
"connector_text",
|
|
656
660
|
"container_upload",
|
|
657
661
|
"document",
|
|
662
|
+
// Server-side refusal fallback marker. Only reaches the wire when the request
|
|
663
|
+
// carries the server-side-fallback beta; otherwise applyServerFallbackReplay
|
|
664
|
+
// strips it first (see toAnthropicMessages' `fallbackBlocks` option).
|
|
665
|
+
"fallback",
|
|
658
666
|
"image",
|
|
659
667
|
"mid_conv_system",
|
|
660
668
|
"redacted_thinking",
|
|
@@ -676,6 +684,42 @@ function isPositionSensitiveThinking(part) {
|
|
|
676
684
|
if (part.type === "thinking") return hasValidThinkingSignature(part);
|
|
677
685
|
return isRawThinking(part);
|
|
678
686
|
}
|
|
687
|
+
function isServerFallbackBlock(part) {
|
|
688
|
+
return part.type === "raw" && part.data.type === "fallback";
|
|
689
|
+
}
|
|
690
|
+
function applyServerFallbackReplay(content, keepMarkers, droppedToolCallIds) {
|
|
691
|
+
let lastFallbackIdx = -1;
|
|
692
|
+
content.forEach((part, idx) => {
|
|
693
|
+
if (isServerFallbackBlock(part)) lastFallbackIdx = idx;
|
|
694
|
+
});
|
|
695
|
+
if (lastFallbackIdx === -1) return content;
|
|
696
|
+
const resultIds = /* @__PURE__ */ new Set();
|
|
697
|
+
for (const part of content) {
|
|
698
|
+
if (part.type === "server_tool_result") resultIds.add(part.toolUseId);
|
|
699
|
+
else if (part.type === "raw" && typeof part.data.tool_use_id === "string")
|
|
700
|
+
resultIds.add(part.data.tool_use_id);
|
|
701
|
+
}
|
|
702
|
+
const out = [];
|
|
703
|
+
content.forEach((part, idx) => {
|
|
704
|
+
if (isServerFallbackBlock(part)) {
|
|
705
|
+
if (keepMarkers) out.push(part);
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
if (idx < lastFallbackIdx) {
|
|
709
|
+
if (part.type === "thinking" || isRawThinking(part)) return;
|
|
710
|
+
if (part.type === "raw" && part.data.type === "connector_text") return;
|
|
711
|
+
if (part.type === "tool_call") {
|
|
712
|
+
droppedToolCallIds?.add(part.id);
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
if (part.type === "server_tool_call" && !resultIds.has(part.id)) return;
|
|
716
|
+
if (part.type === "raw" && part.data.type === "server_tool_use" && !resultIds.has(String(part.data.id)))
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
out.push(part);
|
|
720
|
+
});
|
|
721
|
+
return out.every(isServerFallbackBlock) ? [] : out;
|
|
722
|
+
}
|
|
679
723
|
function toAnthropicAssistantPart(part, idMap) {
|
|
680
724
|
if (part.type === "text") return { type: "text", text: part.text };
|
|
681
725
|
if (part.type === "thinking") {
|
|
@@ -787,6 +831,144 @@ function clampProviderContextImages(messages, provider, supportsImages) {
|
|
|
787
831
|
return message;
|
|
788
832
|
});
|
|
789
833
|
}
|
|
834
|
+
var TOOL_CALL_NAME_RULES = {
|
|
835
|
+
// Anthropic Messages API: tool / tool_use name `^[a-zA-Z0-9_-]{1,128}$`.
|
|
836
|
+
anthropic: { id: "anthropic", maxLength: 128, pattern: /^[a-zA-Z0-9_-]{1,128}$/ },
|
|
837
|
+
// OpenAI Chat Completions: function name a-z A-Z 0-9 _ -, max length 64.
|
|
838
|
+
"openai-chat": { id: "openai-chat", maxLength: 64, pattern: /^[a-zA-Z0-9_-]{1,64}$/ },
|
|
839
|
+
// OpenAI Responses (Codex): same charset; replayed `input[N].name` over 128
|
|
840
|
+
// chars is rejected with `string_above_max_length`.
|
|
841
|
+
"openai-responses": {
|
|
842
|
+
id: "openai-responses",
|
|
843
|
+
maxLength: 128,
|
|
844
|
+
pattern: /^[a-zA-Z0-9_-]{1,128}$/
|
|
845
|
+
},
|
|
846
|
+
// Gemini FunctionDeclaration name: starts with a letter or underscore, then
|
|
847
|
+
// a-z A-Z 0-9 _ . : -, max length 128.
|
|
848
|
+
gemini: { id: "gemini", maxLength: 128, pattern: /^[a-zA-Z_][a-zA-Z0-9_.:-]{0,127}$/ },
|
|
849
|
+
// OpenAI-compatible third parties (GLM, Kimi, DeepSeek, OpenRouter, xAI,
|
|
850
|
+
// local servers, MiniMax, …) don't share one documented charset, so only
|
|
851
|
+
// reject what no declared tool name can contain: blank, >128 chars, or any
|
|
852
|
+
// whitespace / control character (the signature of invocation text).
|
|
853
|
+
generic: { id: "generic", maxLength: 128 }
|
|
854
|
+
};
|
|
855
|
+
var TOOL_NAME_FORBIDDEN_CHARS = /[\s\p{Cc}]/u;
|
|
856
|
+
function isValidToolCallName(name, rule) {
|
|
857
|
+
if (typeof name !== "string" || name.trim().length === 0) return false;
|
|
858
|
+
if (name.length > rule.maxLength) return false;
|
|
859
|
+
if (TOOL_NAME_FORBIDDEN_CHARS.test(name)) return false;
|
|
860
|
+
return rule.pattern ? rule.pattern.test(name) : true;
|
|
861
|
+
}
|
|
862
|
+
function isDefaultOrHost(baseUrl, host) {
|
|
863
|
+
if (!baseUrl) return true;
|
|
864
|
+
try {
|
|
865
|
+
return new URL(baseUrl).hostname === host;
|
|
866
|
+
} catch {
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
function toolCallNameRuleFor(provider, options) {
|
|
871
|
+
switch (provider) {
|
|
872
|
+
case "anthropic":
|
|
873
|
+
return TOOL_CALL_NAME_RULES.anthropic;
|
|
874
|
+
case "openai":
|
|
875
|
+
if (options?.accountId) return TOOL_CALL_NAME_RULES["openai-responses"];
|
|
876
|
+
return isDefaultOrHost(options?.baseUrl, "api.openai.com") ? TOOL_CALL_NAME_RULES["openai-chat"] : TOOL_CALL_NAME_RULES.generic;
|
|
877
|
+
case "gemini":
|
|
878
|
+
return TOOL_CALL_NAME_RULES.gemini;
|
|
879
|
+
default:
|
|
880
|
+
return TOOL_CALL_NAME_RULES.generic;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
function isValidToolCallId(id) {
|
|
884
|
+
return typeof id === "string" && id.trim().length > 0;
|
|
885
|
+
}
|
|
886
|
+
function isRawReasoning(part) {
|
|
887
|
+
return part.type === "raw" && part.data.type === "reasoning";
|
|
888
|
+
}
|
|
889
|
+
function isDanglingReasoning(parts, idx) {
|
|
890
|
+
for (let i = idx + 1; i < parts.length; i++) {
|
|
891
|
+
const next = parts[i];
|
|
892
|
+
if (isRawReasoning(next)) return true;
|
|
893
|
+
if (next.type === "text" || next.type === "tool_call") return false;
|
|
894
|
+
}
|
|
895
|
+
return true;
|
|
896
|
+
}
|
|
897
|
+
function hasReplayableAssistantContent(parts) {
|
|
898
|
+
return parts.some((part) => {
|
|
899
|
+
if (part.type === "text") return part.text.length > 0;
|
|
900
|
+
if (part.type === "thinking") return false;
|
|
901
|
+
if (part.type === "raw") {
|
|
902
|
+
const t = part.data.type;
|
|
903
|
+
return !(t === "thinking" || t === "redacted_thinking" || t === "reasoning" || t === "fallback");
|
|
904
|
+
}
|
|
905
|
+
return true;
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
function dropInvalidToolCalls(messages, rule) {
|
|
909
|
+
const isInvalid = (part) => part.type === "tool_call" && (!isValidToolCallName(part.name, rule) || !isValidToolCallId(part.id));
|
|
910
|
+
const hasInvalid = messages.some(
|
|
911
|
+
(m) => m.role === "assistant" && Array.isArray(m.content) && m.content.some(isInvalid)
|
|
912
|
+
);
|
|
913
|
+
if (!hasInvalid) return messages;
|
|
914
|
+
const out = [];
|
|
915
|
+
let pending = /* @__PURE__ */ new Map();
|
|
916
|
+
let prunedAssistant = null;
|
|
917
|
+
for (const msg of messages) {
|
|
918
|
+
if (msg.role === "user" || msg.role === "system") {
|
|
919
|
+
if (msg.role === "user") pending = /* @__PURE__ */ new Map();
|
|
920
|
+
out.push(msg);
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
if (msg.role === "assistant") {
|
|
924
|
+
pending = /* @__PURE__ */ new Map();
|
|
925
|
+
if (typeof msg.content === "string") {
|
|
926
|
+
out.push(msg);
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
const original = msg.content;
|
|
930
|
+
let dropped = false;
|
|
931
|
+
const kept = [];
|
|
932
|
+
for (const part of original) {
|
|
933
|
+
if (part.type === "tool_call") {
|
|
934
|
+
const keep = !isInvalid(part);
|
|
935
|
+
const queue = pending.get(part.id) ?? [];
|
|
936
|
+
queue.push(keep);
|
|
937
|
+
pending.set(part.id, queue);
|
|
938
|
+
if (!keep) {
|
|
939
|
+
dropped = true;
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
kept.push(part);
|
|
944
|
+
}
|
|
945
|
+
if (!dropped) {
|
|
946
|
+
out.push(msg);
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
const content = kept.filter(
|
|
950
|
+
(part, idx) => !isRawReasoning(part) || !isDanglingReasoning(kept, idx) || isDanglingReasoning(original, original.indexOf(part))
|
|
951
|
+
);
|
|
952
|
+
if (hasReplayableAssistantContent(content)) {
|
|
953
|
+
const pruned = { ...msg, content };
|
|
954
|
+
out.push(pruned);
|
|
955
|
+
prunedAssistant = pruned;
|
|
956
|
+
}
|
|
957
|
+
continue;
|
|
958
|
+
}
|
|
959
|
+
let changed = false;
|
|
960
|
+
const results = msg.content.filter((result) => {
|
|
961
|
+
const queue = pending.get(result.toolCallId);
|
|
962
|
+
const keep = queue && queue.length > 0 ? queue.shift() : true;
|
|
963
|
+
if (!keep) changed = true;
|
|
964
|
+
return keep;
|
|
965
|
+
});
|
|
966
|
+
if (!changed) out.push(msg);
|
|
967
|
+
else if (results.length > 0) out.push({ ...msg, content: results });
|
|
968
|
+
}
|
|
969
|
+
if (prunedAssistant && out[out.length - 1] === prunedAssistant) out.pop();
|
|
970
|
+
return out;
|
|
971
|
+
}
|
|
790
972
|
var NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
791
973
|
var NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
792
974
|
var NON_VIDEO_USER_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
@@ -893,10 +1075,12 @@ function remapAnthropicToolCallId(id, idMap) {
|
|
|
893
1075
|
idMap.set(id, mapped);
|
|
894
1076
|
return mapped;
|
|
895
1077
|
}
|
|
896
|
-
function toAnthropicMessages(messages, cacheControl) {
|
|
1078
|
+
function toAnthropicMessages(messages, cacheControl, options) {
|
|
897
1079
|
let systemText;
|
|
898
1080
|
const out = [];
|
|
899
1081
|
const idMap = /* @__PURE__ */ new Map();
|
|
1082
|
+
const keepFallbackBlocks = options?.fallbackBlocks === true;
|
|
1083
|
+
const droppedToolCallIds = /* @__PURE__ */ new Set();
|
|
900
1084
|
const trajectoryStartIdx = messages.reduce(
|
|
901
1085
|
(last, m, i) => m.role === "user" ? i : last,
|
|
902
1086
|
-1
|
|
@@ -942,17 +1126,23 @@ function toAnthropicMessages(messages, cacheControl) {
|
|
|
942
1126
|
}
|
|
943
1127
|
if (msg.role === "assistant") {
|
|
944
1128
|
if (typeof msg.content === "string" && msg.content === "") continue;
|
|
945
|
-
const content = typeof msg.content === "string" ? msg.content : toAnthropicAssistantContent(
|
|
1129
|
+
const content = typeof msg.content === "string" ? msg.content : toAnthropicAssistantContent(
|
|
1130
|
+
applyServerFallbackReplay(msg.content, keepFallbackBlocks, droppedToolCallIds),
|
|
1131
|
+
msgIdx > trajectoryStartIdx,
|
|
1132
|
+
idMap
|
|
1133
|
+
);
|
|
946
1134
|
if (Array.isArray(content) && content.length === 0) continue;
|
|
947
1135
|
out.push({ role: "assistant", content });
|
|
948
1136
|
continue;
|
|
949
1137
|
}
|
|
950
1138
|
if (msg.role === "tool") {
|
|
1139
|
+
const results = droppedToolCallIds.size ? msg.content.filter((r) => !droppedToolCallIds.has(r.toolCallId)) : msg.content;
|
|
1140
|
+
if (results.length === 0) continue;
|
|
951
1141
|
out.push({
|
|
952
1142
|
role: "user",
|
|
953
1143
|
// Cast covers the video block (used by the Anthropic-compatible MiniMax
|
|
954
1144
|
// API), which isn't in the first-party Anthropic tool_result types.
|
|
955
|
-
content:
|
|
1145
|
+
content: results.map((result) => ({
|
|
956
1146
|
type: "tool_result",
|
|
957
1147
|
tool_use_id: remapAnthropicToolCallId(result.toolCallId, idMap),
|
|
958
1148
|
content: toAnthropicToolResultContent(result.content),
|
|
@@ -1292,6 +1482,48 @@ function fineGrainedToolStreamingEnabled() {
|
|
|
1292
1482
|
const v = raw.trim().toLowerCase();
|
|
1293
1483
|
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
1294
1484
|
}
|
|
1485
|
+
var SERVER_FALLBACK_BETA = "server-side-fallback-2026-07-01";
|
|
1486
|
+
var anthropicServerFallback = {
|
|
1487
|
+
disabled: /* @__PURE__ */ new Set(),
|
|
1488
|
+
reset() {
|
|
1489
|
+
this.disabled.clear();
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
function serverFallbackKey(options) {
|
|
1493
|
+
const auth = options.apiKey?.startsWith("sk-ant-oat") ? "oauth" : "key";
|
|
1494
|
+
return `${options.baseUrl ?? process.env.ANTHROPIC_BASE_URL ?? ""}|${auth}`;
|
|
1495
|
+
}
|
|
1496
|
+
function isDirectAnthropicApi(baseUrl) {
|
|
1497
|
+
const effective = baseUrl ?? process.env.ANTHROPIC_BASE_URL;
|
|
1498
|
+
if (!effective) return true;
|
|
1499
|
+
try {
|
|
1500
|
+
const url = new URL(effective);
|
|
1501
|
+
return url.protocol === "https:" && url.hostname === "api.anthropic.com";
|
|
1502
|
+
} catch {
|
|
1503
|
+
return false;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
function isServerFallbackRejection(err) {
|
|
1507
|
+
const status = err?.status;
|
|
1508
|
+
if (status !== 400) return false;
|
|
1509
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1510
|
+
return /fallbacks|server-side-fallback/i.test(message);
|
|
1511
|
+
}
|
|
1512
|
+
function sumUsageIterations(usage) {
|
|
1513
|
+
const iterations = usage?.iterations;
|
|
1514
|
+
if (!Array.isArray(iterations) || iterations.length === 0) return null;
|
|
1515
|
+
const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
1516
|
+
const totals = { inputTokens: 0, outputTokens: 0, cacheRead: 0, cacheWrite: 0 };
|
|
1517
|
+
for (const it of iterations) {
|
|
1518
|
+
if (!it || typeof it !== "object") continue;
|
|
1519
|
+
const rec = it;
|
|
1520
|
+
totals.inputTokens += num(rec.input_tokens);
|
|
1521
|
+
totals.outputTokens += num(rec.output_tokens);
|
|
1522
|
+
totals.cacheRead += num(rec.cache_read_input_tokens);
|
|
1523
|
+
totals.cacheWrite += num(rec.cache_creation_input_tokens);
|
|
1524
|
+
}
|
|
1525
|
+
return totals;
|
|
1526
|
+
}
|
|
1295
1527
|
function createClient(options) {
|
|
1296
1528
|
const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
|
|
1297
1529
|
const userAgent = isOAuth ? options.userAgent ?? "claude-cli/2.1.75 (external, cli)" : "";
|
|
@@ -1388,7 +1620,11 @@ async function* runStream(options) {
|
|
|
1388
1620
|
const supportsFirstPartyToolExtras = !options.baseUrl || options.baseUrl.includes("api.anthropic.com");
|
|
1389
1621
|
const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);
|
|
1390
1622
|
const downgradedMessages = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);
|
|
1391
|
-
const
|
|
1623
|
+
const fallbackKey = serverFallbackKey(options);
|
|
1624
|
+
const useServerFallback = options.provider !== "minimax" && isDirectAnthropicApi(options.baseUrl) && !anthropicServerFallback.disabled.has(fallbackKey);
|
|
1625
|
+
const { system: rawSystem, messages } = toAnthropicMessages(downgradedMessages, cacheControl, {
|
|
1626
|
+
fallbackBlocks: useServerFallback
|
|
1627
|
+
});
|
|
1392
1628
|
const system = isOAuth ? [
|
|
1393
1629
|
{
|
|
1394
1630
|
type: "text",
|
|
@@ -1458,6 +1694,7 @@ async function* runStream(options) {
|
|
|
1458
1694
|
];
|
|
1459
1695
|
return contextEdits.length ? { context_management: { edits: contextEdits } } : {};
|
|
1460
1696
|
})(),
|
|
1697
|
+
...useServerFallback ? { fallbacks: "default" } : {},
|
|
1461
1698
|
stream: useStreaming
|
|
1462
1699
|
};
|
|
1463
1700
|
const hasAdaptiveThinking = isAdaptiveThinkingModel(options.model);
|
|
@@ -1474,20 +1711,41 @@ async function* runStream(options) {
|
|
|
1474
1711
|
// it Anthropic silently ignores ttl:"1h" and falls back to the 5-min default,
|
|
1475
1712
|
// so a pre-warmed cache expires before the user's first turn. cacheControl.ttl
|
|
1476
1713
|
// is only "1h" on the first-party endpoint (see toAnthropicCacheControl).
|
|
1477
|
-
...cacheControl?.ttl === "1h" ? ["extended-cache-ttl-2025-04-11"] : []
|
|
1714
|
+
...cacheControl?.ttl === "1h" ? ["extended-cache-ttl-2025-04-11"] : [],
|
|
1715
|
+
...useServerFallback ? [SERVER_FALLBACK_BETA] : []
|
|
1478
1716
|
];
|
|
1479
|
-
const
|
|
1717
|
+
const toRequestOptions = (betas) => ({
|
|
1480
1718
|
signal: options.signal ?? void 0,
|
|
1481
|
-
...
|
|
1719
|
+
...betas.length ? { headers: { "anthropic-beta": betas.join(",") } } : {}
|
|
1720
|
+
});
|
|
1721
|
+
const requestOptions = toRequestOptions(betaHeaders);
|
|
1722
|
+
const send = async (create) => {
|
|
1723
|
+
try {
|
|
1724
|
+
return await create(params, requestOptions);
|
|
1725
|
+
} catch (err) {
|
|
1726
|
+
if (!useServerFallback || !isServerFallbackRejection(err)) throw err;
|
|
1727
|
+
anthropicServerFallback.disabled.add(fallbackKey);
|
|
1728
|
+
const { fallbacks: _dropped, ...rest } = params;
|
|
1729
|
+
const retryParams = {
|
|
1730
|
+
...rest,
|
|
1731
|
+
messages: toAnthropicMessages(downgradedMessages, cacheControl, { fallbackBlocks: false }).messages
|
|
1732
|
+
};
|
|
1733
|
+
return create(
|
|
1734
|
+
retryParams,
|
|
1735
|
+
toRequestOptions(betaHeaders.filter((b) => b !== SERVER_FALLBACK_BETA))
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1482
1738
|
};
|
|
1483
1739
|
if (!useStreaming) {
|
|
1484
1740
|
try {
|
|
1485
1741
|
const nonStreamingClient = client.withOptions({
|
|
1486
1742
|
timeout: NON_STREAMING_REQUEST_TIMEOUT_MS
|
|
1487
1743
|
});
|
|
1488
|
-
const message = await
|
|
1489
|
-
|
|
1490
|
-
|
|
1744
|
+
const message = await send(
|
|
1745
|
+
(p, o) => nonStreamingClient.messages.create(
|
|
1746
|
+
{ ...p, stream: false },
|
|
1747
|
+
o
|
|
1748
|
+
)
|
|
1491
1749
|
);
|
|
1492
1750
|
yield* synthesizeEventsFromMessage(message);
|
|
1493
1751
|
return messageToResponse(message);
|
|
@@ -1505,9 +1763,8 @@ async function* runStream(options) {
|
|
|
1505
1763
|
const keepalive = { type: "keepalive" };
|
|
1506
1764
|
let receivedAnyEvent = false;
|
|
1507
1765
|
try {
|
|
1508
|
-
const stream2 = await
|
|
1509
|
-
|
|
1510
|
-
requestOptions
|
|
1766
|
+
const stream2 = await send(
|
|
1767
|
+
(p, o) => client.messages.create(p, o)
|
|
1511
1768
|
);
|
|
1512
1769
|
for await (const event of stream2) {
|
|
1513
1770
|
receivedAnyEvent = true;
|
|
@@ -1685,6 +1942,13 @@ async function* runStream(options) {
|
|
|
1685
1942
|
if (usage?.output_tokens != null) {
|
|
1686
1943
|
outputTokens = usage.output_tokens;
|
|
1687
1944
|
}
|
|
1945
|
+
const totals = sumUsageIterations(usage);
|
|
1946
|
+
if (totals) {
|
|
1947
|
+
inputTokens = totals.inputTokens;
|
|
1948
|
+
outputTokens = totals.outputTokens;
|
|
1949
|
+
cacheRead = totals.cacheRead;
|
|
1950
|
+
cacheWrite = totals.cacheWrite;
|
|
1951
|
+
}
|
|
1688
1952
|
yield keepalive;
|
|
1689
1953
|
break;
|
|
1690
1954
|
}
|
|
@@ -1814,10 +2078,11 @@ function messageToResponse(message) {
|
|
|
1814
2078
|
}
|
|
1815
2079
|
}
|
|
1816
2080
|
const usage = message.usage;
|
|
1817
|
-
const
|
|
1818
|
-
const
|
|
1819
|
-
const
|
|
1820
|
-
const
|
|
2081
|
+
const totals = sumUsageIterations(usage);
|
|
2082
|
+
const inputTokens = totals?.inputTokens ?? usage.input_tokens ?? 0;
|
|
2083
|
+
const outputTokens = totals?.outputTokens ?? usage.output_tokens ?? 0;
|
|
2084
|
+
const cacheRead = totals?.cacheRead ?? usage.cache_read_input_tokens;
|
|
2085
|
+
const cacheWrite = totals?.cacheWrite ?? usage.cache_creation_input_tokens;
|
|
1821
2086
|
return {
|
|
1822
2087
|
message: {
|
|
1823
2088
|
role: "assistant",
|
|
@@ -4025,15 +4290,23 @@ function stream(options) {
|
|
|
4025
4290
|
throw new VideoUnsupportedError();
|
|
4026
4291
|
}
|
|
4027
4292
|
const wireMessages = stripMessageProvenance(options.messages);
|
|
4028
|
-
const
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
options.
|
|
4293
|
+
const sanitized = sanitizeMessagesForWire(wireMessages);
|
|
4294
|
+
const replayable = dropInvalidToolCalls(
|
|
4295
|
+
sanitized,
|
|
4296
|
+
toolCallNameRuleFor(options.provider, {
|
|
4297
|
+
accountId: options.accountId,
|
|
4298
|
+
baseUrl: options.baseUrl
|
|
4299
|
+
})
|
|
4032
4300
|
);
|
|
4301
|
+
const messages = clampProviderContextImages(replayable, options.provider, options.supportsImages);
|
|
4033
4302
|
if (options.onContextPrepared) {
|
|
4034
4303
|
try {
|
|
4035
4304
|
options.onContextPrepared(
|
|
4036
|
-
observePreparedContext(
|
|
4305
|
+
observePreparedContext(
|
|
4306
|
+
replayable === sanitized ? wireMessages : replayable,
|
|
4307
|
+
messages,
|
|
4308
|
+
options.tools ?? []
|
|
4309
|
+
)
|
|
4037
4310
|
);
|
|
4038
4311
|
} catch {
|
|
4039
4312
|
}
|
|
@@ -4448,14 +4721,17 @@ export {
|
|
|
4448
4721
|
ProviderError,
|
|
4449
4722
|
REDACTED as REDACTION_MARKER,
|
|
4450
4723
|
StreamResult,
|
|
4724
|
+
TOOL_CALL_NAME_RULES,
|
|
4451
4725
|
clampProviderContextImages,
|
|
4452
4726
|
classifyProviderError,
|
|
4727
|
+
dropInvalidToolCalls,
|
|
4453
4728
|
environmentSecrets,
|
|
4454
4729
|
formatError,
|
|
4455
4730
|
formatErrorForDisplay,
|
|
4456
4731
|
hasLoneSurrogate,
|
|
4457
4732
|
isHardBillingMessage,
|
|
4458
4733
|
isUsageLimitError,
|
|
4734
|
+
isValidToolCallName,
|
|
4459
4735
|
localWireModelId,
|
|
4460
4736
|
palsuAssistantMessage,
|
|
4461
4737
|
palsuText,
|
|
@@ -4474,6 +4750,7 @@ export {
|
|
|
4474
4750
|
stream,
|
|
4475
4751
|
toAnthropicMessages,
|
|
4476
4752
|
toOpenAIMessages,
|
|
4477
|
-
toWellFormedText
|
|
4753
|
+
toWellFormedText,
|
|
4754
|
+
toolCallNameRuleFor
|
|
4478
4755
|
};
|
|
4479
4756
|
//# sourceMappingURL=index.js.map
|