import type { z } from "zod"; import type { Node } from "./node"; import type { MachineMessage } from "./messages"; import type { CedeResult, SpawnResult, SpawnTarget, SpawnOptions, TransitionToResult, SuspendResult, } from "./transitions"; /** * Options for suspend helper in commands. */ export interface SuspendOptions { /** Custom suspend ID (auto-generated if not provided) */ suspendId?: string; /** Optional metadata for application use */ metadata?: Record; } /** * Context passed to command execute functions. * S is the state type of the current node. */ export interface CommandContext { /** Current state */ state: S; /** Update state with a partial patch */ updateState: (patch: Partial) => void; /** ID of the instance executing this command */ instanceId: string; /** Get messages from the conversation history that belong to this instance */ getInstanceMessages: () => MachineMessage[]; /** Cede control back to parent with optional content (string or MachineMessage[]) */ cede: (content?: string | MachineMessage[]) => CedeResult; /** Spawn one or more child instances */ spawn: ( nodeOrTargets: Node | SpawnTarget[], state?: T, options?: SpawnOptions, ) => SpawnResult; /** Suspend the current instance */ suspend: (reason: string, options?: SuspendOptions) => SuspendResult; } /** * Command definition. * Commands are user-callable methods that bypass LLM inference. * S is the state type this command operates on. */ export interface CommandDefinition< TInput = unknown, TOutput = unknown, S = unknown, > { name: string; description: string; inputSchema: z.ZodType; execute: ( input: TInput, ctx: CommandContext, ) => Promise> | CommandResult; } /** * Base command definition type for storage. * Uses 'any' for input/output to allow heterogeneous command collections. */ // Heterogeneous collections cannot preserve specific input/output types // eslint-disable-next-line @typescript-eslint/no-explicit-any export type AnyCommandDefinition = CommandDefinition; /** * Resume result - command resumes the current instance from suspension. */ export interface ResumeResult { type: "command_resume"; } /** * Standard command result - returns optional messages to enqueue and optional payload. */ export interface CommandValueResult { type: "command_result"; /** Messages to enqueue (user messages, assistant messages, etc.) */ messages?: MachineMessage[]; /** Optional payload/return value */ payload?: T; } /** * Union of all command results. * Commands can return a result with messages/payload, transition, spawn, cede, suspend, or resume. */ export type CommandResult = | CommandValueResult | TransitionToResult | SpawnResult | CedeResult | SuspendResult | ResumeResult; /** * Type guard for CommandValueResult. */ export function isCommandValueResult(result: CommandResult): result is CommandValueResult { return ( typeof result === "object" && result !== null && "type" in result && result.type === "command_result" ); } /** * Helper to create a resume result. * Use this in command execute functions to resume the current instance. */ export function commandResume(): ResumeResult { return { type: "command_resume" }; } /** * Helper to create a command result. * @param payload - Optional payload/return value * @param messages - Optional messages to enqueue */ export function commandResult( payload?: T, messages?: MachineMessage[], ): CommandValueResult { return { type: "command_result", messages, payload }; } /** * Info about a command for frontend display. */ export interface CommandInfo { name: string; description: string; inputSchema: z.ZodType; } /** * Object representing a command invocation. * Can be passed to runMachine to execute a command directly without LLM inference. */ export interface Command { type: "command"; name: string; input: unknown; /** Target specific instance (defaults to active instance) */ instanceId?: string; /** Client-generated ID for optimistic update tracking */ clientId?: string; } /** * Type guard for Command. */ export function isCommand(value: unknown): value is Command { return ( typeof value === "object" && value !== null && "type" in value && value.type === "command" && "name" in value && typeof value.name === "string" ); } /** * Input to resume a suspended instance. * Can be passed to runMachine to resume execution. */ export interface Resume { type: "resume"; /** Instance ID to resume */ instanceId: string; /** Suspend ID that must match the instance's current suspension */ suspendId: string; } /** * Type guard for Resume. */ export function isResume(value: unknown): value is Resume { return ( typeof value === "object" && value !== null && "type" in value && value.type === "resume" && "instanceId" in value && typeof value.instanceId === "string" && "suspendId" in value && typeof value.suspendId === "string" ); } /** * Type guard for ResumeResult. */ export function isResumeResult(value: unknown): value is ResumeResult { return ( typeof value === "object" && value !== null && "type" in value && (value as ResumeResult).type === "command_resume" ); } /** * Result of executing a command. */ export interface CommandExecutionResult { success: boolean; value?: T; error?: string; }