import type { ReactiveController, ReactiveControllerHost } from 'lit'; import type { AgentProvider, AgentMessage, AgentMessageAttachment } from '../providers/agent-provider.js'; export type AgentState = 'idle' | 'sending' | 'streaming' | 'paused' | 'complete' | 'error'; export interface AgentControllerOptions { /** Model identifier (e.g. "claude-sonnet-4-20250514") */ model?: string; /** Inference parameters (temperature, top_p, max_tokens, etc.) */ params?: Record; /** System prompt to prepend to every send */ systemPrompt?: string; /** * Timeout for provider.send() promise resolution in ms. Default: 60_000. * This is the time until the ReadableStream is returned, NOT until first chunk. */ sendTimeout?: number; /** Maximum character length for a single message content. Default: 100_000 */ maxMessageLength?: number; /** Maximum number of messages in conversation. Default: 200 */ maxMessages?: number; /** Called when the response stream begins */ onResponseStart?: (messageId: string) => void; /** Called for each text chunk */ onResponseChunk?: (chunk: string, accumulated: string) => void; /** Called when the full response is received */ onResponseComplete?: (message: AgentMessage) => void; /** Called on error */ onError?: (error: Error) => void; /** Called when the controller state changes */ onStateChange?: (state: AgentState) => void; /** Called when the messages array changes (for external sync/persistence) */ onMessagesChange?: (messages: readonly AgentMessage[]) => void; } /** * AgentController — orchestrates AI/LLM conversations via an AgentProvider. * * Composes StreamingController internally for response streaming. Manages * conversation history, send lifecycle, abort, pause/resume, and payload limits. * * @example * ```ts * import { AgentController } from '@loquix/core/controllers/agent.controller'; * import { MyAIProvider } from './my-ai-provider'; * * class MyChat extends LitElement { * private _agent = new AgentController(this, new MyAIProvider(), { * model: 'claude-sonnet-4-20250514', * onResponseComplete: (msg) => { ... }, * }); * * async handleSend(text: string) { * await this._agent.send(text); * } * } * ``` */ export declare class AgentController implements ReactiveController { private _host; private _provider; private _streaming; private _options; private _state; private _messages; private _abortController; private _currentResponseId; private _currentResponse; constructor(host: ReactiveControllerHost, provider: AgentProvider, options?: AgentControllerOptions); hostConnected(): void; hostDisconnected(): void; /** Current controller state */ get state(): AgentState; /** Full conversation history */ get messages(): readonly AgentMessage[]; /** Text accumulated so far in the current response */ get currentResponseText(): string; /** Whether the controller is currently streaming a response */ get isStreaming(): boolean; /** * Send a user message and start streaming the assistant's response. * * @param content - User message text * @param attachments - Optional file attachments * @throws Error if called while already streaming (must abort first) */ send(content: string, attachments?: AgentMessageAttachment[]): Promise; /** Pause the response stream */ pause(): void; /** Resume the response stream */ resume(): void; /** * Abort the current request or stream. * * - During 'sending': cancels the provider.send() promise * - During 'streaming'/'paused': cancels the stream reader * - During 'idle'/'complete': no-op */ abort(): void; /** * Reset: abort, clear messages, return to idle. */ reset(): void; /** * Restore conversation from persistence. * Must be called while idle. */ setMessages(messages: AgentMessage[]): void; /** * Swap the agent provider. Aborts in-flight requests if any. */ setProvider(provider: AgentProvider): void; /** * Update options (model, params, systemPrompt, etc.) without swapping provider. */ updateOptions(partial: Partial): void; /** Called by StreamingController when the stream completes */ private _handleStreamComplete; private _setState; } //# sourceMappingURL=agent.controller.d.ts.map