mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-02-12 17:22:50 +00:00
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:
@@ -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)
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
97
mcp-server/package-lock.json
generated
97
mcp-server/package-lock.json
generated
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
99
package-lock.json
generated
@@ -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": {
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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': {
|
||||||
|
|||||||
@@ -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[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user