claudeModelId.ts ×9

Frontier kind: Code frontier

unlabeled · c_e5d10e7c3d25

293 tests · 3462 LOC · 19 files · introduces 0 tests · 84 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
9 ranges84 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
489 ranges3462 lines · 19 files · Browse complete extent
All tests (intent)
293 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 84 introduced LOC across 9 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/claude/claudeModelId.ts 84 introduced LOC · 9 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- claudeModelId.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > /**
7 > * Mirror of `extensions/copilot/src/extension/chatSessions/claude/{common,node}/claudeModelId.ts`.
8 > *
9 > * The Claude Agent SDK speaks Anthropic-canonical hyphenated model IDs
10 > * (e.g. `claude-opus-4-6-20251101`). CAPI speaks dotted endpoint IDs
11 > * (`claude-opus-4.6`). The Phase 2 proxy needs bidirectional translation
12 > * at three points: inbound `requestBody.model` (SDK→CAPI), outbound
13 > * `model` fields on streaming events / non-streaming responses (CAPI→SDK),
14 > * and `GET /v1/models` response IDs (CAPI→SDK).
15 > *
16 > * **Keep in sync with the extension copy.** When the model-ID grammar
17 > * changes (new family name, new modifier suffix), update both files.
18 > */
19 >
20 > export interface ParsedClaudeModelId {
21 > readonly name: string;
22 > readonly version: string;
23 > readonly modifiers: string;
24 > toSdkModelId(): string;
25 > toEndpointModelId(): string;
26 > }
27 >
28 > /**
29 > * Known model suffixes that are meaningful variants and should be preserved
30 > * in SDK/endpoint model IDs. Mapped per model family. Date-based suffixes
31 > * (e.g. 20251101) are intentionally excluded — they are build identifiers
32 > * that should not appear in the normalized output.
33 > */
34 > const VALID_SUFFIXES: ReadonlyMap<string, ReadonlySet<string>> = new Map([
35 > ['opus', new Set(['1m'])],
36 > ]);
37 >
38 > const cache = new Map<string, ParsedClaudeModelId | undefined>();
39 >
40 > /**
41 > * Parses a Claude model ID string (SDK or endpoint format) into its components.
42 > * Throws if the model ID is unparseable or not a Claude ID.
43 > *
44 > * Use {@link tryParseClaudeModelId} when the input may not be a valid Claude model ID
45 > * (e.g. model IDs from disk or external sources).
46 > */
47 > export function parseClaudeModelId(modelId: string): ParsedClaudeModelId {
48 const result = tryParseClaudeModelId(modelId);
49 if (!result) {
52 return result;
53 }
55 > /**
56 > * Normalize a Claude model ID to the SDK format (dash-separated version, e.g.
57 > * `claude-haiku-4-5`). The Claude Agent SDK / CLI only recognizes this form;
58 > * given the endpoint format (`claude-haiku-4.5`) it treats the model as unknown
59 > * and falls back to a generic feature set (adaptive thinking + reasoning effort)
60 > * that the model may not support, producing a 400 from CAPI. Unparseable /
61 > * non-Claude IDs pass through unchanged; `undefined` passes through as
62 > * `undefined` so callers can normalize an optional model id in one step.
63 > */
64 > export function toSdkModelId(modelId: string): string;
65 > export function toSdkModelId(modelId: string | undefined): string | undefined;
66 > export function toSdkModelId(modelId: string | undefined): string | undefined {
67 if (modelId === undefined) {
68 return undefined;
70 return tryParseClaudeModelId(modelId)?.toSdkModelId() ?? modelId;
71 }
73 > /**
74 > * Attempts to parse a Claude model ID string (SDK or endpoint format) into its components.
75 > *
76 > * Accepts either format:
77 > * - SDK: `claude-opus-4-5-20251101`, `claude-3-5-sonnet-20241022`, `claude-sonnet-4-20250514`
78 > * - Endpoint: `claude-opus-4.5`, `claude-sonnet-4`, `claude-haiku-3.5`
79 > *
80 > * Returns `undefined` for unparseable or non-Claude IDs.
81 > */
82 > export function tryParseClaudeModelId(modelId: string): ParsedClaudeModelId | undefined {
83 const cacheKey = modelId.toLowerCase();
84 if (cache.has(cacheKey)) {
90 return result;
91 }
93 > const DATE_SUFFIX_RE = /^(?<base>.*)-(?<date>\d{8})$/;
94 >
95 function doParse(lower: string): ParsedClaudeModelId | undefined {
96 let dateSuffix = '';
141 return undefined;
142 }
144 function joinModifiers(mod: string | undefined, dateSuffix: string): string {
145 if (mod && dateSuffix) {
148 return mod || dateSuffix;
149 }
151 function formatModelId(name: string, major: string, minor: string | undefined, versionSep: string, validSuffix: string): string {
152 const base = minor !== undefined
155 return validSuffix ? `${base}-${validSuffix}` : base;
156 }
158 function makeBareResult(name: string): ParsedClaudeModelId {
159 return {
165 };
166 }
168 function makeResult(name: string, major: string, minor: string | undefined, modifiers: string): ParsedClaudeModelId {
169 const version = minor !== undefined ? `${major}.${minor}` : major;
177 };
178 }
180 > /**
181 > * Extracts the valid suffix portion from modifiers for a given model family.
182 > * For example, given modifiers '1m-20251101' and family 'opus', returns '1m'.
183 > * Returns an empty string if no valid suffix is found.
184 > */
185 function extractValidSuffix(name: string, modifiers: string): string {
186 if (!modifiers) {