@code-yeongyu/senpi-ai 2026.9.28 → 2026.9.29-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/api/anthropic-messages.d.ts.map +1 -1
  2. package/dist/api/anthropic-messages.js +76 -24
  3. package/dist/api/anthropic-messages.js.map +1 -1
  4. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  5. package/dist/api/bedrock-converse-stream.js +10 -3
  6. package/dist/api/bedrock-converse-stream.js.map +1 -1
  7. package/dist/api/github-copilot-endpoint.d.ts +19 -0
  8. package/dist/api/github-copilot-endpoint.d.ts.map +1 -0
  9. package/dist/api/github-copilot-endpoint.js +48 -0
  10. package/dist/api/github-copilot-endpoint.js.map +1 -0
  11. package/dist/api/github-copilot-errors.d.ts +9 -0
  12. package/dist/api/github-copilot-errors.d.ts.map +1 -0
  13. package/dist/api/github-copilot-errors.js +78 -0
  14. package/dist/api/github-copilot-errors.js.map +1 -0
  15. package/dist/api/github-copilot-headers.d.ts +1 -0
  16. package/dist/api/github-copilot-headers.d.ts.map +1 -1
  17. package/dist/api/github-copilot-headers.js +3 -0
  18. package/dist/api/github-copilot-headers.js.map +1 -1
  19. package/dist/api/openai-completions.d.ts.map +1 -1
  20. package/dist/api/openai-completions.js +31 -20
  21. package/dist/api/openai-completions.js.map +1 -1
  22. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  23. package/dist/api/openai-responses-shared.js +4 -1
  24. package/dist/api/openai-responses-shared.js.map +1 -1
  25. package/dist/api/openai-responses.d.ts.map +1 -1
  26. package/dist/api/openai-responses.js +48 -9
  27. package/dist/api/openai-responses.js.map +1 -1
  28. package/dist/auth/helpers.d.ts +1 -0
  29. package/dist/auth/helpers.d.ts.map +1 -1
  30. package/dist/auth/helpers.js +1 -0
  31. package/dist/auth/helpers.js.map +1 -1
  32. package/dist/auth/oauth/github-copilot-model-catalog.d.ts +7 -0
  33. package/dist/auth/oauth/github-copilot-model-catalog.d.ts.map +1 -0
  34. package/dist/auth/oauth/github-copilot-model-catalog.js +46 -0
  35. package/dist/auth/oauth/github-copilot-model-catalog.js.map +1 -0
  36. package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  37. package/dist/auth/oauth/github-copilot.js +24 -77
  38. package/dist/auth/oauth/github-copilot.js.map +1 -1
  39. package/dist/auth/pool/slots.d.ts.map +1 -1
  40. package/dist/auth/pool/slots.js +21 -3
  41. package/dist/auth/pool/slots.js.map +1 -1
  42. package/dist/auth/resolve.d.ts +6 -0
  43. package/dist/auth/resolve.d.ts.map +1 -1
  44. package/dist/auth/resolve.js +6 -5
  45. package/dist/auth/resolve.js.map +1 -1
  46. package/dist/auth/types.d.ts +14 -0
  47. package/dist/auth/types.d.ts.map +1 -1
  48. package/dist/auth/types.js.map +1 -1
  49. package/dist/cursor/context-limit-store.d.ts.map +1 -1
  50. package/dist/cursor/context-limit-store.js +23 -18
  51. package/dist/cursor/context-limit-store.js.map +1 -1
  52. package/dist/models.d.ts.map +1 -1
  53. package/dist/models.js +3 -2
  54. package/dist/models.js.map +1 -1
  55. package/dist/openai-responses-compat.d.ts +6 -0
  56. package/dist/openai-responses-compat.d.ts.map +1 -1
  57. package/dist/openai-responses-compat.js.map +1 -1
  58. package/dist/providers/amazon-bedrock.js +13 -13
  59. package/dist/providers/amazon-bedrock.js.map +1 -1
  60. package/dist/providers/data/.manifest.json +1 -1
  61. package/dist/providers/data/amazon-bedrock.json +1 -1
  62. package/dist/providers/data/anthropic.json +1 -1
  63. package/dist/providers/data/azure-openai-responses.json +1 -1
  64. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  65. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  66. package/dist/providers/data/github-copilot.json +1 -1
  67. package/dist/providers/data/mistral.json +1 -1
  68. package/dist/providers/data/openai.json +1 -1
  69. package/dist/providers/data/opencode-go.json +1 -1
  70. package/dist/providers/data/opencode.json +1 -1
  71. package/dist/providers/data/opengateway.json +1 -1
  72. package/dist/providers/data/openrouter.json +1 -1
  73. package/dist/providers/data/together.json +1 -1
  74. package/dist/providers/data/venice.json +1 -1
  75. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  76. package/dist/providers/devin.models.d.ts +5 -3
  77. package/dist/providers/devin.models.d.ts.map +1 -1
  78. package/dist/providers/devin.models.js +6 -5
  79. package/dist/providers/devin.models.js.map +1 -1
  80. package/dist/providers/github-copilot-limits.d.ts +11 -0
  81. package/dist/providers/github-copilot-limits.d.ts.map +1 -0
  82. package/dist/providers/github-copilot-limits.js +65 -0
  83. package/dist/providers/github-copilot-limits.js.map +1 -0
  84. package/dist/providers/github-copilot.d.ts.map +1 -1
  85. package/dist/providers/github-copilot.js +24 -3
  86. package/dist/providers/github-copilot.js.map +1 -1
  87. package/dist/providers/google-vertex.d.ts.map +1 -1
  88. package/dist/providers/google-vertex.js +3 -5
  89. package/dist/providers/google-vertex.js.map +1 -1
  90. package/dist/session-resources.d.ts.map +1 -1
  91. package/dist/session-resources.js +2 -1
  92. package/dist/session-resources.js.map +1 -1
  93. package/dist/types.d.ts +6 -0
  94. package/dist/types.d.ts.map +1 -1
  95. package/dist/types.js.map +1 -1
  96. package/dist/utils/block-symbols.d.ts +4 -0
  97. package/dist/utils/block-symbols.d.ts.map +1 -1
  98. package/dist/utils/block-symbols.js +10 -6
  99. package/dist/utils/block-symbols.js.map +1 -1
  100. package/dist/utils/claude-code-version-cache.d.ts +12 -0
  101. package/dist/utils/claude-code-version-cache.d.ts.map +1 -0
  102. package/dist/utils/claude-code-version-cache.js +60 -0
  103. package/dist/utils/claude-code-version-cache.js.map +1 -0
  104. package/dist/utils/claude-code-version.d.ts +78 -0
  105. package/dist/utils/claude-code-version.d.ts.map +1 -0
  106. package/dist/utils/claude-code-version.js +203 -0
  107. package/dist/utils/claude-code-version.js.map +1 -0
  108. package/dist/utils/cursor-context-limit.d.ts.map +1 -1
  109. package/dist/utils/cursor-context-limit.js +51 -45
  110. package/dist/utils/cursor-context-limit.js.map +1 -1
  111. package/dist/utils/github-copilot-tool-limit.d.ts +10 -0
  112. package/dist/utils/github-copilot-tool-limit.d.ts.map +1 -0
  113. package/dist/utils/github-copilot-tool-limit.js +75 -0
  114. package/dist/utils/github-copilot-tool-limit.js.map +1 -0
  115. package/dist/utils/overflow.d.ts.map +1 -1
  116. package/dist/utils/overflow.js +3 -1
  117. package/dist/utils/overflow.js.map +1 -1
  118. package/dist/utils/process-singleton.d.ts +10 -0
  119. package/dist/utils/process-singleton.d.ts.map +1 -0
  120. package/dist/utils/process-singleton.js +18 -0
  121. package/dist/utils/process-singleton.js.map +1 -0
  122. package/dist/utils/prompt-cache-ttl.d.ts +3 -1
  123. package/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  124. package/dist/utils/prompt-cache-ttl.js +4 -2
  125. package/dist/utils/prompt-cache-ttl.js.map +1 -1
  126. package/dist/utils/retry.d.ts +3 -0
  127. package/dist/utils/retry.d.ts.map +1 -1
  128. package/dist/utils/retry.js +15 -3
  129. package/dist/utils/retry.js.map +1 -1
  130. package/dist/utils/tool-choice-fallback.d.ts +29 -0
  131. package/dist/utils/tool-choice-fallback.d.ts.map +1 -1
  132. package/dist/utils/tool-choice-fallback.js +50 -2
  133. package/dist/utils/tool-choice-fallback.js.map +1 -1
  134. package/dist/utils/tool-schema-compat.d.ts +2 -0
  135. package/dist/utils/tool-schema-compat.d.ts.map +1 -1
  136. package/dist/utils/tool-schema-compat.js +28 -9
  137. package/dist/utils/tool-schema-compat.js.map +1 -1
  138. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"overflow.js","sourceRoot":"","sources":["../../src/utils/overflow.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"../types.ts\";\n\n/**\n * Regex patterns to detect context overflow errors from different providers.\n *\n * These patterns match error messages returned when the input exceeds\n * the model's context window.\n *\n * Provider-specific patterns (with example error messages):\n *\n * - Anthropic: \"prompt is too long: 213462 tokens > 200000 maximum\"\n * - Anthropic: \"413 {\\\"error\\\":{\\\"type\\\":\\\"request_too_large\\\",\\\"message\\\":\\\"Request exceeds the maximum size\\\"}}\"\n * - OpenAI: \"Your input exceeds the context window of this model\"\n * - OpenAI: \"Your input exceeds the model's context window\" / \"exceeds this model's context window\"\n * - OpenAI/LiteLLM: \"Requested token count exceeds the model's maximum context length of 131072 tokens\"\n * - OpenAI-compatible: \"Input length (265330) exceeds model's maximum context length (262144).\"\n * - Google: \"The input token count (1196265) exceeds the maximum number of tokens allowed (1048575)\"\n * - xAI: \"This model's maximum prompt length is 131072 but the request contains 537812 tokens\"\n * - Groq: \"Please reduce the length of the messages or completion\"\n * - OpenRouter: \"This endpoint's maximum context length is X tokens. However, you requested about Y tokens\"\n * - OpenRouter/Poolside: \"Input length X exceeds the maximum allowed input length of Y tokens.\"\n * - Together AI: \"The input (X tokens) is longer than the model's context length (Y tokens).\"\n * - llama.cpp: \"the request exceeds the available context size, try increasing it\"\n * - LM Studio: \"tokens to keep from the initial prompt is greater than the context length\"\n * - GitHub Copilot: \"prompt token count of X exceeds the limit of Y\"\n * - MiniMax: \"invalid params, context window exceeds limit\"\n * - Kimi For Coding: \"Your request exceeded model token limit: X (requested: Y)\"\n * - DS4: \"Prompt has X tokens, but the configured context size is Y tokens\"\n * - Cerebras: \"400/413 status code (no body)\"\n * - Gateways: \"413 Request body too large\" / \"Request Entity Too Large\" / \"Payload Too Large\" (byte-size overflow)\n * - kiro-lb gateways: \"Request payload is 1095225 bytes, over the 1085435 byte limit Kiro accepts.\" / \"Request payload is N tokens, over the M token limit Kiro accepts.\" (HTTP 400 local payload guard)\n * - Kiro upstream via kiro-lb: \"Model context limit reached. Conversation size exceeds model capacity.\" (CONTENT_LENGTH_EXCEEDS_THRESHOLD token overflow)\n * - Mistral: \"Prompt contains X tokens ... too large for model with Y maximum context length\"\n * - z.ai: Does NOT error, accepts overflow silently - handled via usage.input > contextWindow\n * - Xiaomi MiMo: Truncates input to fill contextWindow exactly, then returns finish_reason \"length\"\n * with output=0 (no room left to generate). Detected via stopReason \"length\" + zero output +\n * input filling the context window.\n * - DashScope/Qwen: \"Range of input length should be [1, X]\" (HTTP 400 invalid_parameter_error)\n * - Ollama: Some deployments truncate silently, others return errors like \"prompt too long; exceeded max context length by X tokens\"\n * - pi-ai pre-flight guard (api/context-room.ts): \"Context window exhausted: the conversation is estimated at X of Y tokens, ...\" - raised before any provider call\n */\nconst OVERFLOW_PATTERNS = [\n\t/^Context window exhausted: /, // pi-ai pre-flight guard: no answer room left, provider never called\n\t/prompt is too long/i, // Anthropic token overflow\n\t/request_too_large/i, // Anthropic request byte-size overflow (HTTP 413)\n\t/input is too long for requested model/i, // Amazon Bedrock\n\t/exceeds (?:(?:the|this) )?(?:model'?s )?context window/i, // OpenAI (Completions & Responses API)\n\t/exceeds (?:the )?(?:model'?s )?maximum context length(?: of [\\d,]+ tokens?|\\s*\\([\\d,]+\\))/i, // OpenAI-compatible proxies (LiteLLM)\n\t/input token count.*exceeds the maximum/i, // Google (Gemini)\n\t/maximum prompt length is \\d+/i, // xAI (Grok)\n\t/reduce the length of the messages/i, // Groq\n\t/maximum context length is \\d+ tokens/i, // OpenRouter (most backends)\n\t/exceeds (?:the )?maximum allowed input length of [\\d,]+ tokens?/i, // OpenRouter/Poolside\n\t/input \\(\\d+ tokens\\) is longer than the model'?s context length \\(\\d+ tokens\\)/i, // Together AI\n\t/exceeds the limit of \\d+/i, // GitHub Copilot\n\t/exceeds the available context size/i, // llama.cpp server\n\t/greater than the context length/i, // LM Studio\n\t/context window exceeds limit/i, // MiniMax\n\t/exceeded model token limit/i, // Kimi For Coding\n\t/too large for model with \\d+ maximum context length/i, // Mistral\n\t/prompt has [\\d,]+ tokens?, but the configured context size is [\\d,]+ tokens?/i, // DS4 server\n\t/model_context_window_exceeded/i, // z.ai non-standard finish_reason surfaced as error text\n\t/prompt too long; exceeded (?:max )?context length/i, // Ollama explicit overflow error\n\t/range of input length should be/i, // DashScope / Qwen Token Plan\n\t/context[_ ]length[_ ]exceeded/i, // Generic fallback\n\t/too many tokens/i, // Generic fallback\n\t/token limit exceeded/i, // Generic fallback\n\t/^4(?:00|13)\\s*(?:status code)?\\s*\\(no body\\)/i, // Cerebras: 400/413 with no body\n\t/(?:request[ _])?(?:body|entity|payload)[_ ]too[_ ]large/i, // Gateway HTTP 413 byte-size rejections (\"Request body too large\", \"Request Entity Too Large\", \"body_too_large\", \"Payload Too Large\"). Substring-anchored by design (JSON bodies lack an adjacent status code); a non-context size rejection (e.g. an oversized image) can over-match, which costs one bounded shrink-retry, never a wedge.\n\t/Request payload is \\d+ (?:bytes, over the \\d+ byte|tokens, over the \\d+ token) limit Kiro accepts\\./, // kiro-lb local byte/token payload guard (HTTP 400; Anthropic uses invalid_request_error, OpenAI uses detail).\n\t/Model context limit reached\\. Conversation size exceeds model capacity\\./, // kiro-lb enhancement of Kiro CONTENT_LENGTH_EXCEEDS_THRESHOLD\n];\n\n/**\n * Patterns that indicate non-overflow errors (e.g. rate limiting, server errors).\n * Error messages matching any of these are excluded from overflow detection\n * even if they also match an OVERFLOW_PATTERN.\n *\n * Example: Bedrock formats throttling errors as \"ThrottlingException: Too many tokens,\n * please wait before trying again.\" which would match the /too many tokens/i overflow\n * pattern without this exclusion. Token-quota / TPM messages such as \"Too many tokens\n * per minute\" or \"This request exceeds the limit of 30000 tokens per minute\" similarly\n * match generic overflow fallbacks and must stay on the rate-limit path.\n */\nconst NON_OVERFLOW_PATTERNS = [\n\t/^(Throttling error|Service unavailable):/i, // AWS Bedrock non-overflow errors (human-readable prefixes from formatBedrockError)\n\t/rate limit/i, // Generic rate limiting\n\t/too many requests/i, // Generic HTTP 429 style\n\t/tokens per (?:min|minute|hour|day)/i, // Token-quota windows (TPM/TPH/TPD), not context size\n\t/\\bTPM\\b/i, // Tokens-per-minute abbreviation\n\t/\\bRPM\\b/i, // Requests-per-minute abbreviation\n\t/quota exceeded/i, // Provider quota, not context window\n\t/retry (?:after|in) \\d/i, // Retry-after rate-limit wording\n\t/^429\\b/, // HTTP 429 prefix\n\t/status code 429/i, // HTTP 429 mentioned mid-message\n\t/overloaded/i, // Provider capacity, not context size\n];\n\n/**\n * Cursor's api2.cursor.sh surfaces a context overflow as a bare gRPC\n * `resource_exhausted` end-stream — the same wording its backend uses for\n * quota and poisoned-conversation rejections. Token evidence disambiguates:\n * a request that already streamed or billed tokens overflowed mid-flight,\n * while a zero-token rejection is a quota/conversation failure that must stay\n * on the rate-limit path (the cursor client rotates the conversation id for\n * those and retry handling supplies the backoff).\n */\nconst RESOURCE_EXHAUSTED_PATTERN = /resource.?exhausted/i;\n\n/**\n * Check if an assistant message represents a context overflow error.\n *\n * This handles three cases:\n * 1. Error-based overflow: Most providers return stopReason \"error\" with a\n * specific error message pattern.\n * 2. Silent overflow: Some providers accept overflow requests and return\n * successfully. For these, we check if usage.input exceeds the context window.\n * 3. Length-stop overflow: Xiaomi MiMo can return \"length\" with zero output when\n * the input fills the context window.\n *\n * ## Reliability by Provider\n *\n * **Reliable detection (returns error with detectable message):**\n * - Anthropic: \"prompt is too long: X tokens > Y maximum\" or \"request_too_large\"\n * - OpenAI (Completions & Responses): \"exceeds the context window\", \"exceeds the model's context window\", \"exceeds this model's context window\", \"exceeds the model's maximum context length of X tokens\", or \"exceeds model's maximum context length (X)\"\n * - Google Gemini: \"input token count exceeds the maximum\"\n * - xAI (Grok): \"maximum prompt length is X but request contains Y\"\n * - Groq: \"reduce the length of the messages\"\n * - Cerebras: 400/413 status code (no body)\n * - Mistral: \"Prompt contains X tokens ... too large for model with Y maximum context length\"\n * - OpenRouter (most backends): \"maximum context length is X tokens\"\n * - OpenRouter/Poolside: \"Input length X exceeds the maximum allowed input length of Y tokens.\"\n * - Together AI: \"The input (X tokens) is longer than the model's context length (Y tokens).\"\n * - llama.cpp: \"exceeds the available context size\"\n * - LM Studio: \"greater than the context length\"\n * - Kimi For Coding: \"exceeded model token limit: X (requested: Y)\"\n * - DS4: \"Prompt has X tokens, but the configured context size is Y tokens\"\n * - DashScope/Qwen: \"Range of input length should be [1, X]\"\n *\n * **Unreliable detection:**\n * - z.ai: Sometimes accepts overflow silently (detectable via usage.input > contextWindow),\n * sometimes returns rate limit errors. Pass contextWindow param to detect silent overflow.\n * - Xiaomi MiMo: Truncates input to fit contextWindow then returns stopReason \"length\" with\n * output=0. Pass contextWindow param to detect via the \"filled context + zero output\" signal.\n * - Ollama: May truncate input silently for some setups, but may also return explicit\n * overflow errors that match the patterns above. Silent truncation still cannot be\n * detected here because we do not know the expected token count.\n *\n * ## Custom Providers\n *\n * If you've added custom models via settings.json, this function may not detect\n * overflow errors from those providers. To add support:\n *\n * 1. Send a request that exceeds the model's context window\n * 2. Check the errorMessage in the response\n * 3. Create a regex pattern that matches the error\n * 4. The pattern should be added to OVERFLOW_PATTERNS in this file, or\n * check the errorMessage yourself before calling this function\n *\n * @param message - The assistant message to check\n * @param contextWindow - Optional context window size for detecting silent overflow (z.ai)\n * @returns true if the message indicates a context overflow\n */\nexport function isContextOverflow(message: AssistantMessage, contextWindow?: number): boolean {\n\t// Case 1: Check error message patterns\n\tif (message.stopReason === \"error\" && message.errorMessage) {\n\t\t// Skip messages matching known non-overflow patterns (e.g. throttling / rate-limit)\n\t\tconst isNonOverflow = NON_OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage!));\n\t\tif (!isNonOverflow && OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage!))) {\n\t\t\treturn true;\n\t\t}\n\t\tconst usage = message.usage;\n\t\tconst hasTokenEvidence =\n\t\t\t(usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite) > 0;\n\t\tif (\n\t\t\t!isNonOverflow &&\n\t\t\thasTokenEvidence &&\n\t\t\tRESOURCE_EXHAUSTED_PATTERN.test(message.errorMessage) &&\n\t\t\t(contextWindow === undefined || contextWindow <= 0 || cursorZeroTokenCount(message) >= contextWindow * 0.5)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Case 2: Silent overflow (z.ai style) - successful but usage exceeds context\n\tif (contextWindow && message.stopReason === \"stop\") {\n\t\tconst inputTokens = message.usage.input + message.usage.cacheRead;\n\t\tif (inputTokens > contextWindow) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Case 3: Length-stop overflow (Xiaomi MiMo style) - server truncates oversized input\n\t// to fit the context window, leaving no room for output. Returns stopReason \"length\"\n\t// with output=0 and input+cacheRead filling the context window.\n\tif (contextWindow && message.stopReason === \"length\" && message.usage.output === 0) {\n\t\tconst inputTokens = message.usage.input + message.usage.cacheRead;\n\t\tif (inputTokens >= contextWindow * 0.99) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n/**\n * Check whether a length stop ended below the caller or model's intended output limit.\n * Such responses may be caused by context pressure or provider-side truncation, so callers\n * can make one bounded compact-and-retry attempt. `desiredMaxOutput` must be the original\n * limit before any context-based clamping.\n */\nexport function isRecoverableLength(message: AssistantMessage, desiredMaxOutput: number): boolean {\n\treturn message.stopReason === \"length\" && desiredMaxOutput > 0 && message.usage.output < desiredMaxOutput;\n}\n\n/**\n * Get the overflow patterns for testing purposes.\n */\nexport function getOverflowPatterns(): RegExp[] {\n\treturn [...OVERFLOW_PATTERNS];\n}\n\nfunction cursorZeroTokenCount(message: {\n\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n}): number {\n\tconst usage = message.usage;\n\tif (!usage) return 0;\n\treturn (\n\t\tusage.totalTokens || (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0)\n\t);\n}\n\nexport function isCursorPayloadResourceExhausted(\n\tmessage: {\n\t\tstopReason?: string;\n\t\terrorMessage?: string;\n\t\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n\t},\n\t_estimateTokens: number,\n): boolean {\n\tif (message.stopReason !== \"error\" || !/resource.?exhausted/i.test(message.errorMessage || \"\")) {\n\t\treturn false;\n\t}\n\treturn !(cursorZeroTokenCount(message) > 0);\n}\n\n/**\n * Detects Cursor's verified usage-pool exhaustion signature: a token-bearing\n * `resource_exhausted` error while the conversation is well below the model\n * context window.\n */\nexport function isCursorQuotaResourceExhausted(\n\tmessage: {\n\t\tstopReason?: string;\n\t\terrorMessage?: string;\n\t\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n\t},\n\tcontextWindow: number,\n): boolean {\n\tconst tokens = cursorZeroTokenCount(message);\n\treturn (\n\t\tmessage.stopReason === \"error\" &&\n\t\tRESOURCE_EXHAUSTED_PATTERN.test(message.errorMessage || \"\") &&\n\t\tcontextWindow > 0 &&\n\t\ttokens > 0 &&\n\t\ttokens < contextWindow * 0.5\n\t);\n}\n\nexport function isCursorZeroTokenResourceExhausted(message: {\n\tstopReason?: string;\n\terrorMessage?: string;\n\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n}): boolean {\n\tif (message.stopReason !== \"error\" || !/resource.?exhausted/i.test(message.errorMessage || \"\")) {\n\t\treturn false;\n\t}\n\treturn !(cursorZeroTokenCount(message) > 0);\n}\n\nexport function shouldSkipProviderFallbackForCursorZeroRe(options: { sameModelRemint?: boolean } | undefined): boolean {\n\treturn options?.sameModelRemint === true;\n}\n\nexport function shouldRetryOverflowWithoutCompact(compacted: boolean, errorMessage: string): boolean {\n\tif (compacted) return false;\n\treturn /Nothing to compact/i.test(errorMessage || \"\");\n}\n\nexport function cursorOverflowCompactionSettings<T extends { keepRecentTokens?: number; restorationEnabled?: boolean }>(\n\tsettings: T,\n\tprovider: string | undefined,\n\treason: string | undefined,\n): T {\n\tif (reason !== \"overflow\") return settings;\n\tif (provider !== \"cursor\" && provider !== \"cursor-cli-oauth\") return settings;\n\treturn { ...settings, keepRecentTokens: 0, restorationEnabled: false };\n}\n"]}
1
+ {"version":3,"file":"overflow.js","sourceRoot":"","sources":["../../src/utils/overflow.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"../types.ts\";\n\n/**\n * Regex patterns to detect context overflow errors from different providers.\n *\n * These patterns match error messages returned when the input exceeds\n * the model's context window.\n *\n * Provider-specific patterns (with example error messages):\n *\n * - Anthropic: \"prompt is too long: 213462 tokens > 200000 maximum\"\n * - Anthropic: \"413 {\\\"error\\\":{\\\"type\\\":\\\"request_too_large\\\",\\\"message\\\":\\\"Request exceeds the maximum size\\\"}}\"\n * - OpenAI: \"Your input exceeds the context window of this model\"\n * - OpenAI: \"Your input exceeds the model's context window\" / \"exceeds this model's context window\"\n * - OpenAI/LiteLLM: \"Requested token count exceeds the model's maximum context length of 131072 tokens\"\n * - OpenAI-compatible: \"Input length (265330) exceeds model's maximum context length (262144).\"\n * - Google: \"The input token count (1196265) exceeds the maximum number of tokens allowed (1048575)\"\n * - xAI: \"This model's maximum prompt length is 131072 but the request contains 537812 tokens\"\n * - Groq: \"Please reduce the length of the messages or completion\"\n * - OpenRouter: \"This endpoint's maximum context length is X tokens. However, you requested about Y tokens\"\n * - OpenRouter/Poolside: \"Input length X exceeds the maximum allowed input length of Y tokens.\"\n * - Together AI: \"The input (X tokens) is longer than the model's context length (Y tokens).\"\n * - llama.cpp: \"the request exceeds the available context size, try increasing it\"\n * - LM Studio: \"tokens to keep from the initial prompt is greater than the context length\"\n * - GitHub Copilot: \"prompt token count of X exceeds the limit of Y\"\n * - MiniMax: \"invalid params, context window exceeds limit\"\n * - Kimi For Coding: \"Your request exceeded model token limit: X (requested: Y)\"\n * - DS4: \"Prompt has X tokens, but the configured context size is Y tokens\"\n * - Cerebras: \"400/413 status code (no body)\"\n * - Gateways: \"413 Request body too large\" / \"Request Entity Too Large\" / \"Payload Too Large\" (byte-size overflow)\n * - kiro-lb gateways: \"Request payload is 1095225 bytes, over the 1085435 byte limit Kiro accepts.\" / \"Request payload is N tokens, over the M token limit Kiro accepts.\" (HTTP 400 local payload guard)\n * - Kiro upstream via kiro-lb: \"Model context limit reached. Conversation size exceeds model capacity.\" (CONTENT_LENGTH_EXCEEDS_THRESHOLD token overflow)\n * - Mistral: \"Prompt contains X tokens ... too large for model with Y maximum context length\"\n * - z.ai: Does NOT error, accepts overflow silently - handled via usage.input > contextWindow\n * - Xiaomi MiMo: Truncates input to fill contextWindow exactly, then returns finish_reason \"length\"\n * with output=0 (no room left to generate). Detected via stopReason \"length\" + zero output +\n * input filling the context window.\n * - DashScope/Qwen: \"Range of input length should be [1, X]\" (HTTP 400 invalid_parameter_error)\n * - Ollama: Some deployments truncate silently, others return errors like \"prompt too long; exceeded max context length by X tokens\"\n * - pi-ai pre-flight guard (api/context-room.ts): \"Context window exhausted: the conversation is estimated at X of Y tokens, ...\" - raised before any provider call\n * - anthropic-subscription cold-seed budget: \"The conversation is too long to resend (about X tokens, limit Y). Compacting it and retrying.\" - raised before the re-send is dispatched\n */\nconst OVERFLOW_PATTERNS = [\n\t/^Context window exhausted: /, // pi-ai pre-flight guard: no answer room left, provider never called\n\t/^The conversation is too long to resend \\(about \\d+ tokens, limit \\d+\\)/, // anthropic-subscription cold-seed budget: re-send refused before dispatch\n\t/prompt is too long/i, // Anthropic token overflow\n\t/request_too_large/i, // Anthropic request byte-size overflow (HTTP 413)\n\t/input is too long for requested model/i, // Amazon Bedrock\n\t/exceeds (?:(?:the|this) )?(?:model'?s )?context window/i, // OpenAI (Completions & Responses API)\n\t/exceeds (?:the )?(?:model'?s )?maximum context length(?: of [\\d,]+ tokens?|\\s*\\([\\d,]+\\))/i, // OpenAI-compatible proxies (LiteLLM)\n\t/input token count.*exceeds the maximum/i, // Google (Gemini)\n\t/maximum prompt length is \\d+/i, // xAI (Grok)\n\t/reduce the length of the messages/i, // Groq\n\t/maximum context length is \\d+ tokens/i, // OpenRouter (most backends)\n\t/exceeds (?:the )?maximum allowed input length of [\\d,]+ tokens?/i, // OpenRouter/Poolside\n\t/input \\(\\d+ tokens\\) is longer than the model'?s context length \\(\\d+ tokens\\)/i, // Together AI\n\t/model_max_prompt_tokens_exceeded|exceeds the limit of \\d+/i, // GitHub Copilot\n\t/exceeds the available context size/i, // llama.cpp server\n\t/greater than the context length/i, // LM Studio\n\t/context window exceeds limit/i, // MiniMax\n\t/exceeded model token limit/i, // Kimi For Coding\n\t/too large for model with \\d+ maximum context length/i, // Mistral\n\t/prompt has [\\d,]+ tokens?, but the configured context size is [\\d,]+ tokens?/i, // DS4 server\n\t/model_context_window_exceeded/i, // z.ai non-standard finish_reason surfaced as error text\n\t/prompt too long; exceeded (?:max )?context length/i, // Ollama explicit overflow error\n\t/range of input length should be/i, // DashScope / Qwen Token Plan\n\t/context[_ ]length[_ ]exceeded/i, // Generic fallback\n\t/too many tokens/i, // Generic fallback\n\t/token limit exceeded/i, // Generic fallback\n\t/^4(?:00|13)\\s*(?:status code)?\\s*\\(no body\\)/i, // Cerebras: 400/413 with no body\n\t/(?:request[ _])?(?:body|entity|payload)[_ ]too[_ ]large/i, // Gateway HTTP 413 byte-size rejections (\"Request body too large\", \"Request Entity Too Large\", \"body_too_large\", \"Payload Too Large\"). Substring-anchored by design (JSON bodies lack an adjacent status code); a non-context size rejection (e.g. an oversized image) can over-match, which costs one bounded shrink-retry, never a wedge.\n\t/Request payload is \\d+ (?:bytes, over the \\d+ byte|tokens, over the \\d+ token) limit Kiro accepts\\./, // kiro-lb local byte/token payload guard (HTTP 400; Anthropic uses invalid_request_error, OpenAI uses detail).\n\t/Model context limit reached\\. Conversation size exceeds model capacity\\./, // kiro-lb enhancement of Kiro CONTENT_LENGTH_EXCEEDS_THRESHOLD\n];\n\n/**\n * Patterns that indicate non-overflow errors (e.g. rate limiting, server errors).\n * Error messages matching any of these are excluded from overflow detection\n * even if they also match an OVERFLOW_PATTERN.\n *\n * Example: Bedrock formats throttling errors as \"ThrottlingException: Too many tokens,\n * please wait before trying again.\" which would match the /too many tokens/i overflow\n * pattern without this exclusion. Token-quota / TPM messages such as \"Too many tokens\n * per minute\" or \"This request exceeds the limit of 30000 tokens per minute\" similarly\n * match generic overflow fallbacks and must stay on the rate-limit path.\n */\nconst NON_OVERFLOW_PATTERNS = [\n\t/^(Throttling error|Service unavailable):/i, // AWS Bedrock non-overflow errors (human-readable prefixes from formatBedrockError)\n\t/rate limit/i, // Generic rate limiting\n\t/too many requests/i, // Generic HTTP 429 style\n\t/tokens per (?:min|minute|hour|day)/i, // Token-quota windows (TPM/TPH/TPD), not context size\n\t/\\bTPM\\b/i, // Tokens-per-minute abbreviation\n\t/\\bRPM\\b/i, // Requests-per-minute abbreviation\n\t/quota exceeded/i, // Provider quota, not context window\n\t/retry (?:after|in) \\d/i, // Retry-after rate-limit wording\n\t/^429\\b/, // HTTP 429 prefix\n\t/status code 429/i, // HTTP 429 mentioned mid-message\n\t/overloaded/i, // Provider capacity, not context size\n];\n\n/**\n * Cursor's api2.cursor.sh surfaces a context overflow as a bare gRPC\n * `resource_exhausted` end-stream — the same wording its backend uses for\n * quota and poisoned-conversation rejections. Token evidence disambiguates:\n * a request that already streamed or billed tokens overflowed mid-flight,\n * while a zero-token rejection is a quota/conversation failure that must stay\n * on the rate-limit path (the cursor client rotates the conversation id for\n * those and retry handling supplies the backoff).\n */\nconst RESOURCE_EXHAUSTED_PATTERN = /resource.?exhausted/i;\n\n/**\n * Check if an assistant message represents a context overflow error.\n *\n * This handles three cases:\n * 1. Error-based overflow: Most providers return stopReason \"error\" with a\n * specific error message pattern.\n * 2. Silent overflow: Some providers accept overflow requests and return\n * successfully. For these, we check if usage.input exceeds the context window.\n * 3. Length-stop overflow: Xiaomi MiMo can return \"length\" with zero output when\n * the input fills the context window.\n *\n * ## Reliability by Provider\n *\n * **Reliable detection (returns error with detectable message):**\n * - Anthropic: \"prompt is too long: X tokens > Y maximum\" or \"request_too_large\"\n * - OpenAI (Completions & Responses): \"exceeds the context window\", \"exceeds the model's context window\", \"exceeds this model's context window\", \"exceeds the model's maximum context length of X tokens\", or \"exceeds model's maximum context length (X)\"\n * - Google Gemini: \"input token count exceeds the maximum\"\n * - xAI (Grok): \"maximum prompt length is X but request contains Y\"\n * - Groq: \"reduce the length of the messages\"\n * - Cerebras: 400/413 status code (no body)\n * - Mistral: \"Prompt contains X tokens ... too large for model with Y maximum context length\"\n * - OpenRouter (most backends): \"maximum context length is X tokens\"\n * - OpenRouter/Poolside: \"Input length X exceeds the maximum allowed input length of Y tokens.\"\n * - Together AI: \"The input (X tokens) is longer than the model's context length (Y tokens).\"\n * - llama.cpp: \"exceeds the available context size\"\n * - LM Studio: \"greater than the context length\"\n * - Kimi For Coding: \"exceeded model token limit: X (requested: Y)\"\n * - DS4: \"Prompt has X tokens, but the configured context size is Y tokens\"\n * - DashScope/Qwen: \"Range of input length should be [1, X]\"\n *\n * **Unreliable detection:**\n * - z.ai: Sometimes accepts overflow silently (detectable via usage.input > contextWindow),\n * sometimes returns rate limit errors. Pass contextWindow param to detect silent overflow.\n * - Xiaomi MiMo: Truncates input to fit contextWindow then returns stopReason \"length\" with\n * output=0. Pass contextWindow param to detect via the \"filled context + zero output\" signal.\n * - Ollama: May truncate input silently for some setups, but may also return explicit\n * overflow errors that match the patterns above. Silent truncation still cannot be\n * detected here because we do not know the expected token count.\n *\n * ## Custom Providers\n *\n * If you've added custom models via settings.json, this function may not detect\n * overflow errors from those providers. To add support:\n *\n * 1. Send a request that exceeds the model's context window\n * 2. Check the errorMessage in the response\n * 3. Create a regex pattern that matches the error\n * 4. The pattern should be added to OVERFLOW_PATTERNS in this file, or\n * check the errorMessage yourself before calling this function\n *\n * @param message - The assistant message to check\n * @param contextWindow - Optional context window size for detecting silent overflow (z.ai)\n * @returns true if the message indicates a context overflow\n */\nexport function isContextOverflow(message: AssistantMessage, contextWindow?: number): boolean {\n\t// Case 1: Check error message patterns\n\tif (message.stopReason === \"error\" && message.errorMessage) {\n\t\t// Skip messages matching known non-overflow patterns (e.g. throttling / rate-limit)\n\t\tconst isNonOverflow = NON_OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage!));\n\t\tif (!isNonOverflow && OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage!))) {\n\t\t\treturn true;\n\t\t}\n\t\tconst usage = message.usage;\n\t\tconst hasTokenEvidence =\n\t\t\t(usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite) > 0;\n\t\tif (\n\t\t\t!isNonOverflow &&\n\t\t\thasTokenEvidence &&\n\t\t\tRESOURCE_EXHAUSTED_PATTERN.test(message.errorMessage) &&\n\t\t\t(contextWindow === undefined || contextWindow <= 0 || cursorZeroTokenCount(message) >= contextWindow * 0.5)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Case 2: Silent overflow (z.ai style) - successful but usage exceeds context\n\tif (contextWindow && message.stopReason === \"stop\") {\n\t\tconst inputTokens = message.usage.input + message.usage.cacheRead;\n\t\tif (inputTokens > contextWindow) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Case 3: Length-stop overflow (Xiaomi MiMo style) - server truncates oversized input\n\t// to fit the context window, leaving no room for output. Returns stopReason \"length\"\n\t// with output=0 and input+cacheRead filling the context window.\n\tif (contextWindow && message.stopReason === \"length\" && message.usage.output === 0) {\n\t\tconst inputTokens = message.usage.input + message.usage.cacheRead;\n\t\tif (inputTokens >= contextWindow * 0.99) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n/**\n * Check whether a length stop ended below the caller or model's intended output limit.\n * Such responses may be caused by context pressure or provider-side truncation, so callers\n * can make one bounded compact-and-retry attempt. `desiredMaxOutput` must be the original\n * limit before any context-based clamping.\n */\nexport function isRecoverableLength(message: AssistantMessage, desiredMaxOutput: number): boolean {\n\treturn message.stopReason === \"length\" && desiredMaxOutput > 0 && message.usage.output < desiredMaxOutput;\n}\n\n/**\n * Get the overflow patterns for testing purposes.\n */\nexport function getOverflowPatterns(): RegExp[] {\n\treturn [...OVERFLOW_PATTERNS];\n}\n\nfunction cursorZeroTokenCount(message: {\n\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n}): number {\n\tconst usage = message.usage;\n\tif (!usage) return 0;\n\treturn (\n\t\tusage.totalTokens || (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0)\n\t);\n}\n\nexport function isCursorPayloadResourceExhausted(\n\tmessage: {\n\t\tstopReason?: string;\n\t\terrorMessage?: string;\n\t\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n\t},\n\t_estimateTokens: number,\n): boolean {\n\tif (message.stopReason !== \"error\" || !/resource.?exhausted/i.test(message.errorMessage || \"\")) {\n\t\treturn false;\n\t}\n\treturn !(cursorZeroTokenCount(message) > 0);\n}\n\n/**\n * Detects Cursor's verified usage-pool exhaustion signature: a token-bearing\n * `resource_exhausted` error while the conversation is well below the model\n * context window.\n */\nexport function isCursorQuotaResourceExhausted(\n\tmessage: {\n\t\tstopReason?: string;\n\t\terrorMessage?: string;\n\t\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n\t},\n\tcontextWindow: number,\n): boolean {\n\tconst tokens = cursorZeroTokenCount(message);\n\treturn (\n\t\tmessage.stopReason === \"error\" &&\n\t\tRESOURCE_EXHAUSTED_PATTERN.test(message.errorMessage || \"\") &&\n\t\tcontextWindow > 0 &&\n\t\ttokens > 0 &&\n\t\ttokens < contextWindow * 0.5\n\t);\n}\n\nexport function isCursorZeroTokenResourceExhausted(message: {\n\tstopReason?: string;\n\terrorMessage?: string;\n\tusage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; totalTokens?: number };\n}): boolean {\n\tif (message.stopReason !== \"error\" || !/resource.?exhausted/i.test(message.errorMessage || \"\")) {\n\t\treturn false;\n\t}\n\treturn !(cursorZeroTokenCount(message) > 0);\n}\n\nexport function shouldSkipProviderFallbackForCursorZeroRe(options: { sameModelRemint?: boolean } | undefined): boolean {\n\treturn options?.sameModelRemint === true;\n}\n\nexport function shouldRetryOverflowWithoutCompact(compacted: boolean, errorMessage: string): boolean {\n\tif (compacted) return false;\n\treturn /Nothing to compact/i.test(errorMessage || \"\");\n}\n\nexport function cursorOverflowCompactionSettings<T extends { keepRecentTokens?: number; restorationEnabled?: boolean }>(\n\tsettings: T,\n\tprovider: string | undefined,\n\treason: string | undefined,\n): T {\n\tif (reason !== \"overflow\") return settings;\n\tif (provider !== \"cursor\" && provider !== \"cursor-cli-oauth\") return settings;\n\treturn { ...settings, keepRecentTokens: 0, restorationEnabled: false };\n}\n"]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Returns the one value this process keeps under `key`, creating it on first use.
3
+ *
4
+ * Module-level state that every copy of a module must share lives here instead of in a
5
+ * module-local binding: the release bundle emits some providers as self-contained chunks
6
+ * that carry their own copy of the modules they import (#2334), so a module-local `Map`
7
+ * or `Set` would silently split into one instance per copy.
8
+ */
9
+ export declare function processSingleton<T extends object>(key: string, create: () => T): T;
10
+ //# sourceMappingURL=process-singleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-singleton.d.ts","sourceRoot":"","sources":["../../src/utils/process-singleton.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAOlF"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Returns the one value this process keeps under `key`, creating it on first use.
3
+ *
4
+ * Module-level state that every copy of a module must share lives here instead of in a
5
+ * module-local binding: the release bundle emits some providers as self-contained chunks
6
+ * that carry their own copy of the modules they import (#2334), so a module-local `Map`
7
+ * or `Set` would silently split into one instance per copy.
8
+ */
9
+ export function processSingleton(key, create) {
10
+ const slot = Symbol.for(key);
11
+ const existing = Reflect.get(globalThis, slot);
12
+ if (existing !== undefined)
13
+ return existing;
14
+ const created = create();
15
+ Reflect.set(globalThis, slot, created);
16
+ return created;
17
+ }
18
+ //# sourceMappingURL=process-singleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-singleton.js","sourceRoot":"","sources":["../../src/utils/process-singleton.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAmB,GAAW,EAAE,MAAe;IAC9E,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAkB,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC9D,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["/**\n * Returns the one value this process keeps under `key`, creating it on first use.\n *\n * Module-level state that every copy of a module must share lives here instead of in a\n * module-local binding: the release bundle emits some providers as self-contained chunks\n * that carry their own copy of the modules they import (#2334), so a module-local `Map`\n * or `Set` would silently split into one instance per copy.\n */\nexport function processSingleton<T extends object>(key: string, create: () => T): T {\n\tconst slot = Symbol.for(key);\n\tconst existing: T | undefined = Reflect.get(globalThis, slot);\n\tif (existing !== undefined) return existing;\n\tconst created = create();\n\tReflect.set(globalThis, slot, created);\n\treturn created;\n}\n"]}
@@ -24,7 +24,9 @@ export type PromptCacheLifetime = {
24
24
  };
25
25
  export declare function isAnthropicApiBaseUrl(baseUrl: string): boolean;
26
26
  export declare function getAnthropicCompat(model: Model<"anthropic-messages">): Required<Omit<AnthropicMessagesCompat, "forceAdaptiveThinking" | "supportsMidConvoEffort" | "sessionAffinityFormat">> & Pick<AnthropicMessagesCompat, "sessionAffinityFormat">;
27
- export type ResolvedOpenAICompletionsCompat = Omit<Required<OpenAICompletionsCompat>, "vllmPriority" | "cacheControlFormat" | "toolCallFormat" | "deferredToolsMode" | "toolSchemaFlavor" | "supportsPromptCacheKey" | "chatTemplateArgs" | "supportsThinkingTokenBudget" | "thinkingTokenBudgetField" | "veniceParameters"> & {
27
+ export type ResolvedOpenAICompletionsCompat = Omit<Required<OpenAICompletionsCompat>, "vllmPriority" | "cacheControlFormat" | "toolCallFormat" | "deferredToolsMode" | "toolSchemaFlavor" | "supportsPromptCacheKey" | "chatTemplateArgs" | "supportsThinkingTokenBudget" | "thinkingTokenBudgetField" | "veniceParameters" | "supportsForcedToolChoice"> & {
28
+ /** Declared forced tool_choice support; absent means supported. */
29
+ supportsForcedToolChoice?: OpenAICompletionsCompat["supportsForcedToolChoice"];
28
30
  cacheControlFormat?: OpenAICompletionsCompat["cacheControlFormat"];
29
31
  supportsPromptCacheKey?: OpenAICompletionsCompat["supportsPromptCacheKey"];
30
32
  toolCallFormat?: OpenAICompletionsCompat["toolCallFormat"];
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-cache-ttl.d.ts","sourceRoot":"","sources":["../../src/utils/prompt-cache-ttl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,uBAAuB,EACvB,GAAG,EAEH,KAAK,EACL,uBAAuB,EACvB,WAAW,EACX,MAAM,aAAa,CAAC;AAGrB,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAClD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAClD;;;GAGG;AACH,eAAO,MAAM,wCAAwC,OAAO,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAiB7B,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM9D;AAsBD,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,GAChC,QAAQ,CACV,IAAI,CAAC,uBAAuB,EAAE,uBAAuB,GAAG,wBAAwB,GAAG,uBAAuB,CAAC,CAC3G,GACA,IAAI,CAAC,uBAAuB,EAAE,uBAAuB,CAAC,CAkCtD;AAED,MAAM,MAAM,+BAA+B,GAAG,IAAI,CACjD,QAAQ,CAAC,uBAAuB,CAAC,EAC/B,cAAc,GACd,oBAAoB,GACpB,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,wBAAwB,GACxB,kBAAkB,GAClB,6BAA6B,GAC7B,0BAA0B,GAC1B,kBAAkB,CACpB,GAAG;IACH,kBAAkB,CAAC,EAAE,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IACnE,sBAAsB,CAAC,EAAE,uBAAuB,CAAC,wBAAwB,CAAC,CAAC;IAC3E,cAAc,CAAC,EAAE,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;IAC3D,iBAAiB,CAAC,EAAE,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;IACjE,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IAC/D,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IAC/D,2BAA2B,CAAC,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,CAAC;IACrF,wBAAwB,CAAC,EAAE,uBAAuB,CAAC,0BAA0B,CAAC,CAAC;IAC/E,8EAA8E;IAC9E,YAAY,CAAC,EAAE,uBAAuB,CAAC,cAAc,CAAC,CAAC;IACvD,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;CAC/D,CAAC;AA+GF;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,GAAG,+BAA+B,CAwC9G;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAM5F;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAKxF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAmBzG;AAuED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,mBAAmB,CAgDpG;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAGrG"}
1
+ {"version":3,"file":"prompt-cache-ttl.d.ts","sourceRoot":"","sources":["../../src/utils/prompt-cache-ttl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,uBAAuB,EACvB,GAAG,EAEH,KAAK,EACL,uBAAuB,EACvB,WAAW,EACX,MAAM,aAAa,CAAC;AAGrB,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAClD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAClD;;;GAGG;AACH,eAAO,MAAM,wCAAwC,OAAO,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAiB7B,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM9D;AAuBD,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,GAChC,QAAQ,CACV,IAAI,CAAC,uBAAuB,EAAE,uBAAuB,GAAG,wBAAwB,GAAG,uBAAuB,CAAC,CAC3G,GACA,IAAI,CAAC,uBAAuB,EAAE,uBAAuB,CAAC,CAkCtD;AAED,MAAM,MAAM,+BAA+B,GAAG,IAAI,CACjD,QAAQ,CAAC,uBAAuB,CAAC,EAC/B,cAAc,GACd,oBAAoB,GACpB,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,wBAAwB,GACxB,kBAAkB,GAClB,6BAA6B,GAC7B,0BAA0B,GAC1B,kBAAkB,GAClB,0BAA0B,CAC5B,GAAG;IACH,mEAAmE;IACnE,wBAAwB,CAAC,EAAE,uBAAuB,CAAC,0BAA0B,CAAC,CAAC;IAC/E,kBAAkB,CAAC,EAAE,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IACnE,sBAAsB,CAAC,EAAE,uBAAuB,CAAC,wBAAwB,CAAC,CAAC;IAC3E,cAAc,CAAC,EAAE,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;IAC3D,iBAAiB,CAAC,EAAE,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;IACjE,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IAC/D,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IAC/D,2BAA2B,CAAC,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,CAAC;IACrF,wBAAwB,CAAC,EAAE,uBAAuB,CAAC,0BAA0B,CAAC,CAAC;IAC/E,8EAA8E;IAC9E,YAAY,CAAC,EAAE,uBAAuB,CAAC,cAAc,CAAC,CAAC;IACvD,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;CAC/D,CAAC;AA+GF;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,GAAG,+BAA+B,CAyC9G;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAM5F;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAKxF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAmBzG;AAuED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,mBAAmB,CAgDpG;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAGrG"}
@@ -29,9 +29,10 @@ export function isAnthropicApiBaseUrl(baseUrl) {
29
29
  }
30
30
  /**
31
31
  * Families that reject forced tool use (`tool_choice` `any` / `tool` return 400): every Fable and
32
- * Mythos release, and Claude Opus 5.5 (`claude-opus-5-5`; gateways may spell it `claude-opus-5.5`).
32
+ * Mythos release, Claude Opus 5.5 and Claude Sonnet 5.5 (`claude-opus-5-5`, `claude-sonnet-5-5`;
33
+ * gateways may spell them with a dot).
33
34
  */
34
- const FORCED_TOOL_CHOICE_REJECTING_MODEL_ID = /^claude-(?:(?:fable|mythos)(?:-|$)|opus-5[.-]5(?:[.-]|$))/i;
35
+ const FORCED_TOOL_CHOICE_REJECTING_MODEL_ID = /^claude-(?:(?:fable|mythos)(?:-|$)|(?:opus|sonnet)-5[.-]5(?:[.-]|$))/i;
35
36
  /**
36
37
  * Default for `supportsToolReferences`: first-party Anthropic models except
37
38
  * Haiku (rejects client-side tool_reference blocks) and models that predate
@@ -210,6 +211,7 @@ export function getOpenAICompletionsCompat(model) {
210
211
  sessionAffinityFormat: model.compat.sessionAffinityFormat ?? detected.sessionAffinityFormat,
211
212
  supportsPromptCacheKey: model.compat.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,
212
213
  supportsMaxOutputTokens: model.compat.supportsMaxOutputTokens ?? detected.supportsMaxOutputTokens,
214
+ supportsForcedToolChoice: model.compat.supportsForcedToolChoice,
213
215
  vllmPriority: model.compat.vllmPriority ?? detected.vllmPriority,
214
216
  supportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention,
215
217
  };
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-cache-ttl.js","sourceRoot":"","sources":["../../src/utils/prompt-cache-ttl.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAnthropicMessagesCompat,\n\tApi,\n\tCacheRetention,\n\tModel,\n\tOpenAICompletionsCompat,\n\tProviderEnv,\n} from \"../types.ts\";\nimport { getProviderEnvValue } from \"./provider-env.ts\";\n\nexport const PROMPT_CACHE_TTL_SHORT_SECONDS = 300;\nexport const PROMPT_CACHE_TTL_LONG_SECONDS = 3600;\n/**\n * OpenAI GPT-5.6 and later: `prompt_cache_options.ttl` accepts only `\"30m\"`, and the cache stays\n * eligible at least 30 minutes after the latest write or reuse.\n */\nexport const PROMPT_CACHE_TTL_OPENAI_EXTENDED_SECONDS = 1800;\n\n/**\n * How long a provider promises to keep a prompt prefix cached.\n *\n * - `ttl`: an explicit expiry contract; `ttlSeconds` is the conservative lifetime after the last write or reuse.\n * - `best-effort`: the provider caches automatically but promises no expiry (direct DeepSeek clears unused entries\n * after hours to days), so nothing needs to wake or ping solely to preserve the cache.\n * - `none`: caching is disabled or the lane has no known cache contract.\n */\nexport type PromptCacheLifetime =\n\t| { readonly kind: \"ttl\"; readonly ttlSeconds: number }\n\t| { readonly kind: \"best-effort\" }\n\t| { readonly kind: \"none\" };\n\nconst NO_PROMPT_CACHE: PromptCacheLifetime = { kind: \"none\" };\nconst BEST_EFFORT_PROMPT_CACHE: PromptCacheLifetime = { kind: \"best-effort\" };\n\nfunction ttl(ttlSeconds: number): PromptCacheLifetime {\n\treturn { kind: \"ttl\", ttlSeconds };\n}\n\nfunction hostnameOf(baseUrl: string): string | undefined {\n\ttry {\n\t\treturn new URL(baseUrl).hostname.toLowerCase();\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function isAnthropicApiBaseUrl(baseUrl: string): boolean {\n\ttry {\n\t\treturn new URL(baseUrl).hostname === \"api.anthropic.com\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Families that reject forced tool use (`tool_choice` `any` / `tool` return 400): every Fable and\n * Mythos release, and Claude Opus 5.5 (`claude-opus-5-5`; gateways may spell it `claude-opus-5.5`).\n */\nconst FORCED_TOOL_CHOICE_REJECTING_MODEL_ID = /^claude-(?:(?:fable|mythos)(?:-|$)|opus-5[.-]5(?:[.-]|$))/i;\n\n/**\n * Default for `supportsToolReferences`: first-party Anthropic models except\n * Haiku (rejects client-side tool_reference blocks) and models that predate\n * tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).\n */\nfunction defaultSupportsToolReferences(model: Model<\"anthropic-messages\">): boolean {\n\tif (model.provider !== \"anthropic\" || model.id.includes(\"haiku\")) return false;\n\tconst version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\\d+)(?:-(\\d+))?(?:-|$)/);\n\tif (!version) return false;\n\tconst major = Number(version[1]);\n\tconst minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;\n\treturn major > 4 || (major === 4 && minor >= 5);\n}\n\nexport function getAnthropicCompat(\n\tmodel: Model<\"anthropic-messages\">,\n): Required<\n\tOmit<AnthropicMessagesCompat, \"forceAdaptiveThinking\" | \"supportsMidConvoEffort\" | \"sessionAffinityFormat\">\n> &\n\tPick<AnthropicMessagesCompat, \"sessionAffinityFormat\"> {\n\t// Auto-detect session affinity and cache control support from provider\n\tconst isFireworks = model.provider === \"fireworks\";\n\tconst isCloudflareAiGatewayAnthropic =\n\t\tmodel.provider === \"cloudflare-ai-gateway\" && model.baseUrl.includes(\"anthropic\");\n\tconst isXiaomi = model.provider === \"xiaomi\" || model.provider.startsWith(\"xiaomi-token-plan-\");\n\t// OpenRouter carries prompt-cache affinity on its own x-session-id header and\n\t// rejects x-session-affinity (earendil-works/pi#9102).\n\tconst isOpenRouter = model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\");\n\treturn {\n\t\tsupportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? !isFireworks,\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? !isFireworks,\n\t\tsendSessionAffinityHeaders:\n\t\t\tmodel.compat?.sendSessionAffinityHeaders ?? !!(isFireworks || isCloudflareAiGatewayAnthropic || isOpenRouter),\n\t\tsessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter ? \"openrouter\" : undefined),\n\t\tsupportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks,\n\t\tsupportsDisabledThinking: model.compat?.supportsDisabledThinking ?? !isXiaomi,\n\t\tsupportsTemperature: model.compat?.supportsTemperature ?? true,\n\t\tsupportsToolChoice: model.compat?.supportsToolChoice ?? true,\n\t\tsupportsForcedToolChoice:\n\t\t\tmodel.compat?.supportsForcedToolChoice ?? !FORCED_TOOL_CHOICE_REJECTING_MODEL_ID.test(model.id),\n\t\tallowEmptySignature: model.compat?.allowEmptySignature ?? false,\n\t\tunsignedThinkingReplay:\n\t\t\tmodel.compat?.unsignedThinkingReplay ?? (model.compat?.allowEmptySignature ? \"empty-signature\" : \"text\"),\n\t\tallowedFallbackModels: model.compat?.allowedFallbackModels ?? [],\n\t\tsupportsStrictTools: model.compat?.supportsStrictTools ?? false,\n\t\tsupportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),\n\t\t// Default: first-party Anthropic only. Anthropic-compatible providers\n\t\t// (kimi-coding, fireworks, copilot, gateways) may execute the server-side\n\t\t// search but reject the replayed server_tool_use / web_search_tool_result\n\t\t// blocks on the next request (kimi-coding 400s with `tool_call_id is not\n\t\t// found`).\n\t\tsupportsWebSearch: model.compat?.supportsWebSearch ?? isAnthropicApiBaseUrl(model.baseUrl),\n\t};\n}\n\nexport type ResolvedOpenAICompletionsCompat = Omit<\n\tRequired<OpenAICompletionsCompat>,\n\t| \"vllmPriority\"\n\t| \"cacheControlFormat\"\n\t| \"toolCallFormat\"\n\t| \"deferredToolsMode\"\n\t| \"toolSchemaFlavor\"\n\t| \"supportsPromptCacheKey\"\n\t| \"chatTemplateArgs\"\n\t| \"supportsThinkingTokenBudget\"\n\t| \"thinkingTokenBudgetField\"\n\t| \"veniceParameters\"\n> & {\n\tcacheControlFormat?: OpenAICompletionsCompat[\"cacheControlFormat\"];\n\tsupportsPromptCacheKey?: OpenAICompletionsCompat[\"supportsPromptCacheKey\"];\n\ttoolCallFormat?: OpenAICompletionsCompat[\"toolCallFormat\"];\n\tdeferredToolsMode?: OpenAICompletionsCompat[\"deferredToolsMode\"];\n\ttoolSchemaFlavor?: OpenAICompletionsCompat[\"toolSchemaFlavor\"];\n\tchatTemplateArgs?: OpenAICompletionsCompat[\"chatTemplateArgs\"];\n\tsupportsThinkingTokenBudget?: OpenAICompletionsCompat[\"supportsThinkingTokenBudget\"];\n\tthinkingTokenBudgetField?: OpenAICompletionsCompat[\"thinkingTokenBudgetField\"];\n\t/** vLLM `priority`; off by default and never set on the generated catalog. */\n\tvllmPriority?: OpenAICompletionsCompat[\"vllmPriority\"];\n\t/** Venice `venice_parameters`; only set on the generated Venice catalog. */\n\tveniceParameters?: OpenAICompletionsCompat[\"veniceParameters\"];\n};\n\n/**\n * Detect compatibility settings from provider and baseUrl for known providers.\n * Provider takes precedence over URL-based detection since it's explicitly configured.\n * Returns a fully resolved OpenAICompletionsCompat object with all fields set.\n */\nfunction detectOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst provider = model.provider;\n\tconst baseUrl = model.baseUrl;\n\n\tconst isZai =\n\t\tprovider === \"zai\" ||\n\t\tprovider === \"zai-coding-cn\" ||\n\t\tbaseUrl.includes(\"api.z.ai\") ||\n\t\tbaseUrl.includes(\"open.bigmodel.cn\");\n\tconst isTogether =\n\t\tprovider === \"together\" || baseUrl.includes(\"api.together.ai\") || baseUrl.includes(\"api.together.xyz\");\n\tconst isMoonshot = provider === \"moonshotai\" || provider === \"moonshotai-cn\" || baseUrl.includes(\"api.moonshot.\");\n\tconst isOpenRouter = provider === \"openrouter\" || baseUrl.includes(\"openrouter.ai\");\n\tconst isCloudflareWorkersAI = provider === \"cloudflare-workers-ai\" || baseUrl.includes(\"api.cloudflare.com\");\n\tconst isCloudflareAiGateway = provider === \"cloudflare-ai-gateway\" || baseUrl.includes(\"gateway.ai.cloudflare.com\");\n\tconst isNvidia = provider === \"nvidia\" || baseUrl.includes(\"integrate.api.nvidia.com\");\n\tconst isAntLing = provider === \"ant-ling\" || baseUrl.includes(\"api.ant-ling.com\");\n\tconst isDeepSeek = provider === \"deepseek\" || baseUrl.toLowerCase().includes(\"deepseek.com\");\n\n\tconst isNonStandard =\n\t\tisNvidia ||\n\t\tprovider === \"cerebras\" ||\n\t\tbaseUrl.includes(\"cerebras.ai\") ||\n\t\tprovider === \"xai\" ||\n\t\tbaseUrl.includes(\"api.x.ai\") ||\n\t\tisTogether ||\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tisDeepSeek ||\n\t\tisZai ||\n\t\tisMoonshot ||\n\t\tprovider === \"opencode\" ||\n\t\tbaseUrl.includes(\"opencode.ai\") ||\n\t\tisCloudflareWorkersAI ||\n\t\tisCloudflareAiGateway ||\n\t\tisAntLing;\n\n\tconst useMaxTokens =\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tisDeepSeek ||\n\t\tisMoonshot ||\n\t\tisCloudflareAiGateway ||\n\t\tisTogether ||\n\t\tisNvidia ||\n\t\tisAntLing ||\n\t\tisZai;\n\n\tconst isGrok = provider === \"xai\" || baseUrl.includes(\"api.x.ai\");\n\tconst isOpenRouterDeveloperRoleModel =\n\t\tisOpenRouter && (model.id.startsWith(\"anthropic/\") || model.id.startsWith(\"openai/\"));\n\tconst openRouterCacheControlPrefixes = [\"anthropic/\", \"qwen/\", \"google/\"];\n\tconst cacheControlModelId = model.id.startsWith(\"~\") ? model.id.slice(1) : model.id;\n\tconst supportsOpenRouterCacheControl = openRouterCacheControlPrefixes.some((prefix) =>\n\t\tcacheControlModelId.startsWith(prefix),\n\t);\n\tconst cacheControlFormat = provider === \"openrouter\" && supportsOpenRouterCacheControl ? \"anthropic\" : undefined;\n\n\treturn {\n\t\tsupportsStore: !isNonStandard,\n\t\tsupportsDeveloperRole: isOpenRouterDeveloperRoleModel || (!isNonStandard && !isOpenRouter),\n\t\tsupportsReasoningEffort:\n\t\t\t!isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isAntLing,\n\t\tsupportsUsageInStreaming: true,\n\t\tsupportsFinishReason: true,\n\t\tmaxTokensField: useMaxTokens ? \"max_tokens\" : \"max_completion_tokens\",\n\t\trequiresToolResultName: false,\n\t\trequiresAssistantAfterToolResult: false,\n\t\trequiresThinkingAsText: false,\n\t\trequiresReasoningContentOnAssistantMessages: isDeepSeek,\n\t\tthinkingFormat: isDeepSeek\n\t\t\t? \"deepseek\"\n\t\t\t: isZai\n\t\t\t\t? \"zai\"\n\t\t\t\t: isTogether\n\t\t\t\t\t? \"together\"\n\t\t\t\t\t: isAntLing\n\t\t\t\t\t\t? \"ant-ling\"\n\t\t\t\t\t\t: isOpenRouter\n\t\t\t\t\t\t\t? \"openrouter\"\n\t\t\t\t\t\t\t: \"openai\",\n\t\topenRouterRouting: {},\n\t\tvercelGatewayRouting: {},\n\t\tchatTemplateKwargs: {},\n\t\tzaiToolStream: false,\n\t\tsupportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,\n\t\ttoolSchemaFlavor: isMoonshot ? \"moonshot-mfjs\" : undefined,\n\t\tsupportsDisabledThinking: true,\n\t\ttoolCallFormat: undefined,\n\t\tsupportsOpenAIGrammarTools: false,\n\t\tcacheControlFormat,\n\t\tsendSessionAffinityHeaders: isOpenRouter,\n\t\tdeferredToolsMode: undefined,\n\t\tsessionAffinityFormat: isOpenRouter ? \"openrouter\" : \"openai\",\n\t\tsupportsPromptCacheKey: isMoonshot || baseUrl.includes(\"api.openai.com\"),\n\t\tsupportsMaxOutputTokens: true,\n\t\tsupportsLongCacheRetention: !(\n\t\t\tisTogether ||\n\t\t\tisCloudflareWorkersAI ||\n\t\t\tisCloudflareAiGateway ||\n\t\t\tisNvidia ||\n\t\t\tisAntLing\n\t\t),\n\t};\n}\n\n/**\n * Get resolved compatibility settings for a model.\n * Auto-detects from provider/URL then overrides with explicit model.compat.\n */\nexport function getOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst detected = detectOpenAICompletionsCompat(model);\n\tif (!model.compat) return detected;\n\n\treturn {\n\t\tsupportsStore: model.compat.supportsStore ?? detected.supportsStore,\n\t\tsupportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,\n\t\tsupportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,\n\t\tsupportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,\n\t\tsupportsFinishReason: model.compat.supportsFinishReason ?? detected.supportsFinishReason,\n\t\tmaxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,\n\t\trequiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,\n\t\trequiresAssistantAfterToolResult:\n\t\t\tmodel.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,\n\t\trequiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,\n\t\trequiresReasoningContentOnAssistantMessages:\n\t\t\tmodel.compat.requiresReasoningContentOnAssistantMessages ??\n\t\t\tdetected.requiresReasoningContentOnAssistantMessages,\n\t\tthinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,\n\t\tsupportsDisabledThinking: model.compat.supportsDisabledThinking ?? detected.supportsDisabledThinking,\n\t\topenRouterRouting: model.compat.openRouterRouting ?? detected.openRouterRouting,\n\t\tvercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,\n\t\tchatTemplateKwargs: model.compat.chatTemplateKwargs ?? detected.chatTemplateKwargs,\n\t\tchatTemplateArgs: model.compat.chatTemplateArgs ?? detected.chatTemplateArgs,\n\t\tzaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,\n\t\tsupportsThinkingTokenBudget: model.compat.supportsThinkingTokenBudget ?? detected.supportsThinkingTokenBudget,\n\t\tthinkingTokenBudgetField: model.compat.thinkingTokenBudgetField ?? detected.thinkingTokenBudgetField,\n\t\tsupportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,\n\t\ttoolSchemaFlavor: model.compat.toolSchemaFlavor ?? detected.toolSchemaFlavor,\n\t\ttoolCallFormat: model.compat.toolCallFormat ?? detected.toolCallFormat,\n\t\tsupportsOpenAIGrammarTools: model.compat.supportsOpenAIGrammarTools ?? detected.supportsOpenAIGrammarTools,\n\t\tcacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,\n\t\tsendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,\n\t\tdeferredToolsMode: model.compat.deferredToolsMode ?? detected.deferredToolsMode,\n\t\tsessionAffinityFormat: model.compat.sessionAffinityFormat ?? detected.sessionAffinityFormat,\n\t\tsupportsPromptCacheKey: model.compat.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,\n\t\tsupportsMaxOutputTokens: model.compat.supportsMaxOutputTokens ?? detected.supportsMaxOutputTokens,\n\t\tvllmPriority: model.compat.vllmPriority ?? detected.vllmPriority,\n\t\tsupportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention,\n\t};\n}\n\nexport function getBedrockModelMatchCandidates(modelId: string, modelName?: string): string[] {\n\tconst values = modelName ? [modelId, modelName] : [modelId];\n\treturn values.flatMap((value) => {\n\t\tconst lower = value.toLowerCase();\n\t\treturn [lower, lower.replace(/[\\s_.:]+/g, \"-\")];\n\t});\n}\n\nexport function supportsOneHourCacheTtl(model: Model<\"bedrock-converse-stream\">): boolean {\n\tconst candidates = getBedrockModelMatchCandidates(model.id, model.name);\n\treturn candidates.some((candidate) =>\n\t\t[\"opus-4-5\", \"sonnet-4-5\", \"haiku-4-5\"].some((modelVersion) => candidate.includes(modelVersion)),\n\t);\n}\n\n/**\n * Check if the model supports prompt caching.\n * Supported: Claude 3.5 Haiku, Claude 3.7 Sonnet, Claude 4.x models, Claude 5 models\n *\n * For base models and system-defined inference profiles the model ID / ARN\n * contains the model name, so we can decide locally.\n *\n * For application inference profiles (whose ARNs don't contain the model name),\n * also checks model.name which is user-controlled via models.json or registerProvider.\n * As a last resort, set AWS_BEDROCK_FORCE_CACHE=1 to enable cache points.\n * Amazon Nova models have automatic caching and don't need explicit cache points.\n */\nexport function supportsPromptCaching(model: Model<\"bedrock-converse-stream\">, env?: ProviderEnv): boolean {\n\tconst candidates = getBedrockModelMatchCandidates(model.id, model.name);\n\n\tconst hasClaudeRef = candidates.some((s) => s.includes(\"claude\"));\n\tif (!hasClaudeRef) {\n\t\t// Application inference profiles don't contain the model name in the ARN.\n\t\t// Allow users to force cache points via environment variable.\n\t\tif (getProviderEnvValue(\"AWS_BEDROCK_FORCE_CACHE\", env) === \"1\") return true;\n\t\treturn false;\n\t}\n\t// Claude 5 models (fable-5, opus-5, sonnet-5)\n\tif (candidates.some((s) => s.includes(\"fable-5\") || s.includes(\"opus-5\") || s.includes(\"sonnet-5\"))) return true;\n\t// Claude 4.x models (opus-4, sonnet-4, haiku-4)\n\tif (candidates.some((s) => s.includes(\"-4-\"))) return true;\n\t// Claude 3.7 Sonnet\n\tif (candidates.some((s) => s.includes(\"claude-3-7-sonnet\"))) return true;\n\t// Claude 3.5 Haiku\n\tif (candidates.some((s) => s.includes(\"claude-3-5-haiku\"))) return true;\n\treturn false;\n}\n\nfunction resolveAnthropicCacheRetention(\n\tcacheRetention?: CacheRetention,\n\tenv?: ProviderEnv,\n\tfallback: CacheRetention = \"short\",\n): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION !== undefined) {\n\t\treturn \"short\";\n\t}\n\treturn fallback;\n}\n\nfunction resolveOpenAICompletionsCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveBedrockCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveOpenAIResponsesCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\n/** Direct DeepSeek API: its automatic disk cache is best-effort and carries no expiry contract. */\nfunction isDirectDeepSeekModel(model: Model<\"openai-completions\">): boolean {\n\treturn model.provider === \"deepseek\" || hostnameOf(model.baseUrl) === \"api.deepseek.com\";\n}\n\n/** GPT-5.6 and later (`gpt-5.6-*`, `gpt-5.10`, `gpt-6-*`, `gpt-7`, ...). */\nconst OPENAI_EXTENDED_CACHE_MODEL_ID = /^gpt-(?:5\\.(?:[6-9]|\\d{2,})|(?:[6-9]|\\d{2,})(?:\\.\\d+)?)(?:-|$)/i;\n\n/**\n * The OpenAI-operated Responses lanes (OpenAI API, Azure OpenAI, ChatGPT subscription) serving a GPT-5.6+\n * model, where OpenAI documents a cache lifetime of at least 30 minutes. Gateways that merely proxy the same\n * model ids keep the conservative short lifetime because their routing does not carry that contract.\n */\nfunction hasOpenAIExtendedPromptCache(model: Model<Api>): boolean {\n\tif (model.api === \"openai-responses\") {\n\t\tconst responsesModel = model as Model<\"openai-responses\">;\n\t\tif (responsesModel.compat?.supportsExplicitPromptCacheMode === true) return true;\n\t\tif (responsesModel.provider !== \"openai\" && hostnameOf(responsesModel.baseUrl) !== \"api.openai.com\") return false;\n\t}\n\treturn OPENAI_EXTENDED_CACHE_MODEL_ID.test(model.id);\n}\n\n/**\n * Classify the active model's prompt-cache lifetime from the provider's documented cache contract.\n * `cacheRetention: \"none\"` (or `PI_CACHE_RETENTION` resolving to it) always wins.\n */\nexport function resolvePromptCacheLifetime(model: Model<Api>, env?: ProviderEnv): PromptCacheLifetime {\n\tswitch (model.api) {\n\t\tcase \"claude-sdk-oauth\":\n\t\t\t// The Claude SDK owns prompt caching for this lane and uses Anthropic's default 5m TTL.\n\t\t\treturn ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\tcase \"anthropic-messages\": {\n\t\t\tconst anthropicModel = model as Model<\"anthropic-messages\">;\n\t\t\tconst retention = resolveAnthropicCacheRetention(anthropicModel.cacheRetention, env, \"short\");\n\t\t\tif (retention === \"none\") return NO_PROMPT_CACHE;\n\t\t\treturn retention === \"long\" &&\n\t\t\t\tisAnthropicApiBaseUrl(anthropicModel.baseUrl) &&\n\t\t\t\tgetAnthropicCompat(anthropicModel).supportsLongCacheRetention\n\t\t\t\t? ttl(PROMPT_CACHE_TTL_LONG_SECONDS)\n\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tcase \"bedrock-converse-stream\": {\n\t\t\tconst bedrockModel = model as Model<\"bedrock-converse-stream\">;\n\t\t\tconst retention = resolveBedrockCacheRetention(bedrockModel.cacheRetention, env);\n\t\t\tif (retention === \"none\" || !supportsPromptCaching(bedrockModel, env)) return NO_PROMPT_CACHE;\n\t\t\treturn retention === \"long\" && supportsOneHourCacheTtl(bedrockModel)\n\t\t\t\t? ttl(PROMPT_CACHE_TTL_LONG_SECONDS)\n\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tcase \"openai-completions\": {\n\t\t\tconst completionsModel = model as Model<\"openai-completions\">;\n\t\t\tconst retention = resolveOpenAICompletionsCacheRetention(completionsModel.cacheRetention, env);\n\t\t\tif (retention === \"none\") return NO_PROMPT_CACHE;\n\t\t\tif (isDirectDeepSeekModel(completionsModel)) return BEST_EFFORT_PROMPT_CACHE;\n\t\t\tconst compat = getOpenAICompletionsCompat(completionsModel);\n\t\t\tif (compat.cacheControlFormat === \"anthropic\") {\n\t\t\t\treturn retention === \"long\" && compat.supportsLongCacheRetention\n\t\t\t\t\t? ttl(PROMPT_CACHE_TTL_LONG_SECONDS)\n\t\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t\t}\n\t\t\treturn ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tcase \"openai-responses\":\n\t\tcase \"openai-codex-responses\":\n\t\tcase \"azure-openai-responses\": {\n\t\t\tconst retention = resolveOpenAIResponsesCacheRetention(model.cacheRetention, env);\n\t\t\tif (retention === \"none\") return NO_PROMPT_CACHE;\n\t\t\treturn hasOpenAIExtendedPromptCache(model)\n\t\t\t\t? ttl(PROMPT_CACHE_TTL_OPENAI_EXTENDED_SECONDS)\n\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tdefault:\n\t\t\treturn NO_PROMPT_CACHE;\n\t}\n}\n\n/**\n * Explicit prompt-cache TTL in seconds, or `undefined` when the lane has no expiry contract: caching disabled,\n * unknown, or automatic best-effort (see {@link resolvePromptCacheLifetime}).\n */\nexport function resolvePromptCacheTtlSeconds(model: Model<Api>, env?: ProviderEnv): number | undefined {\n\tconst lifetime = resolvePromptCacheLifetime(model, env);\n\treturn lifetime.kind === \"ttl\" ? lifetime.ttlSeconds : undefined;\n}\n"]}
1
+ {"version":3,"file":"prompt-cache-ttl.js","sourceRoot":"","sources":["../../src/utils/prompt-cache-ttl.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAnthropicMessagesCompat,\n\tApi,\n\tCacheRetention,\n\tModel,\n\tOpenAICompletionsCompat,\n\tProviderEnv,\n} from \"../types.ts\";\nimport { getProviderEnvValue } from \"./provider-env.ts\";\n\nexport const PROMPT_CACHE_TTL_SHORT_SECONDS = 300;\nexport const PROMPT_CACHE_TTL_LONG_SECONDS = 3600;\n/**\n * OpenAI GPT-5.6 and later: `prompt_cache_options.ttl` accepts only `\"30m\"`, and the cache stays\n * eligible at least 30 minutes after the latest write or reuse.\n */\nexport const PROMPT_CACHE_TTL_OPENAI_EXTENDED_SECONDS = 1800;\n\n/**\n * How long a provider promises to keep a prompt prefix cached.\n *\n * - `ttl`: an explicit expiry contract; `ttlSeconds` is the conservative lifetime after the last write or reuse.\n * - `best-effort`: the provider caches automatically but promises no expiry (direct DeepSeek clears unused entries\n * after hours to days), so nothing needs to wake or ping solely to preserve the cache.\n * - `none`: caching is disabled or the lane has no known cache contract.\n */\nexport type PromptCacheLifetime =\n\t| { readonly kind: \"ttl\"; readonly ttlSeconds: number }\n\t| { readonly kind: \"best-effort\" }\n\t| { readonly kind: \"none\" };\n\nconst NO_PROMPT_CACHE: PromptCacheLifetime = { kind: \"none\" };\nconst BEST_EFFORT_PROMPT_CACHE: PromptCacheLifetime = { kind: \"best-effort\" };\n\nfunction ttl(ttlSeconds: number): PromptCacheLifetime {\n\treturn { kind: \"ttl\", ttlSeconds };\n}\n\nfunction hostnameOf(baseUrl: string): string | undefined {\n\ttry {\n\t\treturn new URL(baseUrl).hostname.toLowerCase();\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function isAnthropicApiBaseUrl(baseUrl: string): boolean {\n\ttry {\n\t\treturn new URL(baseUrl).hostname === \"api.anthropic.com\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Families that reject forced tool use (`tool_choice` `any` / `tool` return 400): every Fable and\n * Mythos release, Claude Opus 5.5 and Claude Sonnet 5.5 (`claude-opus-5-5`, `claude-sonnet-5-5`;\n * gateways may spell them with a dot).\n */\nconst FORCED_TOOL_CHOICE_REJECTING_MODEL_ID = /^claude-(?:(?:fable|mythos)(?:-|$)|(?:opus|sonnet)-5[.-]5(?:[.-]|$))/i;\n\n/**\n * Default for `supportsToolReferences`: first-party Anthropic models except\n * Haiku (rejects client-side tool_reference blocks) and models that predate\n * tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).\n */\nfunction defaultSupportsToolReferences(model: Model<\"anthropic-messages\">): boolean {\n\tif (model.provider !== \"anthropic\" || model.id.includes(\"haiku\")) return false;\n\tconst version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\\d+)(?:-(\\d+))?(?:-|$)/);\n\tif (!version) return false;\n\tconst major = Number(version[1]);\n\tconst minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;\n\treturn major > 4 || (major === 4 && minor >= 5);\n}\n\nexport function getAnthropicCompat(\n\tmodel: Model<\"anthropic-messages\">,\n): Required<\n\tOmit<AnthropicMessagesCompat, \"forceAdaptiveThinking\" | \"supportsMidConvoEffort\" | \"sessionAffinityFormat\">\n> &\n\tPick<AnthropicMessagesCompat, \"sessionAffinityFormat\"> {\n\t// Auto-detect session affinity and cache control support from provider\n\tconst isFireworks = model.provider === \"fireworks\";\n\tconst isCloudflareAiGatewayAnthropic =\n\t\tmodel.provider === \"cloudflare-ai-gateway\" && model.baseUrl.includes(\"anthropic\");\n\tconst isXiaomi = model.provider === \"xiaomi\" || model.provider.startsWith(\"xiaomi-token-plan-\");\n\t// OpenRouter carries prompt-cache affinity on its own x-session-id header and\n\t// rejects x-session-affinity (earendil-works/pi#9102).\n\tconst isOpenRouter = model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\");\n\treturn {\n\t\tsupportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? !isFireworks,\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? !isFireworks,\n\t\tsendSessionAffinityHeaders:\n\t\t\tmodel.compat?.sendSessionAffinityHeaders ?? !!(isFireworks || isCloudflareAiGatewayAnthropic || isOpenRouter),\n\t\tsessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter ? \"openrouter\" : undefined),\n\t\tsupportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks,\n\t\tsupportsDisabledThinking: model.compat?.supportsDisabledThinking ?? !isXiaomi,\n\t\tsupportsTemperature: model.compat?.supportsTemperature ?? true,\n\t\tsupportsToolChoice: model.compat?.supportsToolChoice ?? true,\n\t\tsupportsForcedToolChoice:\n\t\t\tmodel.compat?.supportsForcedToolChoice ?? !FORCED_TOOL_CHOICE_REJECTING_MODEL_ID.test(model.id),\n\t\tallowEmptySignature: model.compat?.allowEmptySignature ?? false,\n\t\tunsignedThinkingReplay:\n\t\t\tmodel.compat?.unsignedThinkingReplay ?? (model.compat?.allowEmptySignature ? \"empty-signature\" : \"text\"),\n\t\tallowedFallbackModels: model.compat?.allowedFallbackModels ?? [],\n\t\tsupportsStrictTools: model.compat?.supportsStrictTools ?? false,\n\t\tsupportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),\n\t\t// Default: first-party Anthropic only. Anthropic-compatible providers\n\t\t// (kimi-coding, fireworks, copilot, gateways) may execute the server-side\n\t\t// search but reject the replayed server_tool_use / web_search_tool_result\n\t\t// blocks on the next request (kimi-coding 400s with `tool_call_id is not\n\t\t// found`).\n\t\tsupportsWebSearch: model.compat?.supportsWebSearch ?? isAnthropicApiBaseUrl(model.baseUrl),\n\t};\n}\n\nexport type ResolvedOpenAICompletionsCompat = Omit<\n\tRequired<OpenAICompletionsCompat>,\n\t| \"vllmPriority\"\n\t| \"cacheControlFormat\"\n\t| \"toolCallFormat\"\n\t| \"deferredToolsMode\"\n\t| \"toolSchemaFlavor\"\n\t| \"supportsPromptCacheKey\"\n\t| \"chatTemplateArgs\"\n\t| \"supportsThinkingTokenBudget\"\n\t| \"thinkingTokenBudgetField\"\n\t| \"veniceParameters\"\n\t| \"supportsForcedToolChoice\"\n> & {\n\t/** Declared forced tool_choice support; absent means supported. */\n\tsupportsForcedToolChoice?: OpenAICompletionsCompat[\"supportsForcedToolChoice\"];\n\tcacheControlFormat?: OpenAICompletionsCompat[\"cacheControlFormat\"];\n\tsupportsPromptCacheKey?: OpenAICompletionsCompat[\"supportsPromptCacheKey\"];\n\ttoolCallFormat?: OpenAICompletionsCompat[\"toolCallFormat\"];\n\tdeferredToolsMode?: OpenAICompletionsCompat[\"deferredToolsMode\"];\n\ttoolSchemaFlavor?: OpenAICompletionsCompat[\"toolSchemaFlavor\"];\n\tchatTemplateArgs?: OpenAICompletionsCompat[\"chatTemplateArgs\"];\n\tsupportsThinkingTokenBudget?: OpenAICompletionsCompat[\"supportsThinkingTokenBudget\"];\n\tthinkingTokenBudgetField?: OpenAICompletionsCompat[\"thinkingTokenBudgetField\"];\n\t/** vLLM `priority`; off by default and never set on the generated catalog. */\n\tvllmPriority?: OpenAICompletionsCompat[\"vllmPriority\"];\n\t/** Venice `venice_parameters`; only set on the generated Venice catalog. */\n\tveniceParameters?: OpenAICompletionsCompat[\"veniceParameters\"];\n};\n\n/**\n * Detect compatibility settings from provider and baseUrl for known providers.\n * Provider takes precedence over URL-based detection since it's explicitly configured.\n * Returns a fully resolved OpenAICompletionsCompat object with all fields set.\n */\nfunction detectOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst provider = model.provider;\n\tconst baseUrl = model.baseUrl;\n\n\tconst isZai =\n\t\tprovider === \"zai\" ||\n\t\tprovider === \"zai-coding-cn\" ||\n\t\tbaseUrl.includes(\"api.z.ai\") ||\n\t\tbaseUrl.includes(\"open.bigmodel.cn\");\n\tconst isTogether =\n\t\tprovider === \"together\" || baseUrl.includes(\"api.together.ai\") || baseUrl.includes(\"api.together.xyz\");\n\tconst isMoonshot = provider === \"moonshotai\" || provider === \"moonshotai-cn\" || baseUrl.includes(\"api.moonshot.\");\n\tconst isOpenRouter = provider === \"openrouter\" || baseUrl.includes(\"openrouter.ai\");\n\tconst isCloudflareWorkersAI = provider === \"cloudflare-workers-ai\" || baseUrl.includes(\"api.cloudflare.com\");\n\tconst isCloudflareAiGateway = provider === \"cloudflare-ai-gateway\" || baseUrl.includes(\"gateway.ai.cloudflare.com\");\n\tconst isNvidia = provider === \"nvidia\" || baseUrl.includes(\"integrate.api.nvidia.com\");\n\tconst isAntLing = provider === \"ant-ling\" || baseUrl.includes(\"api.ant-ling.com\");\n\tconst isDeepSeek = provider === \"deepseek\" || baseUrl.toLowerCase().includes(\"deepseek.com\");\n\n\tconst isNonStandard =\n\t\tisNvidia ||\n\t\tprovider === \"cerebras\" ||\n\t\tbaseUrl.includes(\"cerebras.ai\") ||\n\t\tprovider === \"xai\" ||\n\t\tbaseUrl.includes(\"api.x.ai\") ||\n\t\tisTogether ||\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tisDeepSeek ||\n\t\tisZai ||\n\t\tisMoonshot ||\n\t\tprovider === \"opencode\" ||\n\t\tbaseUrl.includes(\"opencode.ai\") ||\n\t\tisCloudflareWorkersAI ||\n\t\tisCloudflareAiGateway ||\n\t\tisAntLing;\n\n\tconst useMaxTokens =\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tisDeepSeek ||\n\t\tisMoonshot ||\n\t\tisCloudflareAiGateway ||\n\t\tisTogether ||\n\t\tisNvidia ||\n\t\tisAntLing ||\n\t\tisZai;\n\n\tconst isGrok = provider === \"xai\" || baseUrl.includes(\"api.x.ai\");\n\tconst isOpenRouterDeveloperRoleModel =\n\t\tisOpenRouter && (model.id.startsWith(\"anthropic/\") || model.id.startsWith(\"openai/\"));\n\tconst openRouterCacheControlPrefixes = [\"anthropic/\", \"qwen/\", \"google/\"];\n\tconst cacheControlModelId = model.id.startsWith(\"~\") ? model.id.slice(1) : model.id;\n\tconst supportsOpenRouterCacheControl = openRouterCacheControlPrefixes.some((prefix) =>\n\t\tcacheControlModelId.startsWith(prefix),\n\t);\n\tconst cacheControlFormat = provider === \"openrouter\" && supportsOpenRouterCacheControl ? \"anthropic\" : undefined;\n\n\treturn {\n\t\tsupportsStore: !isNonStandard,\n\t\tsupportsDeveloperRole: isOpenRouterDeveloperRoleModel || (!isNonStandard && !isOpenRouter),\n\t\tsupportsReasoningEffort:\n\t\t\t!isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isAntLing,\n\t\tsupportsUsageInStreaming: true,\n\t\tsupportsFinishReason: true,\n\t\tmaxTokensField: useMaxTokens ? \"max_tokens\" : \"max_completion_tokens\",\n\t\trequiresToolResultName: false,\n\t\trequiresAssistantAfterToolResult: false,\n\t\trequiresThinkingAsText: false,\n\t\trequiresReasoningContentOnAssistantMessages: isDeepSeek,\n\t\tthinkingFormat: isDeepSeek\n\t\t\t? \"deepseek\"\n\t\t\t: isZai\n\t\t\t\t? \"zai\"\n\t\t\t\t: isTogether\n\t\t\t\t\t? \"together\"\n\t\t\t\t\t: isAntLing\n\t\t\t\t\t\t? \"ant-ling\"\n\t\t\t\t\t\t: isOpenRouter\n\t\t\t\t\t\t\t? \"openrouter\"\n\t\t\t\t\t\t\t: \"openai\",\n\t\topenRouterRouting: {},\n\t\tvercelGatewayRouting: {},\n\t\tchatTemplateKwargs: {},\n\t\tzaiToolStream: false,\n\t\tsupportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,\n\t\ttoolSchemaFlavor: isMoonshot ? \"moonshot-mfjs\" : undefined,\n\t\tsupportsDisabledThinking: true,\n\t\ttoolCallFormat: undefined,\n\t\tsupportsOpenAIGrammarTools: false,\n\t\tcacheControlFormat,\n\t\tsendSessionAffinityHeaders: isOpenRouter,\n\t\tdeferredToolsMode: undefined,\n\t\tsessionAffinityFormat: isOpenRouter ? \"openrouter\" : \"openai\",\n\t\tsupportsPromptCacheKey: isMoonshot || baseUrl.includes(\"api.openai.com\"),\n\t\tsupportsMaxOutputTokens: true,\n\t\tsupportsLongCacheRetention: !(\n\t\t\tisTogether ||\n\t\t\tisCloudflareWorkersAI ||\n\t\t\tisCloudflareAiGateway ||\n\t\t\tisNvidia ||\n\t\t\tisAntLing\n\t\t),\n\t};\n}\n\n/**\n * Get resolved compatibility settings for a model.\n * Auto-detects from provider/URL then overrides with explicit model.compat.\n */\nexport function getOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst detected = detectOpenAICompletionsCompat(model);\n\tif (!model.compat) return detected;\n\n\treturn {\n\t\tsupportsStore: model.compat.supportsStore ?? detected.supportsStore,\n\t\tsupportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,\n\t\tsupportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,\n\t\tsupportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,\n\t\tsupportsFinishReason: model.compat.supportsFinishReason ?? detected.supportsFinishReason,\n\t\tmaxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,\n\t\trequiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,\n\t\trequiresAssistantAfterToolResult:\n\t\t\tmodel.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,\n\t\trequiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,\n\t\trequiresReasoningContentOnAssistantMessages:\n\t\t\tmodel.compat.requiresReasoningContentOnAssistantMessages ??\n\t\t\tdetected.requiresReasoningContentOnAssistantMessages,\n\t\tthinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,\n\t\tsupportsDisabledThinking: model.compat.supportsDisabledThinking ?? detected.supportsDisabledThinking,\n\t\topenRouterRouting: model.compat.openRouterRouting ?? detected.openRouterRouting,\n\t\tvercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,\n\t\tchatTemplateKwargs: model.compat.chatTemplateKwargs ?? detected.chatTemplateKwargs,\n\t\tchatTemplateArgs: model.compat.chatTemplateArgs ?? detected.chatTemplateArgs,\n\t\tzaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,\n\t\tsupportsThinkingTokenBudget: model.compat.supportsThinkingTokenBudget ?? detected.supportsThinkingTokenBudget,\n\t\tthinkingTokenBudgetField: model.compat.thinkingTokenBudgetField ?? detected.thinkingTokenBudgetField,\n\t\tsupportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,\n\t\ttoolSchemaFlavor: model.compat.toolSchemaFlavor ?? detected.toolSchemaFlavor,\n\t\ttoolCallFormat: model.compat.toolCallFormat ?? detected.toolCallFormat,\n\t\tsupportsOpenAIGrammarTools: model.compat.supportsOpenAIGrammarTools ?? detected.supportsOpenAIGrammarTools,\n\t\tcacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,\n\t\tsendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,\n\t\tdeferredToolsMode: model.compat.deferredToolsMode ?? detected.deferredToolsMode,\n\t\tsessionAffinityFormat: model.compat.sessionAffinityFormat ?? detected.sessionAffinityFormat,\n\t\tsupportsPromptCacheKey: model.compat.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,\n\t\tsupportsMaxOutputTokens: model.compat.supportsMaxOutputTokens ?? detected.supportsMaxOutputTokens,\n\t\tsupportsForcedToolChoice: model.compat.supportsForcedToolChoice,\n\t\tvllmPriority: model.compat.vllmPriority ?? detected.vllmPriority,\n\t\tsupportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention,\n\t};\n}\n\nexport function getBedrockModelMatchCandidates(modelId: string, modelName?: string): string[] {\n\tconst values = modelName ? [modelId, modelName] : [modelId];\n\treturn values.flatMap((value) => {\n\t\tconst lower = value.toLowerCase();\n\t\treturn [lower, lower.replace(/[\\s_.:]+/g, \"-\")];\n\t});\n}\n\nexport function supportsOneHourCacheTtl(model: Model<\"bedrock-converse-stream\">): boolean {\n\tconst candidates = getBedrockModelMatchCandidates(model.id, model.name);\n\treturn candidates.some((candidate) =>\n\t\t[\"opus-4-5\", \"sonnet-4-5\", \"haiku-4-5\"].some((modelVersion) => candidate.includes(modelVersion)),\n\t);\n}\n\n/**\n * Check if the model supports prompt caching.\n * Supported: Claude 3.5 Haiku, Claude 3.7 Sonnet, Claude 4.x models, Claude 5 models\n *\n * For base models and system-defined inference profiles the model ID / ARN\n * contains the model name, so we can decide locally.\n *\n * For application inference profiles (whose ARNs don't contain the model name),\n * also checks model.name which is user-controlled via models.json or registerProvider.\n * As a last resort, set AWS_BEDROCK_FORCE_CACHE=1 to enable cache points.\n * Amazon Nova models have automatic caching and don't need explicit cache points.\n */\nexport function supportsPromptCaching(model: Model<\"bedrock-converse-stream\">, env?: ProviderEnv): boolean {\n\tconst candidates = getBedrockModelMatchCandidates(model.id, model.name);\n\n\tconst hasClaudeRef = candidates.some((s) => s.includes(\"claude\"));\n\tif (!hasClaudeRef) {\n\t\t// Application inference profiles don't contain the model name in the ARN.\n\t\t// Allow users to force cache points via environment variable.\n\t\tif (getProviderEnvValue(\"AWS_BEDROCK_FORCE_CACHE\", env) === \"1\") return true;\n\t\treturn false;\n\t}\n\t// Claude 5 models (fable-5, opus-5, sonnet-5)\n\tif (candidates.some((s) => s.includes(\"fable-5\") || s.includes(\"opus-5\") || s.includes(\"sonnet-5\"))) return true;\n\t// Claude 4.x models (opus-4, sonnet-4, haiku-4)\n\tif (candidates.some((s) => s.includes(\"-4-\"))) return true;\n\t// Claude 3.7 Sonnet\n\tif (candidates.some((s) => s.includes(\"claude-3-7-sonnet\"))) return true;\n\t// Claude 3.5 Haiku\n\tif (candidates.some((s) => s.includes(\"claude-3-5-haiku\"))) return true;\n\treturn false;\n}\n\nfunction resolveAnthropicCacheRetention(\n\tcacheRetention?: CacheRetention,\n\tenv?: ProviderEnv,\n\tfallback: CacheRetention = \"short\",\n): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION !== undefined) {\n\t\treturn \"short\";\n\t}\n\treturn fallback;\n}\n\nfunction resolveOpenAICompletionsCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveBedrockCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveOpenAIResponsesCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\n/** Direct DeepSeek API: its automatic disk cache is best-effort and carries no expiry contract. */\nfunction isDirectDeepSeekModel(model: Model<\"openai-completions\">): boolean {\n\treturn model.provider === \"deepseek\" || hostnameOf(model.baseUrl) === \"api.deepseek.com\";\n}\n\n/** GPT-5.6 and later (`gpt-5.6-*`, `gpt-5.10`, `gpt-6-*`, `gpt-7`, ...). */\nconst OPENAI_EXTENDED_CACHE_MODEL_ID = /^gpt-(?:5\\.(?:[6-9]|\\d{2,})|(?:[6-9]|\\d{2,})(?:\\.\\d+)?)(?:-|$)/i;\n\n/**\n * The OpenAI-operated Responses lanes (OpenAI API, Azure OpenAI, ChatGPT subscription) serving a GPT-5.6+\n * model, where OpenAI documents a cache lifetime of at least 30 minutes. Gateways that merely proxy the same\n * model ids keep the conservative short lifetime because their routing does not carry that contract.\n */\nfunction hasOpenAIExtendedPromptCache(model: Model<Api>): boolean {\n\tif (model.api === \"openai-responses\") {\n\t\tconst responsesModel = model as Model<\"openai-responses\">;\n\t\tif (responsesModel.compat?.supportsExplicitPromptCacheMode === true) return true;\n\t\tif (responsesModel.provider !== \"openai\" && hostnameOf(responsesModel.baseUrl) !== \"api.openai.com\") return false;\n\t}\n\treturn OPENAI_EXTENDED_CACHE_MODEL_ID.test(model.id);\n}\n\n/**\n * Classify the active model's prompt-cache lifetime from the provider's documented cache contract.\n * `cacheRetention: \"none\"` (or `PI_CACHE_RETENTION` resolving to it) always wins.\n */\nexport function resolvePromptCacheLifetime(model: Model<Api>, env?: ProviderEnv): PromptCacheLifetime {\n\tswitch (model.api) {\n\t\tcase \"claude-sdk-oauth\":\n\t\t\t// The Claude SDK owns prompt caching for this lane and uses Anthropic's default 5m TTL.\n\t\t\treturn ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\tcase \"anthropic-messages\": {\n\t\t\tconst anthropicModel = model as Model<\"anthropic-messages\">;\n\t\t\tconst retention = resolveAnthropicCacheRetention(anthropicModel.cacheRetention, env, \"short\");\n\t\t\tif (retention === \"none\") return NO_PROMPT_CACHE;\n\t\t\treturn retention === \"long\" &&\n\t\t\t\tisAnthropicApiBaseUrl(anthropicModel.baseUrl) &&\n\t\t\t\tgetAnthropicCompat(anthropicModel).supportsLongCacheRetention\n\t\t\t\t? ttl(PROMPT_CACHE_TTL_LONG_SECONDS)\n\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tcase \"bedrock-converse-stream\": {\n\t\t\tconst bedrockModel = model as Model<\"bedrock-converse-stream\">;\n\t\t\tconst retention = resolveBedrockCacheRetention(bedrockModel.cacheRetention, env);\n\t\t\tif (retention === \"none\" || !supportsPromptCaching(bedrockModel, env)) return NO_PROMPT_CACHE;\n\t\t\treturn retention === \"long\" && supportsOneHourCacheTtl(bedrockModel)\n\t\t\t\t? ttl(PROMPT_CACHE_TTL_LONG_SECONDS)\n\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tcase \"openai-completions\": {\n\t\t\tconst completionsModel = model as Model<\"openai-completions\">;\n\t\t\tconst retention = resolveOpenAICompletionsCacheRetention(completionsModel.cacheRetention, env);\n\t\t\tif (retention === \"none\") return NO_PROMPT_CACHE;\n\t\t\tif (isDirectDeepSeekModel(completionsModel)) return BEST_EFFORT_PROMPT_CACHE;\n\t\t\tconst compat = getOpenAICompletionsCompat(completionsModel);\n\t\t\tif (compat.cacheControlFormat === \"anthropic\") {\n\t\t\t\treturn retention === \"long\" && compat.supportsLongCacheRetention\n\t\t\t\t\t? ttl(PROMPT_CACHE_TTL_LONG_SECONDS)\n\t\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t\t}\n\t\t\treturn ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tcase \"openai-responses\":\n\t\tcase \"openai-codex-responses\":\n\t\tcase \"azure-openai-responses\": {\n\t\t\tconst retention = resolveOpenAIResponsesCacheRetention(model.cacheRetention, env);\n\t\t\tif (retention === \"none\") return NO_PROMPT_CACHE;\n\t\t\treturn hasOpenAIExtendedPromptCache(model)\n\t\t\t\t? ttl(PROMPT_CACHE_TTL_OPENAI_EXTENDED_SECONDS)\n\t\t\t\t: ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);\n\t\t}\n\t\tdefault:\n\t\t\treturn NO_PROMPT_CACHE;\n\t}\n}\n\n/**\n * Explicit prompt-cache TTL in seconds, or `undefined` when the lane has no expiry contract: caching disabled,\n * unknown, or automatic best-effort (see {@link resolvePromptCacheLifetime}).\n */\nexport function resolvePromptCacheTtlSeconds(model: Model<Api>, env?: ProviderEnv): number | undefined {\n\tconst lifetime = resolvePromptCacheLifetime(model, env);\n\treturn lifetime.kind === \"ttl\" ? lifetime.ttlSeconds : undefined;\n}\n"]}
@@ -1,4 +1,7 @@
1
1
  import type { AssistantMessage } from "../types.ts";
2
+ export declare const PROVIDER_REQUEST_ID_MARKER = "request id:";
3
+ export declare function formatProviderRequestId(label: string, id: string): string;
4
+ export declare function stripProviderRequestIds(text: string): string;
2
5
  /**
3
6
  * OpenAI hard account-quota exhaustion (senpi#1969). The wire evidence is a 429
4
7
  * whose body is `{"type":"usage_limit_reached","message":"The usage limit has
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,15 @@
1
1
  import { FORWARDED_EMPTY_RESPONSE_ERROR, FORWARDED_EMPTY_TOOL_USE_ERROR } from "./empty-response-errors.js";
2
+ // A provider's support request id is opaque hex like `C6FD:AB660:AEB5548:6ABA4D81`.
3
+ // It can contain `429` or `500`, which message classifiers read as HTTP statuses,
4
+ // so every id is rendered behind this marker and removed before classification.
5
+ export const PROVIDER_REQUEST_ID_MARKER = "request id:";
6
+ const REQUEST_ID_SEGMENT = /request id: [^\s,;)]+/gi;
7
+ export function formatProviderRequestId(label, id) {
8
+ return `${label} ${PROVIDER_REQUEST_ID_MARKER} ${id}`;
9
+ }
10
+ export function stripProviderRequestIds(text) {
11
+ return text.replace(REQUEST_ID_SEGMENT, PROVIDER_REQUEST_ID_MARKER);
12
+ }
2
13
  function buildProviderErrorPattern(patterns) {
3
14
  return new RegExp(patterns.join("|"), "i");
4
15
  }
@@ -56,7 +67,7 @@ const QUOTA_EXHAUSTION_PATTERNS = [
56
67
  ];
57
68
  const QUOTA_EXHAUSTION_PATTERN = buildProviderErrorPattern(QUOTA_EXHAUSTION_PATTERNS);
58
69
  export function isQuotaExhaustionMessage(errorMessage) {
59
- return errorMessage !== undefined && QUOTA_EXHAUSTION_PATTERN.test(errorMessage);
70
+ return errorMessage !== undefined && QUOTA_EXHAUSTION_PATTERN.test(stripProviderRequestIds(errorMessage));
60
71
  }
61
72
  const NON_RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([
62
73
  ...QUOTA_EXHAUSTION_PATTERNS,
@@ -463,9 +474,10 @@ export function isRetryableErrorMessage(errorMessage) {
463
474
  export function classifyErrorMessage(errorMessage) {
464
475
  if (!errorMessage)
465
476
  return "unknown";
466
- if (NON_RETRYABLE_PROVIDER_ERROR_PATTERN.test(errorMessage))
477
+ const text = stripProviderRequestIds(errorMessage);
478
+ if (NON_RETRYABLE_PROVIDER_ERROR_PATTERN.test(text))
467
479
  return "non-retryable";
468
- if (RETRYABLE_PROVIDER_ERROR_PATTERN.test(errorMessage))
480
+ if (RETRYABLE_PROVIDER_ERROR_PATTERN.test(text))
469
481
  return "retryable";
470
482
  return "unknown";
471
483
  }