agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
41 lines (40 loc) • 2.07 kB
TypeScript
/**
* NormalizeThinking sub-subflow — wraps a consumer's `ThinkingHandler`
* (function-pair contract) in a real footprintjs subflow at chart
* build time. Mounted as a stage AFTER CallLLM inside `sf-call-llm`
* when (and only when) a handler is configured.
*
* runtimeStageId format: `sf-call-llm/thinking-{handler.id}#N`
*
* Two-layer architecture (per Phase 1 panel decision):
* - CONSUMER-FACING: `ThinkingHandler` — simple function-pair
* (id, normalize, parseChunk?)
* - FRAMEWORK-INTERNAL: this file wraps each handler in a real
* footprintjs subflow with own runtimeStageId,
* narrative entry, and InOutRecorder boundary.
*
* Failure isolation: handler `normalize()` throws are caught here.
* Framework emits `agentfootprint.agent.thinking_parse_failed`, sets
* `scope.thinkingBlocks` to empty, and the subflow exits cleanly. The
* agent run continues; the assistant message simply has no thinking
* blocks attached. Same graceful pattern as v2.11.6 `tools.discovery_failed`.
*/
import type { FlowChart } from 'footprintjs';
import type { ThinkingHandler } from '../../thinking/types.js';
/**
* Build a thinking-normalization sub-subflow for a configured handler.
* Mounted as a single-stage subflow inside `sf-call-llm` AFTER CallLLM.
*
* The subflow:
* 1. Reads `scope.rawThinking` (set by CallLLM from `LLMResponse.rawThinking`)
* 2. If rawThinking is undefined → write empty array, exit (early-return)
* 3. Calls `handler.normalize(rawThinking)`
* 4. On success: writes `scope.thinkingBlocks` + emits `stream.thinking_end`
* 5. On throw: writes empty array + emits `agent.thinking_parse_failed`
*
* The result on `scope.thinkingBlocks` is read by toolCalls.ts and
* prepareFinal.ts when constructing the assistant message for
* `scope.history` — that's where the Anthropic signature round-trip
* actually flows from.
*/
export declare function buildThinkingSubflow(handler: ThinkingHandler, providerName: string): FlowChart;