-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Summary
Replace the current claude-code provider (subprocess scraper) with a new claude provider using the official @anthropic-ai/claude-agent-sdk. This follows the same pattern as the copilot provider (PR #211) which replaced the subprocess-based copilot-cli with the typed SDK.
Motivation
The current claude-code provider spawns the Claude CLI as a subprocess and scrapes stdout. The Agent SDK provides:
- Structured messages via
AsyncGenerator<SDKMessage>- typedSDKAssistantMessage,SDKResultMessage - Token usage & cost from
SDKResultMessage.usage,modelUsage,total_cost_usd - Duration from
SDKResultMessage.duration_ms - Tool call tracking via assistant message content blocks or
PostToolUsehooks - Permission control via
permissionMode: 'bypassPermissions'(no interactive prompts) - Model selection via
options.model - Budget control via
options.maxBudgetUsdandoptions.maxTurns - Abort support via
options.abortController
SDK API Overview
import { query } from '@anthropic-ai/claude-agent-sdk';
const q = query({
prompt: 'What is 2+2?',
options: {
model: 'claude-sonnet-4-5-20250929',
permissionMode: 'bypassPermissions',
allowDangerouslySkipPermissions: true,
cwd: '/path/to/workspace',
systemPrompt: 'custom system prompt',
maxTurns: 50,
maxBudgetUsd: 1.0,
abortController: new AbortController(),
}
});
for await (const message of q) {
if (message.type === 'assistant') {
// message.message contains APIAssistantMessage with content blocks
}
if (message.type === 'result') {
// message.result - final text
// message.usage - { input_tokens, output_tokens, cache_* }
// message.modelUsage - per-model breakdown with costUSD
// message.total_cost_usd - total cost
// message.duration_ms - total duration
// message.num_turns - number of turns
}
}Implementation Plan
Follow the same pattern as the copilot provider (see PR #211):
Files to modify
types.ts- Renameclaude-code→claudeinProviderKind, addclaude-codeas aliastargets.ts- Update resolved config and target resolutionindex.ts- Wire new provider, remove oldtargets-validator.ts- Update settings validation
Files to create
claude.ts- New provider using@anthropic-ai/claude-agent-sdk- Lazy-load SDK (same pattern as copilot provider)
- Use
query()withpermissionMode: 'bypassPermissions' - Map
SDKAssistantMessagecontent blocks →ToolCall[]andOutputMessage[] - Extract
usage,total_cost_usd,duration_msfromSDKResultMessage
claude-log-tracker.ts- Log tracker (rename from claude-code variant)claude.test.ts- Unit tests with mocked SDK
Files to delete
claude-code.ts- Old subprocess providerclaude-code-log-tracker.ts- Old log trackerclaude-code.test.ts- Old tests (if exists)
Dependencies
- Add
@anthropic-ai/claude-agent-sdktopackages/core/package.jsonandapps/cli/package.json - Add to CLI's
tsup.config.tsexternal list
Key Design Decisions
- Naming:
claude(canonical),claude-code(alias for backward compat) - Permissions: Use
bypassPermissions+allowDangerouslySkipPermissionsfor unattended eval - Tool calls: Extract from
SDKAssistantMessage.message.contentblocks (typetool_use/tool_result) - Streaming: Iterate the async generator, collect all messages, extract result at end
References
- TypeScript Agent SDK docs
- PR feat(core): add copilot-sdk provider #211 -
copilotprovider implementation (pattern to follow)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels