/** * buildAgentChart — assemble the agent's full footprintjs FlowChart * from stage functions + slot subflows + memory wiring. * * This is the "chart composition" that used to live inline in * `Agent.buildChart()`. Extracted for v2.11.2 so: * * 1. Agent.ts focuses on Agent class lifecycle (constructor, run, * attach, getSpec) instead of chart wiring details. * 2. The reliability gate chart (v2.11.x) wires into ONE focused * file rather than surgically into Agent.ts's 250-line composition * block. * 3. The composition is independently readable + reviewable — * consumers building custom agent shapes have a reference. * * Chart shape: * * Initialize * → [memory READ subflows for each .memory()] * → InjectionEngine (subflow) ← loop target (tool-calls loops here) * → Context (selector, PARALLEL fan-out, failFast) * ⇉ {System Prompt ‖ Messages ‖ Tools} (slot subflows) * → converge * → UpdateSkillHistory * → Cache (sf-cache subflow: decideCacheMarkers → CacheGate * → ApplyMarkers / SkipCaching) * → CallLLM (also emits the per-iteration iteration_start marker) * → [NormalizeThinking] (subflow, only when a ThinkingHandler resolved) * → Route (decider) * ├─ tool-calls (pausable) → loopTo(InjectionEngine) ← branch-sourced loop * └─ final (subflow) → terminal leaf * ┌────── PrepareFinal * ├──── [memory WRITE subflows] * └──── BreakFinal ($break) * * (This chart has no reliability subflow, and never grew one. The plan * described here — "the reliability gate chart mounts as a subflow before * CallLLM with a TranslateFailFast stage after it. Lands in the next * commit." — did not land: `.reliability()` is implemented INLINE in the * CallLLM stage by `executeWithReliability`, and * `buildReliabilityGateChart` is reachable from no shipped path. Verified * 2026-07-28.) */ import type { FlowChart, StructureRecorder } from 'footprintjs'; import type { CachePolicy } from '../../cache/types.js'; import type { MemoryDefinition } from '../../memory/define.types.js'; /** * Stage handlers + slot subflows the chart composer needs. Mostly * passed through verbatim from Agent.buildChart() — the chart shape * is identical to what was inline before. */ export interface AgentChartDeps { /** Memory READ/WRITE pipeline definitions (one per `.memory()`). */ readonly memories: readonly MemoryDefinition[]; /** Evidence bridge (#5): `causalEvidenceRecorder().collect`, threaded into * CAUSAL memories' write mounts so snapshots persist real evidence * (decisions/toolCalls/iterations/duration/tokens) instead of zeros. * Set by the Agent when any mounted memory is CAUSAL. */ readonly causalEvidenceSource?: () => import('../../memory/causal/evidenceRecorder.js').RunEvidence; /** Cache policy for the system-prompt slot, threaded into * CacheDecision's inputMapper so its decision rules can match. */ readonly systemPromptCachePolicy: CachePolicy; /** Hard ReAct iteration cap, threaded into CacheDecision's * inputMapper for max-iteration policies. */ readonly maxIterations: number; readonly seed: (scope: never) => void; readonly callLLM: (scope: never) => Promise; readonly routeDecider: (scope: never) => 'tool-calls' | 'final'; readonly toolCallsHandler: import('footprintjs').PausableHandler; readonly injectionEngineSubflow: FlowChart; /** Relevance entry router (`entryByRelevance`) — a once-per-turn function stage * mounted before the InjectionEngine (off the ReAct loop). Present only when the * skill graph was built with a relevance scorer. */ readonly pickEntryStage?: (scope: never) => Promise; readonly systemPromptSubflow: FlowChart; readonly messagesSubflow: FlowChart; readonly toolsSubflow: FlowChart; /** * Optional thinking-normalization sub-subflow (v2.14+). Mounted as a * stage AFTER CallLLM, BEFORE Route, only when a `ThinkingHandler` * resolved (either auto-wired by `provider.name` or explicitly set * via `.thinkingHandler()`). When undefined, the stage is NOT added — * zero overhead for non-thinking agents (build-time conditional mount). */ readonly thinkingSubflow?: FlowChart; readonly updateSkillHistoryStage: (scope: never) => void; /** * Whether ≥1 Skill is registered. The `UpdateSkillHistory` stage (and * therefore the cache's skill-churn rule) is mounted ONLY when true: * with no skills the window would record "no skill" every iteration and * `detectSkillChurn` could never fire, so the stage would be pure dead * weight + a misleading box. Mirrors the `skills.length > 0` gate that * auto-attaches `read_skill`, and the `thinkingSubflow` conditional mount. */ readonly hasSkills: boolean; /** * ReAct loop semantics. `'dynamic'` (default) re-runs the InjectionEngine + * all 3 slots every iteration (loop → InjectionEngine). `'classic'` * engineers context ONCE (InjectionEngine + system-prompt + tools up front) * and loops only the Messages slot (loop → Messages). See AgentOptions.reactMode. */ readonly reactMode?: 'classic' | 'dynamic'; /** Structure recorders threaded into both `flowChart()` calls (the * main chart and the PrepareFinal sub-chart). Each recorder * observes per-node build events (`onStageAdded` / * `onSubflowMounted` / etc.) for the Agent's chart. Undefined when * the consumer didn't attach any. */ readonly structureRecorders?: readonly StructureRecorder[]; } /** * Build the agent's complete FlowChart from the supplied deps. */ export declare function buildAgentChart(deps: AgentChartDeps): FlowChart;