mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-08-27 21:50:38 +02:00
feat(worker): migrate agent runtime from Claude Agent SDK to pi harness (#389)
* feat(worker): migrate agent runtime from Claude Agent SDK to pi harness * feat: remove Google Vertex AI provider support * fix(worker): route Bedrock and custom-base-URL providers from env * feat(prompts): instruct agents to call submit_exploitation_queue and submit_auth_result * fix(worker): count sub-agent cost and surface compaction failures * refactor(worker): rename claude-executor to pi-executor * feat(worker): pi-event-driven output formatting * fix(worker): gate adaptive thinking to Opus models, drop CLAUDE_THINKING_LEVEL * fix(worker): restore minLength/minItems on vuln-collector schemas * feat(worker): give task sub-agent write+bash, align tool descriptions * feat(worker): add glob custom tool and route code_path globs to it * refactor(prompts): use pi tool names (task, todo_write, read, bash, glob) * refactor(prompts): drop stale MCP terminology for collector tools * refactor(prompts): drop collector server names from deliverable instructions * fix(worker): restore minLength/minItems on pre-recon and exploit collector schemas * feat(worker): load playwright-cli skill via pi resource loader * refactor(cli): remove CLAUDE_CODE_MAX_OUTPUT_TOKENS config * build: drop @anthropic-ai/claude-code from worker image * docs: remove vertex references from llms context * docs(worker): update stale sdk comments * refactor(worker): unify provider precedence between preflight and executor * feat(worker): enforce bounded bash timeouts via pi extension * ci: bump the beta release line to 2.0.0 (#356) * fix(cli): pin npx command hints to beta tag * fix: render agent deliverables before the success commit so resume preserves them (#377) * feat(cli): restructure run folder and improve terminal UX (#383) * feat: surface report at run root and nest run internals under .shannon * feat: use plain-language wording in user-facing terminal messages * feat(cli): guide users to watch scan progress and surface report path on start * docs: sync run-folder layout and CLI wording across docs and comments * feat(cli): add version command reporting package version or git SHA * feat(cli): detect TTY for interactive prompts, color, and progress output * docs: document --yes flag, version command, and tty module * fix(cli): FORCE_COLOR precedence and plain uninstall --yes output * fix(cli): respect empty NO_COLOR * fix(cli): let NO_COLOR take precedence over FORCE_COLOR * docs: mark claude-code-router integration as removed * refactor(worker): converge shared core with shannon-oss (#388) * fix(worker): port keygraph shared-core correctness fixes * refactor(worker): adopt collectors/ and ai/pi/ layout; add task budget cap and cancellation * refactor(worker): drop inconsistent Collector "Server" suffix * refactor(worker): drop unused providerConfig/apiKey seams, resolve credentials from env only * refactor(worker): port oss code_path pattern expansion + external_directory allow * fix(worker): preserve dotfile paths in code_path avoid patterns (.env no longer stripped to env) * feat(worker): render Unprocessed Vulnerabilities section in exploit deliverable (align with oss) * feat(worker): request set_blind_spots for all vuln classes (align auth/ssrf with production prompts) * refactor(worker): adopt unified permissionSystem* naming and helper layout * refactor(worker): inline blind_spots into vuln deliverable section array * chore(worker): drop unused zod dependency (tree is typebox-native) * fix(worker): normalize base32 TOTP secret to accept padding and whitespace * refactor(worker): adopt shared toolResult helper and flatSchema naming in collectors * refactor(worker): use undefined over null in queue-schema builders * docs(worker): converge renderer/collector doc comments to current pi terminology * refactor(worker): adopt schema.ts cleanInput/stringEnum helpers in collectors * feat(worker): converge exploit-collector/renderer with vendored; capture and render overview for blocked findings * refactor(worker): converge session-tools/pipeline/exploitation-checker with vendored * refactor(worker): converge task-tool usage reporting with vendored onUsage callback * refactor(worker): converge structured output onto a submitTool executor channel * docs(worker): expand exploit-renderer docstring to match shannon-oss * docs(worker): adopt richer vuln-renderer docstring from shannon-oss * docs(worker): neutralize billing-detection wording for shannon-oss parity * fix(worker): verify checkpoint hash in the deliverables clone being reset * fix(worker): fail fast on malformed exploitation queue JSON * fix(worker): honor retryable flag when classifying exploitation-queue check failures * fix(worker): fail fast on corrupted session.json in run-scope validation * feat(worker): propagate Temporal cancellation signal into agent and auth pi sessions * fix(worker): mark exploit agent complete when exploitation is skipped so resume skips it * prompts: drop scan description from executive report prompt * refactor(worker): add createGenericSubmitTool for raw JSON-schema submit tools * refactor(worker): gate playwright-cli skill to browser agents via skillsOverride (adopt shannon-oss mechanism) * docs(worker): correct formatLogTime comment to UTC to match toISOString * refactor(worker): converge queue-schemas with shannon-oss (guarded count, decl order) * refactor(worker): converge task-tool with shannon-oss (byte-identical; modelRegistry optional) * fix(worker): use replaceLiteral for all prompt value insertions to prevent $-mangling * fix(worker): classify agent execution failures by error type instead of hardcoding validation * fix(worker): cap auth-failure detail at 250 chars to match shannon-oss * style(worker): apply biome formatting * refactor(worker): remove per-session task delegation cap from task tool * style(cli): collapse usage hint now that the beta tag is gone * chore: mark the pi harness migration as a breaking change BREAKING CHANGE: Google Vertex AI is no longer a supported provider. The CLAUDE_CODE_USE_VERTEX, ANTHROPIC_VERTEX_PROJECT, CLOUD_ML_REGION, and GOOGLE_APPLICATION_CREDENTIALS environment variables, along with the use_vertex, vertex_project, and cloud_ml_region config.toml keys, are removed. Vertex users must switch to Anthropic, AWS Bedrock, or a custom Anthropic-compatible base URL. The CLAUDE_CODE_MAX_OUTPUT_TOKENS environment variable and the max_output_tokens config.toml key are also removed.
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
* then persists everything to ~/.shannon/config.toml with 0o600 permissions.
|
||||
*/
|
||||
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import * as p from '@clack/prompts';
|
||||
@@ -14,7 +13,7 @@ import { requireInteractive } from '../tty.js';
|
||||
|
||||
const SHANNON_HOME = path.join(os.homedir(), '.shannon');
|
||||
|
||||
type Provider = 'anthropic' | 'custom_base_url' | 'bedrock' | 'vertex';
|
||||
type Provider = 'anthropic' | 'custom_base_url' | 'bedrock';
|
||||
|
||||
export async function setup(): Promise<void> {
|
||||
requireInteractive('setup', 'For non-interactive use, export credentials as env vars (e.g. ANTHROPIC_API_KEY).');
|
||||
@@ -27,7 +26,6 @@ export async function setup(): Promise<void> {
|
||||
{ value: 'anthropic' as const, label: 'Claude Direct', hint: 'recommended' },
|
||||
{ value: 'custom_base_url' as const, label: 'Custom Base URL', hint: 'proxies, gateways' },
|
||||
{ value: 'bedrock' as const, label: 'Claude via AWS Bedrock' },
|
||||
{ value: 'vertex' as const, label: 'Claude via Google Vertex AI' },
|
||||
],
|
||||
});
|
||||
if (p.isCancel(provider)) return cancelAndExit();
|
||||
@@ -53,8 +51,6 @@ async function setupProvider(provider: Provider): Promise<ShannonConfig> {
|
||||
return setupCustomBaseUrl();
|
||||
case 'bedrock':
|
||||
return setupBedrock();
|
||||
case 'vertex':
|
||||
return setupVertex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,75 +211,6 @@ async function setupBedrock(): Promise<ShannonConfig> {
|
||||
};
|
||||
}
|
||||
|
||||
async function setupVertex(): Promise<ShannonConfig> {
|
||||
// 1. Collect region and project ID
|
||||
const region = await p.text({
|
||||
message: 'Google Cloud region',
|
||||
placeholder: 'us-east5',
|
||||
validate: required('Region is required'),
|
||||
});
|
||||
if (p.isCancel(region)) return cancelAndExit();
|
||||
|
||||
const projectId = await p.text({
|
||||
message: 'GCP Project ID',
|
||||
validate: required('Project ID is required'),
|
||||
});
|
||||
if (p.isCancel(projectId)) return cancelAndExit();
|
||||
|
||||
// 2. File picker for service account key
|
||||
p.log.info('Select the path to your GCP Service Account JSON key file.');
|
||||
const keySourcePath = await p.path({
|
||||
message: 'Service Account JSON key file',
|
||||
validate: (value) => {
|
||||
if (!value) return 'Path is required';
|
||||
if (!fs.existsSync(value)) return 'File not found';
|
||||
if (!value.endsWith('.json')) return 'Must be a .json file';
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
if (p.isCancel(keySourcePath)) return cancelAndExit();
|
||||
|
||||
// 3. Copy key to ~/.shannon/ and lock permissions
|
||||
const destPath = path.join(SHANNON_HOME, 'google-sa-key.json');
|
||||
fs.mkdirSync(SHANNON_HOME, { recursive: true });
|
||||
fs.copyFileSync(keySourcePath, destPath);
|
||||
fs.chmodSync(destPath, 0o600);
|
||||
p.log.success(`Key copied to ${destPath} (permissions: 0600)`);
|
||||
|
||||
// 4. Model tiers
|
||||
const models = await p.group({
|
||||
small: () =>
|
||||
p.text({
|
||||
message: 'Small model ID',
|
||||
placeholder: 'claude-haiku-4-5@20251001',
|
||||
validate: required('Small model ID is required'),
|
||||
}),
|
||||
medium: () =>
|
||||
p.text({
|
||||
message: 'Medium model ID',
|
||||
placeholder: 'claude-sonnet-4-6',
|
||||
validate: required('Medium model ID is required'),
|
||||
}),
|
||||
large: () =>
|
||||
p.text({
|
||||
message: 'Large model ID',
|
||||
placeholder: 'claude-opus-4-8',
|
||||
validate: required('Large model ID is required'),
|
||||
}),
|
||||
});
|
||||
if (p.isCancel(models)) return cancelAndExit();
|
||||
|
||||
return {
|
||||
vertex: {
|
||||
use: true,
|
||||
region,
|
||||
project_id: projectId,
|
||||
key_path: destPath,
|
||||
},
|
||||
models: { small: models.small, medium: models.medium, large: models.large },
|
||||
};
|
||||
}
|
||||
|
||||
// === Helpers ===
|
||||
|
||||
async function maybePromptAdaptiveThinking(config: ShannonConfig): Promise<void> {
|
||||
|
||||
@@ -10,7 +10,7 @@ import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { ensureImage, ensureInfra, randomSuffix, spawnWorker } from '../docker.js';
|
||||
import { buildEnvFlags, loadEnv, validateCredentials } from '../env.js';
|
||||
import { getCredentialsPath, getWorkspacesDir, initHome } from '../home.js';
|
||||
import { getWorkspacesDir, initHome } from '../home.js';
|
||||
import { isLocal } from '../mode.js';
|
||||
import { FINAL_REPORT_FILENAME, INTERNAL_DIR, resolveConfig, resolveRepo, resolveRunFile } from '../paths.js';
|
||||
import { displaySplash } from '../splash.js';
|
||||
@@ -107,13 +107,6 @@ export async function start(args: StartArgs): Promise<void> {
|
||||
}
|
||||
fs.mkdirSync(path.join(repo.hostPath, '.playwright'), { recursive: true });
|
||||
|
||||
const credentialsPath = getCredentialsPath();
|
||||
const hasCredentials = fs.existsSync(credentialsPath);
|
||||
|
||||
if (hasCredentials) {
|
||||
process.env.GOOGLE_APPLICATION_CREDENTIALS = '/app/credentials/google-sa-key.json';
|
||||
}
|
||||
|
||||
// 10. Resolve output directory
|
||||
const outputDir = args.output ? path.resolve(args.output) : undefined;
|
||||
if (outputDir) {
|
||||
@@ -136,7 +129,6 @@ export async function start(args: StartArgs): Promise<void> {
|
||||
containerName,
|
||||
envFlags: buildEnvFlags(),
|
||||
...(config && { config }),
|
||||
...(hasCredentials && { credentials: credentialsPath }),
|
||||
...(promptsDir && { promptsDir }),
|
||||
...(outputDir && { outputDir }),
|
||||
workspace,
|
||||
|
||||
Reference in New Issue
Block a user