feat(claude-code): pass thinking level as effort
This commit is contained in:
parent
cf34383104
commit
5474e99ae2
3 changed files with 39 additions and 6 deletions
|
|
@ -5,6 +5,10 @@ export * from "./api-registry.js";
|
|||
export * from "./env-api-keys.js";
|
||||
export * from "./models.js";
|
||||
export * from "./providers/anthropic.js";
|
||||
export {
|
||||
mapThinkingLevelToEffort,
|
||||
supportsAdaptiveThinking,
|
||||
} from "./providers/anthropic-shared.js";
|
||||
export * from "./providers/azure-openai-responses.js";
|
||||
export * from "./providers/google.js";
|
||||
export * from "./providers/google-gemini-cli.js";
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ import type {
|
|||
Context,
|
||||
Model,
|
||||
SimpleStreamOptions,
|
||||
ThinkingLevel,
|
||||
ToolCall,
|
||||
} from "@gsd/pi-ai";
|
||||
import type { ExtensionUIContext } from "@gsd/pi-coding-agent";
|
||||
import { EventStream } from "@gsd/pi-ai";
|
||||
import { EventStream, mapThinkingLevelToEffort, supportsAdaptiveThinking } from "@gsd/pi-ai";
|
||||
import { execSync } from "node:child_process";
|
||||
import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
|
||||
import { buildWorkflowMcpServers } from "../gsd/workflow-mcp.js";
|
||||
|
|
@ -600,8 +601,9 @@ export function buildSdkOptions(
|
|||
modelId: string,
|
||||
prompt: string,
|
||||
overrides?: { permissionMode?: "bypassPermissions" | "acceptEdits" | "default" | "plan" },
|
||||
extraOptions: Record<string, unknown> = {},
|
||||
extraOptions: Record<string, unknown> & { reasoning?: ThinkingLevel } = {},
|
||||
): Record<string, unknown> {
|
||||
const { reasoning, ...sdkExtraOptions } = extraOptions;
|
||||
const mcpServers = buildWorkflowMcpServers();
|
||||
const permissionMode = overrides?.permissionMode ?? "bypassPermissions";
|
||||
const disallowedTools = ["AskUserQuestion"];
|
||||
|
|
@ -620,6 +622,10 @@ export function buildSdkOptions(
|
|||
"Bash(pwd)",
|
||||
...(mcpServers ? Object.keys(mcpServers).map((serverName) => `mcp__${serverName}__*`) : []),
|
||||
];
|
||||
const effort =
|
||||
reasoning && supportsAdaptiveThinking(modelId)
|
||||
? mapThinkingLevelToEffort(reasoning, modelId)
|
||||
: undefined;
|
||||
return {
|
||||
pathToClaudeCodeExecutable: getClaudePath(),
|
||||
model: modelId,
|
||||
|
|
@ -634,7 +640,8 @@ export function buildSdkOptions(
|
|||
...(allowedTools.length > 0 ? { allowedTools } : {}),
|
||||
...(mcpServers ? { mcpServers } : {}),
|
||||
betas: modelId.includes("sonnet") ? ["context-1m-2025-08-07"] : [],
|
||||
...extraOptions,
|
||||
...(effort ? { effort } : {}),
|
||||
...sdkExtraOptions,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -828,11 +835,12 @@ async function pumpSdkMessages(
|
|||
{ permissionMode },
|
||||
typeof (options as ClaudeCodeStreamOptions | undefined)?.extensionUIContext === "object"
|
||||
? {
|
||||
reasoning: options?.reasoning,
|
||||
onElicitation: createClaudeCodeElicitationHandler(
|
||||
(options as ClaudeCodeStreamOptions | undefined)?.extensionUIContext,
|
||||
),
|
||||
}
|
||||
: {},
|
||||
: { reasoning: options?.reasoning },
|
||||
);
|
||||
|
||||
const queryResult = sdk.query({
|
||||
|
|
|
|||
|
|
@ -343,6 +343,26 @@ describe("stream-adapter — session persistence (#2859)", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("buildSdkOptions maps reasoning to effort for adaptive Claude Code models (#3917)", () => {
|
||||
const options = buildSdkOptions("claude-sonnet-4-6", "test", undefined, { reasoning: "high" });
|
||||
assert.equal(options.effort, "high");
|
||||
});
|
||||
|
||||
test("buildSdkOptions upgrades xhigh reasoning to max for opus 4.6 (#3917)", () => {
|
||||
const options = buildSdkOptions("claude-opus-4-6", "test", undefined, { reasoning: "xhigh" });
|
||||
assert.equal(options.effort, "max");
|
||||
});
|
||||
|
||||
test("buildSdkOptions omits effort when reasoning is undefined (#3917)", () => {
|
||||
const options = buildSdkOptions("claude-sonnet-4-6", "test");
|
||||
assert.equal("effort" in options, false);
|
||||
});
|
||||
|
||||
test("buildSdkOptions omits effort for non-adaptive Claude models (#3917)", () => {
|
||||
const options = buildSdkOptions("claude-sonnet-4-20250514", "test", undefined, { reasoning: "high" });
|
||||
assert.equal("effort" in options, false);
|
||||
});
|
||||
|
||||
test("buildSdkOptions includes workflow MCP server config when env is set", () => {
|
||||
const prev = {
|
||||
GSD_WORKFLOW_MCP_COMMAND: process.env.GSD_WORKFLOW_MCP_COMMAND,
|
||||
|
|
@ -774,11 +794,12 @@ describe("stream-adapter — MCP elicitation bridge", () => {
|
|||
},
|
||||
};
|
||||
|
||||
const secureValue = "ui-collected-value";
|
||||
const inputCalls: Array<{ opts?: { secure?: boolean } }> = [];
|
||||
const handler = createClaudeCodeElicitationHandler({
|
||||
input: async (_title: string, _placeholder?: string, opts?: { secure?: boolean }) => {
|
||||
inputCalls.push({ opts });
|
||||
return "example-secure-input";
|
||||
return secureValue;
|
||||
},
|
||||
} as any);
|
||||
assert.ok(handler);
|
||||
|
|
@ -787,7 +808,7 @@ describe("stream-adapter — MCP elicitation bridge", () => {
|
|||
assert.deepEqual(result, {
|
||||
action: "accept",
|
||||
content: {
|
||||
TEST_SECURE_FIELD: "example-secure-input",
|
||||
TEST_SECURE_FIELD: secureValue,
|
||||
},
|
||||
});
|
||||
assert.equal(inputCalls.length, 1);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue