UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

138 lines 6.49 kB
/** * GAIA Convergence Layer — deterministic finalization for saturated agent loops. * * Detects three failure modes that cause empty FINAL_ANSWER extraction: * 1. max_turns hit without a final_answer call * 2. Loop detected (same tool + same args called 3× in a 5-turn window) * 3. Token budget exceeded (>120k tokens of conversation context) * * On detection, runs a FORCED COMMIT phase: * - Injects a stripped-down summary prompt: "Based on all observations, answer with * FINAL_ANSWER: X. Do NOT explore further." * - Makes 1 final API call with strict instruction and no tools. * - If still no FINAL_ANSWER in the response, runs the Stage 1 extraction cascade * against ALL prior assistant messages (last to first), returns first non-empty hit. * - If still empty: returns null but logs the failure mode. * * This is NOT a new cognition layer — it is a convergence controller. * It STRIPS information rather than adding it: one final chance to commit, * no tools available, prior context summarized rather than appended. * * Architecture principle (iter 60 post-mortem): * "More information can reduce agent reliability. Past a certain point — * retrieval depth, context size, browsing breadth, tool diversity — information * increases trajectory entropy. The system becomes less likely to finalize coherently." * This layer is the entropy-reducer. * * Refs: #2156, iter 60 (19/25 empty FINAL_ANSWER failures), iter 62 */ /** Token threshold (sum of input tokens across all turns) that triggers overflow detection. */ export declare const TOKEN_OVERFLOW_THRESHOLD = 120000; /** Number of repeated identical tool+args calls in a window that signals a loop. */ export declare const LOOP_REPEAT_THRESHOLD = 3; /** Sliding window size (turns) for loop detection. */ export declare const LOOP_WINDOW_SIZE = 5; /** Tracks state that the convergence layer needs to evaluate triggers. */ export interface ConvergenceState { /** How many agent turns have elapsed so far. */ turnCount: number; /** Sum of input tokens across all turns (used for overflow detection). */ totalTokens: number; /** Ordered log of tool calls for loop detection. */ toolCalls: Array<{ name: string; argsHash: string; turn: number; }>; /** Set by checkConvergenceTriggers when a failure mode is detected. */ detectedFailureMode: 'max_turns' | 'loop' | 'token_overflow' | null; } /** Result of a forced-commit attempt. */ export interface ForceCommitResult { /** The extracted answer, or null if even forced commit could not extract one. */ answer: string | null; /** True when the answer was recovered from prior message history rather than * from the forced-commit API call. */ usedFallback: boolean; /** The failure mode that triggered this forced commit. */ triggerMode: ConvergenceState['detectedFailureMode']; } /** * Produce a stable hash of a tool call's name + args for loop detection. * * Uses SHA-256 truncated to 16 hex chars — collision probability is * negligible for the small call volumes in a single agent run. * * The hash is deterministic: same toolName + same args always → same hash. * Different args always → different hash (within SHA-256 collision bounds). */ export declare function argsHash(toolName: string, args: object): string; /** * Evaluate the current ConvergenceState and return the first failure mode * detected, or null if no trigger has fired. * * Evaluation order: * 1. max_turns — turnCount >= maxTurns * 2. token_overflow — totalTokens >= TOKEN_OVERFLOW_THRESHOLD * 3. loop — same tool+argsHash appears >= LOOP_REPEAT_THRESHOLD times * in the last LOOP_WINDOW_SIZE entries of toolCalls * * Only the FIRST matching trigger is returned (stops at first detection). * The caller is responsible for setting state.detectedFailureMode. */ export declare function checkConvergenceTriggers(state: ConvergenceState, maxTurns: number): ConvergenceState['detectedFailureMode']; /** * Run Stage 1 extraction (FINAL_ANSWER: pattern) against a raw text string. * Returns the matched answer or null. */ export declare function extractFinalAnswerFromText(text: string): string | null; /** * Scan prior assistant messages from last to first, looking for FINAL_ANSWER. * * This is the fallback path when the forced-commit API call still does not * produce a FINAL_ANSWER. We search backwards because the most recent * assistant message is most likely to contain the best answer. */ export declare function extractFromPriorMessages(messages: Array<{ role: string; content: string | unknown; }>): string | null; /** * Run the forced-commit phase for a saturated agent loop. * * Steps: * 1. Append a stripped directive prompt to the message history. * 2. Call the model once with NO tools — forces text-only response. * 3. If FINAL_ANSWER found in the response → return it. * 4. If not → scan prior assistant messages last-to-first for FINAL_ANSWER. * 5. If still empty → return { answer: null, usedFallback: false }. * * The callModel callback must return the raw text response (assistant turn * text blocks concatenated). It should be called WITHOUT tool definitions * so the model cannot call tools in this turn. * * @param messages Current conversation history (mutated: 1 user turn appended) * @param callModel Callback that makes a single API call and returns the response text * @param triggerMode The failure mode that triggered this forced commit */ export declare function forceCommit(messages: Array<{ role: string; content: string | unknown; }>, callModel: (messages: Array<{ role: string; content: string | unknown; }>) => Promise<string>, triggerMode?: ConvergenceState['detectedFailureMode']): Promise<ForceCommitResult>; /** Create a new ConvergenceState with zero counters. */ export declare function createConvergenceState(): ConvergenceState; /** * Update ConvergenceState after each agent turn completes. * * @param state Mutable state object (modified in place) * @param inputTokens Tokens consumed in this turn * @param toolCallsThisTurn Tool calls made in this turn (name + args) */ export declare function recordTurn(state: ConvergenceState, inputTokens: number, toolCallsThisTurn: Array<{ name: string; args: object; }>): void; //# sourceMappingURL=gaia-convergence.d.ts.map