/** * Agent class that uses the agent-loop directly. * No transport abstraction - calls streamSimple via the loop. */ import { type ImageContent, type Message, type Model, type SimpleStreamOptions, type ThinkingBudgets, type Transport } from "@dreb/ai"; import type { AfterToolCallContext, AfterToolCallResult, AgentContext, AgentEvent, AgentMessage, AgentState, AgentTool, BeforeLlmCallResult, BeforeToolCallContext, BeforeToolCallResult, StreamFn, ThinkingLevel, ToolExecutionMode } from "./types.js"; export interface AgentOptions { initialState?: Partial; /** * Called immediately before each LLM request after loop guardrails pass. * May atomically replace the messages and/or model used by the active loop. */ beforeLlmCall?: (context: AgentContext, signal?: AbortSignal) => Promise; /** * Converts AgentMessage[] to LLM-compatible Message[] before each LLM call. * Default filters to user/assistant/toolResult and converts attachments. */ convertToLlm?: (messages: AgentMessage[]) => Message[] | Promise; /** * Optional transform applied to context before convertToLlm. * Use for context pruning, injecting external context, etc. */ transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise; /** * Steering mode: "all" = send all steering messages at once, "one-at-a-time" = one per turn */ steeringMode?: "all" | "one-at-a-time"; /** * Follow-up mode: "all" = send all follow-up messages at once, "one-at-a-time" = one per turn */ followUpMode?: "all" | "one-at-a-time"; /** * Custom stream function (for proxy backends, etc.). Default uses streamSimple. */ streamFn?: StreamFn; /** * Optional session identifier forwarded to LLM providers. * Used by providers that support session-based caching (e.g., OpenAI Codex). */ sessionId?: string; /** * Resolves an API key dynamically for each LLM call. * Useful for expiring tokens (e.g., GitHub Copilot OAuth). */ getApiKey?: (provider: string) => Promise | string | undefined; /** * Inspect or replace provider payloads before they are sent. */ onPayload?: SimpleStreamOptions["onPayload"]; /** * Custom token budgets for thinking levels (token-based providers only). */ thinkingBudgets?: ThinkingBudgets; /** Controls thinking display ("summarized"/"omitted") for providers that honor it. */ thinkingDisplay?: "summarized" | "omitted"; /** * Preferred transport for providers that support multiple transports. */ transport?: Transport; /** * Maximum delay in milliseconds to wait for a retry when the server requests a long wait. * If the server's requested delay exceeds this value, the request fails immediately, * allowing higher-level retry logic to handle it with user visibility. * Default: 60000 (60 seconds). Set to 0 to disable the cap. */ maxRetryDelayMs?: number; /** Tool execution mode. Default: "parallel" */ toolExecution?: ToolExecutionMode; /** * Maximum number of times to retry when a stream drops mid-response. * Default: 3 */ streamRetries?: number; /** * Base delay in milliseconds for exponential backoff between stream retries. * Default: 1000 */ streamRetryBaseDelayMs?: number; /** * Maximum number of times to retry when a turn ends with stopReason "length". * Each retry uses the same configured output limit. Separate from streamRetries. * Default: 2 */ lengthRetries?: number; /** Called before a tool is executed, after arguments have been validated. */ beforeToolCall?: (context: BeforeToolCallContext, signal?: AbortSignal) => Promise; /** Called after a tool finishes executing, before final tool events are emitted. */ afterToolCall?: (context: AfterToolCallContext, signal?: AbortSignal) => Promise; /** * Called before each subsequent LLM call in the agent loop. * If it returns false, the loop exits cleanly. */ shouldContinue?: () => boolean; /** * Optional callback for non-fatal warnings during streaming. * Forwarded to providers via StreamOptions.onWarning. */ onWarning?: (code: string, message: string) => void; } export declare class Agent { private _state; private listeners; private abortController?; private _beforeLlmCall?; private convertToLlm; private transformContext?; private steeringQueue; private followUpQueue; private steeringMode; private followUpMode; streamFn: StreamFn; private _sessionId?; getApiKey?: (provider: string) => Promise | string | undefined; private _onPayload?; private runningPrompt?; private resolveRunningPrompt?; private _thinkingBudgets?; private _thinkingDisplay?; private _transport; private _maxRetryDelayMs?; private _streamRetries?; private _streamRetryBaseDelayMs?; private _lengthRetries?; private _toolExecution; private _beforeToolCall?; private _afterToolCall?; private _shouldContinue?; private _onWarning?; constructor(opts?: AgentOptions); /** * Get the current session ID used for provider caching. */ get sessionId(): string | undefined; /** * Set the session ID for provider caching. * Call this when switching sessions (new session, branch, resume). */ set sessionId(value: string | undefined); /** * Get the current thinking budgets. */ get thinkingBudgets(): ThinkingBudgets | undefined; /** * Set custom thinking budgets for token-based providers. */ set thinkingBudgets(value: ThinkingBudgets | undefined); /** * Get the current thinking display setting. */ get thinkingDisplay(): "summarized" | "omitted" | undefined; /** * Set thinking display for providers that honor it. */ set thinkingDisplay(value: "summarized" | "omitted" | undefined); /** * Get the current preferred transport. */ get transport(): Transport; /** * Set the preferred transport. */ setTransport(value: Transport): void; /** * Get the current max retry delay in milliseconds. */ get maxRetryDelayMs(): number | undefined; /** * Set the maximum delay to wait for server-requested retries. * Set to 0 to disable the cap. */ set maxRetryDelayMs(value: number | undefined); get toolExecution(): ToolExecutionMode; setToolExecution(value: ToolExecutionMode): void; setBeforeToolCall(value: ((context: BeforeToolCallContext, signal?: AbortSignal) => Promise) | undefined): void; setAfterToolCall(value: ((context: AfterToolCallContext, signal?: AbortSignal) => Promise) | undefined): void; setBeforeLlmCall(value: ((context: AgentContext, signal?: AbortSignal) => Promise) | undefined): void; setShouldContinue(value: (() => boolean) | undefined): void; get state(): AgentState; subscribe(fn: (e: AgentEvent) => void): () => void; setSystemPrompt(v: string): void; setModel(m: Model): void; setThinkingLevel(l: ThinkingLevel): void; setSteeringMode(mode: "all" | "one-at-a-time"): void; getSteeringMode(): "all" | "one-at-a-time"; setFollowUpMode(mode: "all" | "one-at-a-time"): void; getFollowUpMode(): "all" | "one-at-a-time"; setTools(t: AgentTool[]): void; replaceMessages(ms: AgentMessage[]): void; appendMessage(m: AgentMessage): void; /** * Queue a steering message while the agent is running. * Delivered after the current assistant turn finishes executing its tool calls, * before the next LLM call. */ steer(m: AgentMessage): void; /** * Queue a follow-up message to be processed after the agent finishes. * Delivered only when agent has no more tool calls or steering messages. */ followUp(m: AgentMessage): void; clearSteeringQueue(): void; clearFollowUpQueue(): void; clearAllQueues(): void; hasQueuedMessages(): boolean; private dequeueSteeringMessages; private dequeueFollowUpMessages; clearMessages(): void; abort(): void; waitForIdle(): Promise; reset(): void; /** Send a prompt with an AgentMessage */ prompt(message: AgentMessage | AgentMessage[]): Promise; prompt(input: string, images?: ImageContent[]): Promise; /** * Continue from current context (used for retries and resuming queued messages). */ continue(): Promise; private _processLoopEvent; private _runLoop; private emit; } //# sourceMappingURL=agent.d.ts.map