mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-09-17 15:32:23 +02:00
feat: multi-provider model support, SARIF output, and exploit-mode fixes (#402)
* feat(worker): record token, cache, and turn usage per agent * feat: replace model tiers with a single SHANNON_AI_MODEL across five providers * feat(cli): rebuild the setup wizard for provider and model selection * docs: document single-model selection and supported providers * feat(worker): use chat completions for OpenAI behind a custom base URL * feat: add SHANNON_AI_OPENAI_FORMAT to pick the wire API for OpenAI gateways * refactor(cli): drop endpoint path hints from the gateway format picker * feat(worker): enable pi in-session provider retry with retry-after backoff * refactor(worker): hand provider error classification to pi and drop the Anthropic ladders * refactor: remove the subscription retry preset and pipeline config section * fix(worker): validate Bedrock credentials with the same live probe as other providers * feat(worker): render the report from structured findings instead of agent-written markdown * fix(worker): dispose the credential probe session on every path * fix(worker): refuse to replace the assembled report with an empty one * refactor(worker): catch post-processing throws across the whole finalization block * revert(worker): drop the report zero-findings guard * docs(worker): correct the retry split and Bedrock credential claims * docs: regenerate llms-full.txt from current sources * feat(cli): build and run the npx flow from a clone * refactor(cli): flatten the setup summary output * feat(cli): reject runs with more than one provider configured * fix(worker): say a rejected bash call never ran * chore(cli): drop grok-4.3 and gpt-5.6-luna from the setup suggestions * feat(worker): capture structured finding locations for SARIF output * fix(worker): enumerate queue confidence so the report inherits it verbatim * feat(worker): give the reporting phase a mode-specific output schema * feat(worker): emit a SARIF 2.1.0 log for exploitative runs * fix(worker): correct SARIF locations and defer fingerprinting to the upload action * fix(worker): drop the confidence suffix from the analysis-mode summary list * feat(worker): give exploit findings a dedicated code location field * feat(worker): carry structured code locations from the vuln queue to the report * fix(worker): join code locations from the vuln queue instead of re-asking agents * fix(worker): spell out the finding_id to category mapping in the tool schema * feat: drop Google/Gemini as a supported AI provider * fix(worker): stop asking the report agent for code locations * docs: correct the provider list and drop the removed rate-limit settings * docs: add provider cyber safeguards and suggested models per provider * docs: document the SARIF output and the report rating thresholds
This commit is contained in:
+22
-9
@@ -12,7 +12,7 @@ import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { setTimeout as sleep } from 'node:timers/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { getMode } from './mode.js';
|
||||
import { getMode, isDevMode } from './mode.js';
|
||||
import { INTERNAL_DIR } from './paths.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
@@ -24,6 +24,17 @@ export function getWorkerImage(version: string): string {
|
||||
return getMode() === 'local' ? DEV_IMAGE : `${NPX_IMAGE_REPO}:${version}`;
|
||||
}
|
||||
|
||||
/** True when the working directory supplies a Dockerfile and build context. */
|
||||
export function canBuildImage(): boolean {
|
||||
if (getMode() === 'local') return true;
|
||||
if (!isDevMode()) return false;
|
||||
|
||||
const hasDockerfile = fs.existsSync(path.resolve('Dockerfile'));
|
||||
const hasCompose = fs.existsSync(path.resolve('docker-compose.yml'));
|
||||
|
||||
return hasDockerfile && hasCompose;
|
||||
}
|
||||
|
||||
function getComposeFile(): string {
|
||||
return getMode() === 'local'
|
||||
? path.resolve('docker-compose.yml')
|
||||
@@ -96,29 +107,31 @@ export async function ensureInfra(): Promise<void> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the worker image locally (local mode only).
|
||||
* Build the worker image from the repository, tagged with the name this mode
|
||||
* resolves at run time.
|
||||
*/
|
||||
export function buildImage(noCache: boolean): void {
|
||||
console.log(`Building ${DEV_IMAGE}...`);
|
||||
export function buildImage(noCache: boolean, version: string): void {
|
||||
const image = getWorkerImage(version);
|
||||
console.log(`Building ${image}...`);
|
||||
const args = ['build'];
|
||||
if (noCache) args.push('--no-cache');
|
||||
args.push('-t', DEV_IMAGE, '.');
|
||||
args.push('-t', image, '.');
|
||||
execFileSync('docker', args, { stdio: 'inherit' });
|
||||
console.log(`Build complete: ${DEV_IMAGE}`);
|
||||
console.log(`Build complete: ${image}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the worker image is available.
|
||||
* Local mode: auto-builds if missing. NPX mode: pulls from Docker Hub.
|
||||
* Buildable checkout: auto-builds if missing. Otherwise: pulls from Docker Hub.
|
||||
*/
|
||||
export function ensureImage(version: string): void {
|
||||
const image = getWorkerImage(version);
|
||||
const exists = runQuiet('docker', ['image', 'inspect', image]);
|
||||
if (exists) return;
|
||||
|
||||
if (getMode() === 'local') {
|
||||
if (canBuildImage()) {
|
||||
console.log('Shannon image not found, building...');
|
||||
buildImage(false);
|
||||
buildImage(false, version);
|
||||
} else {
|
||||
console.log(`Pulling ${image}...`);
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user