import { T as ToolDefinition, M as Message, f as MaybePromise, e as ToolCall, q as ToolCallHandlerContext, g as ToolAuthorizer, A as ArgsValidator } from './message-CyXbT7Zj.cjs'; import { C as ChatMemory, a as Retriever } from './memory-mFMVJZXL.cjs'; type StreamStatus = 'idle' | 'streaming' | 'complete' | 'error'; interface StreamToolCallPayload { id: string; name: string; args: string; result?: string; } interface TokenUsage { promptTokens: number; completionTokens: number; totalTokens: number; } interface StreamChunk { type: 'text' | 'tool_call' | 'tool_result' | 'reasoning' | 'usage' | 'error' | 'done'; content?: string; toolCall?: StreamToolCallPayload; usage?: TokenUsage; metadata?: Record; } interface StreamSource { stream: () => AsyncIterableIterator; abort: () => void; } interface UseStreamOptions { onChunk?: (chunk: StreamChunk) => void; onComplete?: (text: string) => void; onError?: (error: Error) => void; } interface UseStreamReturn { data: StreamChunk | null; text: string; status: StreamStatus; error: Error | null; stop: () => void; } interface AdapterContext { systemPrompt?: string; temperature?: number; maxTokens?: number; tools?: ToolDefinition[]; metadata?: Record; } interface AdapterRequest { messages: Message[]; context?: AdapterContext; } /** * Hints about what an adapter supports. Every field is optional; an * adapter may omit the whole `capabilities` object, and consumers * should treat omission as 'unknown — assume the feature works and * handle errors if it doesn't'. * * This is an additive extension to the Adapter contract (ADR 0001) — * adapters without capabilities remain fully compliant. Consumers * that care (router / ensemble adapters, UI that hides the tool * toggle when the provider can't use tools) can read the hints. */ interface AdapterCapabilities { /** Does the adapter stream responses natively? */ streaming?: boolean; /** Does it support tool calling (function calling)? */ tools?: boolean; /** Does it emit a separate reasoning/thinking stream (o1/o3 style)? */ reasoning?: boolean; /** Accepts image inputs in the message list? */ multiModal?: boolean; /** Supports confirmations / structured-output primitives? */ structuredOutput?: boolean; /** Emits token/usage data in chunk metadata? */ usage?: boolean; /** Anything else — e.g. provider-specific hints. */ extensions?: Record; } type AdapterFactory = { createSource: (request: AdapterRequest) => StreamSource; /** Optional capabilities hint. See AdapterCapabilities. */ capabilities?: AdapterCapabilities; }; interface SkillDefinition { name: string; description: string; systemPrompt: string; examples?: Array<{ input: string; output: string; }>; tools?: string[]; delegates?: string[]; temperature?: number; metadata?: Record; onActivate?: () => MaybePromise<{ tools?: ToolDefinition[]; }>; } type AgentEvent = { type: 'llm:start'; model?: string; messageCount: number; } | { type: 'llm:first-token'; latencyMs: number; } | { type: 'llm:end'; content: string; usage?: { promptTokens: number; completionTokens: number; }; durationMs: number; } | { type: 'tool:start'; name: string; args: Record; } | { type: 'tool:end'; name: string; result: string; durationMs: number; } | { type: 'memory:load'; messageCount: number; } | { type: 'memory:save'; messageCount: number; } | { type: 'agent:step'; step: number; action: string; } | { type: 'agent:delegate:start'; name: string; task: string; depth: number; } | { type: 'agent:delegate:end'; name: string; result: string; durationMs: number; depth: number; } /** * A domain-level progress step the agent (not the runtime) defines — e.g. a * multi-stage pipeline reporting "classify", "sanitize", "publish". Lets agents * emit their own stages through the SAME observer channel as runtime events, so * one Observer renders both. The runtime never emits this; agents do. */ | { type: 'progress'; label: string; status: 'start' | 'ok' | 'skip' | 'error'; detail?: string; durationMs?: number; } | { type: 'run-aborted'; } | { type: 'error'; error: Error; }; interface Observer { name: string; on: (event: AgentEvent) => void | Promise; } interface ChatConfig { adapter: AdapterFactory; systemPrompt?: string; temperature?: number; maxTokens?: number; tools?: ToolDefinition[]; skills?: SkillDefinition[]; memory?: ChatMemory; retriever?: Retriever; initialMessages?: Message[]; /** * Maximum number of LLM ↔ tool feedback turns per `send()`. * After a tool call, the controller feeds the result back to the model * so it can continue reasoning. This caps that loop to prevent runaway * cost if a model keeps requesting tools. Default: 5. Set to 1 to disable. */ maxToolIterations?: number; onMessage?: (message: Message) => void; onError?: (error: Error) => void; onToolCall?: (toolCall: ToolCall, context: ToolCallHandlerContext) => MaybePromise; authorizeToolCall?: ToolAuthorizer; observers?: Observer[]; /** * Opt-in runtime validator for tool-call arguments (ADR-0008). When set, * args produced by the model are checked against each tool's JSON Schema * before execution; mismatches raise `AK_TOOL_INVALID_INPUT`. Omit for the * default passthrough behaviour. Use `createAjvValidator()` from * `@agentskit/tools/validation`. */ validateArgs?: ArgsValidator; } interface ChatState { messages: Message[]; status: StreamStatus; input: string; error: Error | null; /** * Token usage accumulated across every LLM call in this chat session. * Populated when the adapter surfaces usage (OpenAI, Anthropic, Gemini, * Ollama all do). Zeroed by `clear()`. */ usage: TokenUsage; } interface EditOptions { /** * When editing a user message, also regenerate the assistant response * that followed it (truncating any later turns). Default: true. */ regenerate?: boolean; } interface ChatController { getState: () => ChatState; subscribe: (listener: () => void) => () => void; send: (text: string) => Promise; stop: () => void; retry: () => Promise; /** * Edit a message by id. For user messages, truncates all subsequent * turns and regenerates (unless opts.regenerate === false). * For assistant messages, updates the content in place. */ edit: (messageId: string, newContent: string, opts?: EditOptions) => Promise; /** * Regenerate the assistant response. If `messageId` names an assistant * message, that one is replaced. Otherwise regenerates the last * assistant turn (same as retry()). */ regenerate: (messageId?: string) => Promise; setInput: (value: string) => void; setMessages: (messages: Message[]) => void; clear: () => Promise; updateConfig: (config: Partial) => void; proposeToolCall: (proposal: Pick) => Promise; approve: (toolCallId: string) => Promise; deny: (toolCallId: string, reason?: string) => Promise; } interface ChatReturn extends ChatState { send: (text: string) => Promise; stop: () => void; retry: () => Promise; edit: (messageId: string, newContent: string, opts?: EditOptions) => Promise; regenerate: (messageId?: string) => Promise; setInput: (value: string) => void; clear: () => Promise; proposeToolCall: (proposal: Pick) => Promise; approve: (toolCallId: string) => Promise; deny: (toolCallId: string, reason?: string) => Promise; } export type { AgentEvent as A, ChatConfig as C, EditOptions as E, Observer as O, StreamChunk as S, TokenUsage as T, UseStreamOptions as U, ChatController as a, StreamSource as b, SkillDefinition as c, AdapterCapabilities as d, AdapterContext as e, AdapterFactory as f, AdapterRequest as g, ChatReturn as h, ChatState as i, StreamStatus as j, StreamToolCallPayload as k, UseStreamReturn as l };