@earendil-works/pi-ai 1.2.0 → 1.4.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/README.md +83 -37
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +66 -64
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +8 -4
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +28 -18
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/classifier-shared.d.ts.map +1 -1
- package/dist/api/classifier-shared.js +4 -3
- package/dist/api/classifier-shared.js.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.js +8 -0
- package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
- package/dist/api/google-generative-ai.js +4 -4
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +3 -1
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +9 -9
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/lazy.d.ts +7 -2
- package/dist/api/lazy.d.ts.map +1 -1
- package/dist/api/lazy.js +24 -5
- package/dist/api/lazy.js.map +1 -1
- package/dist/api/llama-cpp-classify.d.ts.map +1 -1
- package/dist/api/llama-cpp-classify.js +2 -1
- package/dist/api/llama-cpp-classify.js.map +1 -1
- package/dist/api/mistral-conversations.js +4 -4
- package/dist/api/mistral-conversations.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +17 -11
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +43 -35
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +26 -0
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +76 -11
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +38 -13
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.d.ts.map +1 -1
- package/dist/api/openrouter-images.js +4 -3
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +3 -3
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +2 -1
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/system-one-shared.d.ts +29 -2
- package/dist/api/system-one-shared.d.ts.map +1 -1
- package/dist/api/system-one-shared.js +55 -3
- package/dist/api/system-one-shared.js.map +1 -1
- package/dist/api/transform-messages.d.ts +16 -1
- package/dist/api/transform-messages.d.ts.map +1 -1
- package/dist/api/transform-messages.js +28 -15
- package/dist/api/transform-messages.js.map +1 -1
- package/dist/api/typesafe-system-one.d.ts.map +1 -1
- package/dist/api/typesafe-system-one.js +10 -0
- package/dist/api/typesafe-system-one.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +4 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +19 -6
- package/dist/models.js.map +1 -1
- package/dist/providers/compat-schema.d.ts +171 -0
- package/dist/providers/compat-schema.d.ts.map +1 -1
- package/dist/providers/compat-schema.js +23 -2
- package/dist/providers/compat-schema.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/anthropic.json +1 -1
- package/dist/providers/data/azure.json +1 -1
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cerebras.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/dist/providers/data/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/google-vertex.json +1 -1
- package/dist/providers/data/google.json +1 -1
- package/dist/providers/data/groq.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/kimi-coding.json +1 -1
- package/dist/providers/data/meta.json +1 -1
- package/dist/providers/data/minimax-cn.json +1 -1
- package/dist/providers/data/minimax.json +1 -1
- package/dist/providers/data/mistral.json +1 -1
- package/dist/providers/data/moonshotai-cn.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-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/dist/providers/data/qwen-token-plan.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/together.json +1 -1
- package/dist/providers/data/typesafe.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/xai.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/dist/providers/data/xiaomi.json +1 -1
- package/dist/providers/data/zai-coding-cn.json +1 -1
- package/dist/providers/kimi-coding.d.ts +1 -1
- package/dist/providers/kimi-coding.js +3 -3
- package/dist/providers/kimi-coding.js.map +1 -1
- package/dist/providers/model-schema.d.ts.map +1 -1
- package/dist/providers/model-schema.js +4 -2
- package/dist/providers/model-schema.js.map +1 -1
- package/dist/providers/opencode-go.d.ts +3 -1
- package/dist/providers/opencode-go.d.ts.map +1 -1
- package/dist/providers/opencode-go.js +2 -0
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/telemetry.d.ts +288 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +191 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +18 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/identity.d.ts +65 -0
- package/dist/utils/identity.d.ts.map +1 -0
- package/dist/utils/identity.js +141 -0
- package/dist/utils/identity.js.map +1 -0
- package/dist/utils/json-parse.d.ts +10 -0
- package/dist/utils/json-parse.d.ts.map +1 -1
- package/dist/utils/json-parse.js +26 -1
- package/dist/utils/json-parse.js.map +1 -1
- package/dist/utils/overflow.d.ts +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +6 -1
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +21 -8
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/transcript.d.ts +22 -8
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +29 -18
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +3 -0
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +3 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +2 -2
- package/dist/utils/assistant-message-frame.d.ts +0 -77
- package/dist/utils/assistant-message-frame.d.ts.map +0 -1
- package/dist/utils/assistant-message-frame.js +0 -425
- package/dist/utils/assistant-message-frame.js.map +0 -1
- package/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js +0 -12
- package/dist/utils/pi-user-agent.js.map +0 -1
package/dist/utils/retry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"../types.ts\";\n\nfunction buildProviderErrorPattern(patterns: readonly string[]): RegExp {\n\treturn new RegExp(patterns.join(\"|\"), \"i\");\n}\n\nconst NON_RETRYABLE_PROVIDER_LIMIT_ERROR_PATTERN = buildProviderErrorPattern([\n\t// OpenCode Go/free-tier limits returned as 429 JSON error types by OpenCode's\n\t// Zen API. These are subscription/account limits, not transient throttles.\n\t\"GoUsageLimitError\",\n\t\"FreeUsageLimitError\",\n\n\t// OpenCode Go subscription-limit text asks users to enable available-balance\n\t// usage after rolling/weekly/monthly limits are reached.\n\t\"Monthly usage limit reached\",\n\t\"available balance\",\n\n\t// Generic quota/budget/billing exhaustion. `insufficient_quota` is OpenAI's\n\t// quota/billing error code; the other strings cover common gateway wording.\n\t\"insufficient_quota\",\n\t\"out of budget\",\n\t\"quota exceeded\",\n\t\"billing\",\n\n\t// Sign in with ChatGPT: the subscription's shared usage limit, which resets\n\t// after hours rather than seconds.\n\t\"subscription_sharing_usage_limit_exceeded\",\n]);\n\nconst RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([\n\t// Generic provider load, HTTP status, and server-side transient failures.\n\t\"overloaded\",\n\t\"server_busy\",\n\t\"servers are currently busy\",\n\t\"currently experiencing high demand\",\n\t\"model is at capacity\",\n\t\"rate.?limit\",\n\t\"too many requests\",\n\t\"429\",\n\t\"500\",\n\t\"502\",\n\t\"503\",\n\t\"504\",\n\t\"520\",\n\t\"524\",\n\t\"service.?unavailable\",\n\t\"server.?error\",\n\t\"internal.?error\",\n\n\t// Wrapper/provider text for transient upstream failures, including OpenRouter\n\t// \"Provider returned error\" responses (#2264) and gateway wording such as\n\t// \"The upstream provider returned an error\" (#10842).\n\t\"provider.?returned.?(?:an.?)?error\",\n\t\"exceeded request buffer limit while retrying upstream\",\n\n\t// Network, proxy, and fetch transport failures. This includes OpenAI Codex\n\t// raw-fetch failures such as \"upstream connect\", \"connection refused\", and\n\t// \"reset before headers\" (#733), plus OpenRouter connection drops (#3317).\n\t\"network.?error\",\n\t\"connection.?error\",\n\t\"connection.?refused\",\n\t\"connection.?lost\",\n\t\"other side closed\",\n\t\"fetch failed\",\n\t\"getaddrinfo\",\n\t\"ENOTFOUND\",\n\t\"EAI_AGAIN\",\n\t\"upstream.?connect\",\n\t\"reset before headers\",\n\t\"socket hang up\",\n\t\"socket connection was closed\",\n\t\"timed? out\",\n\t\"timeout\",\n\t\"terminated\",\n\n\t// WebSocket transports can report close/error text instead of HTTP/fetch text.\n\t\"websocket.?closed\",\n\t\"websocket.?error\",\n\n\t// Premature stream endings from SDKs and transports. Anthropic can throw\n\t// \"stream ended without ...\" and \"Anthropic stream ended before message_stop\"\n\t// (#4433); Bedrock/Smithy can throw an HTTP/2 no-response error (#3594).\n\t\"ended without\",\n\t\"stream ended before message_stop\",\n\t\"stream ended before a terminal response event\",\n\t\"http2 request did not get a response\",\n\t// Node ERR_HTTP2_STREAM_CANCEL: the HTTP/2 session died before the request was\n\t// sent, e.g. after the Bedrock SDK's 5-minute session timeout (#10379).\n\t\"pending stream has been canceled\",\n\n\t// Provider-requested retry delay cap failures should flow through the outer\n\t// retry policy so callers can surface/abort the backoff (#1123).\n\t\"retry delay\",\n\n\t// Explicit retry guidance emitted mid-stream by OpenAI Responses and Bedrock\n\t// stream exceptions (#6019).\n\t\"you can retry your request\",\n\t\"try your request again\",\n\t\"please retry your request\",\n\n\t// gRPC based providers (e.g. NVIDIA NIM)\n\t\"ResourceExhausted\",\n\n\t// Sign in with ChatGPT: usage or user data temporarily unavailable. Usage\n\t// failures can arrive mid-stream without an HTTP 503 in the message.\n\t\"subscription_sharing_usage_unavailable\",\n\t\"subscription_sharing_user_unavailable\",\n]);\n\n/**\n * Retry policy: bounded attempts with exponential backoff (`baseDelayMs * 2^(attempt-1)`).\n * `maxAgentDelayMs` caps each computed delay and defaults to 60 seconds.\n * Matches `settings.retry` (`enabled`, `maxRetries`, `baseDelayMs`, `maxAgentDelayMs`) in coding-agent; kept\n * here so the classifier and the policy-driven retry loop live together and stay reusable\n * by the SDK and other callers.\n */\nexport interface RetryPolicy {\n\tenabled: boolean;\n\t/** Max retry attempts (0 = no retries). The initial call never counts as a retry. */\n\tmaxRetries: number;\n\t/** Base delay in ms. Per-attempt delay is `baseDelayMs * 2^(attempt-1)` before jitter. */\n\tbaseDelayMs: number;\n\t/** Optional cap for agent-level retry delays in ms. Defaults to 60 seconds. */\n\tmaxAgentDelayMs?: number;\n}\n\nexport const DEFAULT_MAX_AGENT_RETRY_DELAY_MS = 60_000;\n\nexport function retryDelayMs(policy: Pick<RetryPolicy, \"baseDelayMs\" | \"maxAgentDelayMs\">, attempt: number): number {\n\tconst delay = policy.baseDelayMs * 2 ** Math.max(0, attempt - 1);\n\tconst safeDelay = Number.isSafeInteger(delay) ? delay : Number.MAX_SAFE_INTEGER;\n\treturn Math.min(safeDelay, policy.maxAgentDelayMs ?? DEFAULT_MAX_AGENT_RETRY_DELAY_MS);\n}\n\n/** Optional callbacks emitted by {@link retryAssistantCall} around each retry. */\nexport interface RetryCallbacks {\n\t/** Emitted before the backoff sleep of each retry attempt (1-indexed). */\n\tonRetryScheduled?: (\n\t\tattempt: number,\n\t\tmaxAttempts: number,\n\t\tdelayMs: number,\n\t\terrorMessage: string,\n\t) => void | Promise<void>;\n\t/** Emitted after the backoff sleep, immediately before the retried call starts. */\n\tonRetryAttemptStart?: () => void | Promise<void>;\n\t/** Emitted once when the loop ends: success if a later call completed normally. */\n\tonRetryFinished?: (success: boolean, attempt: number, finalError?: string) => void | Promise<void>;\n}\n\nclass RetrySleepAbortError extends Error {\n\tconstructor() {\n\t\tsuper(\"Aborted\");\n\t}\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(new RetrySleepAbortError());\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout(resolve, ms);\n\t\tsignal?.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\treject(new RetrySleepAbortError());\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n}\n\n/**\n * Run a single assistant-producing call with bounded retry on transient errors.\n *\n * Behavior:\n * - A successful response is returned immediately. Aborts are terminal and never\n * retried, but reported as unsuccessful if they happen after a retry was scheduled.\n * Aborts during the backoff sleep are normalized to an aborted `AssistantMessage`\n * too, so callers do not need to care when cancellation happened.\n * - A non-retryable error (per {@link isRetryableAssistantError}, including quota/\n * billing exhaustion) is returned immediately so deterministic errors fail fast.\n * - Otherwise retries up to `maxRetries` times with exponential backoff, emitting\n * `onRetryScheduled` before each sleep, `onRetryAttemptStart` after each sleep before\n * the retried call starts, and `onRetryFinished` once at the end (whether the loop\n * ends in success, exhausted retries, or an aborted backoff).\n *\n * When `policy` is undefined or disabled, the first response is returned unchanged\n * (equivalent to calling `produce()` directly).\n */\nexport async function retryAssistantCall(\n\tproduce: () => Promise<AssistantMessage>,\n\tpolicy: RetryPolicy | undefined,\n\tsignal: AbortSignal | undefined,\n\tcallbacks?: RetryCallbacks,\n): Promise<AssistantMessage> {\n\tconst maxAttempts = policy?.enabled ? policy.maxRetries : 0;\n\n\tlet attempt = 0;\n\tlet lastRetry: { attempt: number; errorMessage: string } | undefined;\n\tfor (;;) {\n\t\tconst response = await produce();\n\n\t\t// Abort: terminal but not successful. Never retry an aborted message.\n\t\tif (response.stopReason === \"aborted\") {\n\t\t\tif (lastRetry) await callbacks?.onRetryFinished?.(false, lastRetry.attempt);\n\t\t\treturn response;\n\t\t}\n\n\t\t// Success: non-error, non-abort responses return as-is.\n\t\tif (response.stopReason !== \"error\") {\n\t\t\tif (lastRetry) await callbacks?.onRetryFinished?.(true, lastRetry.attempt);\n\t\t\treturn response;\n\t\t}\n\n\t\t// Non-retryable, or budget exhausted: return the final error message.\n\t\tif (attempt >= maxAttempts || !isRetryableAssistantError(response)) {\n\t\t\tif (lastRetry) await callbacks?.onRetryFinished?.(false, lastRetry.attempt, response.errorMessage);\n\t\t\treturn response;\n\t\t}\n\n\t\tattempt++;\n\t\tlastRetry = { attempt, errorMessage: response.errorMessage || \"Unknown error\" };\n\t\tconst delayMs = retryDelayMs(policy!, attempt);\n\t\tawait callbacks?.onRetryScheduled?.(attempt, maxAttempts, delayMs, lastRetry.errorMessage);\n\n\t\t// Normalize aborts during retry backoff to the same AssistantMessage shape as\n\t\t// provider stream aborts, so callers do not need to care when cancellation happened.\n\t\ttry {\n\t\t\tawait sleep(delayMs, signal);\n\t\t} catch (error) {\n\t\t\tawait callbacks?.onRetryFinished?.(false, attempt, lastRetry.errorMessage);\n\t\t\tif (error instanceof RetrySleepAbortError) {\n\t\t\t\tconst { errorMessage: _errorMessage, ...rest } = response;\n\t\t\t\treturn { ...rest, stopReason: \"aborted\" };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tawait callbacks?.onRetryAttemptStart?.();\n\t}\n}\n\n/**\n * Classifies whether a failed assistant message looks like a transient provider\n * or transport error, so callers can decide if the last assistant turn should be\n * restarted.\n *\n * This does not implement retry policy. Callers should first handle context\n * overflow separately, then apply their own retry budget, backoff, and reporting\n * before restarting the assistant turn.\n */\nexport function isRetryableAssistantError(message: AssistantMessage): boolean {\n\tif (message.stopReason !== \"error\" || !message.errorMessage) return false;\n\tconst errorMessage = message.errorMessage;\n\tif (NON_RETRYABLE_PROVIDER_LIMIT_ERROR_PATTERN.test(errorMessage)) return false;\n\treturn RETRYABLE_PROVIDER_ERROR_PATTERN.test(errorMessage);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"../types.ts\";\n\nfunction buildProviderErrorPattern(patterns: readonly string[]): RegExp {\n\treturn new RegExp(patterns.join(\"|\"), \"i\");\n}\n\nconst NON_RETRYABLE_PROVIDER_LIMIT_ERROR_PATTERN = buildProviderErrorPattern([\n\t// OpenCode Go/free-tier limits returned as 429 JSON error types by OpenCode's\n\t// Zen API. These are subscription/account limits, not transient throttles.\n\t\"GoUsageLimitError\",\n\t\"FreeUsageLimitError\",\n\n\t// OpenCode Go subscription-limit text asks users to enable available-balance\n\t// usage after rolling/weekly/monthly limits are reached.\n\t\"Monthly usage limit reached\",\n\t\"available balance\",\n\n\t// Generic quota/budget/billing exhaustion. `insufficient_quota` is OpenAI's\n\t// quota/billing error code; the other strings cover common gateway wording.\n\t\"insufficient_quota\",\n\t\"out of budget\",\n\t\"quota exceeded\",\n\t\"billing\",\n\n\t// Sign in with ChatGPT: the subscription's shared usage limit, which resets\n\t// after hours rather than seconds.\n\t\"subscription_sharing_usage_limit_exceeded\",\n\t// Sign in with ChatGPT on a ChatGPT Business plan: a usage limit set by the\n\t// workspace admin. Only the admin can raise it.\n\t\"subscription_sharing_workplace_individual_usage_limit_exceeded\",\n]);\n\nconst RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([\n\t// Generic provider load, HTTP status, and server-side transient failures.\n\t\"overloaded\",\n\t\"server_busy\",\n\t\"servers are currently busy\",\n\t\"currently experiencing high demand\",\n\t\"model is at capacity\",\n\t\"rate.?limit\",\n\t\"too many requests\",\n\t// Status codes must not be part of a longer word or number, e.g. a request id or byte count (#11057).\n\t\"(?<![a-z0-9])(?:429|500|502|503|504|520|524)(?![a-z0-9])\",\n\t// Also matches \"The service is temporarily unavailable\" (#10965).\n\t\"service.?(?:is.?)?(?:temporarily.?)?unavailable\",\n\t\"server.?error\",\n\t\"internal.?error\",\n\n\t// Wrapper/provider text for transient upstream failures, including OpenRouter\n\t// \"Provider returned error\" responses (#2264) and gateway wording such as\n\t// \"The upstream provider returned an error\" (#10842).\n\t\"provider.?returned.?(?:an.?)?error\",\n\t\"exceeded request buffer limit while retrying upstream\",\n\t// Gateway failure relaying the upstream response stream, sent as an OpenAI\n\t// Responses `response.failed` event without an error code (#10920).\n\t\"unable to forward upstream\",\n\t// Other gateway upstream failures relayed as `response.failed` error codes (#10920).\n\t\"upstream.?request.?failed\",\n\t\"upstream_stream_read_error\",\n\t\"stream was interrupted\",\n\t\"http/?2 stream failed\",\n\n\t// Network, proxy, and fetch transport failures. This includes OpenAI Codex\n\t// raw-fetch failures such as \"upstream connect\", \"connection refused\", and\n\t// \"reset before headers\" (#733), plus OpenRouter connection drops (#3317).\n\t\"network.?error\",\n\t\"connection.?error\",\n\t\"connection.?refused\",\n\t\"connection.?lost\",\n\t\"other side closed\",\n\t\"fetch failed\",\n\t// node-fetch system errors, e.g. the Google ADC OAuth token refresh used by\n\t// google-vertex. The reason is often empty (#10996).\n\t\"request to \\\\S+ failed, reason:\",\n\t\"getaddrinfo\",\n\t\"ENOTFOUND\",\n\t\"EAI_AGAIN\",\n\t\"upstream.?connect\",\n\t\"reset before headers\",\n\t\"socket hang up\",\n\t\"socket connection was closed\",\n\t\"timed? out\",\n\t\"timeout\",\n\t\"terminated\",\n\n\t// WebSocket transports can report close/error text instead of HTTP/fetch text.\n\t\"websocket.?closed\",\n\t\"websocket.?error\",\n\n\t// Premature stream endings from SDKs and transports. Anthropic can throw\n\t// \"stream ended without ...\" and \"Anthropic stream ended before message_stop\"\n\t// (#4433); Bedrock/Smithy can throw an HTTP/2 no-response error (#3594).\n\t\"ended without\",\n\t\"stream ended before message_stop\",\n\t\"stream ended before a terminal response event\",\n\t\"http2 request did not get a response\",\n\t// Codex CLI mid-stream disconnect, relayed by proxies that wrap the Codex CLI,\n\t// e.g. \"stream disconnected before completion: stream closed before response.completed\" (#11057).\n\t\"stream disconnected before completion\",\n\t// Node ERR_HTTP2_STREAM_CANCEL: the HTTP/2 session died before the request was\n\t// sent, e.g. after the Bedrock SDK's 5-minute session timeout (#10379).\n\t\"pending stream has been canceled\",\n\n\t// Provider-requested retry delay cap failures should flow through the outer\n\t// retry policy so callers can surface/abort the backoff (#1123).\n\t\"retry delay\",\n\n\t// Explicit retry guidance emitted mid-stream by OpenAI Responses and Bedrock\n\t// stream exceptions (#6019).\n\t\"you can retry your request\",\n\t\"try your request again\",\n\t\"please retry your request\",\n\n\t// gRPC based providers (e.g. NVIDIA NIM)\n\t\"ResourceExhausted\",\n\n\t// Sign in with ChatGPT: usage or user data temporarily unavailable. Usage\n\t// failures can arrive mid-stream without an HTTP 503 in the message.\n\t\"subscription_sharing_usage_unavailable\",\n\t\"subscription_sharing_user_unavailable\",\n]);\n\n/**\n * Retry policy: bounded attempts with exponential backoff (`baseDelayMs * 2^(attempt-1)`).\n * `maxAgentDelayMs` caps each computed delay and defaults to 60 seconds.\n * Matches `settings.retry` (`enabled`, `maxRetries`, `baseDelayMs`, `maxAgentDelayMs`) in coding-agent; kept\n * here so the classifier and the policy-driven retry loop live together and stay reusable\n * by the SDK and other callers.\n */\nexport interface RetryPolicy {\n\tenabled: boolean;\n\t/** Max retry attempts (0 = no retries). The initial call never counts as a retry. */\n\tmaxRetries: number;\n\t/** Base delay in ms. Per-attempt delay is `baseDelayMs * 2^(attempt-1)` before jitter. */\n\tbaseDelayMs: number;\n\t/** Optional cap for agent-level retry delays in ms. Defaults to 60 seconds. */\n\tmaxAgentDelayMs?: number;\n}\n\nexport const DEFAULT_MAX_AGENT_RETRY_DELAY_MS = 60_000;\n\nexport function retryDelayMs(policy: Pick<RetryPolicy, \"baseDelayMs\" | \"maxAgentDelayMs\">, attempt: number): number {\n\tconst delay = policy.baseDelayMs * 2 ** Math.max(0, attempt - 1);\n\tconst safeDelay = Number.isSafeInteger(delay) ? delay : Number.MAX_SAFE_INTEGER;\n\treturn Math.min(safeDelay, policy.maxAgentDelayMs ?? DEFAULT_MAX_AGENT_RETRY_DELAY_MS);\n}\n\n/** Optional callbacks emitted by {@link retryAssistantCall} around each retry. */\nexport interface RetryCallbacks {\n\t/** Emitted before the backoff sleep of each retry attempt (1-indexed). */\n\tonRetryScheduled?: (\n\t\tattempt: number,\n\t\tmaxAttempts: number,\n\t\tdelayMs: number,\n\t\terrorMessage: string,\n\t) => void | Promise<void>;\n\t/** Emitted after the backoff sleep, immediately before the retried call starts. */\n\tonRetryAttemptStart?: () => void | Promise<void>;\n\t/** Emitted once when the loop ends: success if a later call completed normally. */\n\tonRetryFinished?: (success: boolean, attempt: number, finalError?: string) => void | Promise<void>;\n}\n\nclass RetrySleepAbortError extends Error {\n\tconstructor() {\n\t\tsuper(\"Aborted\");\n\t}\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(new RetrySleepAbortError());\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout(resolve, ms);\n\t\tsignal?.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\treject(new RetrySleepAbortError());\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n}\n\n/**\n * Run a single assistant-producing call with bounded retry on transient errors.\n *\n * Behavior:\n * - A successful response is returned immediately. Aborts are terminal and never\n * retried, but reported as unsuccessful if they happen after a retry was scheduled.\n * Aborts during the backoff sleep are normalized to an aborted `AssistantMessage`\n * too, so callers do not need to care when cancellation happened.\n * - A non-retryable error (per {@link isRetryableAssistantError}, including quota/\n * billing exhaustion) is returned immediately so deterministic errors fail fast.\n * - Otherwise retries up to `maxRetries` times with exponential backoff, emitting\n * `onRetryScheduled` before each sleep, `onRetryAttemptStart` after each sleep before\n * the retried call starts, and `onRetryFinished` once at the end (whether the loop\n * ends in success, exhausted retries, or an aborted backoff).\n *\n * When `policy` is undefined or disabled, the first response is returned unchanged\n * (equivalent to calling `produce()` directly).\n */\nexport async function retryAssistantCall(\n\tproduce: () => Promise<AssistantMessage>,\n\tpolicy: RetryPolicy | undefined,\n\tsignal: AbortSignal | undefined,\n\tcallbacks?: RetryCallbacks,\n): Promise<AssistantMessage> {\n\tconst maxAttempts = policy?.enabled ? policy.maxRetries : 0;\n\n\tlet attempt = 0;\n\tlet lastRetry: { attempt: number; errorMessage: string } | undefined;\n\tfor (;;) {\n\t\tconst response = await produce();\n\n\t\t// Abort: terminal but not successful. Never retry an aborted message.\n\t\tif (response.stopReason === \"aborted\") {\n\t\t\tif (lastRetry) await callbacks?.onRetryFinished?.(false, lastRetry.attempt);\n\t\t\treturn response;\n\t\t}\n\n\t\t// Success: non-error, non-abort responses return as-is.\n\t\tif (response.stopReason !== \"error\") {\n\t\t\tif (lastRetry) await callbacks?.onRetryFinished?.(true, lastRetry.attempt);\n\t\t\treturn response;\n\t\t}\n\n\t\t// Non-retryable, or budget exhausted: return the final error message.\n\t\tif (attempt >= maxAttempts || !isRetryableAssistantError(response)) {\n\t\t\tif (lastRetry) await callbacks?.onRetryFinished?.(false, lastRetry.attempt, response.errorMessage);\n\t\t\treturn response;\n\t\t}\n\n\t\tattempt++;\n\t\tlastRetry = { attempt, errorMessage: response.errorMessage || \"Unknown error\" };\n\t\tconst delayMs = retryDelayMs(policy!, attempt);\n\t\tawait callbacks?.onRetryScheduled?.(attempt, maxAttempts, delayMs, lastRetry.errorMessage);\n\n\t\t// Normalize aborts during retry backoff to the same AssistantMessage shape as\n\t\t// provider stream aborts, so callers do not need to care when cancellation happened.\n\t\ttry {\n\t\t\tawait sleep(delayMs, signal);\n\t\t} catch (error) {\n\t\t\tawait callbacks?.onRetryFinished?.(false, attempt, lastRetry.errorMessage);\n\t\t\tif (error instanceof RetrySleepAbortError) {\n\t\t\t\tconst { errorMessage: _errorMessage, ...rest } = response;\n\t\t\t\treturn { ...rest, stopReason: \"aborted\" };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tawait callbacks?.onRetryAttemptStart?.();\n\t}\n}\n\n/**\n * Classifies whether a failed assistant message looks like a transient provider\n * or transport error, so callers can decide if the last assistant turn should be\n * restarted.\n *\n * This does not implement retry policy. Callers should first handle context\n * overflow separately, then apply their own retry budget, backoff, and reporting\n * before restarting the assistant turn.\n */\nexport function isRetryableAssistantError(message: AssistantMessage): boolean {\n\tif (message.stopReason !== \"error\" || !message.errorMessage) return false;\n\tconst errorMessage = message.errorMessage;\n\tif (NON_RETRYABLE_PROVIDER_LIMIT_ERROR_PATTERN.test(errorMessage)) return false;\n\treturn RETRYABLE_PROVIDER_ERROR_PATTERN.test(errorMessage);\n}\n"]}
|
|
@@ -68,20 +68,34 @@ export declare function getDeclaredTools(messages: TranscriptMessages): Tool[];
|
|
|
68
68
|
export declare function hasToolRedefinitions(messages: TranscriptMessages): boolean;
|
|
69
69
|
/** Whether tool history contains a removal or same-name redeclaration that an addition-only transport cannot replay. */
|
|
70
70
|
export declare function hasNonAdditiveToolChanges(messages: TranscriptMessages): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* How a transport can express tool changes after the first request.
|
|
73
|
+
*
|
|
74
|
+
* - `"none"`: only the top-level tool list exists; it always holds the current tools.
|
|
75
|
+
* - `"additions"`: tools can be added at a later message, but not removed or redefined.
|
|
76
|
+
* - `"changes"`: every tool, including the initial ones, is declared in place, and a later
|
|
77
|
+
* declaration under the same name replaces the earlier one. Removals are not expressible on
|
|
78
|
+
* the wire, so the transport announces them as text and the removed tools stay declared.
|
|
79
|
+
*/
|
|
80
|
+
export type TranscriptToolSupport = "none" | "additions" | "changes";
|
|
71
81
|
export interface TranscriptTools {
|
|
72
82
|
/** Tools sent in the top-level request field. */
|
|
73
83
|
requestTools: Tool[];
|
|
74
84
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
85
|
+
* Number of leading system messages whose tool changes `requestTools` already holds. Every
|
|
86
|
+
* later system message carries its own tool changes in place.
|
|
77
87
|
*/
|
|
78
|
-
|
|
88
|
+
foldedSystemMessages: number;
|
|
79
89
|
}
|
|
80
90
|
/**
|
|
81
|
-
* Split tool declarations between the top-level request field and in-place
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
91
|
+
* Split tool declarations between the top-level request field and in-place changes.
|
|
92
|
+
*
|
|
93
|
+
* With `"changes"`, the top-level list stays empty and every system message, including the
|
|
94
|
+
* leading one, declares its tools in place: an in-place declaration can replace an earlier
|
|
95
|
+
* in-place one, but not a top-level one. With `"additions"`, a removal or redefinition cannot be
|
|
96
|
+
* expressed in place, so the top-level list becomes the tool state after the last such change;
|
|
97
|
+
* later additions stay anchored, and the cached prefix is invalidated once per removal instead
|
|
98
|
+
* of on every later addition. With `"none"`, the top-level list is the current tool set.
|
|
85
99
|
*/
|
|
86
|
-
export declare function resolveTranscriptTools(messages: TranscriptMessages,
|
|
100
|
+
export declare function resolveTranscriptTools(messages: TranscriptMessages, support: TranscriptToolSupport): TranscriptTools;
|
|
87
101
|
//# sourceMappingURL=transcript.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/utils/transcript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG3G,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;GAGG;AACH,wBAAgB,0BAA0B,CACzC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,GACvB,aAAa,GAAG,SAAS,CAU3B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAIpE;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC;AAM7D,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAG/F;AAED,+FAA+F;AAC/F,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAE1E;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EAAE,CAQpE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAuB/F;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAG3E;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,CAIpF;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,iBAAiB,EAC1B,8BAA8B,EAAE,OAAO,GAAG,SAAS,GACjD,iBAAiB,CAEnB;AAED,wGAAwG;AACxG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAOlD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAElE;AAED,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,IAAI,EAAE,CAAC;IACnB,YAAY,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,GAAG,gBAAgB,CAiBzG;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EAAE,CAOrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAW1E;AAED,wHAAwH;AACxH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/utils/transcript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG3G,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;GAGG;AACH,wBAAgB,0BAA0B,CACzC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,GACvB,aAAa,GAAG,SAAS,CAU3B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAIpE;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC;AAM7D,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAG/F;AAED,+FAA+F;AAC/F,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAE1E;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EAAE,CAQpE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAuB/F;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAG3E;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,CAIpF;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,iBAAiB,EAC1B,8BAA8B,EAAE,OAAO,GAAG,SAAS,GACjD,iBAAiB,CAEnB;AAED,wGAAwG;AACxG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAOlD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAElE;AAED,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,IAAI,EAAE,CAAC;IACnB,YAAY,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,GAAG,gBAAgB,CAiBzG;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EAAE,CAOrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAW1E;AAED,wHAAwH;AACxH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAE/E;AAmBD;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,eAAe;IAC/B,iDAAiD;IACjD,YAAY,EAAE,IAAI,EAAE,CAAC;IACrB;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,OAAO,EAAE,qBAAqB,GAAG,eAAe,CAWpH"}
|
package/dist/utils/transcript.js
CHANGED
|
@@ -175,33 +175,44 @@ export function hasToolRedefinitions(messages) {
|
|
|
175
175
|
}
|
|
176
176
|
/** Whether tool history contains a removal or same-name redeclaration that an addition-only transport cannot replay. */
|
|
177
177
|
export function hasNonAdditiveToolChanges(messages) {
|
|
178
|
+
return findLastNonAdditiveToolChange(messages.filter(isSystemMessage)) >= 0;
|
|
179
|
+
}
|
|
180
|
+
/** Index of the last system message with a removal or same-name redeclaration, or -1. */
|
|
181
|
+
function findLastNonAdditiveToolChange(systemMessages) {
|
|
182
|
+
// A name declared before counts as a redeclaration even after its removal: Kimi K3 ignores a
|
|
183
|
+
// removed tool that a later tool message declares again (verified October 2026).
|
|
178
184
|
const declared = new Set();
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
let last = -1;
|
|
186
|
+
for (let index = 0; index < systemMessages.length; index++) {
|
|
187
|
+
const message = systemMessages[index];
|
|
182
188
|
if ((message.toolsRemoved?.length ?? 0) > 0)
|
|
183
|
-
|
|
189
|
+
last = index;
|
|
184
190
|
for (const tool of message.toolsAdded ?? []) {
|
|
185
191
|
if (declared.has(tool.name))
|
|
186
|
-
|
|
192
|
+
last = index;
|
|
187
193
|
declared.add(tool.name);
|
|
188
194
|
}
|
|
189
195
|
}
|
|
190
|
-
return
|
|
196
|
+
return last;
|
|
191
197
|
}
|
|
192
198
|
/**
|
|
193
|
-
* Split tool declarations between the top-level request field and in-place
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
199
|
+
* Split tool declarations between the top-level request field and in-place changes.
|
|
200
|
+
*
|
|
201
|
+
* With `"changes"`, the top-level list stays empty and every system message, including the
|
|
202
|
+
* leading one, declares its tools in place: an in-place declaration can replace an earlier
|
|
203
|
+
* in-place one, but not a top-level one. With `"additions"`, a removal or redefinition cannot be
|
|
204
|
+
* expressed in place, so the top-level list becomes the tool state after the last such change;
|
|
205
|
+
* later additions stay anchored, and the cached prefix is invalidated once per removal instead
|
|
206
|
+
* of on every later addition. With `"none"`, the top-level list is the current tool set.
|
|
197
207
|
*/
|
|
198
|
-
export function resolveTranscriptTools(messages,
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
requestTools:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
208
|
+
export function resolveTranscriptTools(messages, support) {
|
|
209
|
+
const systemMessages = messages.filter(isSystemMessage);
|
|
210
|
+
if (support === "none") {
|
|
211
|
+
return { requestTools: getCurrentTools(systemMessages), foldedSystemMessages: systemMessages.length };
|
|
212
|
+
}
|
|
213
|
+
if (support === "changes")
|
|
214
|
+
return { requestTools: [], foldedSystemMessages: 0 };
|
|
215
|
+
const folded = Math.max(getInitialSystemMessage(messages) ? 1 : 0, findLastNonAdditiveToolChange(systemMessages) + 1);
|
|
216
|
+
return { requestTools: getCurrentTools(systemMessages.slice(0, folded)), foldedSystemMessages: folded };
|
|
206
217
|
}
|
|
207
218
|
//# sourceMappingURL=transcript.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/utils/transcript.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, Message, SystemMessage, Tool, ToolReference, TranscriptContext } from \"../types.ts\";\nimport { contentText, getSystemMessageText } from \"./text.ts\";\n\nexport type { TranscriptContext } from \"../types.ts\";\n\n/**\n * Build the leading system message for a prompt and tool set. Returns undefined when\n * both are empty, so an empty transcript stays empty.\n */\nexport function createInitialSystemMessage(\n\tsystemPrompt: string | undefined,\n\ttools: Tool[] | undefined,\n): SystemMessage | undefined {\n\tconst hasSystemPrompt = systemPrompt !== undefined && systemPrompt.length > 0;\n\tconst hasTools = tools !== undefined && tools.length > 0;\n\tif (!hasSystemPrompt && !hasTools) return undefined;\n\treturn {\n\t\trole: \"system\",\n\t\tcontent: systemPrompt ?? \"\",\n\t\t...(hasTools ? { toolsAdded: tools } : {}),\n\t\ttimestamp: 0,\n\t};\n}\n\n/**\n * Fold `Context.systemPrompt` and `Context.tools` into a leading system message.\n * This is the only entry point that produces a {@link TranscriptContext}; every\n * provider-facing function expects the result.\n */\nexport function normalizeContext(context: Context): TranscriptContext {\n\tconst initialMessage = createInitialSystemMessage(context.systemPrompt, context.tools);\n\tconst messages = initialMessage ? [initialMessage, ...context.messages] : context.messages;\n\treturn { messages } as TranscriptContext;\n}\n\n/**\n * Any message list. The replay helpers only read entries whose role is `\"system\"`, so\n * agent transcripts that carry custom message roles can be passed without filtering.\n */\nexport type TranscriptMessages = readonly { role: string }[];\n\nfunction isSystemMessage(message: { role: string }): message is SystemMessage {\n\treturn message.role === \"system\";\n}\n\n/** Return the leading system message, if the transcript starts with one. */\nexport function getInitialSystemMessage(messages: TranscriptMessages): SystemMessage | undefined {\n\tconst first = messages[0];\n\treturn first && isSystemMessage(first) ? first : undefined;\n}\n\n/** Drop the leading system message for APIs that carry the prompt outside the message list. */\nexport function withoutInitialSystemMessage(messages: Message[]): Message[] {\n\treturn getInitialSystemMessage(messages) ? messages.slice(1) : messages;\n}\n\n/** Resolve the tools available after applying every transcript delta in order. */\nexport function getCurrentTools(messages: TranscriptMessages): Tool[] {\n\tconst tools = new Map<string, Tool>();\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\tfor (const tool of message.toolsRemoved ?? []) tools.delete(tool.name);\n\t\tfor (const tool of message.toolsAdded ?? []) tools.set(tool.name, tool);\n\t}\n\treturn [...tools.values()];\n}\n\n/**\n * Replay every system message into one leading system message holding the current\n * prompt and tools. Later `content` is appended to the base prompt, `sections` are\n * patched by name, and tools are resolved with {@link getCurrentTools}.\n */\nexport function getCurrentSystemMessage(messages: TranscriptMessages): SystemMessage | undefined {\n\tconst content: string[] = [];\n\tconst sections = new Map<string, string>();\n\tlet timestamp: number | undefined;\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\ttimestamp ??= message.timestamp;\n\t\tconst text = contentText(message.content);\n\t\tif (text.length > 0) content.push(text);\n\t\tfor (const [name, value] of Object.entries(message.sections ?? {})) {\n\t\t\tif (value === null) sections.delete(name);\n\t\t\telse sections.set(name, value);\n\t\t}\n\t}\n\tconst tools = getCurrentTools(messages);\n\tif (timestamp === undefined && tools.length === 0) return undefined;\n\treturn {\n\t\trole: \"system\",\n\t\tcontent: content.join(\"\\n\\n\"),\n\t\t...(sections.size > 0 ? { sections: Object.fromEntries(sections) } : {}),\n\t\t...(tools.length > 0 ? { toolsAdded: tools } : {}),\n\t\ttimestamp: timestamp ?? 0,\n\t};\n}\n\n/** Render the current system prompt text after replaying every system message. */\nexport function getCurrentSystemPrompt(messages: TranscriptMessages): string {\n\tconst message = getCurrentSystemMessage(messages);\n\treturn message ? getSystemMessageText(message) : \"\";\n}\n\n/**\n * Rebuild the transcript for APIs without mid-conversation system messages: the replayed\n * system message leads, and every later system message is dropped.\n */\nexport function collapseSystemMessages(context: TranscriptContext): TranscriptContext {\n\tconst head = getCurrentSystemMessage(context.messages);\n\tconst messages = context.messages.filter((message) => message.role !== \"system\");\n\treturn { messages: head ? [head, ...messages] : messages } as TranscriptContext;\n}\n\n/** Keep later system messages in place when the model accepts them; otherwise collapse them. */\nexport function resolveTranscript(\n\tcontext: TranscriptContext,\n\tsupportsMidConvoSystemMessages: boolean | undefined,\n): TranscriptContext {\n\treturn supportsMidConvoSystemMessages ? context : collapseSystemMessages(context);\n}\n\n/** Strip executable and display-only fields from a tool before transcript comparison or persistence. */\nexport function toToolDeclaration(tool: Tool): Tool {\n\treturn {\n\t\tname: tool.name,\n\t\tdescription: tool.description,\n\t\tparameters: JSON.parse(JSON.stringify(tool.parameters)) as Tool[\"parameters\"],\n\t\t...(tool.constrainedSampling === undefined ? {} : { constrainedSampling: tool.constrainedSampling }),\n\t};\n}\n\n/**\n * Whether two tools declare the same interface to the model.\n *\n * Both sides go through {@link toToolDeclaration} first: its JSON round-trip drops the\n * typebox symbol keys and `undefined` fields that a structural comparison would see, and\n * builds both objects with the same key order, so comparing the serialized declarations\n * is exact. This avoids a deep-equal dependency in a browser-safe package.\n */\nexport function declarationsEqual(left: Tool, right: Tool): boolean {\n\treturn JSON.stringify(toToolDeclaration(left)) === JSON.stringify(toToolDeclaration(right));\n}\n\nexport interface ToolStateChanges {\n\ttoolsAdded: Tool[];\n\ttoolsRemoved: ToolReference[];\n}\n\n/** Compare two complete tool states. A changed definition is a removal followed by an addition. */\nexport function getToolStateChanges(previous: readonly Tool[], current: readonly Tool[]): ToolStateChanges {\n\tconst previousTools = new Map(previous.map((tool) => [tool.name, tool]));\n\tconst currentTools = new Map(current.map((tool) => [tool.name, tool]));\n\treturn {\n\t\ttoolsAdded: current\n\t\t\t.filter((tool) => {\n\t\t\t\tconst previousTool = previousTools.get(tool.name);\n\t\t\t\treturn previousTool === undefined || !declarationsEqual(previousTool, tool);\n\t\t\t})\n\t\t\t.map(toToolDeclaration),\n\t\ttoolsRemoved: previous\n\t\t\t.filter((tool) => {\n\t\t\t\tconst currentTool = currentTools.get(tool.name);\n\t\t\t\treturn currentTool === undefined || !declarationsEqual(tool, currentTool);\n\t\t\t})\n\t\t\t.map((tool) => ({ name: tool.name })),\n\t};\n}\n\n/** Every definition referenced by transcript tool state, in first-declaration order. */\nexport function getDeclaredTools(messages: TranscriptMessages): Tool[] {\n\tconst definitions = new Map<string, Tool>();\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\tfor (const tool of message.toolsAdded ?? []) definitions.set(tool.name, tool);\n\t}\n\treturn [...definitions.values()];\n}\n\n/**\n * Whether a tool name was declared twice with different definitions. A transport that can\n * only reference previously declared tools by name cannot replay such a history.\n *\n * @deprecated No built-in transport needs this anymore: Anthropic expresses redefinitions with\n * inline `tool_definition` blocks. Kept for API compatibility and will be removed in a future release.\n */\nexport function hasToolRedefinitions(messages: TranscriptMessages): boolean {\n\tconst declared = new Map<string, Tool>();\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\tfor (const tool of message.toolsAdded ?? []) {\n\t\t\tconst previous = declared.get(tool.name);\n\t\t\tif (previous !== undefined && !declarationsEqual(previous, tool)) return true;\n\t\t\tdeclared.set(tool.name, tool);\n\t\t}\n\t}\n\treturn false;\n}\n\n/** Whether tool history contains a removal or same-name redeclaration that an addition-only transport cannot replay. */\nexport function hasNonAdditiveToolChanges(messages: TranscriptMessages): boolean {\n\tconst declared = new Set<string>();\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\tif ((message.toolsRemoved?.length ?? 0) > 0) return true;\n\t\tfor (const tool of message.toolsAdded ?? []) {\n\t\t\tif (declared.has(tool.name)) return true;\n\t\t\tdeclared.add(tool.name);\n\t\t}\n\t}\n\treturn false;\n}\n\nexport interface TranscriptTools {\n\t/** Tools sent in the top-level request field. */\n\trequestTools: Tool[];\n\t/**\n\t * Whether later system messages carry their own `toolsAdded` as in-place additions.\n\t * When false, `requestTools` already holds the complete current tool set.\n\t */\n\tanchorsAdditions: boolean;\n}\n\n/**\n * Split tool declarations between the top-level request field and in-place additions.\n * Transports that can anchor additions at a system message keep the initial tools at the\n * top and load later ones where they appear; that only works when no tool was removed or\n * redeclared, so everything else sends the current tool list.\n */\nexport function resolveTranscriptTools(messages: TranscriptMessages, supportsToolAdditions: boolean): TranscriptTools {\n\tconst anchorsAdditions = supportsToolAdditions && !hasNonAdditiveToolChanges(messages);\n\treturn {\n\t\trequestTools: anchorsAdditions\n\t\t\t? (getInitialSystemMessage(messages)?.toolsAdded ?? [])\n\t\t\t: getCurrentTools(messages),\n\t\tanchorsAdditions,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/utils/transcript.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, Message, SystemMessage, Tool, ToolReference, TranscriptContext } from \"../types.ts\";\nimport { contentText, getSystemMessageText } from \"./text.ts\";\n\nexport type { TranscriptContext } from \"../types.ts\";\n\n/**\n * Build the leading system message for a prompt and tool set. Returns undefined when\n * both are empty, so an empty transcript stays empty.\n */\nexport function createInitialSystemMessage(\n\tsystemPrompt: string | undefined,\n\ttools: Tool[] | undefined,\n): SystemMessage | undefined {\n\tconst hasSystemPrompt = systemPrompt !== undefined && systemPrompt.length > 0;\n\tconst hasTools = tools !== undefined && tools.length > 0;\n\tif (!hasSystemPrompt && !hasTools) return undefined;\n\treturn {\n\t\trole: \"system\",\n\t\tcontent: systemPrompt ?? \"\",\n\t\t...(hasTools ? { toolsAdded: tools } : {}),\n\t\ttimestamp: 0,\n\t};\n}\n\n/**\n * Fold `Context.systemPrompt` and `Context.tools` into a leading system message.\n * This is the only entry point that produces a {@link TranscriptContext}; every\n * provider-facing function expects the result.\n */\nexport function normalizeContext(context: Context): TranscriptContext {\n\tconst initialMessage = createInitialSystemMessage(context.systemPrompt, context.tools);\n\tconst messages = initialMessage ? [initialMessage, ...context.messages] : context.messages;\n\treturn { messages } as TranscriptContext;\n}\n\n/**\n * Any message list. The replay helpers only read entries whose role is `\"system\"`, so\n * agent transcripts that carry custom message roles can be passed without filtering.\n */\nexport type TranscriptMessages = readonly { role: string }[];\n\nfunction isSystemMessage(message: { role: string }): message is SystemMessage {\n\treturn message.role === \"system\";\n}\n\n/** Return the leading system message, if the transcript starts with one. */\nexport function getInitialSystemMessage(messages: TranscriptMessages): SystemMessage | undefined {\n\tconst first = messages[0];\n\treturn first && isSystemMessage(first) ? first : undefined;\n}\n\n/** Drop the leading system message for APIs that carry the prompt outside the message list. */\nexport function withoutInitialSystemMessage(messages: Message[]): Message[] {\n\treturn getInitialSystemMessage(messages) ? messages.slice(1) : messages;\n}\n\n/** Resolve the tools available after applying every transcript delta in order. */\nexport function getCurrentTools(messages: TranscriptMessages): Tool[] {\n\tconst tools = new Map<string, Tool>();\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\tfor (const tool of message.toolsRemoved ?? []) tools.delete(tool.name);\n\t\tfor (const tool of message.toolsAdded ?? []) tools.set(tool.name, tool);\n\t}\n\treturn [...tools.values()];\n}\n\n/**\n * Replay every system message into one leading system message holding the current\n * prompt and tools. Later `content` is appended to the base prompt, `sections` are\n * patched by name, and tools are resolved with {@link getCurrentTools}.\n */\nexport function getCurrentSystemMessage(messages: TranscriptMessages): SystemMessage | undefined {\n\tconst content: string[] = [];\n\tconst sections = new Map<string, string>();\n\tlet timestamp: number | undefined;\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\ttimestamp ??= message.timestamp;\n\t\tconst text = contentText(message.content);\n\t\tif (text.length > 0) content.push(text);\n\t\tfor (const [name, value] of Object.entries(message.sections ?? {})) {\n\t\t\tif (value === null) sections.delete(name);\n\t\t\telse sections.set(name, value);\n\t\t}\n\t}\n\tconst tools = getCurrentTools(messages);\n\tif (timestamp === undefined && tools.length === 0) return undefined;\n\treturn {\n\t\trole: \"system\",\n\t\tcontent: content.join(\"\\n\\n\"),\n\t\t...(sections.size > 0 ? { sections: Object.fromEntries(sections) } : {}),\n\t\t...(tools.length > 0 ? { toolsAdded: tools } : {}),\n\t\ttimestamp: timestamp ?? 0,\n\t};\n}\n\n/** Render the current system prompt text after replaying every system message. */\nexport function getCurrentSystemPrompt(messages: TranscriptMessages): string {\n\tconst message = getCurrentSystemMessage(messages);\n\treturn message ? getSystemMessageText(message) : \"\";\n}\n\n/**\n * Rebuild the transcript for APIs without mid-conversation system messages: the replayed\n * system message leads, and every later system message is dropped.\n */\nexport function collapseSystemMessages(context: TranscriptContext): TranscriptContext {\n\tconst head = getCurrentSystemMessage(context.messages);\n\tconst messages = context.messages.filter((message) => message.role !== \"system\");\n\treturn { messages: head ? [head, ...messages] : messages } as TranscriptContext;\n}\n\n/** Keep later system messages in place when the model accepts them; otherwise collapse them. */\nexport function resolveTranscript(\n\tcontext: TranscriptContext,\n\tsupportsMidConvoSystemMessages: boolean | undefined,\n): TranscriptContext {\n\treturn supportsMidConvoSystemMessages ? context : collapseSystemMessages(context);\n}\n\n/** Strip executable and display-only fields from a tool before transcript comparison or persistence. */\nexport function toToolDeclaration(tool: Tool): Tool {\n\treturn {\n\t\tname: tool.name,\n\t\tdescription: tool.description,\n\t\tparameters: JSON.parse(JSON.stringify(tool.parameters)) as Tool[\"parameters\"],\n\t\t...(tool.constrainedSampling === undefined ? {} : { constrainedSampling: tool.constrainedSampling }),\n\t};\n}\n\n/**\n * Whether two tools declare the same interface to the model.\n *\n * Both sides go through {@link toToolDeclaration} first: its JSON round-trip drops the\n * typebox symbol keys and `undefined` fields that a structural comparison would see, and\n * builds both objects with the same key order, so comparing the serialized declarations\n * is exact. This avoids a deep-equal dependency in a browser-safe package.\n */\nexport function declarationsEqual(left: Tool, right: Tool): boolean {\n\treturn JSON.stringify(toToolDeclaration(left)) === JSON.stringify(toToolDeclaration(right));\n}\n\nexport interface ToolStateChanges {\n\ttoolsAdded: Tool[];\n\ttoolsRemoved: ToolReference[];\n}\n\n/** Compare two complete tool states. A changed definition is a removal followed by an addition. */\nexport function getToolStateChanges(previous: readonly Tool[], current: readonly Tool[]): ToolStateChanges {\n\tconst previousTools = new Map(previous.map((tool) => [tool.name, tool]));\n\tconst currentTools = new Map(current.map((tool) => [tool.name, tool]));\n\treturn {\n\t\ttoolsAdded: current\n\t\t\t.filter((tool) => {\n\t\t\t\tconst previousTool = previousTools.get(tool.name);\n\t\t\t\treturn previousTool === undefined || !declarationsEqual(previousTool, tool);\n\t\t\t})\n\t\t\t.map(toToolDeclaration),\n\t\ttoolsRemoved: previous\n\t\t\t.filter((tool) => {\n\t\t\t\tconst currentTool = currentTools.get(tool.name);\n\t\t\t\treturn currentTool === undefined || !declarationsEqual(tool, currentTool);\n\t\t\t})\n\t\t\t.map((tool) => ({ name: tool.name })),\n\t};\n}\n\n/** Every definition referenced by transcript tool state, in first-declaration order. */\nexport function getDeclaredTools(messages: TranscriptMessages): Tool[] {\n\tconst definitions = new Map<string, Tool>();\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\tfor (const tool of message.toolsAdded ?? []) definitions.set(tool.name, tool);\n\t}\n\treturn [...definitions.values()];\n}\n\n/**\n * Whether a tool name was declared twice with different definitions. A transport that can\n * only reference previously declared tools by name cannot replay such a history.\n *\n * @deprecated No built-in transport needs this anymore: Anthropic expresses redefinitions with\n * inline `tool_definition` blocks. Kept for API compatibility and will be removed in a future release.\n */\nexport function hasToolRedefinitions(messages: TranscriptMessages): boolean {\n\tconst declared = new Map<string, Tool>();\n\tfor (const message of messages) {\n\t\tif (!isSystemMessage(message)) continue;\n\t\tfor (const tool of message.toolsAdded ?? []) {\n\t\t\tconst previous = declared.get(tool.name);\n\t\t\tif (previous !== undefined && !declarationsEqual(previous, tool)) return true;\n\t\t\tdeclared.set(tool.name, tool);\n\t\t}\n\t}\n\treturn false;\n}\n\n/** Whether tool history contains a removal or same-name redeclaration that an addition-only transport cannot replay. */\nexport function hasNonAdditiveToolChanges(messages: TranscriptMessages): boolean {\n\treturn findLastNonAdditiveToolChange(messages.filter(isSystemMessage)) >= 0;\n}\n\n/** Index of the last system message with a removal or same-name redeclaration, or -1. */\nfunction findLastNonAdditiveToolChange(systemMessages: readonly SystemMessage[]): number {\n\t// A name declared before counts as a redeclaration even after its removal: Kimi K3 ignores a\n\t// removed tool that a later tool message declares again (verified October 2026).\n\tconst declared = new Set<string>();\n\tlet last = -1;\n\tfor (let index = 0; index < systemMessages.length; index++) {\n\t\tconst message = systemMessages[index];\n\t\tif ((message.toolsRemoved?.length ?? 0) > 0) last = index;\n\t\tfor (const tool of message.toolsAdded ?? []) {\n\t\t\tif (declared.has(tool.name)) last = index;\n\t\t\tdeclared.add(tool.name);\n\t\t}\n\t}\n\treturn last;\n}\n\n/**\n * How a transport can express tool changes after the first request.\n *\n * - `\"none\"`: only the top-level tool list exists; it always holds the current tools.\n * - `\"additions\"`: tools can be added at a later message, but not removed or redefined.\n * - `\"changes\"`: every tool, including the initial ones, is declared in place, and a later\n * declaration under the same name replaces the earlier one. Removals are not expressible on\n * the wire, so the transport announces them as text and the removed tools stay declared.\n */\nexport type TranscriptToolSupport = \"none\" | \"additions\" | \"changes\";\n\nexport interface TranscriptTools {\n\t/** Tools sent in the top-level request field. */\n\trequestTools: Tool[];\n\t/**\n\t * Number of leading system messages whose tool changes `requestTools` already holds. Every\n\t * later system message carries its own tool changes in place.\n\t */\n\tfoldedSystemMessages: number;\n}\n\n/**\n * Split tool declarations between the top-level request field and in-place changes.\n *\n * With `\"changes\"`, the top-level list stays empty and every system message, including the\n * leading one, declares its tools in place: an in-place declaration can replace an earlier\n * in-place one, but not a top-level one. With `\"additions\"`, a removal or redefinition cannot be\n * expressed in place, so the top-level list becomes the tool state after the last such change;\n * later additions stay anchored, and the cached prefix is invalidated once per removal instead\n * of on every later addition. With `\"none\"`, the top-level list is the current tool set.\n */\nexport function resolveTranscriptTools(messages: TranscriptMessages, support: TranscriptToolSupport): TranscriptTools {\n\tconst systemMessages = messages.filter(isSystemMessage);\n\tif (support === \"none\") {\n\t\treturn { requestTools: getCurrentTools(systemMessages), foldedSystemMessages: systemMessages.length };\n\t}\n\tif (support === \"changes\") return { requestTools: [], foldedSystemMessages: 0 };\n\tconst folded = Math.max(\n\t\tgetInitialSystemMessage(messages) ? 1 : 0,\n\t\tfindLastNonAdditiveToolChange(systemMessages) + 1,\n\t);\n\treturn { requestTools: getCurrentTools(systemMessages.slice(0, folded)), foldedSystemMessages: folded };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAmSlD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAMvE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAmSlD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAMvE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAoCzE"}
|
package/dist/utils/validation.js
CHANGED
|
@@ -278,6 +278,9 @@ export function validateToolCall(tools, toolCall) {
|
|
|
278
278
|
* @throws Error with formatted message if validation fails
|
|
279
279
|
*/
|
|
280
280
|
export function validateToolArguments(tool, toolCall) {
|
|
281
|
+
if (toolCall.argumentsError) {
|
|
282
|
+
throw new Error(`Invalid arguments for tool "${toolCall.name}": ${toolCall.argumentsError}`);
|
|
283
|
+
}
|
|
281
284
|
const args = structuredClone(toolCall.arguments);
|
|
282
285
|
normalizeOptionalNulls(args, tool.parameters);
|
|
283
286
|
Value.Convert(tool.parameters, args);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,MAAM,cAAc,GAAG,IAAI,OAAO,EAAsC,CAAC;AACzE,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAahD,SAAS,cAAc,CAAC,MAAwB;IAC/C,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,IAAY;IACpD,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,QAAQ;YACZ,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;QAClC,KAAK,SAAS;YACb,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7D,KAAK,SAAS;YACb,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC;QACnC,KAAK,QAAQ;YACZ,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;QAClC,KAAK,MAAM;YACV,OAAO,KAAK,KAAK,IAAI,CAAC;QACvB,KAAK,OAAO;YACX,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7B,KAAK,QAAQ;YACZ,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7E;YACC,OAAO,KAAK,CAAC;IACf,CAAC;AACF,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAwB;IACtD,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,MAA4B,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,IAAY;IAC1D,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,QAAQ,EAAE,CAAC;YACf,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,CAAC,CAAC;YACV,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACtD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7B,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC7B,OAAO,MAAM,CAAC;gBACf,CAAC;YACF,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;gBAChC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,KAAK,SAAS,EAAE,CAAC;YAChB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,CAAC,CAAC;YACV,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACtD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7B,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC9B,OAAO,MAAM,CAAC;gBACf,CAAC;YACF,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;gBAChC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,KAAK,SAAS,EAAE,CAAC;YAChB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,KAAK,CAAC;YACd,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC/B,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC;gBACb,CAAC;gBACD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;oBACvB,OAAO,KAAK,CAAC;gBACd,CAAC;YACF,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC/B,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;oBACjB,OAAO,IAAI,CAAC;gBACb,CAAC;gBACD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;oBACjB,OAAO,KAAK,CAAC;gBACd,CAAC;YACF,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,KAAK,QAAQ,EAAE,CAAC;YACf,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,EAAE,CAAC;YACX,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,KAAK,MAAM,EAAE,CAAC;YACb,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;gBACpD,OAAO,IAAI,CAAC;YACb,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD;YACC,OAAO,KAAK,CAAC;IACf,CAAC;AACF,CAAC;AAED,SAAS,yBAAyB,CAAC,KAA8B,EAAE,MAAwB;IAC1F,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACrC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAE/E,IAAI,UAAU,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAChE,IAAI,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;gBACrB,SAAS;YACV,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;QAC/D,CAAC;IACF,CAAC;IAED,IAAI,MAAM,CAAC,oBAAoB,IAAI,OAAO,MAAM,CAAC,oBAAoB,KAAK,QAAQ,EAAE,CAAC;QACpF,KAAK,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1D,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,SAAS;YACV,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,aAAa,EAAE,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAC/E,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAgB,EAAE,MAAwB;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YACnD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,CAAC,UAAU,EAAE,CAAC;gBACjB,SAAS;YACV,CAAC;YACD,KAAK,CAAC,KAAK,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO;IACR,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YACnD,KAAK,CAAC,KAAK,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,OAA2B;IACzE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC;QAChB,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc,EAAE,MAAwB;IACrE,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACnC,SAAS,GAAG,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,SAAS,GAAG,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,SAAS,GAAG,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,kBAAkB,GACvB,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACpG,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACnD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACtC,MAAM,SAAS,GAAG,qBAAqB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YAC/D,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC7B,SAAS,GAAG,SAAS,CAAC;gBACtB,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;IAED,IACC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC9B,OAAO,SAAS,KAAK,QAAQ;QAC7B,SAAS,KAAK,IAAI;QAClB,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EACxB,CAAC;QACF,yBAAyB,CAAC,SAAoC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/D,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc,EAAE,MAAwB;IACvE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;gBACnD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACvC,IAAI,UAAU;oBAAE,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;YAClE,CAAC;QACF,CAAC;aAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,CAAC;QACD,OAAO;IACR,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU;QAAE,OAAO;IAE9E,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAChD,KAAK,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACvE,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC;YAAE,SAAS;QAC/B,IACC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI;YACpB,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAClB,OAAQ,cAAqC,CAAC,IAAI,KAAK,QAAQ;YAC/D,qBAAqB,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAC3D,CAAC;YACF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACP,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,YAAY,CAAC,MAA0B;IAC/C,MAAM,GAAG,GAAG,MAAgB,CAAC;IAC7B,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,MAAM,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACnC,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAgC;IAC7D,IAAI,KAAK,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,kBAAkB,GAAI,KAAK,CAAC,MAA4C,CAAC,kBAAkB,CAAC;QAClG,MAAM,gBAAgB,GAAG,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC;QACjD,IAAI,gBAAgB,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC3E,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;QACxE,CAAC;IACF,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACvE,OAAO,IAAI,IAAI,MAAM,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,QAAkB;IACjE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,SAAS,QAAQ,CAAC,IAAI,aAAa,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAU,EAAE,QAAkB;IACnE,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACjD,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,UAA8B,CAAC,CAAC;IAClE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAErC,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC3E,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,UAA8B,CAAC,CAAC;QAChF,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACtB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBAClG,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClB,CAAC;gBACD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACP,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YAClD,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GACX,SAAS;SACP,MAAM,CAAC,IAAI,CAAC;SACZ,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,oBAAoB,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;SACtE,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC;IAE5C,MAAM,YAAY,GAAG,+BAA+B,QAAQ,CAAC,IAAI,OAAO,MAAM,4BAA4B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IAExJ,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;AAC/B,CAAC","sourcesContent":["import { Compile } from \"typebox/compile\";\nimport type { TLocalizedValidationError } from \"typebox/error\";\nimport { Value } from \"typebox/value\";\nimport type { Tool, ToolCall } from \"../types.ts\";\n\nconst validatorCache = new WeakMap<object, ReturnType<typeof Compile>>();\nconst TYPEBOX_KIND = Symbol.for(\"TypeBox.Kind\");\n\ninterface JsonSchemaObject {\n\ttype?: string | string[];\n\tproperties?: Record<string, JsonSchemaObject>;\n\trequired?: string[];\n\titems?: JsonSchemaObject | JsonSchemaObject[];\n\tadditionalProperties?: boolean | JsonSchemaObject;\n\tallOf?: JsonSchemaObject[];\n\tanyOf?: JsonSchemaObject[];\n\toneOf?: JsonSchemaObject[];\n}\n\nfunction getSchemaTypes(schema: JsonSchemaObject): string[] {\n\tif (typeof schema.type === \"string\") {\n\t\treturn [schema.type];\n\t}\n\tif (Array.isArray(schema.type)) {\n\t\treturn schema.type.filter((type): type is string => typeof type === \"string\");\n\t}\n\treturn [];\n}\n\nfunction matchesJsonType(value: unknown, type: string): boolean {\n\tswitch (type) {\n\t\tcase \"number\":\n\t\t\treturn typeof value === \"number\";\n\t\tcase \"integer\":\n\t\t\treturn typeof value === \"number\" && Number.isInteger(value);\n\t\tcase \"boolean\":\n\t\t\treturn typeof value === \"boolean\";\n\t\tcase \"string\":\n\t\t\treturn typeof value === \"string\";\n\t\tcase \"null\":\n\t\t\treturn value === null;\n\t\tcase \"array\":\n\t\t\treturn Array.isArray(value);\n\t\tcase \"object\":\n\t\t\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction getSubSchemaValidator(schema: JsonSchemaObject): ReturnType<typeof Compile> | undefined {\n\ttry {\n\t\treturn getValidator(schema as Tool[\"parameters\"]);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction coercePrimitiveByType(value: unknown, type: string): unknown {\n\tswitch (type) {\n\t\tcase \"number\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (typeof value === \"string\" && value.trim() !== \"\") {\n\t\t\t\tconst parsed = Number(value);\n\t\t\t\tif (Number.isFinite(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof value === \"boolean\") {\n\t\t\t\treturn value ? 1 : 0;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"integer\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (typeof value === \"string\" && value.trim() !== \"\") {\n\t\t\t\tconst parsed = Number(value);\n\t\t\t\tif (Number.isInteger(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof value === \"boolean\") {\n\t\t\t\treturn value ? 1 : 0;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"boolean\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tif (value === \"true\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (value === \"false\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof value === \"number\") {\n\t\t\t\tif (value === 1) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"string\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"null\": {\n\t\t\tif (value === \"\" || value === 0 || value === false) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tdefault:\n\t\t\treturn value;\n\t}\n}\n\nfunction applySchemaObjectCoercion(value: Record<string, unknown>, schema: JsonSchemaObject): void {\n\tconst properties = schema.properties;\n\tconst definedKeys = new Set<string>(properties ? Object.keys(properties) : []);\n\n\tif (properties) {\n\t\tfor (const [key, propertySchema] of Object.entries(properties)) {\n\t\t\tif (!(key in value)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue[key] = coerceWithJsonSchema(value[key], propertySchema);\n\t\t}\n\t}\n\n\tif (schema.additionalProperties && typeof schema.additionalProperties === \"object\") {\n\t\tfor (const [key, propertyValue] of Object.entries(value)) {\n\t\t\tif (definedKeys.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue[key] = coerceWithJsonSchema(propertyValue, schema.additionalProperties);\n\t\t}\n\t}\n}\n\nfunction applySchemaArrayCoercion(value: unknown[], schema: JsonSchemaObject): void {\n\tif (Array.isArray(schema.items)) {\n\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\tconst itemSchema = schema.items[index];\n\t\t\tif (!itemSchema) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue[index] = coerceWithJsonSchema(value[index], itemSchema);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (schema.items && typeof schema.items === \"object\") {\n\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\tvalue[index] = coerceWithJsonSchema(value[index], schema.items);\n\t\t}\n\t}\n}\n\nfunction coerceWithUnionSchema(value: unknown, schemas: JsonSchemaObject[]): unknown {\n\tfor (const schema of schemas) {\n\t\tconst validator = getSubSchemaValidator(schema);\n\t\tif (validator?.Check(value)) {\n\t\t\treturn value;\n\t\t}\n\t}\n\n\tfor (const schema of schemas) {\n\t\tconst candidate = structuredClone(value);\n\t\tconst coerced = coerceWithJsonSchema(candidate, schema);\n\t\tconst validator = getSubSchemaValidator(schema);\n\t\tif (validator?.Check(coerced)) {\n\t\t\treturn coerced;\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction coerceWithJsonSchema(value: unknown, schema: JsonSchemaObject): unknown {\n\tlet nextValue = value;\n\n\tif (Array.isArray(schema.allOf)) {\n\t\tfor (const nested of schema.allOf) {\n\t\t\tnextValue = coerceWithJsonSchema(nextValue, nested);\n\t\t}\n\t}\n\n\tif (Array.isArray(schema.anyOf)) {\n\t\tnextValue = coerceWithUnionSchema(nextValue, schema.anyOf);\n\t}\n\n\tif (Array.isArray(schema.oneOf)) {\n\t\tnextValue = coerceWithUnionSchema(nextValue, schema.oneOf);\n\t}\n\n\tconst schemaTypes = getSchemaTypes(schema);\n\tconst matchesUnionMember =\n\t\tschemaTypes.length > 1 && schemaTypes.some((schemaType) => matchesJsonType(nextValue, schemaType));\n\tif (schemaTypes.length > 0 && !matchesUnionMember) {\n\t\tfor (const schemaType of schemaTypes) {\n\t\t\tconst candidate = coercePrimitiveByType(nextValue, schemaType);\n\t\t\tif (candidate !== nextValue) {\n\t\t\t\tnextValue = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (\n\t\tschemaTypes.includes(\"object\") &&\n\t\ttypeof nextValue === \"object\" &&\n\t\tnextValue !== null &&\n\t\t!Array.isArray(nextValue)\n\t) {\n\t\tapplySchemaObjectCoercion(nextValue as Record<string, unknown>, schema);\n\t}\n\n\tif (schemaTypes.includes(\"array\") && Array.isArray(nextValue)) {\n\t\tapplySchemaArrayCoercion(nextValue, schema);\n\t}\n\n\treturn nextValue;\n}\n\nfunction normalizeOptionalNulls(value: unknown, schema: JsonSchemaObject): void {\n\tif (Array.isArray(value)) {\n\t\tif (Array.isArray(schema.items)) {\n\t\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\t\tconst itemSchema = schema.items[index];\n\t\t\t\tif (itemSchema) normalizeOptionalNulls(value[index], itemSchema);\n\t\t\t}\n\t\t} else if (schema.items) {\n\t\t\tfor (const item of value) normalizeOptionalNulls(item, schema.items);\n\t\t}\n\t\treturn;\n\t}\n\tif (typeof value !== \"object\" || value === null || !schema.properties) return;\n\n\tconst object = value as Record<string, unknown>;\n\tconst required = new Set(schema.required ?? []);\n\tfor (const [key, propertySchema] of Object.entries(schema.properties)) {\n\t\tif (!(key in object)) continue;\n\t\tif (\n\t\t\tobject[key] === null &&\n\t\t\t!required.has(key) &&\n\t\t\ttypeof (propertySchema as { $ref?: unknown }).$ref !== \"string\" &&\n\t\t\tgetSubSchemaValidator(propertySchema)?.Check(null) === false\n\t\t) {\n\t\t\tdelete object[key];\n\t\t} else {\n\t\t\tnormalizeOptionalNulls(object[key], propertySchema);\n\t\t}\n\t}\n}\n\nfunction getValidator(schema: Tool[\"parameters\"]): ReturnType<typeof Compile> {\n\tconst key = schema as object;\n\tconst cached = validatorCache.get(key);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\tconst validator = Compile(schema);\n\tvalidatorCache.set(key, validator);\n\treturn validator;\n}\n\nfunction formatValidationPath(error: TLocalizedValidationError): string {\n\tif (error.keyword === \"required\") {\n\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\tconst requiredProperty = requiredProperties?.[0];\n\t\tif (requiredProperty) {\n\t\t\tconst basePath = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\t\t\treturn basePath ? `${basePath}.${requiredProperty}` : requiredProperty;\n\t\t}\n\t}\n\tconst path = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\treturn path || \"root\";\n}\n\n/**\n * Finds a tool by name and validates the tool call arguments against its TypeBox schema\n * @param tools Array of tool definitions\n * @param toolCall The tool call from the LLM\n * @returns The validated arguments\n * @throws Error if tool is not found or validation fails\n */\nexport function validateToolCall(tools: Tool[], toolCall: ToolCall): any {\n\tconst tool = tools.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\tthrow new Error(`Tool \"${toolCall.name}\" not found`);\n\t}\n\treturn validateToolArguments(tool, toolCall);\n}\n\n/**\n * Validates tool call arguments against the tool's TypeBox schema\n * @param tool The tool definition with TypeBox schema\n * @param toolCall The tool call from the LLM\n * @returns The validated (and potentially coerced) arguments\n * @throws Error with formatted message if validation fails\n */\nexport function validateToolArguments(tool: Tool, toolCall: ToolCall): any {\n\tconst args = structuredClone(toolCall.arguments);\n\tnormalizeOptionalNulls(args, tool.parameters as JsonSchemaObject);\n\tValue.Convert(tool.parameters, args);\n\n\tconst validator = getValidator(tool.parameters);\n\tif (!Object.getOwnPropertySymbols(tool.parameters).includes(TYPEBOX_KIND)) {\n\t\tconst coerced = coerceWithJsonSchema(args, tool.parameters as JsonSchemaObject);\n\t\tif (coerced !== args) {\n\t\t\tif (typeof args === \"object\" && args !== null && typeof coerced === \"object\" && coerced !== null) {\n\t\t\t\tfor (const key of Object.keys(args)) {\n\t\t\t\t\tdelete args[key];\n\t\t\t\t}\n\t\t\t\tObject.assign(args, coerced);\n\t\t\t} else {\n\t\t\t\treturn validator.Check(coerced) ? coerced : args;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (validator.Check(args)) {\n\t\treturn args;\n\t}\n\n\tconst errors =\n\t\tvalidator\n\t\t\t.Errors(args)\n\t\t\t.map((error) => ` - ${formatValidationPath(error)}: ${error.message}`)\n\t\t\t.join(\"\\n\") || \"Unknown validation error\";\n\n\tconst errorMessage = `Validation failed for tool \"${toolCall.name}\":\\n${errors}\\n\\nReceived arguments:\\n${JSON.stringify(toolCall.arguments, null, 2)}`;\n\n\tthrow new Error(errorMessage);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Compile } from \"typebox/compile\";\nimport type { TLocalizedValidationError } from \"typebox/error\";\nimport { Value } from \"typebox/value\";\nimport type { Tool, ToolCall } from \"../types.ts\";\n\nconst validatorCache = new WeakMap<object, ReturnType<typeof Compile>>();\nconst TYPEBOX_KIND = Symbol.for(\"TypeBox.Kind\");\n\ninterface JsonSchemaObject {\n\ttype?: string | string[];\n\tproperties?: Record<string, JsonSchemaObject>;\n\trequired?: string[];\n\titems?: JsonSchemaObject | JsonSchemaObject[];\n\tadditionalProperties?: boolean | JsonSchemaObject;\n\tallOf?: JsonSchemaObject[];\n\tanyOf?: JsonSchemaObject[];\n\toneOf?: JsonSchemaObject[];\n}\n\nfunction getSchemaTypes(schema: JsonSchemaObject): string[] {\n\tif (typeof schema.type === \"string\") {\n\t\treturn [schema.type];\n\t}\n\tif (Array.isArray(schema.type)) {\n\t\treturn schema.type.filter((type): type is string => typeof type === \"string\");\n\t}\n\treturn [];\n}\n\nfunction matchesJsonType(value: unknown, type: string): boolean {\n\tswitch (type) {\n\t\tcase \"number\":\n\t\t\treturn typeof value === \"number\";\n\t\tcase \"integer\":\n\t\t\treturn typeof value === \"number\" && Number.isInteger(value);\n\t\tcase \"boolean\":\n\t\t\treturn typeof value === \"boolean\";\n\t\tcase \"string\":\n\t\t\treturn typeof value === \"string\";\n\t\tcase \"null\":\n\t\t\treturn value === null;\n\t\tcase \"array\":\n\t\t\treturn Array.isArray(value);\n\t\tcase \"object\":\n\t\t\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction getSubSchemaValidator(schema: JsonSchemaObject): ReturnType<typeof Compile> | undefined {\n\ttry {\n\t\treturn getValidator(schema as Tool[\"parameters\"]);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction coercePrimitiveByType(value: unknown, type: string): unknown {\n\tswitch (type) {\n\t\tcase \"number\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (typeof value === \"string\" && value.trim() !== \"\") {\n\t\t\t\tconst parsed = Number(value);\n\t\t\t\tif (Number.isFinite(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof value === \"boolean\") {\n\t\t\t\treturn value ? 1 : 0;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"integer\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (typeof value === \"string\" && value.trim() !== \"\") {\n\t\t\t\tconst parsed = Number(value);\n\t\t\t\tif (Number.isInteger(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof value === \"boolean\") {\n\t\t\t\treturn value ? 1 : 0;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"boolean\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tif (value === \"true\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (value === \"false\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof value === \"number\") {\n\t\t\t\tif (value === 1) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"string\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tcase \"null\": {\n\t\t\tif (value === \"\" || value === 0 || value === false) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tdefault:\n\t\t\treturn value;\n\t}\n}\n\nfunction applySchemaObjectCoercion(value: Record<string, unknown>, schema: JsonSchemaObject): void {\n\tconst properties = schema.properties;\n\tconst definedKeys = new Set<string>(properties ? Object.keys(properties) : []);\n\n\tif (properties) {\n\t\tfor (const [key, propertySchema] of Object.entries(properties)) {\n\t\t\tif (!(key in value)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue[key] = coerceWithJsonSchema(value[key], propertySchema);\n\t\t}\n\t}\n\n\tif (schema.additionalProperties && typeof schema.additionalProperties === \"object\") {\n\t\tfor (const [key, propertyValue] of Object.entries(value)) {\n\t\t\tif (definedKeys.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue[key] = coerceWithJsonSchema(propertyValue, schema.additionalProperties);\n\t\t}\n\t}\n}\n\nfunction applySchemaArrayCoercion(value: unknown[], schema: JsonSchemaObject): void {\n\tif (Array.isArray(schema.items)) {\n\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\tconst itemSchema = schema.items[index];\n\t\t\tif (!itemSchema) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue[index] = coerceWithJsonSchema(value[index], itemSchema);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (schema.items && typeof schema.items === \"object\") {\n\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\tvalue[index] = coerceWithJsonSchema(value[index], schema.items);\n\t\t}\n\t}\n}\n\nfunction coerceWithUnionSchema(value: unknown, schemas: JsonSchemaObject[]): unknown {\n\tfor (const schema of schemas) {\n\t\tconst validator = getSubSchemaValidator(schema);\n\t\tif (validator?.Check(value)) {\n\t\t\treturn value;\n\t\t}\n\t}\n\n\tfor (const schema of schemas) {\n\t\tconst candidate = structuredClone(value);\n\t\tconst coerced = coerceWithJsonSchema(candidate, schema);\n\t\tconst validator = getSubSchemaValidator(schema);\n\t\tif (validator?.Check(coerced)) {\n\t\t\treturn coerced;\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction coerceWithJsonSchema(value: unknown, schema: JsonSchemaObject): unknown {\n\tlet nextValue = value;\n\n\tif (Array.isArray(schema.allOf)) {\n\t\tfor (const nested of schema.allOf) {\n\t\t\tnextValue = coerceWithJsonSchema(nextValue, nested);\n\t\t}\n\t}\n\n\tif (Array.isArray(schema.anyOf)) {\n\t\tnextValue = coerceWithUnionSchema(nextValue, schema.anyOf);\n\t}\n\n\tif (Array.isArray(schema.oneOf)) {\n\t\tnextValue = coerceWithUnionSchema(nextValue, schema.oneOf);\n\t}\n\n\tconst schemaTypes = getSchemaTypes(schema);\n\tconst matchesUnionMember =\n\t\tschemaTypes.length > 1 && schemaTypes.some((schemaType) => matchesJsonType(nextValue, schemaType));\n\tif (schemaTypes.length > 0 && !matchesUnionMember) {\n\t\tfor (const schemaType of schemaTypes) {\n\t\t\tconst candidate = coercePrimitiveByType(nextValue, schemaType);\n\t\t\tif (candidate !== nextValue) {\n\t\t\t\tnextValue = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (\n\t\tschemaTypes.includes(\"object\") &&\n\t\ttypeof nextValue === \"object\" &&\n\t\tnextValue !== null &&\n\t\t!Array.isArray(nextValue)\n\t) {\n\t\tapplySchemaObjectCoercion(nextValue as Record<string, unknown>, schema);\n\t}\n\n\tif (schemaTypes.includes(\"array\") && Array.isArray(nextValue)) {\n\t\tapplySchemaArrayCoercion(nextValue, schema);\n\t}\n\n\treturn nextValue;\n}\n\nfunction normalizeOptionalNulls(value: unknown, schema: JsonSchemaObject): void {\n\tif (Array.isArray(value)) {\n\t\tif (Array.isArray(schema.items)) {\n\t\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\t\tconst itemSchema = schema.items[index];\n\t\t\t\tif (itemSchema) normalizeOptionalNulls(value[index], itemSchema);\n\t\t\t}\n\t\t} else if (schema.items) {\n\t\t\tfor (const item of value) normalizeOptionalNulls(item, schema.items);\n\t\t}\n\t\treturn;\n\t}\n\tif (typeof value !== \"object\" || value === null || !schema.properties) return;\n\n\tconst object = value as Record<string, unknown>;\n\tconst required = new Set(schema.required ?? []);\n\tfor (const [key, propertySchema] of Object.entries(schema.properties)) {\n\t\tif (!(key in object)) continue;\n\t\tif (\n\t\t\tobject[key] === null &&\n\t\t\t!required.has(key) &&\n\t\t\ttypeof (propertySchema as { $ref?: unknown }).$ref !== \"string\" &&\n\t\t\tgetSubSchemaValidator(propertySchema)?.Check(null) === false\n\t\t) {\n\t\t\tdelete object[key];\n\t\t} else {\n\t\t\tnormalizeOptionalNulls(object[key], propertySchema);\n\t\t}\n\t}\n}\n\nfunction getValidator(schema: Tool[\"parameters\"]): ReturnType<typeof Compile> {\n\tconst key = schema as object;\n\tconst cached = validatorCache.get(key);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\tconst validator = Compile(schema);\n\tvalidatorCache.set(key, validator);\n\treturn validator;\n}\n\nfunction formatValidationPath(error: TLocalizedValidationError): string {\n\tif (error.keyword === \"required\") {\n\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\tconst requiredProperty = requiredProperties?.[0];\n\t\tif (requiredProperty) {\n\t\t\tconst basePath = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\t\t\treturn basePath ? `${basePath}.${requiredProperty}` : requiredProperty;\n\t\t}\n\t}\n\tconst path = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\treturn path || \"root\";\n}\n\n/**\n * Finds a tool by name and validates the tool call arguments against its TypeBox schema\n * @param tools Array of tool definitions\n * @param toolCall The tool call from the LLM\n * @returns The validated arguments\n * @throws Error if tool is not found or validation fails\n */\nexport function validateToolCall(tools: Tool[], toolCall: ToolCall): any {\n\tconst tool = tools.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\tthrow new Error(`Tool \"${toolCall.name}\" not found`);\n\t}\n\treturn validateToolArguments(tool, toolCall);\n}\n\n/**\n * Validates tool call arguments against the tool's TypeBox schema\n * @param tool The tool definition with TypeBox schema\n * @param toolCall The tool call from the LLM\n * @returns The validated (and potentially coerced) arguments\n * @throws Error with formatted message if validation fails\n */\nexport function validateToolArguments(tool: Tool, toolCall: ToolCall): any {\n\tif (toolCall.argumentsError) {\n\t\tthrow new Error(`Invalid arguments for tool \"${toolCall.name}\": ${toolCall.argumentsError}`);\n\t}\n\tconst args = structuredClone(toolCall.arguments);\n\tnormalizeOptionalNulls(args, tool.parameters as JsonSchemaObject);\n\tValue.Convert(tool.parameters, args);\n\n\tconst validator = getValidator(tool.parameters);\n\tif (!Object.getOwnPropertySymbols(tool.parameters).includes(TYPEBOX_KIND)) {\n\t\tconst coerced = coerceWithJsonSchema(args, tool.parameters as JsonSchemaObject);\n\t\tif (coerced !== args) {\n\t\t\tif (typeof args === \"object\" && args !== null && typeof coerced === \"object\" && coerced !== null) {\n\t\t\t\tfor (const key of Object.keys(args)) {\n\t\t\t\t\tdelete args[key];\n\t\t\t\t}\n\t\t\t\tObject.assign(args, coerced);\n\t\t\t} else {\n\t\t\t\treturn validator.Check(coerced) ? coerced : args;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (validator.Check(args)) {\n\t\treturn args;\n\t}\n\n\tconst errors =\n\t\tvalidator\n\t\t\t.Errors(args)\n\t\t\t.map((error) => ` - ${formatValidationPath(error)}: ${error.message}`)\n\t\t\t.join(\"\\n\") || \"Unknown validation error\";\n\n\tconst errorMessage = `Validation failed for tool \"${toolCall.name}\":\\n${errors}\\n\\nReceived arguments:\\n${JSON.stringify(toolCall.arguments, null, 2)}`;\n\n\tthrow new Error(errorMessage);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,aAAa,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC","sourcesContent":["// The @earendil-works/pi-ai package version. scripts/sync-versions.js keeps it in sync with package.json.\nexport const PI_AI_VERSION = \"1.4.0\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@earendil-works/pi-ai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"@anthropic-ai/sdk": "0.129.0",
|
|
71
71
|
"@aws-sdk/client-bedrock-runtime": "3.1127.0",
|
|
72
|
-
"@earendil-works/pi-telemetry": "
|
|
72
|
+
"@earendil-works/pi-telemetry": "1.4.0",
|
|
73
73
|
"@google/genai": "2.21.0",
|
|
74
74
|
"@smithy/node-http-handler": "4.12.1",
|
|
75
75
|
"http-proxy-agent": "9.1.0",
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import type { AssistantMessage, AssistantMessageEvent, TextContent, ThinkingContent, ToolCall } from "../types.ts";
|
|
2
|
-
/**
|
|
3
|
-
* Compact, replayable assistant-message progress. Terminal settlement is
|
|
4
|
-
* intentionally excluded and must be persisted separately.
|
|
5
|
-
*/
|
|
6
|
-
export type AssistantMessageFrame = {
|
|
7
|
-
type: "start";
|
|
8
|
-
partial: AssistantMessage;
|
|
9
|
-
} | {
|
|
10
|
-
type: "text_start";
|
|
11
|
-
contentIndex: number;
|
|
12
|
-
content: TextContent;
|
|
13
|
-
} | {
|
|
14
|
-
type: "text_delta";
|
|
15
|
-
contentIndex: number;
|
|
16
|
-
delta: string;
|
|
17
|
-
} | {
|
|
18
|
-
type: "text_end";
|
|
19
|
-
contentIndex: number;
|
|
20
|
-
content: string;
|
|
21
|
-
textSignature?: string;
|
|
22
|
-
} | {
|
|
23
|
-
type: "thinking_start";
|
|
24
|
-
contentIndex: number;
|
|
25
|
-
content: ThinkingContent;
|
|
26
|
-
} | {
|
|
27
|
-
type: "thinking_delta";
|
|
28
|
-
contentIndex: number;
|
|
29
|
-
delta: string;
|
|
30
|
-
} | {
|
|
31
|
-
type: "thinking_end";
|
|
32
|
-
contentIndex: number;
|
|
33
|
-
content: string;
|
|
34
|
-
thinkingSignature?: string;
|
|
35
|
-
redacted?: boolean;
|
|
36
|
-
} | {
|
|
37
|
-
type: "toolcall_start";
|
|
38
|
-
contentIndex: number;
|
|
39
|
-
toolCall: ToolCall;
|
|
40
|
-
} | {
|
|
41
|
-
type: "toolcall_checkpoint";
|
|
42
|
-
contentIndex: number;
|
|
43
|
-
json: string;
|
|
44
|
-
} | {
|
|
45
|
-
type: "toolcall_delta";
|
|
46
|
-
contentIndex: number;
|
|
47
|
-
delta: string;
|
|
48
|
-
} | {
|
|
49
|
-
type: "toolcall_end";
|
|
50
|
-
contentIndex: number;
|
|
51
|
-
id: string;
|
|
52
|
-
name: string;
|
|
53
|
-
arguments: ToolCall["arguments"];
|
|
54
|
-
thoughtSignature?: string;
|
|
55
|
-
namespace?: string;
|
|
56
|
-
};
|
|
57
|
-
/**
|
|
58
|
-
* Encodes one assistant stream. `partial` remains a shared live accumulator;
|
|
59
|
-
* the encoder uses per-block offsets to avoid replaying deltas already visible
|
|
60
|
-
* when an older queued event is consumed.
|
|
61
|
-
*/
|
|
62
|
-
export declare class AssistantMessageFrameEncoder {
|
|
63
|
-
private started;
|
|
64
|
-
private terminal;
|
|
65
|
-
private readonly blocks;
|
|
66
|
-
encode(event: AssistantMessageEvent): AssistantMessageFrame | undefined;
|
|
67
|
-
private startBlock;
|
|
68
|
-
private block;
|
|
69
|
-
private endBlock;
|
|
70
|
-
private encodeTextDelta;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Replay compact frames without mutating them. Returns `undefined` when the
|
|
74
|
-
* iterable contains no start frame.
|
|
75
|
-
*/
|
|
76
|
-
export declare function reduceAssistantMessageFrames(frames: Iterable<AssistantMessageFrame>): AssistantMessage | undefined;
|
|
77
|
-
//# sourceMappingURL=assistant-message-frame.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-message-frame.d.ts","sourceRoot":"","sources":["../../src/utils/assistant-message-frame.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGnH;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACnF;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/D;IACA,IAAI,EAAE,cAAc,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;CAClB,GACD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/D;IACA,IAAI,EAAE,cAAc,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAqGL;;;;GAIG;AACH,qBAAa,4BAA4B;IACxC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAE/D,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,qBAAqB,GAAG,SAAS,CA6ItE;IAED,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,eAAe;CAgBvB;AA0CD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,gBAAgB,GAAG,SAAS,CAsHlH"}
|