From e8a7881307bbf2714f4a2bf85ceb5ef877b6e036 Mon Sep 17 00:00:00 2001 From: Lex Christopherson Date: Wed, 25 Mar 2026 12:22:40 -0600 Subject: [PATCH] fix(claude-code-cli): resolve SDK executable path and update model IDs - Add pathToClaudeCodeExecutable to SDK query options, resolving the system `claude` binary via `which claude`. Without this, the SDK looks for a bundled cli.js that doesn't exist when installed as a library dependency. - Remove env option that was replacing the subprocess environment and stripping auth credentials, causing "Not logged in" errors. - Update model IDs to current versions: claude-opus-4-6 (1M ctx), claude-sonnet-4-6 (1M ctx), claude-haiku-4-5 (200K ctx). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../extensions/claude-code-cli/models.ts | 25 ++++++++++-------- .../claude-code-cli/stream-adapter.ts | 26 ++++++++++++++++++- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/resources/extensions/claude-code-cli/models.ts b/src/resources/extensions/claude-code-cli/models.ts index 66edcf67c..99ea17b16 100644 --- a/src/resources/extensions/claude-code-cli/models.ts +++ b/src/resources/extensions/claude-code-cli/models.ts @@ -4,36 +4,39 @@ * Costs are zero because inference is covered by the user's Claude Code * subscription. The SDK's `result` message still provides token counts * for display in the TUI. + * + * Context windows and max tokens match the Anthropic API definitions + * in models.generated.ts. */ const ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }; export const CLAUDE_CODE_MODELS = [ { - id: "claude-opus-4-20250514", - name: "Claude Opus 4 (via Claude Code)", + id: "claude-opus-4-6", + name: "Claude Opus 4.6 (via Claude Code)", reasoning: true, input: ["text", "image"] as ("text" | "image")[], cost: ZERO_COST, - contextWindow: 200_000, - maxTokens: 32_768, + contextWindow: 1_000_000, + maxTokens: 128_000, }, { - id: "claude-sonnet-4-20250514", - name: "Claude Sonnet 4 (via Claude Code)", + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6 (via Claude Code)", reasoning: true, input: ["text", "image"] as ("text" | "image")[], cost: ZERO_COST, - contextWindow: 200_000, - maxTokens: 16_384, + contextWindow: 1_000_000, + maxTokens: 64_000, }, { - id: "claude-haiku-4-5-20251001", + id: "claude-haiku-4-5", name: "Claude Haiku 4.5 (via Claude Code)", - reasoning: false, + reasoning: true, input: ["text", "image"] as ("text" | "image")[], cost: ZERO_COST, contextWindow: 200_000, - maxTokens: 8_192, + maxTokens: 64_000, }, ]; diff --git a/src/resources/extensions/claude-code-cli/stream-adapter.ts b/src/resources/extensions/claude-code-cli/stream-adapter.ts index 0327c00a6..8a916b1ac 100644 --- a/src/resources/extensions/claude-code-cli/stream-adapter.ts +++ b/src/resources/extensions/claude-code-cli/stream-adapter.ts @@ -16,6 +16,7 @@ import type { SimpleStreamOptions, } from "@gsd/pi-ai"; import { EventStream } from "@gsd/pi-ai"; +import { execSync } from "node:child_process"; import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js"; import type { SDKAssistantMessage, @@ -46,6 +47,29 @@ function createAssistantStream(): AssistantMessageEventStream { ) as AssistantMessageEventStream; } +// --------------------------------------------------------------------------- +// Claude binary resolution +// --------------------------------------------------------------------------- + +let cachedClaudePath: string | null = null; + +/** + * Resolve the path to the system-installed `claude` binary. + * The SDK defaults to a bundled cli.js which doesn't exist when + * installed as a library — we need to point it at the real CLI. + */ +function getClaudePath(): string { + if (cachedClaudePath) return cachedClaudePath; + try { + cachedClaudePath = execSync("which claude", { timeout: 5_000, stdio: "pipe" }) + .toString() + .trim(); + } catch { + cachedClaudePath = "claude"; // fall back to PATH resolution + } + return cachedClaudePath; +} + // --------------------------------------------------------------------------- // Prompt extraction // --------------------------------------------------------------------------- @@ -145,6 +169,7 @@ async function pumpSdkMessages( const queryResult = sdk.query({ prompt, options: { + pathToClaudeCodeExecutable: getClaudePath(), model: modelId, includePartialMessages: true, persistSession: false, @@ -154,7 +179,6 @@ async function pumpSdkMessages( allowDangerouslySkipPermissions: true, settingSources: ["project"], systemPrompt: { type: "preset", preset: "claude_code" }, - env: { CLAUDE_AGENT_SDK_CLIENT_APP: "gsd" }, betas: modelId.includes("sonnet") ? ["context-1m-2025-08-07"] : [], }, });