/** * selfExplain — the IN-CONVERSATION door over the agent's own trace. * * `.selfExplain()` on the builder mounts ONE skill plus ONE scoped tool * provider. Day to day the tool catalog carries only the skill's * activation row — the trace tools are NOT in the skill (skill `tools` * land in the static registry, exposed every iteration); they ride a * `skillScopedTools` provider gated on the skill's activation, composed * with whatever provider the consumer already set. When the user asks a * why-question the LLM activates the skill, and the NEXT iteration's * catalog gains the trace tools, bound to the agent's own PREVIOUS * COMPLETED run. * * The two pieces here: * * 1. `SelfExplainBinding` — the late-binding seam, a plain CombinedRecorder * attached like any consumer recorder (zero engine changes): * * - capture at `onRunEnd`/`onRunFailed`: the just-finished run's * snapshot becomes the explainable evidence (a FAILED run is * still a completed trace — "why did you fail?" works); * - rotate at `onRunStart`: a FRESH ControlDepRecorder per run. The * retired instance never sees the new run's events, so its live * `asLookup()` survives Convention-4's runId reset — the captured * control edges stay valid for the whole next turn. * * B13 safety lives here: `Agent.run()` reassigns its executor at run * START, so resolving artifacts mid-run through `getLastSnapshot()` * would expose the IN-FLIGHT run. Capturing only at terminal flush * means the binding can never serve anything but a completed run. * * 2. `buildSelfExplainSkill` — the skill in two modes: * * - INLINE (default): the skill unlocks the 5 trace tools in the * main agent's own loop (same model). * - DELEGATE: the skill unlocks ONE tool — `explain_run(question)` — * whose execute runs a nested `traceDebugAgent` on the consumer's * chosen (cheaper) provider/model and returns its evidence-cited * answer. The main conversation pays for one tool call; the * trace-walking loop happens at the delegate's price. Loaded via * dynamic import so the builder never statically pulls Agent * through this module (no core ↔ lib cycle). */ import { type CombinedRecorder, type RuntimeSnapshot } from 'footprintjs'; import type { Injection } from '../injection-engine/types.js'; import type { AgentOptions } from '../../core/agent/types.js'; import type { ToolProvider } from '../../tool-providers/types.js'; import type { TraceToolpackArtifacts, TraceToolpackOptions } from './types.js'; /** Consumer surface for `.selfExplain()` on the Agent builder. */ export interface SelfExplainOptions { /** Appended to the recommended skill body (ours stays; yours adds). */ readonly instruction?: string; /** * Answer why-questions on a SEPARATE (typically cheaper) model: the * skill unlocks one `explain_run` tool that runs a nested * `traceDebugAgent` and returns its evidence-cited answer. */ readonly delegate?: { readonly provider: AgentOptions['provider']; readonly model: string; readonly maxIterations?: number; }; /** Skill id (activation key for `read_skill`). Default 'self-explain'. */ readonly id?: string; /** Bounding dials forwarded to the toolpack. */ readonly toolpack?: TraceToolpackOptions; } /** * The late-binding seam. Create one per built Agent, attach * `binding.recorder()` via `agent.attach()`, and point `bindTo()` at the * agent's `getLastSnapshot`. `artifacts` then always answers with the * previous COMPLETED run — never the in-flight one. */ export declare class SelfExplainBinding { private getSnapshot; private ctrl; private captured; bindTo(getSnapshot: () => RuntimeSnapshot | undefined): void; /** Evidence of the previous completed run, or undefined before the first. */ get artifacts(): TraceToolpackArtifacts | undefined; /** The recorder to attach — forwards flow events to the per-run ctrl. */ recorder(): CombinedRecorder; } /** The default skill id — the activation key the LLM passes to read_skill. */ export declare const SELF_EXPLAIN_SKILL_ID = "self-explain"; /** * The skill `.selfExplain()` mounts — methodology body ONLY. The trace * tools deliberately do NOT ride the skill: skill `tools` land in the * static registry (exposed every iteration); catalog gating is the * ToolProvider's job — see {@link buildSelfExplainToolProvider}. */ export declare function buildSelfExplainSkill(options: SelfExplainOptions): Injection; /** * The gated tool delivery — `skillScopedTools` (the shipped primitive) * scoped to the skill's id, composed with the consumer's own provider * when they set one. The iteration after activation, `ctx.activeSkillId` * matches and the catalog gains the trace tools (inline) or the single * `explain_run` tool (delegate). */ export declare function buildSelfExplainToolProvider(binding: SelfExplainBinding, options: SelfExplainOptions, existing?: ToolProvider): ToolProvider; //# sourceMappingURL=selfExplain.d.ts.map