{"version":3,"file":"anthropic-capabilities.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic-capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE5D,MAAM,WAAW,0BAA0B;IAC1C,cAAc,EAAE,uBAAuB,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAcD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,0BAA0B,GAAG,IAAI,CAEnH;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS,CAEnH;AAED,4CAA4C;AAC5C,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAmFD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,0BAA0B,CAMvG;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAEpF;AAED,eAAO,MAAM,sBAAsB,0BAAkB,CAAC","sourcesContent":["/**\n * Per-(provider, model) capability lookup for Anthropic-family Claude models.\n *\n * Two layers:\n *\n *  1. Runtime cache populated from each provider's model-discovery endpoint:\n *       - github-copilot: GET {baseUrl}/models  (OpenAI-style with capabilities)\n *       - anthropic:      GET {baseUrl}/v1/models  (Anthropic-native capabilities)\n *     The discovery layer (see anthropic-discovery.ts) feeds this cache via\n *     `setDiscoveredCapabilities`. Discovery is provider-aware because the\n *     same conceptual model can have different capabilities on different\n *     relays (e.g. claude-opus-4.6 caps at 200k on GitHub Copilot, but the\n *     1M tier on Copilot is exposed as a separate model id \"claude-opus-4.6-1m\";\n *     on the direct Anthropic API the 1M tier on opus-4.5 is gated by the\n *     `context-1m-2025-08-07` beta header on the same id).\n *\n *  2. Static fallback table consulted only when discovery has not (yet) run\n *     for the (provider, model) pair, or has failed (offline, 4xx, 5xx, or\n *     the provider exposes no discovery endpoint — e.g. Bedrock, Vertex).\n *     The static table is intentionally *conservative*: it only encodes\n *     opt-ins we know to be safe on every relay we have tested. Anything\n *     uncertain (xhighEffort, contextBeta) is left off and is only enabled\n *     after discovery confirms it.\n *\n * The capability shape:\n *   - thinkingSchema : which extended-thinking request shape the model\n *                      accepts. \"legacy\" -> {thinking:{type:\"enabled\",\n *                      budget_tokens:N}}.  \"adaptive\" -> {thinking:{type:\n *                      \"adaptive\"}, output_config:{effort:...}}.\n *   - contextBeta    : optional `anthropic-beta` value to opt into a larger\n *                      context window via header (Anthropic-direct only).\n *   - contextWindow  : ceiling once contextBeta (if any) is applied.\n *                      When set, overrides models.generated.ts at registry\n *                      load time so the modeline/picker/compaction logic\n *                      see the real value.\n *   - xhighEffort    : true when \"xhigh\" thinking should map to adaptive\n *                      effort \"max\" instead of clamping to \"high\".\n *                      Only valid when the underlying account/relay exposes\n *                      effort=max for the model.\n */\n\nexport type AnthropicThinkingSchema = \"legacy\" | \"adaptive\";\n\nexport interface AnthropicModelCapabilities {\n\tthinkingSchema: AnthropicThinkingSchema;\n\tcontextBeta?: string;\n\tcontextWindow?: number;\n\txhighEffort?: boolean;\n}\n\nconst CONTEXT_1M_BETA = \"context-1m-2025-08-07\";\n\n// ----------------------------------------------------------------------------\n// Runtime cache (populated by anthropic-discovery.ts)\n// ----------------------------------------------------------------------------\n\nconst discoveredCache = new Map<string, AnthropicModelCapabilities>();\n\nfunction cacheKey(provider: string, modelId: string): string {\n\treturn `${provider}::${modelId}`;\n}\n\nexport function setDiscoveredCapabilities(provider: string, modelId: string, caps: AnthropicModelCapabilities): void {\n\tdiscoveredCache.set(cacheKey(provider, modelId), caps);\n}\n\nexport function getDiscoveredCapabilities(provider: string, modelId: string): AnthropicModelCapabilities | undefined {\n\treturn discoveredCache.get(cacheKey(provider, modelId));\n}\n\n/** Clear the discovery cache. Test-only. */\nexport function _clearDiscoveredCapabilitiesForTests(): void {\n\tdiscoveredCache.clear();\n}\n\n// ----------------------------------------------------------------------------\n// Static fallback table\n// ----------------------------------------------------------------------------\n\n/**\n * Ordered list of static entries.\n *\n * Each entry can optionally restrict its match to specific providers. This\n * encodes the asymmetry we have empirically verified:\n *\n *  - On the direct Anthropic API and on AWS Bedrock (which mirrors the\n *    same Messages API), Opus 4.6 / 4.7 accept `output_config.effort=max`\n *    per Anthropic's own /v1/models capability advertisement.\n *  - On the GitHub Copilot Anthropic relay, the *same* model ids cap\n *    reasoning_effort at [\"low\",\"medium\",\"high\"]; sending effort=max is\n *    rejected. Copilot exposes the higher tier as a distinct model id\n *    whose reasoning_effort list includes \"xhigh\". So for Copilot we\n *    leave xhighEffort off here\n *    and let the discovery layer fill it in per actual model id.\n *\n * First match wins.\n */\nconst CAPABILITY_ENTRIES: Array<{\n\tmatch: (id: string) => boolean;\n\tproviders?: ReadonlyArray<string>;\n\tcaps: AnthropicModelCapabilities;\n}> = [\n\t// Opus 4.7 — adaptive thinking. xhigh -> effort=max on the direct\n\t// Anthropic API and Bedrock; not on Copilot (uses separate model ids).\n\t{\n\t\tmatch: (id) => id.includes(\"opus-4-7\") || id.includes(\"opus-4.7\"),\n\t\tproviders: [\"anthropic\", \"amazon-bedrock\", \"openrouter\"],\n\t\tcaps: { thinkingSchema: \"adaptive\", xhighEffort: true },\n\t},\n\t{\n\t\tmatch: (id) => id.includes(\"opus-4-7\") || id.includes(\"opus-4.7\"),\n\t\tcaps: { thinkingSchema: \"adaptive\" },\n\t},\n\t// Opus 4.6 — same provider-conditional xhighEffort.\n\t{\n\t\tmatch: (id) => id.includes(\"opus-4-6\") || id.includes(\"opus-4.6\"),\n\t\tproviders: [\"anthropic\", \"amazon-bedrock\", \"openrouter\"],\n\t\tcaps: { thinkingSchema: \"adaptive\", xhighEffort: true },\n\t},\n\t{\n\t\tmatch: (id) => id.includes(\"opus-4-6\") || id.includes(\"opus-4.6\"),\n\t\tcaps: { thinkingSchema: \"adaptive\" },\n\t},\n\t// Opus 4.5 — legacy thinking. The 1M context window via the context-1m\n\t// beta header is direct-Anthropic-only (and even there the Anthropic\n\t// /v1/models endpoint is the authoritative source — discovery confirms\n\t// the beta and the resulting window). The Copilot relay rejects this\n\t// header (it offers 1M via separate model ids only).\n\t{\n\t\tmatch: (id) => id.includes(\"opus-4-5\") || id.includes(\"opus-4.5\"),\n\t\tcaps: { thinkingSchema: \"legacy\" },\n\t},\n\t// Sonnet 4.6 — adaptive thinking on all relays.\n\t{\n\t\tmatch: (id) => id.includes(\"sonnet-4-6\") || id.includes(\"sonnet-4.6\"),\n\t\tcaps: { thinkingSchema: \"adaptive\" },\n\t},\n];\n\nconst DEFAULT_CAPABILITIES: AnthropicModelCapabilities = {\n\tthinkingSchema: \"legacy\",\n};\n\nfunction staticCapabilities(modelId: string, provider?: string): AnthropicModelCapabilities {\n\tfor (const entry of CAPABILITY_ENTRIES) {\n\t\tif (!entry.match(modelId)) continue;\n\t\tif (entry.providers && (!provider || !entry.providers.includes(provider))) continue;\n\t\treturn entry.caps;\n\t}\n\treturn DEFAULT_CAPABILITIES;\n}\n\n// ----------------------------------------------------------------------------\n// Public lookup\n// ----------------------------------------------------------------------------\n\n/**\n * Resolve capabilities for a Claude model.\n *\n * When `provider` is supplied, the runtime cache populated by discovery is\n * consulted first. Falls back to the static table otherwise.\n *\n * Backward-compatible signature: callers that do not have a provider id\n * (e.g. registry-load time, before any auth has happened) can omit it and\n * get the static fallback.\n */\nexport function getAnthropicCapabilities(modelId: string, provider?: string): AnthropicModelCapabilities {\n\tif (provider) {\n\t\tconst cached = discoveredCache.get(cacheKey(provider, modelId));\n\t\tif (cached) return cached;\n\t}\n\treturn staticCapabilities(modelId, provider);\n}\n\nexport function supportsAdaptiveThinking(modelId: string, provider?: string): boolean {\n\treturn getAnthropicCapabilities(modelId, provider).thinkingSchema === \"adaptive\";\n}\n\nexport const CONTEXT_1M_BETA_HEADER = CONTEXT_1M_BETA;\n"]}