import { O as OracleUsage, P as ProviderId, a as OracleContentBlock, b as OracleStopReason, c as OracleReceipt, T as ToolUseBlock, A as AudioBlock, D as DocumentBlock, I as ImageBlock, d as TextBlock, e as ThinkingBlock, f as ToolResultBlock, M as ModelSpec, E as Effort, g as OracleRequest, h as OracleResponse, C as Catalog, i as AiTelemetry, S as SearchCitation, j as AiTelemetryAttributes, k as OracleTool, l as OracleMessage, m as ThinkingMode, R as RequestEcho } from './pricing-DLKPPaXJ.js'; export { n as AudioMediaType, o as AudioSource, p as Capabilities, q as CodeExecutionPower, r as DEFAULT_CATALOG, s as DocumentSource, t as EFFORT_LEVELS, u as ImageMediaType, v as ImageSource, L as LongContextPricing, w as ModelKind, x as ModelPricing, N as NativeEffort, y as OracleRole, z as ResponseFormat, B as Superpowers, F as ThinkingControl, G as ThinkingSupport, H as TokenRates, J as ToolChoice, W as WebSearchPower, K as addUsage, Q as buildCatalog, U as chatCapabilities, V as costUsd, X as defaultEffortMap, Y as defaultWebSearchPower, Z as emptyUsage, _ as mergeCitations, $ as modelPricing, a0 as nativeEffort, a1 as priceCall, a2 as pricedModels, a3 as promptTokens, a4 as providersInCatalog, a5 as ratesForPrompt, a6 as resolveModel, a7 as scaleLongContext, a8 as supportedEffortLevels, a9 as validateRequest } from './pricing-DLKPPaXJ.js'; /** The closed taxonomy of normalized error codes carried by every OdlaAIError * and by the streaming `error` event. */ type OracleErrorType = "invalid_request" | "auth" | "rate_limit" | "context_window" | "cancelled" | "deadline_exceeded" | "tool_input_invalid" | "capability_unsupported" | "config" | "provider_error"; /** The plain-data error shape used inside the streaming `error` event. */ interface OracleErrorShape { code: OracleErrorType; message: string; /** HTTP status from the upstream provider, when applicable. */ providerStatus?: number; /** Seconds until a retry might succeed (rate limit / overload). */ retryAfter?: number; } /** Base class for every error odla-ai throws. Carries a stable string `code` * (the odla ecosystem convention — see odla-db's AuthError/RuleError) so * callers branch on `err.code`, never on message text. */ declare class OdlaAIError extends Error { readonly code: OracleErrorType; readonly providerStatus?: number; readonly retryAfter?: number; /** Sanitized provider usage when a response was received before a later * validation/tool-shape failure. Omitted when usage is genuinely unknown. */ readonly usage?: OracleUsage; constructor(code: OracleErrorType, message: string, opts?: { providerStatus?: number; retryAfter?: number; cause?: unknown; usage?: OracleUsage; }); toShape(): OracleErrorShape; } /** A provider/model is not configured — e.g. no API key for its provider, or an * unknown canonical model id. The library analog of odla-db's 501 gating. */ declare class ConfigError extends OdlaAIError { constructor(message: string); } /** Authentication with the provider failed (bad/missing key). */ declare class AuthError extends OdlaAIError { constructor(message: string, opts?: { providerStatus?: number; cause?: unknown; }); } /** The provider rate-limited or is overloaded; check `retryAfter`. */ declare class RateLimitError extends OdlaAIError { constructor(message: string, opts?: { providerStatus?: number; retryAfter?: number; cause?: unknown; }); } /** The request asked a model to do something it cannot — audio to Claude, tools * to a text-only model, web search where unsupported, etc. Raised before any * network call by `validateRequest`. */ declare class CapabilityError extends OdlaAIError { constructor(message: string); } /** The request exceeded the model's context window. */ declare class ContextWindowError extends OdlaAIError { constructor(message: string, opts?: { providerStatus?: number; cause?: unknown; }); } /** The request was malformed / rejected as invalid by the provider. */ declare class InvalidRequestError extends OdlaAIError { constructor(message: string, opts?: { providerStatus?: number; cause?: unknown; }); } /** A provider returned tool arguments that are malformed or do not satisfy the * declared JSON Schema. Tool handlers are never invoked for this error. */ declare class ToolInputError extends OdlaAIError { readonly tool?: string; constructor(message: string, opts?: { tool?: string; cause?: unknown; usage?: OracleUsage; }); } /** The caller cancelled a request. This is not an upstream failure and should * not be retried unless the caller explicitly starts a new operation. */ declare class CancelledError extends OdlaAIError { constructor(message?: string, opts?: { cause?: unknown; }); } /** The request's absolute deadline elapsed. Callers may choose a new deadline, * but should not classify this as a provider outage. */ declare class DeadlineExceededError extends OdlaAIError { constructor(message?: string, opts?: { cause?: unknown; }); } /** Any other upstream provider failure (5xx, transport, unexpected shape). */ declare class ProviderError extends OdlaAIError { constructor(message: string, opts?: { providerStatus?: number; cause?: unknown; usage?: OracleUsage; }); } /** A discriminated union of SSE events with the same vocabulary regardless of * provider. The anthropic adapter passes these through nearly 1:1; the openai * and google adapters map their native streams onto this shape. */ type OracleEvent = MessageStartEvent | ContentBlockStartEvent | ContentBlockDeltaEvent | ContentBlockStopEvent | MessageDeltaEvent | MessageStopEvent | OracleReceiptEvent | OracleErrorEvent; interface MessageStartEvent { type: "message_start"; message: { id: string; model: string; provider: ProviderId; role: "assistant"; content: []; usage: OracleUsage; }; } interface ContentBlockStartEvent { type: "content_block_start"; index: number; contentBlock: OracleContentBlock; } type ContentBlockDelta = { type: "text_delta"; text: string; } | { type: "thinking_delta"; thinking: string; } | { type: "input_json_delta"; partialJson: string; }; interface ContentBlockDeltaEvent { type: "content_block_delta"; index: number; delta: ContentBlockDelta; } interface ContentBlockStopEvent { type: "content_block_stop"; index: number; } interface MessageDeltaEvent { type: "message_delta"; delta: { stopReason?: OracleStopReason; }; usage: OracleUsage; } interface MessageStopEvent { type: "message_stop"; } /** Final accounting receipt emitted by platform-hosted SSE streams. Direct * provider streams omit it because they have no platform usage ledger. */ interface OracleReceiptEvent { type: "receipt"; receipt: OracleReceipt; } interface OracleErrorEvent { type: "error"; error: OracleErrorShape; } /** Type guard: narrows a content block to a `TextBlock` (`type: "text"`). */ declare function isTextBlock(b: OracleContentBlock): b is TextBlock; /** Type guard: narrows a content block to an `ImageBlock` (`type: "image"`). */ declare function isImageBlock(b: OracleContentBlock): b is ImageBlock; /** Type guard: narrows a content block to an `AudioBlock` (`type: "audio"`). */ declare function isAudioBlock(b: OracleContentBlock): b is AudioBlock; /** Type guard: narrows a content block to a `DocumentBlock` (`type: "document"`). */ declare function isDocumentBlock(b: OracleContentBlock): b is DocumentBlock; /** Type guard: narrows a content block to a `ToolUseBlock` (`type: "tool_use"`). */ declare function isToolUseBlock(b: OracleContentBlock): b is ToolUseBlock; /** Type guard: narrows a content block to a `ToolResultBlock` (`type: "tool_result"`). */ declare function isToolResultBlock(b: OracleContentBlock): b is ToolResultBlock; /** Type guard: narrows a content block to a `ThinkingBlock` (`type: "thinking"`). */ declare function isThinkingBlock(b: OracleContentBlock): b is ThinkingBlock; /** Normalize a message's `content` (string shorthand or block array) to blocks. */ declare function blocksOf(content: string | OracleContentBlock[]): OracleContentBlock[]; /** Concatenate the text of every TextBlock. Image/audio/tool/thinking ignored. */ declare function extractText(content: OracleContentBlock[]): string; /** Collect every tool_use block from response or message content. */ declare function extractToolUses(content: OracleContentBlock[]): ToolUseBlock[]; /** One deterministic validation failure at a JSONPath-like location. */ interface JsonSchemaIssue { path: string; message: string; } /** Complete supported-subset schema validation result; unknown keywords fail validation. */ interface JsonSchemaValidation { valid: boolean; issues: JsonSchemaIssue[]; } /** Validate a JSON-compatible value against the supported JSON Schema subset. * Unknown or unsupported keywords are validation failures, not ignored hints. */ declare function validateJsonSchema(schema: unknown, value: unknown): JsonSchemaValidation; /** Built-in Anthropic (Claude) catalog: one `ModelSpec` per model (canonical id, native id, capabilities, limits, pricing, thinking descriptor). */ declare const ANTHROPIC_MODELS: ModelSpec[]; /** Built-in OpenAI catalog: one `ModelSpec` per model (canonical id == native id, capabilities, limits, pricing, thinking descriptor). */ declare const OPENAI_MODELS: ModelSpec[]; /** Built-in Google (Gemini) catalog: one `ModelSpec` per model (canonical id == native id, capabilities, limits, pricing, thinking descriptor). */ declare const GOOGLE_MODELS: ModelSpec[]; /** Capability hints derivable from a provider's model listing, where the * provider exposes any. Absence of a hint means "unknown", not "unsupported". */ interface DiscoveryHints { imageIn?: boolean; documentIn?: boolean; /** The model reasons at all, by whatever mechanism (Anthropic * `capabilities.thinking.supported`). A model can support thinking without * supporting the adaptive toggle — Haiku 4.5 is budget-style only. */ thinking?: boolean; /** `thinking: {type: "adaptive"}` is accepted (Anthropic * `capabilities.thinking.types.adaptive.supported`). */ adaptiveThinking?: boolean; /** Legacy `thinking: {type: "enabled", budget_tokens}` is accepted * (Anthropic `capabilities.thinking.types.enabled.supported`). */ budgetThinking?: boolean; /** Effort/reasoning levels the listing declares supported (Anthropic). */ effortLevels?: Effort[]; structuredOutput?: boolean; webSearch?: boolean; /** Raw generation methods/actions (Google), e.g. "generateContent". */ generationMethods?: string[]; } /** One model discovered live from a provider's list-models API, normalized so a * caller can diff it against a Catalog (join on provider + nativeId). */ interface DiscoveredModel { provider: ProviderId; /** Provider-native id; Google's "models/" prefix is stripped. */ nativeId: string; displayName?: string; /** Anthropic max_input_tokens; Google inputTokenLimit; absent for OpenAI. */ contextWindow?: number; /** Anthropic max_tokens; Google outputTokenLimit; absent for OpenAI. */ maxOutput?: number; hints?: DiscoveryHints; /** The untouched provider payload, for fields normalization doesn't cover. */ raw: Record; } interface Provider { readonly id: ProviderId; /** One assistant turn. Server-side tools (e.g. web search) are resolved * internally; the returned response is final for this turn (its stopReason is * never "pause_turn"). Client-side tool calls return with stopReason * "tool_use" for the agent loop to handle. */ create(spec: ModelSpec, req: OracleRequest): Promise; /** The same turn as an async stream of normalized OracleEvents. */ stream(spec: ModelSpec, req: OracleRequest): AsyncIterable; /** List the provider's live models, normalized for catalog diffing. Optional * so injected/custom providers remain valid without implementing discovery. */ listModels?(opts?: { signal?: AbortSignal; }): Promise; } /** Constructs a provider adapter bound to a resolved API key. */ type ProviderFactory = (apiKey: string) => Provider; /** Static per-provider keys. */ type KeyMap = Partial>; /** Dynamic key lookup — return undefined to signal "no key for this provider". */ type KeyResolver = (provider: ProviderId) => string | undefined | Promise; interface KeyOptions { keys?: KeyMap; /** Consulted first; falls back to `keys` when it returns undefined. */ resolveKey?: KeyResolver; } /** Best-effort key-shape check (used by smoke/diagnostics, never for gating — * formats drift). */ declare function looksLikeKey(provider: ProviderId, key: string): boolean; /** Redact anything that looks like a provider secret from a string (logs/errors). */ declare function redact(text: string): string; /** Return a stable SHA-256 credential fingerprint suitable for cache and * capacity-pool identities. The raw key is never retained in the result. */ declare function fingerprintCredential(apiKey: string): Promise; /** Provider-account limits for one native model. Rate limits are interpreted * with `headroom` reserved; concurrency is an explicit hard ceiling. */ interface ModelCapacityLimits { /** Provider tokens per minute. */ tokensPerMinute?: number; /** Provider requests per minute. */ requestsPerMinute?: number; /** Provider tokens per day. */ tokensPerDay?: number; /** Maximum requests simultaneously in flight. */ maxParallelRequests?: number; /** Fraction of provider rate budgets held back. Defaults to 0.20. */ headroom?: number; } /** Stable, secret-free identity for a provider credential and native model. */ interface CapacityPoolIdentity { provider: string; credential: string; model: string; } /** One queued admission request. Deadlines include time spent waiting. */ interface CapacityAdmissionRequest { pool: CapacityPoolIdentity; limits: ModelCapacityLimits; estimatedTokens: number; signal?: AbortSignal; deadline?: number; } /** A granted capacity slot. Settle it exactly once after provider I/O ends. */ interface CapacityLease { readonly queuedMs: number; readonly startedAt: number; settle(actualTokens?: number): void | Promise; } /** Observable scheduler state transitions. Pool identities contain only a * credential fingerprint, never the provider key. */ interface CapacityEvent { type: "queued" | "started" | "settled"; pool: CapacityPoolIdentity; at: number; estimatedTokens: number; actualTokens?: number; queuedMs?: number; queueDepth: number; activeRequests: number; } /** Options for the in-memory scheduler. */ interface CapacitySchedulerOptions { onEvent?: (event: CapacityEvent) => void; } /** FIFO admission controller shared by every `init()` using it. */ interface CapacityScheduler { acquire(request: CapacityAdmissionRequest): Promise; } /** Create a simple FIFO scheduler. Estimated usage advances the next-start * clock at admission; only positive actual-token excess advances it again. */ declare function createCapacityScheduler(options?: CapacitySchedulerOptions): CapacityScheduler; /** Capacity configuration applied by an `Ai` facade. */ interface AiCapacityOptions { /** Limits or a resolver for a credential-model pool. Returning undefined * bypasses scheduling for that call. */ limits: ModelCapacityLimits | ((pool: CapacityPoolIdentity) => ModelCapacityLimits | undefined | Promise); /** Shared scheduler. Omit to use the process-wide scheduler. */ scheduler?: CapacityScheduler; /** Stable credential identity for injected providers. Key-backed providers * are fingerprinted automatically. */ injectedCredentialId?: string | ((provider: string) => string); /** Override the conservative request token estimator. */ estimateTokens?: (request: OracleRequest) => number; } /** Count all disjoint provider token classes for capacity reconciliation. */ declare function totalUsageTokens(usage: OracleUsage | undefined): number; /** Estimate request tokens without provider-specific tokenizers. Output is not * added: the default 20% headroom reserves response uncertainty. */ declare function estimateRequestTokens(request: OracleRequest): number; /** Process-wide scheduler used unless a caller supplies an isolated one. */ declare const defaultCapacityScheduler: CapacityScheduler; interface InitOptions { /** Static per-provider API keys (BYO). */ keys?: KeyMap; /** Dynamic per-provider key lookup (multi-tenant / per-call). Consulted first. */ resolveKey?: KeyResolver; /** Model used when a call omits `model`. */ defaultModel?: string; /** Override / extend the built-in model catalog. */ catalog?: Catalog; /** Inject provider adapters directly (tests, custom transports). When present * for a provider, it is used verbatim and no key is required. */ providers?: Partial>; /** Optional provider-account capacity control. Pools are isolated by * credential fingerprint and provider-native model id. */ capacity?: AiCapacityOptions; /** Automatic OpenTelemetry provider-call spans. Enabled by default and a * no-op until the host app configures an OTel tracer provider. */ telemetry?: false | { operation?: string; attributes?: AiTelemetryAttributes; }; } /** Any turn's input — a canonical request with `model` optional (defaultModel fills). */ type ChatInput = Omit & { model?: string; }; interface ExtractTool { name: string; description?: string; /** JSON Schema for the forced tool's arguments. */ parameters: Record; } /** A forced structured extraction: schema in, validated object out. */ interface ExtractCall { model?: string; system?: string | TextBlock[]; user: string | OracleContentBlock[]; tool: ExtractTool; maxTokens?: number; signal?: AbortSignal; deadline?: number; telemetry?: AiTelemetry | false; } /** A web-search-enabled call: the model searches and returns prose. */ interface SearchCall { model?: string; system?: string | TextBlock[]; user: string | OracleContentBlock[]; maxTokens?: number; signal?: AbortSignal; deadline?: number; telemetry?: AiTelemetry | false; } interface Ai { /** The active model catalog. */ readonly catalog: Catalog; /** One assistant turn (non-streaming). */ chat(input: ChatInput): Promise; /** One assistant turn as a stream of normalized OracleEvents. */ stream(input: ChatInput): AsyncIterable; /** Forced single-tool extraction → validated object. */ extract(c: ExtractCall): Promise<{ value: T; usage: OracleUsage; }>; /** * Web-search-grounded prose answer, plus the sources the provider attributed. * `citations` is empty when the provider reported none — never assume a * grounded-looking answer carries evidence. */ search(c: SearchCall): Promise<{ text: string; usage: OracleUsage; citations: SearchCitation[]; }>; } /** The minimal inference surface the agent loop and eval harness depend on. */ type Inference = Pick; /** * Build the `Ai` facade (bring-your-own-keys). Resolves a canonical model id to * its provider, supplies keys statically (`keys`) or dynamically (`resolveKey`), * validates each request against the model's capabilities, and exposes * `chat`/`stream`/`extract`/`search` plus the active `catalog`. Only the SDK of a * provider you actually call is loaded (via the lazy provider registry). */ declare function init(opts?: InitOptions): Ai; /** * Resolve the adapter for a provider, lazy-`import()`ing its module (and only * that provider's SDK) on first use and caching the instance per (provider, key) * so repeated calls reuse one SDK client. */ declare function getProvider(id: ProviderId, apiKey: string): Promise; /** Test seam: register a provider instance directly (used to inject mocks). */ declare function registerProvider(id: ProviderId, apiKey: string, provider: Provider): void; /** Test seam: clear the adapter cache. */ declare function clearProviderCache(): void; /** * List a provider's live models via its list-models API, normalized for * diffing against a Catalog (join on provider + nativeId). Note that provider * listings never include pricing. Throws ConfigError if the resolved provider * (e.g. an injected custom adapter) does not implement discovery. */ declare function listModels(provider: ProviderId, apiKey: string, opts?: { signal?: AbortSignal; }): Promise; /** Map any provider error to an OdlaAIError, returning it (does not throw). * Re-returns an OdlaAIError unchanged (already normalized). */ declare function normalizeError(err: unknown, provider: ProviderId, signal?: AbortSignal): OdlaAIError; type TaintLabel = "web_untrusted" | "operator_pasted_untrusted" | "llm_inherited" | `tool_untrusted:${string}`; type TaintSet = Set; /** Build a `TaintSet` from labels — the CaMeL-style taint carried through a run and checked against each tool's allowlist. */ declare function taint(...labels: TaintLabel[]): TaintSet; /** Raised when a tool's taint allowlist doesn't cover the conversation's taint. * Carries the sink, the label it met, and the allowlist, so a caller can say * something other than the diagnostic sentence. */ declare class TaintError extends OdlaAIError { readonly sink: string; readonly label: string; readonly allowed: readonly string[]; constructor(input: { sink: string; label: string; allowed: readonly string[]; } | string); } /** * Throw unless every label currently on the conversation is in the sink's * allowlist. `llm_inherited` is intentionally excludable: a tool that lists it as * *not* accepted is one where model-derived instructions must never reach the * sink (the classic injected-instruction propagation case). */ declare function assertSinkAcceptsTaint(sink: string, allowed: TaintLabel[], actual: TaintSet): void; /** What a tool returns after running. */ interface ToolOutput { content: string | OracleContentBlock[]; isError?: boolean; } /** Context handed to a tool handler when it runs. */ interface ToolContext { /** * Stable provider-issued identity for this exact tool invocation. * * Agent runs always populate this from the matching `tool_use` block. It is * optional only so existing direct handler callers remain source-compatible; * handlers that use it as an idempotency key should fail closed when absent. */ toolCallId?: string; /** The taint currently on the conversation feeding this call. */ taint: TaintSet; /** Optional cancellation signal, threaded from the run. */ signal?: AbortSignal; } type ToolHandler = (input: Record, ctx: ToolContext) => Promise | ToolOutput; interface ToolDef { name: string; description: string; /** JSON Schema for the tool arguments. */ inputSchema: Record; /** Local executor. Omit for provider server tools resolved inside the adapter. */ handler?: ToolHandler; /** * Opt in to concurrent execution with adjacent tool calls carrying the same * marker. Omit for effects and for handlers whose ordering is significant. * Results are still returned to the model in request order, and any * unmarked call is an exclusive barrier before and after its execution. */ concurrency?: "parallel"; /** Taint labels this tool's output introduces into the conversation. */ outputTaint?: TaintLabel[]; /** If set, the tool only runs when the conversation taint ⊆ this allowlist. */ acceptsTaint?: TaintLabel[]; } /** Project a ToolDef to the wire-level OracleTool the model sees. */ declare function toOracleTool(t: ToolDef): OracleTool; interface Skill { /** Skill name — used as the heading for its instructions in the system prompt. */ name: string; /** Guidance appended to the persona's system prompt (when/how to use the tools). */ instructions?: string; /** The tools this skill contributes to the agent. */ tools: ToolDef[]; } interface ComposedPersona { system: string | undefined; tools: ToolDef[]; } /** Merge a persona's own tools/system with its attached skills: skill tools are * appended to the tool list, and each skill's instructions become a titled * section of the system prompt. Order is preserved (persona first, then skills). */ declare function composeSkills(system: string | undefined, tools: ToolDef[] | undefined, skills: Skill[] | undefined): ComposedPersona; interface MemoryScope { /** Messages to prepend before this run's input. */ load(): Promise | OracleMessage[]; /** Persist the messages produced during this run (excludes what load() returned). */ append(messages: OracleMessage[]): Promise | void; } /** A simple process-lifetime memory scope. */ declare class InMemoryScope implements MemoryScope { private messages; load(): OracleMessage[]; append(messages: OracleMessage[]): void; clear(): void; } interface Persona { /** Human-readable role name (e.g. "researcher", "triager"). */ name: string; /** Canonical model id the persona runs on. */ model: string; /** System prompt defining the persona's behavior. */ system?: string; /** Tools the persona may call. Handlers run locally; handler-less tools are * provider server tools. */ tools?: ToolDef[]; /** Skills to attach — each contributes tools + instructions to the persona. */ skills?: Skill[]; /** Enable the provider's web-search server tool for this persona. */ webSearch?: boolean; /** Max model turns before the loop stops (default 8). */ maxSteps?: number; /** Reasoning depth (applied only where the model supports it). */ effort?: Effort; /** Reasoning mode (applied only where the model supports it). */ thinking?: ThinkingMode; temperature?: number; /** Max output tokens per model turn (default 4096). */ maxTokens?: number; /** Persistent memory scope loaded before, and appended after, each run. */ memory?: MemoryScope; } /** What the policy is given when the conversation has grown too large. */ interface CompactionInput { /** The conversation as it stands, including the turn that tripped the limit. */ messages: OracleMessage[]; /** Model turns taken so far. */ steps: number; /** Input tokens the provider reported for the most recent turn. */ inputTokens: number; } /** How a run shortens its own conversation when it gets expensive. */ interface CompactionPolicy { /** * Compact once a turn's reported input tokens reach this. * * Measured against the provider's report rather than an estimate, because the * number that matters is the one being billed. */ whenInputTokensExceed: number; /** * Return a shorter conversation, or `null` when nothing can safely be * dropped. * * `null` rather than a throw: a threshold set below the size of a single * exchange is an ordinary misconfiguration, and it should cost the run its * compaction, not its life. */ compact(input: CompactionInput): OracleMessage[] | null | Promise; } /** * Reject a compaction that would make the next request invalid. * * Three ways a policy goes wrong, all of which fail far from here if allowed * through: dropping a tool_result but keeping its tool_use (a provider 400), * returning nothing (a request with no messages), and returning something no * shorter (an infinite compaction loop, since the trigger would still be met). */ declare function assertCompacted(before: OracleMessage[], after: OracleMessage[]): void; /** One conversation-shortening, for the run's own record of what it dropped. */ interface CompactionRecord { /** The turn after which it happened. */ afterStep: number; /** Input tokens reported for that turn — what tripped the policy. */ inputTokens: number; messagesBefore: number; messagesAfter: number; } /** Options for {@link keepRecentExchanges}. */ interface KeepRecentOptions { /** Trigger, in input tokens reported for one turn. */ whenInputTokensExceed: number; /** How many of the most recent tool exchanges to keep in full. Default 3. */ keep?: number; /** * How many leading messages are the task itself and must never be dropped. * Default 1 — the user turn that started the run. */ preserveLeading?: number; } /** * The default policy: keep the task and the most recent exchanges, replace the * rest with a note saying what was done. * * The note is derived, not generated. Summarizing with a model would add a * request, a cost, and a failure mode to the very operation whose job is to * reduce all three — and for a coding agent the useful content is mechanical * anyway: which tools already ran, so the agent does not re-read what it read. */ declare function keepRecentExchanges(options: KeepRecentOptions): CompactionPolicy; /** One resolved tool call within a run. */ interface ToolCallRecord { toolUse: ToolUseBlock; output: ToolOutput; } interface AgentRunInput { /** A single user turn (convenience). */ input?: string | OracleContentBlock[]; /** Or an explicit list of messages (takes precedence when both are given). */ messages?: OracleMessage[]; signal?: AbortSignal; /** Absolute Unix timestamp in milliseconds for model requests and tools. */ deadline?: number; /** Run-wide limits. Token limits are evaluated after each provider response; * output allowance also caps the next request's maxTokens. */ budget?: AgentRunBudget; /** Clock for per-step timing. Defaults to `Date.now`; inject a fake so a test * can assert exact durations. */ now?: () => number; /** * Shorten the conversation when it gets expensive. * * Without one, a run re-sends its whole history every turn, so input cost * grows with the square of its length — which is what stops a long-horizon * goal, not the step limit. See {@link keepRecentExchanges} for a default. */ compaction?: CompactionPolicy; } /** Run-wide limits: tool calls stop before effects; token usage stops later turns after provider reporting. */ interface AgentRunBudget { maxInputTokens?: number; maxOutputTokens?: number; maxTotalTokens?: number; maxToolCalls?: number; } type StoppedReason = "end_turn" | "max_steps" | "refusal" | "budget_exhausted"; /** * One model turn within a run. The aggregate `usage` on `AgentRun` says what a * run cost in total; this says where it went — which turn was expensive, which * was slow, how many turns it really took, and what the adapter actually sent * each time. * * That last part is why the echo is per-step rather than only on the final * response: a run whose third turn quietly lost its reasoning setting is * exactly the case `verifyEcho` exists to catch, and a final-turn-only echo * cannot see it. */ interface StepRecord { /** 1-based turn number; the last one equals `AgentRun.steps`. */ index: number; /** Usage for this turn alone, not cumulative. */ usage: OracleUsage; /** USD cost of this turn. Absent when the model's pricing is unknown — * never zero, since unknown pricing is not free. */ costUsd?: number; /** Wall-clock milliseconds spent in the provider call. */ durationMs: number; /** The provider's stop reason for this turn. */ stopReason: OracleStopReason; /** What the adapter actually sent for this turn, when it reported it. */ echo?: RequestEcho; /** Tool calls executed in response to this turn, in order. */ toolCalls: ToolCallRecord[]; } interface AgentRun { /** Concatenated text of the final assistant turn. */ finalText: string; /** The last assistant response. */ response: OracleResponse; /** The full conversation (loaded memory + input + assistant/tool turns). */ messages: OracleMessage[]; /** Accumulated usage across every model turn. */ usage: OracleUsage; /** Number of model turns taken. */ steps: number; /** Per-turn breakdown, one entry per model turn, in order. `steps` is its * length; this is where the cost and time actually went. */ trace: StepRecord[]; /** Every tool call executed, in order. */ toolCalls: ToolCallRecord[]; /** Conversation shortenings, in order. Empty when none were needed — which * is also what it says when no policy was supplied. */ compactions: CompactionRecord[]; stoppedReason: StoppedReason; } /** * Run the tool-use agent loop: model turn → execute requested tools → model turn, * until the model stops asking for tools (`end_turn`), refuses (`refusal`), or * `persona.maxSteps` (default 8) is hit (`max_steps`). Composes the persona's * skills into its tools/system prompt, enforces per-tool taint allowlists, and * loads/appends `persona.memory` when set. Returns `{ finalText, response, * messages, usage, steps, toolCalls, stoppedReason }`. */ declare function runAgent(inference: Inference, persona: Persona, input: AgentRunInput): Promise; /** A fully data-describable agent configuration. Every field is JSON-safe. */ interface HarnessSpec { /** Stable identifier for this configuration (used as the persona name). */ id?: string; /** Canonical model id from the catalog. */ model: string; system?: string; /** Name of a toolset in the `ToolsetRegistry`. Omit for a tool-less harness. */ toolset?: string; /** Enable the provider's server-side web-search tool. */ webSearch?: boolean; /** Max model turns before the loop stops. */ maxSteps?: number; effort?: Effort; thinking?: ThinkingMode; temperature?: number; /** Max output tokens per model turn. */ maxTokens?: number; /** Run-wide token and tool-call limits. */ budget?: AgentRunBudget; } /** Named sets of real tools, supplied by the host. The registry is the code * half of the split — it never travels with the spec. */ type ToolsetRegistry = Record; /** * Join a `HarnessSpec` to real tools, producing a runnable `Persona`. * * Throws `ConfigError` when the spec names a toolset the registry does not * have. That is deliberate: silently producing a tool-less persona would run * happily and score differently, so a typo'd toolset name would corrupt a * comparison rather than fail it. */ declare function toPersona(spec: HarnessSpec, registry?: ToolsetRegistry): Persona; /** Why a harness cannot run as specified. */ type HarnessRejection = /** The catalog has no such model. */ "unknown_model" /** The model has no thinking toggle, but the spec asks for `adaptive`. */ | "thinking_unsupported" /** The model always reasons, but the spec asks for `off`. */ | "thinking_not_disableable" /** The model does not offer the requested effort level. */ | "effort_unsupported" /** The spec wants tools; the model cannot call them. */ | "tools_unsupported" /** The spec wants server-side web search; the model has none. */ | "web_search_unsupported" /** The model cannot combine function tools with an explicit effort level. */ | "effort_conflicts_with_tools" /** The adapter would drop the requested temperature on this reasoning model. */ | "temperature_ignored"; /** * The result of `resolveHarness`: either the resolved catalog entry, or a * machine-readable `code` plus a human-readable `reason`. There is deliberately * no "resolved with adjustments" variant — a harness runs as specified or it * does not run, so nothing here can express a silent substitution. */ type HarnessResolution = { ok: true; spec: ModelSpec; } | { ok: false; code: HarnessRejection; reason: string; }; /** Options for `resolveHarness`. */ interface ResolveHarnessOptions { catalog?: Catalog; /** How many tools the harness will send. Defaults to 1 when the spec names a * toolset, since tool presence changes what some models accept. */ toolCount?: number; } /** * Decide whether `harness` can run as literally specified on its model. * * Returns `{ ok: true, spec }` with the resolved catalog entry, or * `{ ok: false, code, reason }` naming the incompatibility. Never throws for an * unsupported combination — an unknown model is a rejection, not an error — so * a planner can enumerate a full matrix and skip the illegal cells loudly. */ declare function resolveHarness(harness: HarnessSpec, opts?: ResolveHarnessOptions): HarnessResolution; /** One field where intent and reality disagree. */ interface EchoMismatch { field: "model" | "thinking" | "effort" | "temperature" | "maxTokens" | "tools"; /** What the harness asked for, rendered for a human. */ intended: string; /** What the adapter actually sent. */ actual: string; detail: string; } /** * Compare a `HarnessSpec` against the `RequestEcho` of the call it produced. * Returns every field where the adapter sent something other than what was * asked for — an empty array means the request was transmitted faithfully. * * Fields the harness left unset are not checked, with one exception: an effort * knob the harness never requested but the adapter sent anyway is reported, * because a cell running with reasoning explicitly disabled is not comparable * to cells running on their model's default. */ declare function verifyEcho(harness: HarnessSpec, spec: ModelSpec, echo: RequestEcho): EchoMismatch[]; /** True when the adapter transmitted the harness faithfully. */ declare function isFaithful(mismatches: EchoMismatch[]): boolean; /** One evaluation case — an input plus whatever the grader needs to judge it. */ interface EvalCase { name?: string; /** A user turn (string / blocks) or an explicit conversation (message array). */ input: string | OracleContentBlock[] | OracleMessage[]; /** Grader-specific expectation (exact string, JSON subset, rubric text, …). */ expected?: unknown; meta?: Record; } interface GradeContext { case: EvalCase; /** The system-under-test's final text output. */ output: string; /** The final model response. */ response: OracleResponse; } interface GradeResult { pass: boolean; /** 0..1 when a grader scores rather than passes/fails. */ score?: number; reason?: string; } type Grader = (ctx: GradeContext) => Promise | GradeResult; interface EvalResult { case: EvalCase; output: string; grade: GradeResult; response: OracleResponse; usage: OracleUsage; } interface EvalReport { total: number; passed: number; failed: number; passRate: number; results: EvalResult[]; usage: OracleUsage; } interface EvaluateOptions { inference: Inference; cases: EvalCase[]; grader: Grader; /** Run each case through this persona (agent loop). Mutually exclusive with model. */ persona?: Persona; /** Or run each case as a single chat with this model + system. */ model?: string; system?: string; maxTokens?: number; /** Max cases run concurrently (default 5). */ concurrency?: number; } /** * Eval harness: run each case through a `persona` (agent loop) or a plain `model` * chat, grade it with `grader`, and return an `EvalReport` (per-case results, * pass/fail counts, passRate, summed usage). Cases run concurrently up to * `concurrency` (default 5); throws if neither `persona` nor `model` is given. */ declare function evaluate(opts: EvaluateOptions): Promise; /** Pass when trimmed output equals `case.expected` (stringified). */ declare function exactMatch(): Grader; /** Pass when output contains `case.expected` (case-insensitive by default). */ declare function includes(opts?: { caseInsensitive?: boolean; }): Grader; /** Pass when output parses as JSON and contains every key/value in * `case.expected` (a recursive subset match). */ declare function structuredMatch(): Grader; /** Grade open-ended output with a judge model. `case.expected` is the rubric. * The judge is asked to return a strict JSON verdict which is tolerantly parsed. */ declare function llmJudge(opts: { inference: Inference; model: string; extraGuidance?: string; }): Grader; /** Entity namespaces odla-ai owns in odla-db (all non-`$`, so no platform clash). */ declare const NS: { readonly conversation: "agent_conversation"; readonly message: "agent_message"; readonly run: "agent_run"; }; /** Serialized odla-db schema (POST to `/app/:id/schema` as `{ schema: AGENT_SCHEMA }`). */ declare const AGENT_SCHEMA: { readonly entities: { readonly agent_conversation: { readonly attrs: { readonly key: { readonly type: "string"; readonly unique: true; readonly indexed: true; readonly optional: false; }; readonly sessionId: { readonly type: "string"; readonly unique: false; readonly indexed: true; readonly optional: false; }; readonly title: { readonly type: "string"; readonly unique: false; readonly indexed: false; readonly optional: true; }; readonly createdAt: { readonly type: "date"; readonly unique: false; readonly indexed: true; readonly optional: false; }; readonly updatedAt: { readonly type: "date"; readonly unique: false; readonly indexed: true; readonly optional: false; }; }; }; readonly agent_message: { readonly attrs: { readonly key: { readonly type: "string"; readonly unique: true; readonly indexed: true; readonly optional: false; }; readonly sessionId: { readonly type: "string"; readonly unique: false; readonly indexed: true; readonly optional: false; }; readonly seq: { readonly type: "number"; readonly unique: false; readonly indexed: true; readonly optional: false; }; readonly role: { readonly type: "string"; readonly unique: false; readonly indexed: false; readonly optional: false; }; readonly content: { readonly type: "string"; readonly unique: false; readonly indexed: false; readonly optional: false; }; readonly createdAt: { readonly type: "date"; readonly unique: false; readonly indexed: true; readonly optional: false; }; }; }; readonly agent_run: { readonly attrs: { readonly key: { readonly type: "string"; readonly unique: true; readonly indexed: true; readonly optional: false; }; readonly sessionId: { readonly type: "string"; readonly unique: false; readonly indexed: true; readonly optional: false; }; readonly persona: { readonly type: "string"; readonly unique: false; readonly indexed: false; readonly optional: true; }; readonly status: { readonly type: "string"; readonly unique: false; readonly indexed: true; readonly optional: false; }; readonly steps: { readonly type: "number"; readonly unique: false; readonly indexed: false; readonly optional: false; }; readonly inputTokens: { readonly type: "number"; readonly unique: false; readonly indexed: false; readonly optional: false; }; readonly outputTokens: { readonly type: "number"; readonly unique: false; readonly indexed: false; readonly optional: false; }; readonly finalText: { readonly type: "string"; readonly unique: false; readonly indexed: false; readonly optional: true; }; readonly trace: { readonly type: "json"; readonly unique: false; readonly indexed: false; readonly optional: false; }; readonly createdAt: { readonly type: "date"; readonly unique: false; readonly indexed: true; readonly optional: false; }; }; }; }; readonly links: {}; }; type OdlaScalar = string | number | boolean | null; interface OdlaLookup { ns: string; attr: string; value: OdlaScalar; } /** Entity reference: a raw id, or a natural-key `Lookup` for idempotent upsert. */ type OdlaEntityRef = string | OdlaLookup; /** Attribute values for an op. Typed `any` on purpose: odla-db's real `transact` * constrains attrs to its own `Value` type, while odla-ai builds attrs from * mixed sources (message content, run traces). `any` is the one value type * assignable in both directions, so a real `@odla-ai/db` `AdminDb` satisfies * `OdlaDbClient` with no cast at the call site. */ type OdlaAttrs = Record; /** The odla-db transaction op union (subset we emit). */ type OdlaOp = { t: "update"; ns: string; id: OdlaEntityRef; attrs: OdlaAttrs; } | { t: "merge"; ns: string; id: OdlaEntityRef; attrs: OdlaAttrs; } | { t: "delete"; ns: string; id: OdlaEntityRef; } | { t: "link"; ns: string; id: OdlaEntityRef; label: string; target: OdlaEntityRef; } | { t: "unlink"; ns: string; id: OdlaEntityRef; label: string; target: OdlaEntityRef; }; /** An InstaQL-style query object, e.g. `{ ns: { $: { where, order, limit } } }`. */ type OdlaQuery = Record; /** The subset of the odla-db Admin client odla-ai uses. */ interface OdlaDbClient { /** Apply ops atomically; a stable `mutationId` gives exactly-once replay. * Mirrors odla-db 0.5's AdminDb: `duplicate` means the mutationId was * already applied and the ops did not re-run. */ transact(ops: OdlaOp[], opts?: { mutationId?: string; }): Promise<{ txId: number; duplicate: boolean; }>; /** Run an InstaQL query; returns namespace → rows. */ query(query: OdlaQuery): Promise[]>>; /** Read one of this app's secrets by name (app-key credential; read-only). */ secrets: { get(name: string): Promise; }; } interface OdlaDbMemoryOptions { db: OdlaDbClient; /** Groups a conversation's turns; stable across runs to accumulate history. */ sessionId: string; /** Optional human-readable title stored on the conversation node. */ title?: string; /** Override entity namespaces (default NS.message / NS.conversation). */ namespaces?: { message?: string; conversation?: string; }; } /** * A `MemoryScope` backed by odla-db. `load()` replays a session's prior turns * (ordered by `seq`); `append()` upserts new turns by natural key under a * deterministic `mutationId`, so a retried run never duplicates. Takes an * injected odla-db client — odla-ai keeps zero runtime dependency on @odla-ai/db. */ declare class OdlaDbMemory implements MemoryScope { private readonly db; private readonly sessionId; private readonly title; private readonly msgNs; private readonly convNs; private loadedCount; constructor(opts: OdlaDbMemoryOptions); load(): Promise; append(messages: OracleMessage[]): Promise; } interface PersistRunOptions { db: OdlaDbClient; /** Groups runs (typically the same session as the memory scope). */ sessionId: string; personaName?: string; /** Stable id for exactly-once persistence; defaults to `${sessionId}:${now}`. */ runId?: string; namespace?: string; } /** Write a run trace; returns the record key. */ declare function persistRun(run: AgentRun, opts: PersistRunOptions): Promise; interface QueryRunsOptions { db: OdlaDbClient; sessionId: string; limit?: number; namespace?: string; } /** Read persisted runs for a session, newest first. */ declare function queryRuns(opts: QueryRunsOptions): Promise[]>; /** Default secret name per provider. */ declare const DEFAULT_SECRET_NAMES: Record; interface OdlaDbKeyResolverOptions { /** Map a provider to its secret name (default `_api_key`). Use this * to scope per-end-user keys, e.g. `(p) => \`${p}_api_key__${userSub}\``. */ secretName?: (provider: ProviderId) => string; /** Cache resolved keys in memory (default true). */ cache?: boolean; /** Maximum age for a cached secret (default 60 seconds; 0 disables caching). * This bounds provider-key rotation propagation in warm isolates. */ ttlMs?: number; /** Version included in the cache key. Change it to invalidate a known key * generation immediately without waiting for the TTL. */ cacheVersion?: string | ((provider: ProviderId) => string); } /** Build a KeyResolver that reads provider keys from odla-db secrets. A missing * secret resolves to `undefined` (→ that provider is simply unavailable, and * odla-ai throws its own ConfigError) rather than surfacing odla-db's 404. */ declare function odlaDbKeyResolver(db: OdlaDbClient, opts?: OdlaDbKeyResolverOptions): KeyResolver; interface InitFromPlatformOptions { /** Platform base URL (e.g. "https://odla.ai"). */ platform: string; /** The Registry app id, not the environment's database tenant id. */ appId: string; /** Which environment's config to use ("dev", "prod", ...). */ env: string; /** Existing backend app key. Required only for hosted mode. */ appKey?: string; /** Tenant client used to resolve provider secrets in BYOK mode. */ db?: OdlaDbClient; /** Transport override (tests / non-global fetch). */ fetch?: typeof fetch; /** public-config cache TTL in ms (default 60s; 0 disables caching). */ ttlMs?: number; /** Extra init() options. Platform routing still owns the active catalog and * hosted provider transports. */ initOptions?: Omit; /** BYOK secret resolver cache controls. */ keyResolverOptions?: OdlaDbKeyResolverOptions; } interface PlatformAi { ai: Ai; mode: "hosted" | "byok"; provider: ProviderId; model?: string; /** Registry service-config revision selecting this mode/model. */ revision: number; /** Hosted model-policy revision, when hosted mode is active. */ policyRevision?: number; } /** Drop all cached platform configs (tests, or to force an immediate refetch). */ declare function clearPlatformAiCache(): void; /** Build an `Ai` from the app's attested platform configuration. */ declare function initFromPlatform(opts: InitFromPlatformOptions): Promise; type FetchLike = typeof fetch; interface ProvisionContext { /** Platform origin exposing the proxied db operator routes, normally https://odla.ai. */ endpoint: string; /** Operator `ADMIN_SECRET` or an `odla_dev_...` developer token (owns the app). */ token: string; fetch?: FetchLike; } /** Create an app (owned by the token's developer). Returns its id. */ declare function createApp(ctx: ProvisionContext, opts?: { appId?: string; name?: string; }): Promise; /** Mint a per-app `odla_sk_...` key (shown once). */ declare function mintAppKey(ctx: ProvisionContext, appId: string): Promise; /** Push odla-ai's agent memory/run schema (authenticated with the app key). */ declare function pushAgentSchema(ctx: { endpoint: string; fetch?: FetchLike; }, appId: string, appKey: string): Promise; /** Store a named secret (operator/dev token). Value must be a non-`$` string. */ declare function putSecret(ctx: ProvisionContext, appId: string, name: string, value: string): Promise; /** Per-namespace CEL permission rules (odla-db is DEFAULT-DENY: end-users can't * read or write any namespace until its rules are set; the app key bypasses * rules, so agent-only apps work without them). */ type AppRules = Record; interface ProvisionAgentAppOptions extends ProvisionContext { appId?: string; appName?: string; /** Provider keys to store as odla-db secrets (read later via odlaDbKeyResolver). */ providerKeys?: Partial>; /** Map a provider to its secret name (default `_api_key`). */ secretName?: (provider: ProviderId) => string; /** Push the agent schema (default true). */ pushSchema?: boolean; /** Permission rules to install. odla-db is default-deny, so set these for any * namespace end-users should reach (e.g. own-rows-only: * `{ todos: { view: "auth.id == data.ownerId", create: "auth.id == data.ownerId" } }`). * Omit for agent-only apps — the app key bypasses rules. */ rules?: AppRules; } interface ProvisionedApp { appId: string; /** The minted `odla_sk_...` app key — pass as `adminToken` to `@odla-ai/db`'s init. */ appKey: string; } /** One call to stand up an agent app: create → mint key → push schema → store * provider keys as secrets. Returns the appId + app key for the runtime client. */ declare function provisionAgentApp(opts: ProvisionAgentAppOptions): Promise; interface EntityCrudSkillOptions { /** The injected odla-db client (from @odla-ai/db's init). */ db: OdlaDbClient; /** Entity namespace, e.g. "todos". */ entity: string; /** JSON-Schema `properties` for the create/update fields (e.g. { text: { type: "string" }, done: { type: "boolean" } }). */ fields: Record; /** Field names required to create (default: none). */ required?: string[]; /** Skill name (default `${entity} management`). */ name?: string; /** Extra instructions appended to the generated guidance. */ instructions?: string; /** Singular noun for tool names (default: `entity` with a trailing "s" stripped). */ singular?: string; /** Plural noun for the list tool (default: `entity`). */ plural?: string; /** Input field carrying the entity id in update/delete (default "id"). */ idField?: string; /** Generate a new id on create (default crypto.randomUUID). */ genId?: () => string; /** Attr stamped with Date.now() on create; pass false to disable (default "createdAt"). */ stampCreatedAt?: string | false; /** Default ordering for the list tool (default { createdAt: "asc" }). */ order?: Record; } /** Build a CRUD Skill for one odla-db entity. */ declare function entityCrudSkill(opts: EntityCrudSkillOptions): Skill; export { AGENT_SCHEMA, ANTHROPIC_MODELS, type AgentRun, type AgentRunBudget, type AgentRunInput, type Ai, type AiCapacityOptions, AiTelemetry, AiTelemetryAttributes, AudioBlock, AuthError, CancelledError, CapabilityError, type CapacityAdmissionRequest, type CapacityEvent, type CapacityLease, type CapacityPoolIdentity, type CapacityScheduler, type CapacitySchedulerOptions, Catalog, type ChatInput, type CompactionInput, type CompactionPolicy, type CompactionRecord, type ComposedPersona, ConfigError, type ContentBlockDelta, type ContentBlockDeltaEvent, type ContentBlockStartEvent, type ContentBlockStopEvent, ContextWindowError, DEFAULT_SECRET_NAMES, DeadlineExceededError, type DiscoveredModel, type DiscoveryHints, DocumentBlock, type EchoMismatch, Effort, type EntityCrudSkillOptions, type EvalCase, type EvalReport, type EvalResult, type EvaluateOptions, type ExtractCall, type ExtractTool, GOOGLE_MODELS, type GradeContext, type GradeResult, type Grader, type HarnessRejection, type HarnessResolution, type HarnessSpec, ImageBlock, InMemoryScope, type Inference, type InitFromPlatformOptions, type InitOptions, InvalidRequestError, type JsonSchemaIssue, type JsonSchemaValidation, type KeepRecentOptions, type KeyMap, type KeyOptions, type KeyResolver, type MemoryScope, type MessageDeltaEvent, type MessageStartEvent, type MessageStopEvent, type ModelCapacityLimits, ModelSpec, NS, OPENAI_MODELS, OdlaAIError, type OdlaDbClient, type OdlaDbKeyResolverOptions, OdlaDbMemory, type OdlaDbMemoryOptions, type OdlaEntityRef, type OdlaLookup, type OdlaOp, type OdlaQuery, type OdlaScalar, OracleContentBlock, type OracleErrorEvent, type OracleErrorShape, type OracleErrorType, type OracleEvent, OracleMessage, OracleReceipt, type OracleReceiptEvent, OracleRequest, OracleResponse, OracleStopReason, OracleTool, OracleUsage, type PersistRunOptions, type Persona, type PlatformAi, type Provider, ProviderError, type ProviderFactory, ProviderId, type ProvisionAgentAppOptions, type ProvisionContext, type ProvisionedApp, type QueryRunsOptions, RateLimitError, RequestEcho, type ResolveHarnessOptions, type SearchCall, SearchCitation, type Skill, type StepRecord, type StoppedReason, TaintError, type TaintLabel, type TaintSet, TextBlock, ThinkingBlock, ThinkingMode, type ToolCallRecord, type ToolContext, type ToolDef, type ToolHandler, ToolInputError, type ToolOutput, ToolResultBlock, ToolUseBlock, type ToolsetRegistry, assertCompacted, assertSinkAcceptsTaint, blocksOf, clearPlatformAiCache, clearProviderCache, composeSkills, createApp, createCapacityScheduler, defaultCapacityScheduler, entityCrudSkill, estimateRequestTokens, evaluate, exactMatch, extractText, extractToolUses, fingerprintCredential, getProvider, includes, init, initFromPlatform, isAudioBlock, isDocumentBlock, isFaithful, isImageBlock, isTextBlock, isThinkingBlock, isToolResultBlock, isToolUseBlock, keepRecentExchanges, listModels, llmJudge, looksLikeKey, mintAppKey, normalizeError, odlaDbKeyResolver, persistRun, provisionAgentApp, pushAgentSchema, putSecret, queryRuns, redact, registerProvider, resolveHarness, runAgent, structuredMatch, taint, toOracleTool, toPersona, totalUsageTokens, validateJsonSchema, verifyEcho };