feat: upgrade claude-agent-sdk to 0.2.38 and adapt to new SDK types (#113)

* feat: upgrade claude-agent-sdk to 0.2.38 and adapt to new SDK types

- Bump @anthropic-ai/claude-agent-sdk from 0.1.x to 0.2.38 (both root and mcp-server)
- Bump zod from 3.x to 4.x (SDK peer dependency)
- Add allowDangerouslySkipPermissions to query options (required for bypassPermissions)
- Suppress new SDK message types (tool_progress, tool_use_summary, auth_status)
- Use structured error field on assistant messages instead of text-sniffing
- Add stop_reason to result message handling for diagnostics
- Add SDKAssistantMessageError type matching SDK's string literal union

* chore: remove CLAUDE_CODE_MAX_OUTPUT_TOKENS from all config and docs
This commit is contained in:
ezl-keygraph
2026-02-11 00:19:59 +05:30
committed by GitHub
parent b210952de8
commit d28a511070
11 changed files with 278 additions and 33 deletions

View File

@@ -1,9 +1,6 @@
# Shannon Environment Configuration # Shannon Environment Configuration
# Copy this file to .env and fill in your credentials # Copy this file to .env and fill in your credentials
# Recommended output token configuration for larger tool outputs
CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000
# ============================================================================= # =============================================================================
# OPTION 1: Direct Anthropic (default, no router) # OPTION 1: Direct Anthropic (default, no router)
# ============================================================================= # =============================================================================

View File

@@ -18,7 +18,6 @@ This is an AI-powered penetration testing agent designed for defensive security
cp .env.example .env cp .env.example .env
# Edit .env: # Edit .env:
# ANTHROPIC_API_KEY=your-key # ANTHROPIC_API_KEY=your-key
# CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000 # Prevents token limits during long reports
# Start a pentest workflow # Start a pentest workflow
./shannon start URL=<url> REPO=<name> ./shannon start URL=<url> REPO=<name>

View File

@@ -119,12 +119,10 @@ cd shannon
# Option A: Export environment variables # Option A: Export environment variables
export ANTHROPIC_API_KEY="your-api-key" # or CLAUDE_CODE_OAUTH_TOKEN export ANTHROPIC_API_KEY="your-api-key" # or CLAUDE_CODE_OAUTH_TOKEN
export CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000 # recommended
# Option B: Create a .env file # Option B: Create a .env file
cat > .env << 'EOF' cat > .env << 'EOF'
ANTHROPIC_API_KEY=your-api-key ANTHROPIC_API_KEY=your-api-key
CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000
EOF EOF
# 3. Run a pentest # 3. Run a pentest

View File

@@ -24,7 +24,6 @@ services:
- ANTHROPIC_AUTH_TOKEN=${ANTHROPIC_AUTH_TOKEN:-} # Auth token for router - ANTHROPIC_AUTH_TOKEN=${ANTHROPIC_AUTH_TOKEN:-} # Auth token for router
- ROUTER_DEFAULT=${ROUTER_DEFAULT:-} # Model name when using router (e.g., "gemini,gemini-2.5-pro") - ROUTER_DEFAULT=${ROUTER_DEFAULT:-} # Model name when using router (e.g., "gemini,gemini-2.5-pro")
- CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN:-} - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN:-}
- CLAUDE_CODE_MAX_OUTPUT_TOKENS=${CLAUDE_CODE_MAX_OUTPUT_TOKENS:-64000}
depends_on: depends_on:
temporal: temporal:
condition: service_healthy condition: service_healthy

View File

@@ -8,8 +8,8 @@
"name": "@shannon/mcp-server", "name": "@shannon/mcp-server",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.0", "@anthropic-ai/claude-agent-sdk": "^0.2.38",
"zod": "^3.22.4" "zod": "^4.3.6"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^25.0.3", "@types/node": "^25.0.3",
@@ -17,9 +17,9 @@
} }
}, },
"node_modules/@anthropic-ai/claude-agent-sdk": { "node_modules/@anthropic-ai/claude-agent-sdk": {
"version": "0.1.25", "version": "0.2.38",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.1.25.tgz", "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.38.tgz",
"integrity": "sha512-qwuydYaA3uamz4ivDzYXfL2PBjGwc0+beeIyo3nvtZQOtFLjH7xPdBK2w3+9KnB3L6V7VooAMdTXPpQyxCwcOg==", "integrity": "sha512-U1vpf3rlSkw1qUlzC6CBibBA30ouQnla9JnuqYFLQ2zBb1U2NUCXIElrnV7RwWrI5e9ZKCHgR+1uaCwROONo7w==",
"license": "SEE LICENSE IN README.md", "license": "SEE LICENSE IN README.md",
"engines": { "engines": {
"node": ">=18.0.0" "node": ">=18.0.0"
@@ -30,10 +30,12 @@
"@img/sharp-linux-arm": "^0.33.5", "@img/sharp-linux-arm": "^0.33.5",
"@img/sharp-linux-arm64": "^0.33.5", "@img/sharp-linux-arm64": "^0.33.5",
"@img/sharp-linux-x64": "^0.33.5", "@img/sharp-linux-x64": "^0.33.5",
"@img/sharp-linuxmusl-arm64": "^0.33.5",
"@img/sharp-linuxmusl-x64": "^0.33.5",
"@img/sharp-win32-x64": "^0.33.5" "@img/sharp-win32-x64": "^0.33.5"
}, },
"peerDependencies": { "peerDependencies": {
"zod": "^3.24.1" "zod": "^4.0.0"
} }
}, },
"node_modules/@img/sharp-darwin-arm64": { "node_modules/@img/sharp-darwin-arm64": {
@@ -160,6 +162,38 @@
"url": "https://opencollective.com/libvips" "url": "https://opencollective.com/libvips"
} }
}, },
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
"integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
"cpu": [
"arm64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
"integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
"cpu": [
"x64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-linux-arm": { "node_modules/@img/sharp-linux-arm": {
"version": "0.33.5", "version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
@@ -226,6 +260,50 @@
"@img/sharp-libvips-linux-x64": "1.0.4" "@img/sharp-libvips-linux-x64": "1.0.4"
} }
}, },
"node_modules/@img/sharp-linuxmusl-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
"integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
"integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-x64": "1.0.4"
}
},
"node_modules/@img/sharp-win32-x64": { "node_modules/@img/sharp-win32-x64": {
"version": "0.33.5", "version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
@@ -277,10 +355,11 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/zod": { "node_modules/zod": {
"version": "3.25.76", "version": "4.3.6",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
"license": "MIT", "license": "MIT",
"peer": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"
} }

View File

@@ -8,8 +8,8 @@
"clean": "rm -rf dist" "clean": "rm -rf dist"
}, },
"dependencies": { "dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.0", "@anthropic-ai/claude-agent-sdk": "^0.2.38",
"zod": "^3.22.4" "zod": "^4.3.6"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^25.0.3", "@types/node": "^25.0.3",

99
package-lock.json generated
View File

@@ -8,7 +8,7 @@
"name": "shannon", "name": "shannon",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.0", "@anthropic-ai/claude-agent-sdk": "^0.2.38",
"@temporalio/activity": "^1.11.0", "@temporalio/activity": "^1.11.0",
"@temporalio/client": "^1.11.0", "@temporalio/client": "^1.11.0",
"@temporalio/worker": "^1.11.0", "@temporalio/worker": "^1.11.0",
@@ -21,12 +21,9 @@
"figlet": "^1.9.3", "figlet": "^1.9.3",
"gradient-string": "^3.0.0", "gradient-string": "^3.0.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"zod": "^3.22.4", "zod": "^4.3.6",
"zx": "^8.0.0" "zx": "^8.0.0"
}, },
"bin": {
"shannon": "dist/shannon.js"
},
"devDependencies": { "devDependencies": {
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/node": "^25.0.3", "@types/node": "^25.0.3",
@@ -34,9 +31,9 @@
} }
}, },
"node_modules/@anthropic-ai/claude-agent-sdk": { "node_modules/@anthropic-ai/claude-agent-sdk": {
"version": "0.1.25", "version": "0.2.38",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.1.25.tgz", "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.38.tgz",
"integrity": "sha512-qwuydYaA3uamz4ivDzYXfL2PBjGwc0+beeIyo3nvtZQOtFLjH7xPdBK2w3+9KnB3L6V7VooAMdTXPpQyxCwcOg==", "integrity": "sha512-U1vpf3rlSkw1qUlzC6CBibBA30ouQnla9JnuqYFLQ2zBb1U2NUCXIElrnV7RwWrI5e9ZKCHgR+1uaCwROONo7w==",
"license": "SEE LICENSE IN README.md", "license": "SEE LICENSE IN README.md",
"engines": { "engines": {
"node": ">=18.0.0" "node": ">=18.0.0"
@@ -47,10 +44,12 @@
"@img/sharp-linux-arm": "^0.33.5", "@img/sharp-linux-arm": "^0.33.5",
"@img/sharp-linux-arm64": "^0.33.5", "@img/sharp-linux-arm64": "^0.33.5",
"@img/sharp-linux-x64": "^0.33.5", "@img/sharp-linux-x64": "^0.33.5",
"@img/sharp-linuxmusl-arm64": "^0.33.5",
"@img/sharp-linuxmusl-x64": "^0.33.5",
"@img/sharp-win32-x64": "^0.33.5" "@img/sharp-win32-x64": "^0.33.5"
}, },
"peerDependencies": { "peerDependencies": {
"zod": "^3.24.1" "zod": "^4.0.0"
} }
}, },
"node_modules/@grpc/grpc-js": { "node_modules/@grpc/grpc-js": {
@@ -208,6 +207,38 @@
"url": "https://opencollective.com/libvips" "url": "https://opencollective.com/libvips"
} }
}, },
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
"integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
"cpu": [
"arm64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
"integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
"cpu": [
"x64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-linux-arm": { "node_modules/@img/sharp-linux-arm": {
"version": "0.33.5", "version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
@@ -274,6 +305,50 @@
"@img/sharp-libvips-linux-x64": "1.0.4" "@img/sharp-libvips-linux-x64": "1.0.4"
} }
}, },
"node_modules/@img/sharp-linuxmusl-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
"integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
"integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-x64": "1.0.4"
}
},
"node_modules/@img/sharp-win32-x64": { "node_modules/@img/sharp-win32-x64": {
"version": "0.33.5", "version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
@@ -2544,9 +2619,9 @@
} }
}, },
"node_modules/zod": { "node_modules/zod": {
"version": "3.25.76", "version": "4.3.6",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"funding": { "funding": {

View File

@@ -11,7 +11,7 @@
"temporal:query": "node dist/temporal/query.js" "temporal:query": "node dist/temporal/query.js"
}, },
"dependencies": { "dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.0", "@anthropic-ai/claude-agent-sdk": "^0.2.38",
"@temporalio/activity": "^1.11.0", "@temporalio/activity": "^1.11.0",
"@temporalio/client": "^1.11.0", "@temporalio/client": "^1.11.0",
"@temporalio/worker": "^1.11.0", "@temporalio/worker": "^1.11.0",
@@ -24,7 +24,7 @@
"figlet": "^1.9.3", "figlet": "^1.9.3",
"gradient-string": "^3.0.0", "gradient-string": "^3.0.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"zod": "^3.22.4", "zod": "^4.3.6",
"zx": "^8.0.0" "zx": "^8.0.0"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -223,6 +223,7 @@ export async function runClaudePrompt(
maxTurns: 10_000, maxTurns: 10_000,
cwd: sourceDir, cwd: sourceDir,
permissionMode: 'bypassPermissions' as const, permissionMode: 'bypassPermissions' as const,
allowDangerouslySkipPermissions: true,
mcpServers, mcpServers,
}; };

View File

@@ -22,6 +22,7 @@ import type { AuditLogger } from './audit-logger.js';
import type { ProgressManager } from './progress-manager.js'; import type { ProgressManager } from './progress-manager.js';
import type { import type {
AssistantMessage, AssistantMessage,
SDKAssistantMessageError,
ResultMessage, ResultMessage,
ToolUseMessage, ToolUseMessage,
ToolResultMessage, ToolResultMessage,
@@ -100,13 +101,86 @@ export function detectApiError(content: string): ApiErrorDetection {
return { detected: false }; return { detected: false };
} }
// Maps SDK structured error types to our error handling.
function handleStructuredError(
errorType: SDKAssistantMessageError,
content: string
): ApiErrorDetection {
switch (errorType) {
case 'billing_error':
return {
detected: true,
shouldThrow: new PentestError(
`Billing error (structured): ${content.slice(0, 100)}`,
'billing',
true // Retryable with backoff
),
};
case 'rate_limit':
return {
detected: true,
shouldThrow: new PentestError(
`Rate limit hit (structured): ${content.slice(0, 100)}`,
'network',
true // Retryable with backoff
),
};
case 'authentication_failed':
return {
detected: true,
shouldThrow: new PentestError(
`Authentication failed: ${content.slice(0, 100)}`,
'config',
false // Not retryable - needs API key fix
),
};
case 'server_error':
return {
detected: true,
shouldThrow: new PentestError(
`Server error (structured): ${content.slice(0, 100)}`,
'network',
true // Retryable
),
};
case 'invalid_request':
return {
detected: true,
shouldThrow: new PentestError(
`Invalid request: ${content.slice(0, 100)}`,
'config',
false // Not retryable - needs code fix
),
};
case 'max_output_tokens':
return {
detected: true,
shouldThrow: new PentestError(
`Max output tokens reached: ${content.slice(0, 100)}`,
'billing',
true // Retryable - may succeed with different content
),
};
case 'unknown':
default:
return { detected: true };
}
}
export function handleAssistantMessage( export function handleAssistantMessage(
message: AssistantMessage, message: AssistantMessage,
turnCount: number turnCount: number
): AssistantResult { ): AssistantResult {
const content = extractMessageContent(message); const content = extractMessageContent(message);
const cleanedContent = filterJsonToolCalls(content); const cleanedContent = filterJsonToolCalls(content);
const errorDetection = detectApiError(content);
// Prefer structured error field from SDK, fall back to text-sniffing
let errorDetection: ApiErrorDetection;
if (message.error) {
errorDetection = handleStructuredError(message.error, content);
} else {
errorDetection = detectApiError(content);
}
const result: AssistantResult = { const result: AssistantResult = {
content, content,
@@ -141,6 +215,14 @@ export function handleResultMessage(message: ResultMessage): ResultData {
result.subtype = message.subtype; result.subtype = message.subtype;
} }
// Capture stop_reason for diagnostics (helps debug early stops, budget exceeded, etc.)
if (message.stop_reason !== undefined) {
result.stop_reason = message.stop_reason;
if (message.stop_reason && message.stop_reason !== 'end_turn') {
console.log(chalk.yellow(` Stop reason: ${message.stop_reason}`));
}
}
return result; return result;
} }
@@ -247,6 +329,9 @@ export async function dispatchMessage(
} }
case 'user': case 'user':
case 'tool_progress':
case 'tool_use_summary':
case 'auth_status':
return { type: 'continue' }; return { type: 'continue' };
case 'tool_use': { case 'tool_use': {

View File

@@ -46,6 +46,7 @@ export interface ResultData {
cost: number; cost: number;
duration_ms: number; duration_ms: number;
subtype?: string; subtype?: string;
stop_reason?: string | null;
permissionDenials: number; permissionDenials: number;
} }
@@ -66,8 +67,18 @@ export interface ContentBlock {
text?: string; text?: string;
} }
export type SDKAssistantMessageError =
| 'authentication_failed'
| 'billing_error'
| 'rate_limit'
| 'invalid_request'
| 'server_error'
| 'max_output_tokens'
| 'unknown';
export interface AssistantMessage { export interface AssistantMessage {
type: 'assistant'; type: 'assistant';
error?: SDKAssistantMessageError;
message: { message: {
content: ContentBlock[] | string; content: ContentBlock[] | string;
}; };
@@ -79,6 +90,7 @@ export interface ResultMessage {
total_cost_usd?: number; total_cost_usd?: number;
duration_ms?: number; duration_ms?: number;
subtype?: string; subtype?: string;
stop_reason?: string | null;
permission_denials?: unknown[]; permission_denials?: unknown[];
} }