import type { Capability, ToolDeclaration, PromptSection, CapabilityAction } from './index.js'; import type { LanguageModel } from 'ai'; import type { FlowConfig, FlowContext, ExtractionNodeConfig } from '../types/index.js'; import type { ExecutableTool } from '../foundation/ToolExecutor.js'; export interface FlowCapabilityConfig { flow: FlowConfig; initialNode: string; state?: FlowCapabilityState; defaultRolePrompt?: string; } export interface FlowCapabilityState { context: FlowContext; initialized: boolean; flowEnded: boolean; } /** * Headless flow state machine that exposes flow behavior as tools. * * Owns: node graph, transitions, current node, collectedData, * oscillation tracking, extraction node handling, contract validation. * * Does NOT own: LLM calls, streaming, AI SDK imports. The host * (Gemini Live, AI SDK, LiveKit) handles inference. */ export declare class FlowCapability implements Capability { private nodes; private transitions; private context; private currentNodeConfig; private initialized; private flowEnded; private _justTransitioned; private maxOscillations; private defaultRolePrompt?; /** Tracks transition edges within a single process() call for oscillation detection. */ private turnTransitionCounts; /** Events emitted during transitions (node-enter, node-exit, flow-transition, etc.). */ private pendingEvents; constructor(config: FlowCapabilityConfig); /** Flow context snapshot (read-only for orchestration). */ get flowContext(): FlowContext; getNodeModel(defaultModel: LanguageModel): LanguageModel; /** * Expression transitions for the current node — first matching predicate wins. */ evaluateExpressionTransitions(): string | null; /** * Attempt a graph transition (used by orchestration for expression / tool-node edges). */ tryTransition(nodeId: string, data?: Record): { error?: string; }; /** * Run the current tool node once: resolve tool, execute, branch on success/failure. * Returns whether the tool-node path ran (even if no outbound edge matched). */ executeToolNodeFromAuthority(args: { resolveTool: (name: string) => ExecutableTool | undefined; executeWrapped: (toolName: string, tool: ExecutableTool, input: unknown) => Promise; }): Promise; getTools(): ToolDeclaration[]; getPromptSections(): PromptSection[]; processToolResult(toolName: string, args: unknown, result: unknown): CapabilityAction | null; /** Initialize the flow (transition to initial node). */ initialize(): FlowEvent[]; /** Call at the start of each user turn to reset oscillation tracking. */ resetTurnTracking(): void; /** Record a user message in the flow context. */ appendUserMessage(content: string): void; /** Record an assistant message in the flow context. */ appendAssistantMessage(content: string): void; get currentNode(): string | undefined; currentNodeIsExtractionNode(): boolean; currentExtractionNode(): ExtractionNodeConfig | null; get collectedData(): Record; updateCollectedData(verified: Record): boolean; get hasEnded(): boolean; get isInitialized(): boolean; getState(): FlowCapabilityState; /** Drain accumulated flow events (node-enter, node-exit, etc.). */ drainEvents(): FlowEvent[]; private pickToolNodeTransition; private executeTransition; private mergeExtractedData; private checkExtractionComplete; private getMissingExtractionFields; private applyContextStrategy; private getRelevantCollectedData; private buildExtractionContinueEnvelope; } export type FlowEvent = { type: 'node-enter'; nodeName: string; } | { type: 'node-exit'; nodeName: string; } | { type: 'flow-transition'; from: string; to: string; } | { type: 'flow-end'; reason: string; };