import z from 'zod'; import type { AgentEventStreamer } from '../Agent/stream/types'; import type { AgentLLMContext, AgentMessage, AgentToolCallContent, AgentToolDefinition } from '../Agent/types'; import type { OtelInfoType, PromiseAble } from '../types'; /** * The standardized input payload passed to a Custom LLM Integration function. * * If you are building a custom adapter (e.g. for Vertex AI or Bedrock), your job is to * map these Arvo-standard fields onto your provider's specific API request format. */ export type AgentLLMIntegrationParam = { /** * The reason for this LLM invocation. Use this to optimize your prompt strategy: * - `'init'`: Fresh start. Ingest system prompt and initial context. * - `'tool_result'`: Resume. The input contains new tool outputs. * - `'output_error_feedback'`: Correction. The previous response failed Zod validation; * you should prompt the model to fix its format. */ lifecycle: 'init' | 'tool_result' | 'output_error_feedback'; /** The full conversation history in Arvo's standard format (needs mapping to provider format). */ messages: AgentMessage[]; /** The computed system prompt (generated by the context builder on Agent init). */ system: string | null; /** List of available tools. You must convert these to your provider's tool/function schema. */ tools: AgentToolDefinition[]; /** * Agent loop limits. * If `exhausted` is true, you should inject a system instruction forcing the LLM to stop calling tools * and synthesize a final answer. */ agentCycles: AgentLLMContext['toolInteractions'] & { exhausted: boolean; }; /** * The required output mode. * - `'text' | 'media'`: Standard chat completion. * - `'json'`: Structured Output mode. You should enforce the provided Zod `format` via your provider's JSON mode. */ outputFormat: { type: 'text'; } | { type: 'json'; format: z.ZodTypeAny; }; /** * A function to log streaming events from the llm */ onStream: AgentEventStreamer; }; /** * The normalized response object your Custom Integration must return. * * You must parse your provider's raw response (e.g. OpenAI `Choice`, Anthropic `ContentBlock`) * and normalize it into one of these three mutually exclusive types so the Agent Loop can act on it. */ export declare const AgentLLMIntegrationOutputSchema: z.ZodIntersection; }, "strip", z.ZodTypeAny, { tokens: { prompt: number; completion: number; }; }, { tokens: { prompt: number; completion: number; }; }>; /** * A standardized cost metric for Arvo's throttling/billing (e.g. 1 unit = 1 input token). * You define the calculation logic in your integration. */ executionUnits: z.ZodNumber; }, "strip", z.ZodTypeAny, { usage: { tokens: { prompt: number; completion: number; }; }; executionUnits: number; }, { usage: { tokens: { prompt: number; completion: number; }; }; executionUnits: number; }>, z.ZodDiscriminatedUnion<"type", [z.ZodObject<{ /** The LLM wants to execute tools. */ type: z.ZodLiteral<"tool_call">; toolRequests: z.ZodArray; toolUseId: z.ZodString; name: z.ZodString; input: z.ZodRecord; }, "type">, "strip", z.ZodTypeAny, { toolUseId: string; name: string; input: Record; }, { toolUseId: string; name: string; input: Record; }>, "many">; }, "strip", z.ZodTypeAny, { type: "tool_call"; toolRequests: { toolUseId: string; name: string; input: Record; }[]; }, { type: "tool_call"; toolRequests: { toolUseId: string; name: string; input: Record; }[]; }>, z.ZodObject<{ /** The LLM responded with conversational text. */ type: z.ZodLiteral<"text">; content: z.ZodString; }, "strip", z.ZodTypeAny, { type: "text"; content: string; }, { type: "text"; content: string; }>, z.ZodObject<{ /** * The LLM responded with Structured JSON (requested via `outputFormat`). * `parsedContent` must be the valid JS object result of parsing `content`. * You can use `tryParseJson` utility from `@arvo-tools/agentic` */ type: z.ZodLiteral<"json">; content: z.ZodString; parsedContent: z.ZodNullable>; }, "strip", z.ZodTypeAny, { type: "json"; content: string; parsedContent: Record | null; }, { type: "json"; content: string; parsedContent: Record | null; }>]>>; export type AgentLLMIntegrationOutput = z.infer; /** * Interface for an LLM Provider Adapter function. * * This function bridges the generic Arvo Agent Loop and a specific Model Provider (OpenAI, Anthropic, Bedrock, etc.). * * @remarks * **Implementation Responsibilities:** * 1. **Map Input:** Convert Arvo's standard `AgentMessage[]` and `AgentToolDefinition[]` into the provider's specific API format. * 2. **Invoke Model:** Make the actual network call to the LLM (handling retries/timeouts internally). * 3. **Instrumentation:** Use the provided `config.otelInfo` to link your network call to the existing OpenTelemetry Trace. * 4. **Normalize Output:** Parse the provider's response (Content vs. Tool Calls) into the standard `AgentLLMIntegrationOutput`. * * @param param - The current state of the Agent (System Prompt, History, Tools, Lifecycle Constraints). * @param config - Observability context containing the active Trace Headers and Span. * @returns A Promise resolving to the standardized output (Text, JSON, or Tool Requests) that the Agent Loop can act upon. */ export type AgentLLMIntegration = (param: AgentLLMIntegrationParam, config: { otelInfo: OtelInfoType; }) => Promise; export type CommonIntegrationConfig = { /** * A calculator function to determine the abstract "Execution Units" (cost) of the LLM call. * * This allows mapping raw token usage to a unified cost metric used by the `Arvo` event system. * For example, $Cost = (PromptTokens \times Price_{in}) + (CompletionTokens \times Price_{out})$. * * @param prompt - The number of input tokens used. * @param completion - The number of output tokens generated. * @returns The calculated execution units (e.g., cost in cents or arbitrary units). */ executionunits?: (prompt: number, completion: number) => number; /** * A custom system instruction injected when the agent exceeds its `maxToolInteractions` limit. * * Use this to guide the model to either summarize its current progress, give up gracefully, or * attempt a final answer without further tool usage. */ toolLimitPrompt?: (toolInteractions: AgentLLMIntegrationParam['agentCycles']) => string; /** * An optional interceptor to transform messages or system instructions immediately before the LLM call. * * This is useful for last-mile modifications, such as filtering sensitive data or appending dynamic * context, without permanently altering the Agent's state history. * * @returns A promise resolving to the modified `messages` array and `system` prompt string. */ contextTransformer?: (param: { messages: AgentMessage[]; system: string | null; }) => PromiseAble<{ messages: AgentMessage[]; system: string | null; }>; }; export type LLMExecutionResult = { toolRequests: Omit[] | null; response: string | null; usage: NonNullable; }; //# sourceMappingURL=types.d.ts.map