mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-07-23 13:01:00 +02:00
d0b0ec3378
* 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
91 lines
2.8 KiB
TypeScript
91 lines
2.8 KiB
TypeScript
// Copyright (C) 2025 Keygraph, Inc.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License version 3
|
|
// as published by the Free Software Foundation.
|
|
|
|
/**
|
|
* Consolidated billing/spending cap detection utilities.
|
|
*
|
|
* Anthropic's spending cap behavior is inconsistent:
|
|
* - Sometimes a proper provider error (billing_error)
|
|
* - Sometimes the model responds with text about the cap
|
|
* - Sometimes partial billing before cutoff
|
|
*
|
|
* This module provides defense-in-depth detection with shared pattern lists
|
|
* to prevent drift between detection points.
|
|
*/
|
|
|
|
/**
|
|
* Text patterns for model-output sniffing (what the model says).
|
|
* Used by the pi executor and the behavioral heuristic.
|
|
*/
|
|
export const BILLING_TEXT_PATTERNS = [
|
|
'spending cap',
|
|
'spending limit',
|
|
'cap reached',
|
|
'budget exceeded',
|
|
'usage limit',
|
|
] as const;
|
|
|
|
/**
|
|
* API patterns for error message classification (what the API returns).
|
|
* Used by classifyErrorForTemporal in error-handling.ts.
|
|
*/
|
|
export const BILLING_API_PATTERNS = [
|
|
'billing_error',
|
|
'credit balance is too low',
|
|
'insufficient credits',
|
|
'usage is blocked due to insufficient credits',
|
|
'please visit plans & billing',
|
|
'please visit plans and billing',
|
|
'usage limit reached',
|
|
'quota exceeded',
|
|
'daily rate limit',
|
|
'limit will reset',
|
|
'billing limit reached',
|
|
] as const;
|
|
|
|
/**
|
|
* Checks if text matches any billing text pattern.
|
|
* Used for sniffing model output content for spending cap messages.
|
|
*/
|
|
export function matchesBillingTextPattern(text: string): boolean {
|
|
const lowerText = text.toLowerCase();
|
|
return BILLING_TEXT_PATTERNS.some((pattern) => lowerText.includes(pattern));
|
|
}
|
|
|
|
/**
|
|
* Checks if an error message matches any billing API pattern.
|
|
* Used for classifying API error messages.
|
|
*/
|
|
export function matchesBillingApiPattern(message: string): boolean {
|
|
const lowerMessage = message.toLowerCase();
|
|
return BILLING_API_PATTERNS.some((pattern) => lowerMessage.includes(pattern));
|
|
}
|
|
|
|
/**
|
|
* Behavioral heuristic for detecting spending cap.
|
|
*
|
|
* When the model hits a spending cap, it often returns a short message
|
|
* with $0 cost. Legitimate agent work NEVER costs $0 with only 1-2 turns.
|
|
*
|
|
* This combines three signals:
|
|
* 1. Very low turn count (<=2)
|
|
* 2. Zero cost ($0)
|
|
* 3. Text matches billing patterns
|
|
*
|
|
* @param turns - Number of turns the agent took
|
|
* @param cost - Total cost in USD
|
|
* @param resultText - The result text from the agent
|
|
* @returns true if this looks like a spending cap hit
|
|
*/
|
|
export function isSpendingCapBehavior(turns: number, cost: number, resultText: string): boolean {
|
|
// Only check if turns <= 2 AND cost is exactly 0
|
|
if (turns > 2 || cost !== 0) {
|
|
return false;
|
|
}
|
|
|
|
return matchesBillingTextPattern(resultText);
|
|
}
|