@code-yeongyu/senpi-ai 2026.9.23 → 2026.9.24-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 (85) hide show
  1. package/dist/api/anthropic-messages.js +1 -1
  2. package/dist/api/anthropic-messages.js.map +1 -1
  3. package/dist/api/anthropic-tool-references.d.ts.map +1 -1
  4. package/dist/api/anthropic-tool-references.js +8 -35
  5. package/dist/api/anthropic-tool-references.js.map +1 -1
  6. package/dist/api/openai-completions.d.ts.map +1 -1
  7. package/dist/api/openai-completions.js +10 -6
  8. package/dist/api/openai-completions.js.map +1 -1
  9. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  10. package/dist/api/openai-responses-shared.js +4 -3
  11. package/dist/api/openai-responses-shared.js.map +1 -1
  12. package/dist/api/openai-responses.d.ts.map +1 -1
  13. package/dist/api/openai-responses.js +53 -1
  14. package/dist/api/openai-responses.js.map +1 -1
  15. package/dist/api/openrouter-images.js +1 -1
  16. package/dist/api/openrouter-images.js.map +1 -1
  17. package/dist/api/pi-messages.d.ts.map +1 -1
  18. package/dist/api/pi-messages.js +17 -1
  19. package/dist/api/pi-messages.js.map +1 -1
  20. package/dist/cursor/catalog-grouping.d.ts +18 -1
  21. package/dist/cursor/catalog-grouping.d.ts.map +1 -1
  22. package/dist/cursor/catalog-grouping.js +103 -3
  23. package/dist/cursor/catalog-grouping.js.map +1 -1
  24. package/dist/cursor/selection-descriptor.d.ts +3 -1
  25. package/dist/cursor/selection-descriptor.d.ts.map +1 -1
  26. package/dist/cursor/selection-descriptor.js +15 -3
  27. package/dist/cursor/selection-descriptor.js.map +1 -1
  28. package/dist/cursor/store-migration.d.ts +7 -2
  29. package/dist/cursor/store-migration.d.ts.map +1 -1
  30. package/dist/cursor/store-migration.js +92 -20
  31. package/dist/cursor/store-migration.js.map +1 -1
  32. package/dist/image-models.generated.d.ts +30 -0
  33. package/dist/image-models.generated.d.ts.map +1 -1
  34. package/dist/image-models.generated.js +30 -0
  35. package/dist/image-models.generated.js.map +1 -1
  36. package/dist/index.d.ts +2 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +2 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/model.d.ts +9 -1
  41. package/dist/model.d.ts.map +1 -1
  42. package/dist/model.js.map +1 -1
  43. package/dist/models.d.ts +6 -0
  44. package/dist/models.d.ts.map +1 -1
  45. package/dist/models.js +15 -0
  46. package/dist/models.js.map +1 -1
  47. package/dist/openai-responses-compat.d.ts +17 -0
  48. package/dist/openai-responses-compat.d.ts.map +1 -1
  49. package/dist/openai-responses-compat.js +4 -1
  50. package/dist/openai-responses-compat.js.map +1 -1
  51. package/dist/providers/cursor.d.ts.map +1 -1
  52. package/dist/providers/cursor.js +1 -0
  53. package/dist/providers/cursor.js.map +1 -1
  54. package/dist/providers/data/.manifest.json +1 -1
  55. package/dist/providers/data/amazon-bedrock.json +1 -1
  56. package/dist/providers/data/chatgpt-subscription.json +1 -1
  57. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  58. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  59. package/dist/providers/data/fireworks.json +1 -1
  60. package/dist/providers/data/github-copilot.json +1 -1
  61. package/dist/providers/data/google.json +1 -1
  62. package/dist/providers/data/minimax-cn.json +1 -1
  63. package/dist/providers/data/minimax.json +1 -1
  64. package/dist/providers/data/moonshotai-cn.json +1 -1
  65. package/dist/providers/data/moonshotai.json +1 -1
  66. package/dist/providers/data/openai.json +1 -1
  67. package/dist/providers/data/opencode-go.json +1 -1
  68. package/dist/providers/data/opencode.json +1 -1
  69. package/dist/providers/data/opengateway.json +1 -1
  70. package/dist/providers/data/openrouter.json +1 -1
  71. package/dist/providers/data/together.json +1 -1
  72. package/dist/providers/data/venice.json +1 -1
  73. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  74. package/dist/types.d.ts +11 -0
  75. package/dist/types.d.ts.map +1 -1
  76. package/dist/types.js.map +1 -1
  77. package/dist/utils/prompt-cache-ttl.d.ts +30 -0
  78. package/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  79. package/dist/utils/prompt-cache-ttl.js +71 -14
  80. package/dist/utils/prompt-cache-ttl.js.map +1 -1
  81. package/dist/utils/tool-name-match.d.ts +30 -0
  82. package/dist/utils/tool-name-match.d.ts.map +1 -0
  83. package/dist/utils/tool-name-match.js +71 -0
  84. package/dist/utils/tool-name-match.js.map +1 -0
  85. package/package.json +2 -2
@@ -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\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\nexport function resolvePromptCacheTtlSeconds(model: Model<Api>, env?: ProviderEnv): number | undefined {\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 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 undefined;\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? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t: 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 undefined;\n\t\t\treturn retention === \"long\" && supportsOneHourCacheTtl(bedrockModel)\n\t\t\t\t? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t: 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 undefined;\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? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t\t: PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t\t}\n\t\t\treturn 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\treturn retention === \"none\" ? undefined : PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\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, 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"]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Lenient tool-name matching shared by the inbound tool-call resolver
3
+ * (`@earendil-works/pi-agent-core` `resolveToolNameAlias`) and the Anthropic
4
+ * tool-reference repair, so both paths accept the same shapes.
5
+ *
6
+ * Models write tool names in shapes no tool was registered under: recased
7
+ * (`LazyWeather` for `lazy_weather`), under a gateway namespace in any case
8
+ * (`mcp__686f__Eval`, `MCP__686f__Eval`), under a namespace whose id contains
9
+ * underscores (`mcp__my_server__Memory`), or without the `mcp_<server>_`
10
+ * prefix senpi's own MCP tools carry (`create_issue` for
11
+ * `mcp_github_create_issue`).
12
+ *
13
+ * A namespace is cut only at its delimiter: `__` for the gateway form, the
14
+ * first `_` for `mcp_<server>_<tool>`. It is never cut inside the tool's own
15
+ * name, so `mcp__sandbox__run_bash` cannot fall through to a local `bash`.
16
+ * Each form is tried most specific first (exact, case/separator fold, then a
17
+ * registered tool whose unprefixed name folds the same), and a step resolves
18
+ * only when exactly one tool matches it: the matcher never guesses between two
19
+ * candidates.
20
+ */
21
+ export declare function foldToolName(name: string): string;
22
+ /**
23
+ * The name itself, then its unprefixed remainders, longest first:
24
+ * `mcp__my_srv__x__Tool` -> `x__Tool`, `Tool`; `mcp_github_create_issue` ->
25
+ * `create_issue`.
26
+ */
27
+ export declare function toolNameForms(name: string): string[];
28
+ /** Resolve `requested` to the one available tool it names, or `undefined` when none or several match. */
29
+ export declare function resolveToolNameMatch(requested: string, available: Iterable<string>): string | undefined;
30
+ //# sourceMappingURL=tool-name-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-name-match.d.ts","sourceRoot":"","sources":["../../src/utils/tool-name-match.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAcpD;AAOD,yGAAyG;AACzG,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAevG"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Lenient tool-name matching shared by the inbound tool-call resolver
3
+ * (`@earendil-works/pi-agent-core` `resolveToolNameAlias`) and the Anthropic
4
+ * tool-reference repair, so both paths accept the same shapes.
5
+ *
6
+ * Models write tool names in shapes no tool was registered under: recased
7
+ * (`LazyWeather` for `lazy_weather`), under a gateway namespace in any case
8
+ * (`mcp__686f__Eval`, `MCP__686f__Eval`), under a namespace whose id contains
9
+ * underscores (`mcp__my_server__Memory`), or without the `mcp_<server>_`
10
+ * prefix senpi's own MCP tools carry (`create_issue` for
11
+ * `mcp_github_create_issue`).
12
+ *
13
+ * A namespace is cut only at its delimiter: `__` for the gateway form, the
14
+ * first `_` for `mcp_<server>_<tool>`. It is never cut inside the tool's own
15
+ * name, so `mcp__sandbox__run_bash` cannot fall through to a local `bash`.
16
+ * Each form is tried most specific first (exact, case/separator fold, then a
17
+ * registered tool whose unprefixed name folds the same), and a step resolves
18
+ * only when exactly one tool matches it: the matcher never guesses between two
19
+ * candidates.
20
+ */
21
+ const GATEWAY_NAMESPACE = /^mcp__(.+)$/i;
22
+ const GATEWAY_DELIMITER = /_{2,}/g;
23
+ const SERVER_NAMESPACE = /^mcp_([^_]+)_(.+)$/i;
24
+ export function foldToolName(name) {
25
+ return name.toLowerCase().replaceAll(/[-_]/g, "");
26
+ }
27
+ /**
28
+ * The name itself, then its unprefixed remainders, longest first:
29
+ * `mcp__my_srv__x__Tool` -> `x__Tool`, `Tool`; `mcp_github_create_issue` ->
30
+ * `create_issue`.
31
+ */
32
+ export function toolNameForms(name) {
33
+ const forms = [name];
34
+ const gateway = GATEWAY_NAMESPACE.exec(name);
35
+ if (gateway) {
36
+ const rest = gateway[1] ?? "";
37
+ for (const run of rest.matchAll(GATEWAY_DELIMITER)) {
38
+ const suffix = rest.slice(run.index + run[0].length);
39
+ if (run.index > 0 && suffix.length > 0)
40
+ forms.push(suffix);
41
+ }
42
+ return forms;
43
+ }
44
+ const tool = SERVER_NAMESPACE.exec(name)?.[2];
45
+ if (tool !== undefined)
46
+ forms.push(tool);
47
+ return forms;
48
+ }
49
+ function uniqueMatch(names, matches) {
50
+ const found = names.filter(matches);
51
+ return found.length === 1 ? found[0] : undefined;
52
+ }
53
+ /** Resolve `requested` to the one available tool it names, or `undefined` when none or several match. */
54
+ export function resolveToolNameMatch(requested, available) {
55
+ const names = [...new Set(available)];
56
+ for (const form of toolNameForms(requested)) {
57
+ if (names.includes(form))
58
+ return form;
59
+ const key = foldToolName(form);
60
+ const folded = uniqueMatch(names, (name) => foldToolName(name) === key);
61
+ if (folded !== undefined)
62
+ return folded;
63
+ const unprefixed = uniqueMatch(names, (name) => toolNameForms(name)
64
+ .slice(1)
65
+ .some((registeredForm) => foldToolName(registeredForm) === key));
66
+ if (unprefixed !== undefined)
67
+ return unprefixed;
68
+ }
69
+ return undefined;
70
+ }
71
+ //# sourceMappingURL=tool-name-match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-name-match.js","sourceRoot":"","sources":["../../src/utils/tool-name-match.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,iBAAiB,GAAG,cAAc,CAAC;AACzC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AACnC,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C,MAAM,UAAU,YAAY,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,KAAwB,EAAE,OAAkC;IAChF,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,SAA2B;IAClF,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACxE,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACxC,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAC9C,aAAa,CAAC,IAAI,CAAC;aACjB,KAAK,CAAC,CAAC,CAAC;aACR,IAAI,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,GAAG,CAAC,CAChE,CAAC;QACF,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,UAAU,CAAC;IACjD,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["/**\n * Lenient tool-name matching shared by the inbound tool-call resolver\n * (`@earendil-works/pi-agent-core` `resolveToolNameAlias`) and the Anthropic\n * tool-reference repair, so both paths accept the same shapes.\n *\n * Models write tool names in shapes no tool was registered under: recased\n * (`LazyWeather` for `lazy_weather`), under a gateway namespace in any case\n * (`mcp__686f__Eval`, `MCP__686f__Eval`), under a namespace whose id contains\n * underscores (`mcp__my_server__Memory`), or without the `mcp_<server>_`\n * prefix senpi's own MCP tools carry (`create_issue` for\n * `mcp_github_create_issue`).\n *\n * A namespace is cut only at its delimiter: `__` for the gateway form, the\n * first `_` for `mcp_<server>_<tool>`. It is never cut inside the tool's own\n * name, so `mcp__sandbox__run_bash` cannot fall through to a local `bash`.\n * Each form is tried most specific first (exact, case/separator fold, then a\n * registered tool whose unprefixed name folds the same), and a step resolves\n * only when exactly one tool matches it: the matcher never guesses between two\n * candidates.\n */\n\nconst GATEWAY_NAMESPACE = /^mcp__(.+)$/i;\nconst GATEWAY_DELIMITER = /_{2,}/g;\nconst SERVER_NAMESPACE = /^mcp_([^_]+)_(.+)$/i;\n\nexport function foldToolName(name: string): string {\n\treturn name.toLowerCase().replaceAll(/[-_]/g, \"\");\n}\n\n/**\n * The name itself, then its unprefixed remainders, longest first:\n * `mcp__my_srv__x__Tool` -> `x__Tool`, `Tool`; `mcp_github_create_issue` ->\n * `create_issue`.\n */\nexport function toolNameForms(name: string): string[] {\n\tconst forms = [name];\n\tconst gateway = GATEWAY_NAMESPACE.exec(name);\n\tif (gateway) {\n\t\tconst rest = gateway[1] ?? \"\";\n\t\tfor (const run of rest.matchAll(GATEWAY_DELIMITER)) {\n\t\t\tconst suffix = rest.slice(run.index + run[0].length);\n\t\t\tif (run.index > 0 && suffix.length > 0) forms.push(suffix);\n\t\t}\n\t\treturn forms;\n\t}\n\tconst tool = SERVER_NAMESPACE.exec(name)?.[2];\n\tif (tool !== undefined) forms.push(tool);\n\treturn forms;\n}\n\nfunction uniqueMatch(names: readonly string[], matches: (name: string) => boolean): string | undefined {\n\tconst found = names.filter(matches);\n\treturn found.length === 1 ? found[0] : undefined;\n}\n\n/** Resolve `requested` to the one available tool it names, or `undefined` when none or several match. */\nexport function resolveToolNameMatch(requested: string, available: Iterable<string>): string | undefined {\n\tconst names = [...new Set(available)];\n\tfor (const form of toolNameForms(requested)) {\n\t\tif (names.includes(form)) return form;\n\t\tconst key = foldToolName(form);\n\t\tconst folded = uniqueMatch(names, (name) => foldToolName(name) === key);\n\t\tif (folded !== undefined) return folded;\n\t\tconst unprefixed = uniqueMatch(names, (name) =>\n\t\t\ttoolNameForms(name)\n\t\t\t\t.slice(1)\n\t\t\t\t.some((registeredForm) => foldToolName(registeredForm) === key),\n\t\t);\n\t\tif (unprefixed !== undefined) return unprefixed;\n\t}\n\treturn undefined;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-ai",
3
- "version": "2026.9.23",
3
+ "version": "2026.9.24-2",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -84,7 +84,7 @@
84
84
  "dependencies": {
85
85
  "@anthropic-ai/sdk": "0.127.0",
86
86
  "@aws-sdk/client-bedrock-runtime": "3.1136.0",
87
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.23",
87
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.24-2",
88
88
  "@google/genai": "2.23.0",
89
89
  "@smithy/node-http-handler": "4.12.1",
90
90
  "http-proxy-agent": "9.1.0",