/** * 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, providerNames, 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): FlowChart;