/** * Concrete agent-loop LLM executor implementation. * * Implements {@link LlmExecutor}: tool-call orchestration, multi-turn replay, * optional context-compression via {@link ContextEngine}, usage aggregation, * and discriminated-union {@link ExecutionEvent} emission. * * @module llm/concrete-executor * @task T9290 * @epic T9261 T-LLM-CRED-CENTRALIZATION * @see ADR-072 §Decision §"LlmExecutor — agent-loop level" */ import type { ContextEngine, ExecutionEvent, ExecutionRequest, LlmExecutor, LlmSession, SendOptions } from '@cleocode/contracts/llm/interfaces.js'; import type { NormalizedResponse, TransportMessage } from '@cleocode/contracts/llm/normalized-response.js'; import type { AuxiliaryFallbackChain, AuxiliaryFallbackResult } from './auxiliary-fallback.js'; /** * Construction options for {@link ConcreteExecutor}. */ export interface ConcreteExecutorOptions { /** Pre-initialized session to use for all LLM calls. */ readonly session: LlmSession; /** * Optional context-compression engine. * * When undefined, compression checks are silently skipped — no events are * emitted and no errors are thrown. */ readonly contextEngine?: ContextEngine; /** * Optional auxiliary fallback chain for cross-provider fallover. * * When set, {@link ConcreteExecutor.auxiliary} will fall through to the next * provider in the chain when the primary provider's credential pool is * exhausted. When absent, auxiliary calls use only the bound session's * provider (original behaviour). * * Configure via `cleo config set llm.auxiliaryFallback "anthropic,openrouter,groq"`. * * @task T9319 */ readonly auxiliaryFallbackChain?: AuxiliaryFallbackChain; } /** * Concrete implementation of {@link LlmExecutor}. * * Each {@link run} call drives a multi-turn tool-call loop using the bound * session. The session history is owned by the caller — this executor appends * messages to it as the loop progresses. * * @example * ```ts * const executor = new ConcreteExecutor({ session }); * for await (const event of executor.run({ messages: [{ role: 'user', content: 'Hi' }] })) { * if (event.kind === 'done') console.log(event.usage); * } * ``` */ export declare class ConcreteExecutor implements LlmExecutor { /** The underlying session used for all LLM calls. */ readonly session: LlmSession; private readonly _contextEngine; private readonly _auxiliaryFallbackChain; /** * @param opts - Executor construction options. */ constructor(opts: ConcreteExecutorOptions); /** * Execute the full agent tool-call loop for the given request. * * Yields {@link ExecutionEvent} values as they occur. The generator * terminates when: * - The model returns a stop reason other than `'tool_use'` / `'tool_calls'`. * - The `maxIterations` limit is reached. * - An unrecoverable error occurs (emits `error` event then returns). * * @param request - Execution parameters including messages, tools, and handler. */ run(request: ExecutionRequest): AsyncGenerator; /** * Execute a single-turn completion without entering the tool-call loop. * * Intended for auxiliary calls (context compression summaries, dream cycles, * hygiene scans). Uses the same underlying session but does NOT append messages * to the session history. * * When {@link ConcreteExecutorOptions.auxiliaryFallbackChain} is configured, * automatically falls through to the next provider in the chain when the * primary provider's credential pool is exhausted (all credentials on cooldown * due to 401/429 errors). Returns an {@link AuxiliaryFallbackResult} that * includes `meta.fallbackChain` describing the path taken. * * Without a fallback chain, falls back to the original single-provider * behaviour (calls the bound session directly). * * @param messages - Messages to send. * @param opts - Optional per-call overrides. * @returns The normalized provider response (or AuxiliaryFallbackResult when * a fallback chain is active). * * @task T9319 */ auxiliary(messages: TransportMessage[], opts?: SendOptions): Promise; } //# sourceMappingURL=concrete-executor.d.ts.map