1
>
/*---------------------------------------------------------------------------------------------
claudeModelConfig.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
>
import { localize } from '../../../nls.js';
7
>
import { getReasoningEffortDescription, getReasoningEffortLabel } from './reasoningEffort.js';
8
>
import type { ConfigSchema, ModelSelection } from './state/protocol/state.js';
9
>
10
>
/**
11
>
* Sub-key in `ModelSelection.config` carrying the user's reasoning-effort
12
>
* pick from the model picker. Mirror of CopilotAgent's
13
>
* `ThinkingLevelConfigKey` (copilotAgent.ts:83) so a single picker contract
14
>
* spans both providers — the picker writes `model.config.thinkingLevel`,
15
>
* and each provider narrows that string at materialize.
16
>
*/
17
>
export const CLAUDE_THINKING_LEVEL_KEY = 'thinkingLevel';
18
>
19
>
/**
20
>
* Reasoning-effort values accepted by the Claude SDK's `Options.effort`
21
>
* (startup). Hand-rolled here — not imported from the SDK — to keep `common/`
22
>
* SDK-free; structurally identical to the SDK's exported `EffortLevel` so it
23
>
* assigns into `Options.effort` without a cast.
24
>
*/
25
>
export type ClaudeEffortLevel = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
26
>
27
>
/**
28
>
* The effort union the SDK's runtime hot-swap setter
29
>
* `Query.applyFlagSettings({ effortLevel })` is *declared* to accept. Note it
30
>
* excludes `'max'` — but see {@link toRuntimeEffortLevel}: a `'max'` value can
31
>
* still flow through this type at runtime, because the SDK's declared type is
32
>
* narrower than what the API actually accepts.
33
>
*/
34
>
export type ClaudeRuntimeEffortLevel = 'low' | 'medium' | 'high' | 'xhigh';
35
>
36
>
/**
37
>
* Coerce a startup {@link ClaudeEffortLevel} to the {@link ClaudeRuntimeEffortLevel}
38
>
* union the SDK's `applyFlagSettings({ effortLevel })` setter is typed to accept.
39
>
*
40
>
* This used to clamp `'max'` down to `'xhigh'`, because the SDK's
41
>
* `Settings.effortLevel` .d.ts type omits `'max'`. That type is wrong: the
42
>
* Anthropic API / Copilot CAPI accept `'max'` end-to-end — confirmed with
43
>
* Anthropic, and verified by watching a `'max'` turn round-trip successfully
44
>
* (the exported `EffortLevel` union and the wire `output_config.effort` field
45
>
* both include `'max'`). So `'max'` is now passed straight through.
46
>
*
47
>
* The cast is deliberate: this returns a value its own return type says it
48
>
* cannot — `'max'` is not a member of {@link ClaudeRuntimeEffortLevel}. Keeping
49
>
* the narrow return type lets every downstream consumer stay honest against the
50
>
* SDK's declared surface while the single lie lives here. Drop the cast (and
51
>
* widen the return type, or restore a real clamp) once the SDK's
52
>
* `Settings.effortLevel` type is corrected upstream
53
>
* (anthropics/claude-agent-sdk-typescript#377).
54
>
*/
55
>
export function toRuntimeEffortLevel(effort: ClaudeEffortLevel | undefined): ClaudeRuntimeEffortLevel | undefined {
56
return effort as ClaudeRuntimeEffortLevel | undefined;
57
}
59
>
/**
60
>
* Pull `thinkingLevel` out of `ModelSelection.config` and narrow it to
61
>
* {@link ClaudeEffortLevel}. Returns `undefined` when the model selection
62
>
* is absent or carries an unrecognized value (the SDK then falls through
63
>
* to its own default). Mirror of CopilotAgent's `_getReasoningEffort`
64
>
* (copilotAgent.ts:487).
65
>
*/
66
>
export function resolveClaudeEffort(model: ModelSelection | undefined): ClaudeEffortLevel | undefined {
67
const raw = model?.config?.[CLAUDE_THINKING_LEVEL_KEY];
68
switch (raw) {