@odla-ai/ai 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -90,6 +90,7 @@ interface OracleUsage {
90
90
  cacheCreationTokens?: number;
91
91
  cacheReadTokens?: number;
92
92
  }
93
+ /** A fresh zeroed usage tally (0 input/output tokens, no cache fields) — the seed for accumulation. */
93
94
  declare function emptyUsage(): OracleUsage;
94
95
  /** Accumulate `more` into `into`, in place. Cache fields sum when present. */
95
96
  declare function addUsage(into: OracleUsage, more: OracleUsage): void;
@@ -140,6 +141,12 @@ interface OracleRequest {
140
141
  /** Provider-specific escape hatch, passed through opaquely. Using it gives up
141
142
  * portability across providers. */
142
143
  providerExtras?: Record<string, unknown>;
144
+ /** Cancel the provider request. Adapters pass this to the vendor SDK rather
145
+ * than limiting cancellation to local tool handlers. */
146
+ signal?: AbortSignal;
147
+ /** Absolute Unix timestamp in milliseconds. The SDK combines this deadline
148
+ * with `signal`; whichever fires first cancels the provider request. */
149
+ deadline?: number;
143
150
  }
144
151
  type OracleStopReason = "end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | "pause_turn" | "refusal" | "error";
145
152
  interface OracleResponse {
@@ -155,7 +162,7 @@ interface OracleResponse {
155
162
 
156
163
  /** The closed taxonomy of normalized error codes carried by every OdlaAIError
157
164
  * and by the streaming `error` event. */
158
- type OracleErrorType = "invalid_request" | "auth" | "rate_limit" | "context_window" | "tool_input_invalid" | "capability_unsupported" | "config" | "provider_error";
165
+ type OracleErrorType = "invalid_request" | "auth" | "rate_limit" | "context_window" | "cancelled" | "deadline_exceeded" | "tool_input_invalid" | "capability_unsupported" | "config" | "provider_error";
159
166
  /** The plain-data error shape used inside the streaming `error` event. */
160
167
  interface OracleErrorShape {
161
168
  code: OracleErrorType;
@@ -219,6 +226,29 @@ declare class InvalidRequestError extends OdlaAIError {
219
226
  cause?: unknown;
220
227
  });
221
228
  }
229
+ /** A provider returned tool arguments that are malformed or do not satisfy the
230
+ * declared JSON Schema. Tool handlers are never invoked for this error. */
231
+ declare class ToolInputError extends OdlaAIError {
232
+ readonly tool?: string;
233
+ constructor(message: string, opts?: {
234
+ tool?: string;
235
+ cause?: unknown;
236
+ });
237
+ }
238
+ /** The caller cancelled a request. This is not an upstream failure and should
239
+ * not be retried unless the caller explicitly starts a new operation. */
240
+ declare class CancelledError extends OdlaAIError {
241
+ constructor(message?: string, opts?: {
242
+ cause?: unknown;
243
+ });
244
+ }
245
+ /** The request's absolute deadline elapsed. Callers may choose a new deadline,
246
+ * but should not classify this as a provider outage. */
247
+ declare class DeadlineExceededError extends OdlaAIError {
248
+ constructor(message?: string, opts?: {
249
+ cause?: unknown;
250
+ });
251
+ }
222
252
  /** Any other upstream provider failure (5xx, transport, unexpected shape). */
223
253
  declare class ProviderError extends OdlaAIError {
224
254
  constructor(message: string, opts?: {
@@ -281,12 +311,19 @@ interface OracleErrorEvent {
281
311
  error: OracleErrorShape;
282
312
  }
283
313
 
314
+ /** Type guard: narrows a content block to a `TextBlock` (`type: "text"`). */
284
315
  declare function isTextBlock(b: OracleContentBlock): b is TextBlock;
316
+ /** Type guard: narrows a content block to an `ImageBlock` (`type: "image"`). */
285
317
  declare function isImageBlock(b: OracleContentBlock): b is ImageBlock;
318
+ /** Type guard: narrows a content block to an `AudioBlock` (`type: "audio"`). */
286
319
  declare function isAudioBlock(b: OracleContentBlock): b is AudioBlock;
320
+ /** Type guard: narrows a content block to a `DocumentBlock` (`type: "document"`). */
287
321
  declare function isDocumentBlock(b: OracleContentBlock): b is DocumentBlock;
322
+ /** Type guard: narrows a content block to a `ToolUseBlock` (`type: "tool_use"`). */
288
323
  declare function isToolUseBlock(b: OracleContentBlock): b is ToolUseBlock;
324
+ /** Type guard: narrows a content block to a `ToolResultBlock` (`type: "tool_result"`). */
289
325
  declare function isToolResultBlock(b: OracleContentBlock): b is ToolResultBlock;
326
+ /** Type guard: narrows a content block to a `ThinkingBlock` (`type: "thinking"`). */
290
327
  declare function isThinkingBlock(b: OracleContentBlock): b is ThinkingBlock;
291
328
  /** Normalize a message's `content` (string shorthand or block array) to blocks. */
292
329
  declare function blocksOf(content: string | OracleContentBlock[]): OracleContentBlock[];
@@ -295,6 +332,20 @@ declare function extractText(content: OracleContentBlock[]): string;
295
332
  /** Collect every tool_use block from response or message content. */
296
333
  declare function extractToolUses(content: OracleContentBlock[]): ToolUseBlock[];
297
334
 
335
+ /** One deterministic validation failure at a JSONPath-like location. */
336
+ interface JsonSchemaIssue {
337
+ path: string;
338
+ message: string;
339
+ }
340
+ /** Complete supported-subset schema validation result; unknown keywords fail validation. */
341
+ interface JsonSchemaValidation {
342
+ valid: boolean;
343
+ issues: JsonSchemaIssue[];
344
+ }
345
+ /** Validate a JSON-compatible value against the supported JSON Schema subset.
346
+ * Unknown or unsupported keywords are validation failures, not ignored hints. */
347
+ declare function validateJsonSchema(schema: unknown, value: unknown): JsonSchemaValidation;
348
+
298
349
  /** The kind of model — chat/multimodal is the v1 focus; the others are modeled
299
350
  * so embeddings, transcription, TTS, and image generation slot in later. */
300
351
  type ModelKind = "chat" | "embed" | "transcribe" | "tts" | "image";
@@ -342,10 +393,13 @@ declare function chatCapabilities(overrides?: Partial<Capabilities>): Capabiliti
342
393
  */
343
394
  declare function validateRequest(spec: ModelSpec, req: OracleRequest): void;
344
395
 
396
+ /** Built-in Anthropic (Claude) catalog: one `ModelSpec` per model (canonical id, native id, capabilities, limits). */
345
397
  declare const ANTHROPIC_MODELS: ModelSpec[];
346
398
 
399
+ /** Built-in OpenAI catalog: one `ModelSpec` per model (canonical id == native id, capabilities, context window). */
347
400
  declare const OPENAI_MODELS: ModelSpec[];
348
401
 
402
+ /** Built-in Google (Gemini) catalog: one `ModelSpec` per model (canonical id == native id, capabilities, context window). */
349
403
  declare const GOOGLE_MODELS: ModelSpec[];
350
404
 
351
405
  /** Canonical id → spec. */
@@ -417,6 +471,8 @@ interface ExtractCall {
417
471
  user: string | OracleContentBlock[];
418
472
  tool: ExtractTool;
419
473
  maxTokens?: number;
474
+ signal?: AbortSignal;
475
+ deadline?: number;
420
476
  }
421
477
  /** A web-search-enabled call: the model searches and returns prose. */
422
478
  interface SearchCall {
@@ -424,6 +480,8 @@ interface SearchCall {
424
480
  system?: string | TextBlock[];
425
481
  user: string | OracleContentBlock[];
426
482
  maxTokens?: number;
483
+ signal?: AbortSignal;
484
+ deadline?: number;
427
485
  }
428
486
  interface Ai {
429
487
  /** The active model catalog. */
@@ -445,11 +503,23 @@ interface Ai {
445
503
  }
446
504
  /** The minimal inference surface the agent loop and eval harness depend on. */
447
505
  type Inference = Pick<Ai, "chat" | "stream" | "catalog">;
506
+ /**
507
+ * Build the `Ai` facade (bring-your-own-keys). Resolves a canonical model id to
508
+ * its provider, supplies keys statically (`keys`) or dynamically (`resolveKey`),
509
+ * validates each request against the model's capabilities, and exposes
510
+ * `chat`/`stream`/`extract`/`search` plus the active `catalog`. Only the SDK of a
511
+ * provider you actually call is loaded (via the lazy provider registry).
512
+ */
448
513
  declare function init(opts?: InitOptions): Ai;
449
514
 
450
515
  /** Generate the `llms.txt` context document for a given model catalog. */
451
516
  declare function generateLlmsTxt(catalog?: Catalog): string;
452
517
 
518
+ /**
519
+ * Resolve the adapter for a provider, lazy-`import()`ing its module (and only
520
+ * that provider's SDK) on first use and caching the instance per (provider, key)
521
+ * so repeated calls reuse one SDK client.
522
+ */
453
523
  declare function getProvider(id: ProviderId, apiKey: string): Promise<Provider>;
454
524
  /** Test seam: register a provider instance directly (used to inject mocks). */
455
525
  declare function registerProvider(id: ProviderId, apiKey: string, provider: Provider): void;
@@ -458,10 +528,11 @@ declare function clearProviderCache(): void;
458
528
 
459
529
  /** Map any provider error to an OdlaAIError, returning it (does not throw).
460
530
  * Re-returns an OdlaAIError unchanged (already normalized). */
461
- declare function normalizeError(err: unknown, provider: ProviderId): OdlaAIError;
531
+ declare function normalizeError(err: unknown, provider: ProviderId, signal?: AbortSignal): OdlaAIError;
462
532
 
463
533
  type TaintLabel = "web_untrusted" | "operator_pasted_untrusted" | "llm_inherited" | `tool_untrusted:${string}`;
464
534
  type TaintSet = Set<TaintLabel>;
535
+ /** Build a `TaintSet` from labels — the CaMeL-style taint carried through a run and checked against each tool's allowlist. */
465
536
  declare function taint(...labels: TaintLabel[]): TaintSet;
466
537
  /** Raised when a tool's taint allowlist doesn't cover the conversation's taint. */
467
538
  declare class TaintError extends OdlaAIError {
@@ -572,8 +643,20 @@ interface AgentRunInput {
572
643
  /** Or an explicit list of messages (takes precedence when both are given). */
573
644
  messages?: OracleMessage[];
574
645
  signal?: AbortSignal;
575
- }
576
- type StoppedReason = "end_turn" | "max_steps" | "refusal";
646
+ /** Absolute Unix timestamp in milliseconds for model requests and tools. */
647
+ deadline?: number;
648
+ /** Run-wide limits. Token limits are evaluated after each provider response;
649
+ * output allowance also caps the next request's maxTokens. */
650
+ budget?: AgentRunBudget;
651
+ }
652
+ /** Run-wide limits: tool calls stop before effects; token usage stops later turns after provider reporting. */
653
+ interface AgentRunBudget {
654
+ maxInputTokens?: number;
655
+ maxOutputTokens?: number;
656
+ maxTotalTokens?: number;
657
+ maxToolCalls?: number;
658
+ }
659
+ type StoppedReason = "end_turn" | "max_steps" | "refusal" | "budget_exhausted";
577
660
  interface AgentRun {
578
661
  /** Concatenated text of the final assistant turn. */
579
662
  finalText: string;
@@ -589,6 +672,14 @@ interface AgentRun {
589
672
  toolCalls: ToolCallRecord[];
590
673
  stoppedReason: StoppedReason;
591
674
  }
675
+ /**
676
+ * Run the tool-use agent loop: model turn → execute requested tools → model turn,
677
+ * until the model stops asking for tools (`end_turn`), refuses (`refusal`), or
678
+ * `persona.maxSteps` (default 8) is hit (`max_steps`). Composes the persona's
679
+ * skills into its tools/system prompt, enforces per-tool taint allowlists, and
680
+ * loads/appends `persona.memory` when set. Returns `{ finalText, response,
681
+ * messages, usage, steps, toolCalls, stoppedReason }`.
682
+ */
592
683
  declare function runAgent(inference: Inference, persona: Persona, input: AgentRunInput): Promise<AgentRun>;
593
684
 
594
685
  /** One evaluation case — an input plus whatever the grader needs to judge it. */
@@ -643,6 +734,12 @@ interface EvaluateOptions {
643
734
  /** Max cases run concurrently (default 5). */
644
735
  concurrency?: number;
645
736
  }
737
+ /**
738
+ * Eval harness: run each case through a `persona` (agent loop) or a plain `model`
739
+ * chat, grade it with `grader`, and return an `EvalReport` (per-case results,
740
+ * pass/fail counts, passRate, summed usage). Cases run concurrently up to
741
+ * `concurrency` (default 5); throws if neither `persona` nor `model` is given.
742
+ */
646
743
  declare function evaluate(opts: EvaluateOptions): Promise<EvalReport>;
647
744
 
648
745
  /** Pass when trimmed output equals `case.expected` (stringified). */
@@ -888,6 +985,12 @@ interface OdlaDbMemoryOptions {
888
985
  conversation?: string;
889
986
  };
890
987
  }
988
+ /**
989
+ * A `MemoryScope` backed by odla-db. `load()` replays a session's prior turns
990
+ * (ordered by `seq`); `append()` upserts new turns by natural key under a
991
+ * deterministic `mutationId`, so a retried run never duplicates. Takes an
992
+ * injected odla-db client — odla-ai keeps zero runtime dependency on @odla-ai/db.
993
+ */
891
994
  declare class OdlaDbMemory implements MemoryScope {
892
995
  private readonly db;
893
996
  private readonly sessionId;
@@ -928,6 +1031,12 @@ interface OdlaDbKeyResolverOptions {
928
1031
  secretName?: (provider: ProviderId) => string;
929
1032
  /** Cache resolved keys in memory (default true). */
930
1033
  cache?: boolean;
1034
+ /** Maximum age for a cached secret (default 60 seconds; 0 disables caching).
1035
+ * This bounds provider-key rotation propagation in warm isolates. */
1036
+ ttlMs?: number;
1037
+ /** Version included in the cache key. Change it to invalidate a known key
1038
+ * generation immediately without waiting for the TTL. */
1039
+ cacheVersion?: string | ((provider: ProviderId) => string);
931
1040
  }
932
1041
  /** Build a KeyResolver that reads provider keys from odla-db secrets. A missing
933
1042
  * secret resolves to `undefined` (→ that provider is simply unavailable, and
@@ -951,6 +1060,8 @@ interface InitFromPlatformOptions {
951
1060
  * owned by this helper; `defaultModel` is used only when the platform
952
1061
  * config sets no model. */
953
1062
  initOptions?: Omit<InitOptions, "resolveKey">;
1063
+ /** Secret resolver cache controls. Defaults to a finite 60-second TTL. */
1064
+ keyResolverOptions?: OdlaDbKeyResolverOptions;
954
1065
  }
955
1066
  interface PlatformAi {
956
1067
  ai: Ai;
@@ -960,15 +1071,14 @@ interface PlatformAi {
960
1071
  /** Drop all cached platform configs (tests, or to force an immediate refetch). */
961
1072
  declare function clearPlatformAiCache(): void;
962
1073
  /** Build an `Ai` from the app's platform registration: provider/model from
963
- * public-config (cached ~60s), API key from the tenant's odla-db secrets at
964
- * call time. On cache refresh the existing `Ai` (and its warm key-resolver
965
- * cache) is reused unless provider/model changed. Note the first call's
966
- * `db`/`initOptions` are captured for the cache entry's lifetime. */
1074
+ * public-config (cached ~60s), API key from the supplied tenant's odla-db
1075
+ * secrets at call time. Only public config is shared globally; every call
1076
+ * builds a facade bound to its own `db` and init options. */
967
1077
  declare function initFromPlatform(opts: InitFromPlatformOptions): Promise<PlatformAi>;
968
1078
 
969
1079
  type FetchLike = typeof fetch;
970
1080
  interface ProvisionContext {
971
- /** The odla-db worker URL always human-supplied, never hardcoded. */
1081
+ /** Platform origin exposing the proxied db operator routes, normally https://odla.ai. */
972
1082
  endpoint: string;
973
1083
  /** Operator `ADMIN_SECRET` or an `odla_dev_...` developer token (owns the app). */
974
1084
  token: string;
@@ -1050,4 +1160,4 @@ interface EntityCrudSkillOptions {
1050
1160
  /** Build a CRUD Skill for one odla-db entity. */
1051
1161
  declare function entityCrudSkill(opts: EntityCrudSkillOptions): Skill;
1052
1162
 
1053
- export { AGENT_SCHEMA, ANTHROPIC_MODELS, type AgentRun, type AgentRunInput, type Ai, type AudioBlock, type AudioMediaType, type AudioSource, AuthError, type Capabilities, CapabilityError, type Catalog, type ChatInput, type ComposedPersona, ConfigError, type ContentBlockDelta, type ContentBlockDeltaEvent, type ContentBlockStartEvent, type ContentBlockStopEvent, ContextWindowError, DEFAULT_CATALOG, DEFAULT_SECRET_NAMES, type DocumentBlock, type DocumentSource, type Effort, type EntityCrudSkillOptions, type EvalCase, type EvalReport, type EvalResult, type EvaluateOptions, type ExtractCall, type ExtractTool, GOOGLE_MODELS, type GradeContext, type GradeResult, type Grader, type ImageBlock, type ImageMediaType, type ImageSource, InMemoryScope, type Inference, type InitFromPlatformOptions, type InitOptions, InvalidRequestError, type KeyMap, type KeyOptions, type KeyResolver, type MemoryScope, type MessageDeltaEvent, type MessageStartEvent, type MessageStopEvent, type ModelKind, type ModelSpec, NS, OPENAI_MODELS, OdlaAIError, type OdlaDbClient, type OdlaDbKeyResolverOptions, OdlaDbMemory, type OdlaDbMemoryOptions, type OdlaEntityRef, type OdlaLookup, type OdlaOp, type OdlaQuery, type OdlaScalar, type OracleContentBlock, type OracleErrorEvent, type OracleErrorShape, type OracleErrorType, type OracleEvent, type OracleMessage, type OracleRequest, type OracleResponse, type OracleRole, type OracleStopReason, type OracleTool, type OracleUsage, type PersistRunOptions, type Persona, type PlatformAi, type Provider, ProviderError, type ProviderFactory, type ProviderId, type ProvisionAgentAppOptions, type ProvisionContext, type ProvisionedApp, type QueryRunsOptions, RateLimitError, type ResponseFormat, type SearchCall, type Skill, type StoppedReason, TaintError, type TaintLabel, type TaintSet, type TextBlock, type ThinkingBlock, type ThinkingMode, type ToolCallRecord, type ToolChoice, type ToolContext, type ToolDef, type ToolHandler, type ToolOutput, type ToolResultBlock, type ToolUseBlock, addUsage, assertSinkAcceptsTaint, blocksOf, buildCatalog, chatCapabilities, clearPlatformAiCache, clearProviderCache, composeSkills, createApp, emptyUsage, entityCrudSkill, evaluate, exactMatch, extractText, extractToolUses, generateLlmsTxt, getProvider, includes, init, initFromPlatform, isAudioBlock, isDocumentBlock, isImageBlock, isTextBlock, isThinkingBlock, isToolResultBlock, isToolUseBlock, llmJudge, looksLikeKey, mintAppKey, normalizeError, odlaDbKeyResolver, persistRun, providersInCatalog, provisionAgentApp, pushAgentSchema, putSecret, queryRuns, redact, registerProvider, resolveModel, runAgent, structuredMatch, taint, toOracleTool, validateRequest };
1163
+ export { AGENT_SCHEMA, ANTHROPIC_MODELS, type AgentRun, type AgentRunBudget, type AgentRunInput, type Ai, type AudioBlock, type AudioMediaType, type AudioSource, AuthError, CancelledError, type Capabilities, CapabilityError, type Catalog, type ChatInput, type ComposedPersona, ConfigError, type ContentBlockDelta, type ContentBlockDeltaEvent, type ContentBlockStartEvent, type ContentBlockStopEvent, ContextWindowError, DEFAULT_CATALOG, DEFAULT_SECRET_NAMES, DeadlineExceededError, type DocumentBlock, type DocumentSource, type Effort, type EntityCrudSkillOptions, type EvalCase, type EvalReport, type EvalResult, type EvaluateOptions, type ExtractCall, type ExtractTool, GOOGLE_MODELS, type GradeContext, type GradeResult, type Grader, type ImageBlock, type ImageMediaType, type ImageSource, InMemoryScope, type Inference, type InitFromPlatformOptions, type InitOptions, InvalidRequestError, type JsonSchemaIssue, type JsonSchemaValidation, type KeyMap, type KeyOptions, type KeyResolver, type MemoryScope, type MessageDeltaEvent, type MessageStartEvent, type MessageStopEvent, type ModelKind, type ModelSpec, NS, OPENAI_MODELS, OdlaAIError, type OdlaDbClient, type OdlaDbKeyResolverOptions, OdlaDbMemory, type OdlaDbMemoryOptions, type OdlaEntityRef, type OdlaLookup, type OdlaOp, type OdlaQuery, type OdlaScalar, type OracleContentBlock, type OracleErrorEvent, type OracleErrorShape, type OracleErrorType, type OracleEvent, type OracleMessage, type OracleRequest, type OracleResponse, type OracleRole, type OracleStopReason, type OracleTool, type OracleUsage, type PersistRunOptions, type Persona, type PlatformAi, type Provider, ProviderError, type ProviderFactory, type ProviderId, type ProvisionAgentAppOptions, type ProvisionContext, type ProvisionedApp, type QueryRunsOptions, RateLimitError, type ResponseFormat, type SearchCall, type Skill, type StoppedReason, TaintError, type TaintLabel, type TaintSet, type TextBlock, type ThinkingBlock, type ThinkingMode, type ToolCallRecord, type ToolChoice, type ToolContext, type ToolDef, type ToolHandler, ToolInputError, type ToolOutput, type ToolResultBlock, type ToolUseBlock, addUsage, assertSinkAcceptsTaint, blocksOf, buildCatalog, chatCapabilities, clearPlatformAiCache, clearProviderCache, composeSkills, createApp, emptyUsage, entityCrudSkill, evaluate, exactMatch, extractText, extractToolUses, generateLlmsTxt, getProvider, includes, init, initFromPlatform, isAudioBlock, isDocumentBlock, isImageBlock, isTextBlock, isThinkingBlock, isToolResultBlock, isToolUseBlock, llmJudge, looksLikeKey, mintAppKey, normalizeError, odlaDbKeyResolver, persistRun, providersInCatalog, provisionAgentApp, pushAgentSchema, putSecret, queryRuns, redact, registerProvider, resolveModel, runAgent, structuredMatch, taint, toOracleTool, validateJsonSchema, validateRequest };
package/dist/index.d.ts CHANGED
@@ -90,6 +90,7 @@ interface OracleUsage {
90
90
  cacheCreationTokens?: number;
91
91
  cacheReadTokens?: number;
92
92
  }
93
+ /** A fresh zeroed usage tally (0 input/output tokens, no cache fields) — the seed for accumulation. */
93
94
  declare function emptyUsage(): OracleUsage;
94
95
  /** Accumulate `more` into `into`, in place. Cache fields sum when present. */
95
96
  declare function addUsage(into: OracleUsage, more: OracleUsage): void;
@@ -140,6 +141,12 @@ interface OracleRequest {
140
141
  /** Provider-specific escape hatch, passed through opaquely. Using it gives up
141
142
  * portability across providers. */
142
143
  providerExtras?: Record<string, unknown>;
144
+ /** Cancel the provider request. Adapters pass this to the vendor SDK rather
145
+ * than limiting cancellation to local tool handlers. */
146
+ signal?: AbortSignal;
147
+ /** Absolute Unix timestamp in milliseconds. The SDK combines this deadline
148
+ * with `signal`; whichever fires first cancels the provider request. */
149
+ deadline?: number;
143
150
  }
144
151
  type OracleStopReason = "end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | "pause_turn" | "refusal" | "error";
145
152
  interface OracleResponse {
@@ -155,7 +162,7 @@ interface OracleResponse {
155
162
 
156
163
  /** The closed taxonomy of normalized error codes carried by every OdlaAIError
157
164
  * and by the streaming `error` event. */
158
- type OracleErrorType = "invalid_request" | "auth" | "rate_limit" | "context_window" | "tool_input_invalid" | "capability_unsupported" | "config" | "provider_error";
165
+ type OracleErrorType = "invalid_request" | "auth" | "rate_limit" | "context_window" | "cancelled" | "deadline_exceeded" | "tool_input_invalid" | "capability_unsupported" | "config" | "provider_error";
159
166
  /** The plain-data error shape used inside the streaming `error` event. */
160
167
  interface OracleErrorShape {
161
168
  code: OracleErrorType;
@@ -219,6 +226,29 @@ declare class InvalidRequestError extends OdlaAIError {
219
226
  cause?: unknown;
220
227
  });
221
228
  }
229
+ /** A provider returned tool arguments that are malformed or do not satisfy the
230
+ * declared JSON Schema. Tool handlers are never invoked for this error. */
231
+ declare class ToolInputError extends OdlaAIError {
232
+ readonly tool?: string;
233
+ constructor(message: string, opts?: {
234
+ tool?: string;
235
+ cause?: unknown;
236
+ });
237
+ }
238
+ /** The caller cancelled a request. This is not an upstream failure and should
239
+ * not be retried unless the caller explicitly starts a new operation. */
240
+ declare class CancelledError extends OdlaAIError {
241
+ constructor(message?: string, opts?: {
242
+ cause?: unknown;
243
+ });
244
+ }
245
+ /** The request's absolute deadline elapsed. Callers may choose a new deadline,
246
+ * but should not classify this as a provider outage. */
247
+ declare class DeadlineExceededError extends OdlaAIError {
248
+ constructor(message?: string, opts?: {
249
+ cause?: unknown;
250
+ });
251
+ }
222
252
  /** Any other upstream provider failure (5xx, transport, unexpected shape). */
223
253
  declare class ProviderError extends OdlaAIError {
224
254
  constructor(message: string, opts?: {
@@ -281,12 +311,19 @@ interface OracleErrorEvent {
281
311
  error: OracleErrorShape;
282
312
  }
283
313
 
314
+ /** Type guard: narrows a content block to a `TextBlock` (`type: "text"`). */
284
315
  declare function isTextBlock(b: OracleContentBlock): b is TextBlock;
316
+ /** Type guard: narrows a content block to an `ImageBlock` (`type: "image"`). */
285
317
  declare function isImageBlock(b: OracleContentBlock): b is ImageBlock;
318
+ /** Type guard: narrows a content block to an `AudioBlock` (`type: "audio"`). */
286
319
  declare function isAudioBlock(b: OracleContentBlock): b is AudioBlock;
320
+ /** Type guard: narrows a content block to a `DocumentBlock` (`type: "document"`). */
287
321
  declare function isDocumentBlock(b: OracleContentBlock): b is DocumentBlock;
322
+ /** Type guard: narrows a content block to a `ToolUseBlock` (`type: "tool_use"`). */
288
323
  declare function isToolUseBlock(b: OracleContentBlock): b is ToolUseBlock;
324
+ /** Type guard: narrows a content block to a `ToolResultBlock` (`type: "tool_result"`). */
289
325
  declare function isToolResultBlock(b: OracleContentBlock): b is ToolResultBlock;
326
+ /** Type guard: narrows a content block to a `ThinkingBlock` (`type: "thinking"`). */
290
327
  declare function isThinkingBlock(b: OracleContentBlock): b is ThinkingBlock;
291
328
  /** Normalize a message's `content` (string shorthand or block array) to blocks. */
292
329
  declare function blocksOf(content: string | OracleContentBlock[]): OracleContentBlock[];
@@ -295,6 +332,20 @@ declare function extractText(content: OracleContentBlock[]): string;
295
332
  /** Collect every tool_use block from response or message content. */
296
333
  declare function extractToolUses(content: OracleContentBlock[]): ToolUseBlock[];
297
334
 
335
+ /** One deterministic validation failure at a JSONPath-like location. */
336
+ interface JsonSchemaIssue {
337
+ path: string;
338
+ message: string;
339
+ }
340
+ /** Complete supported-subset schema validation result; unknown keywords fail validation. */
341
+ interface JsonSchemaValidation {
342
+ valid: boolean;
343
+ issues: JsonSchemaIssue[];
344
+ }
345
+ /** Validate a JSON-compatible value against the supported JSON Schema subset.
346
+ * Unknown or unsupported keywords are validation failures, not ignored hints. */
347
+ declare function validateJsonSchema(schema: unknown, value: unknown): JsonSchemaValidation;
348
+
298
349
  /** The kind of model — chat/multimodal is the v1 focus; the others are modeled
299
350
  * so embeddings, transcription, TTS, and image generation slot in later. */
300
351
  type ModelKind = "chat" | "embed" | "transcribe" | "tts" | "image";
@@ -342,10 +393,13 @@ declare function chatCapabilities(overrides?: Partial<Capabilities>): Capabiliti
342
393
  */
343
394
  declare function validateRequest(spec: ModelSpec, req: OracleRequest): void;
344
395
 
396
+ /** Built-in Anthropic (Claude) catalog: one `ModelSpec` per model (canonical id, native id, capabilities, limits). */
345
397
  declare const ANTHROPIC_MODELS: ModelSpec[];
346
398
 
399
+ /** Built-in OpenAI catalog: one `ModelSpec` per model (canonical id == native id, capabilities, context window). */
347
400
  declare const OPENAI_MODELS: ModelSpec[];
348
401
 
402
+ /** Built-in Google (Gemini) catalog: one `ModelSpec` per model (canonical id == native id, capabilities, context window). */
349
403
  declare const GOOGLE_MODELS: ModelSpec[];
350
404
 
351
405
  /** Canonical id → spec. */
@@ -417,6 +471,8 @@ interface ExtractCall {
417
471
  user: string | OracleContentBlock[];
418
472
  tool: ExtractTool;
419
473
  maxTokens?: number;
474
+ signal?: AbortSignal;
475
+ deadline?: number;
420
476
  }
421
477
  /** A web-search-enabled call: the model searches and returns prose. */
422
478
  interface SearchCall {
@@ -424,6 +480,8 @@ interface SearchCall {
424
480
  system?: string | TextBlock[];
425
481
  user: string | OracleContentBlock[];
426
482
  maxTokens?: number;
483
+ signal?: AbortSignal;
484
+ deadline?: number;
427
485
  }
428
486
  interface Ai {
429
487
  /** The active model catalog. */
@@ -445,11 +503,23 @@ interface Ai {
445
503
  }
446
504
  /** The minimal inference surface the agent loop and eval harness depend on. */
447
505
  type Inference = Pick<Ai, "chat" | "stream" | "catalog">;
506
+ /**
507
+ * Build the `Ai` facade (bring-your-own-keys). Resolves a canonical model id to
508
+ * its provider, supplies keys statically (`keys`) or dynamically (`resolveKey`),
509
+ * validates each request against the model's capabilities, and exposes
510
+ * `chat`/`stream`/`extract`/`search` plus the active `catalog`. Only the SDK of a
511
+ * provider you actually call is loaded (via the lazy provider registry).
512
+ */
448
513
  declare function init(opts?: InitOptions): Ai;
449
514
 
450
515
  /** Generate the `llms.txt` context document for a given model catalog. */
451
516
  declare function generateLlmsTxt(catalog?: Catalog): string;
452
517
 
518
+ /**
519
+ * Resolve the adapter for a provider, lazy-`import()`ing its module (and only
520
+ * that provider's SDK) on first use and caching the instance per (provider, key)
521
+ * so repeated calls reuse one SDK client.
522
+ */
453
523
  declare function getProvider(id: ProviderId, apiKey: string): Promise<Provider>;
454
524
  /** Test seam: register a provider instance directly (used to inject mocks). */
455
525
  declare function registerProvider(id: ProviderId, apiKey: string, provider: Provider): void;
@@ -458,10 +528,11 @@ declare function clearProviderCache(): void;
458
528
 
459
529
  /** Map any provider error to an OdlaAIError, returning it (does not throw).
460
530
  * Re-returns an OdlaAIError unchanged (already normalized). */
461
- declare function normalizeError(err: unknown, provider: ProviderId): OdlaAIError;
531
+ declare function normalizeError(err: unknown, provider: ProviderId, signal?: AbortSignal): OdlaAIError;
462
532
 
463
533
  type TaintLabel = "web_untrusted" | "operator_pasted_untrusted" | "llm_inherited" | `tool_untrusted:${string}`;
464
534
  type TaintSet = Set<TaintLabel>;
535
+ /** Build a `TaintSet` from labels — the CaMeL-style taint carried through a run and checked against each tool's allowlist. */
465
536
  declare function taint(...labels: TaintLabel[]): TaintSet;
466
537
  /** Raised when a tool's taint allowlist doesn't cover the conversation's taint. */
467
538
  declare class TaintError extends OdlaAIError {
@@ -572,8 +643,20 @@ interface AgentRunInput {
572
643
  /** Or an explicit list of messages (takes precedence when both are given). */
573
644
  messages?: OracleMessage[];
574
645
  signal?: AbortSignal;
575
- }
576
- type StoppedReason = "end_turn" | "max_steps" | "refusal";
646
+ /** Absolute Unix timestamp in milliseconds for model requests and tools. */
647
+ deadline?: number;
648
+ /** Run-wide limits. Token limits are evaluated after each provider response;
649
+ * output allowance also caps the next request's maxTokens. */
650
+ budget?: AgentRunBudget;
651
+ }
652
+ /** Run-wide limits: tool calls stop before effects; token usage stops later turns after provider reporting. */
653
+ interface AgentRunBudget {
654
+ maxInputTokens?: number;
655
+ maxOutputTokens?: number;
656
+ maxTotalTokens?: number;
657
+ maxToolCalls?: number;
658
+ }
659
+ type StoppedReason = "end_turn" | "max_steps" | "refusal" | "budget_exhausted";
577
660
  interface AgentRun {
578
661
  /** Concatenated text of the final assistant turn. */
579
662
  finalText: string;
@@ -589,6 +672,14 @@ interface AgentRun {
589
672
  toolCalls: ToolCallRecord[];
590
673
  stoppedReason: StoppedReason;
591
674
  }
675
+ /**
676
+ * Run the tool-use agent loop: model turn → execute requested tools → model turn,
677
+ * until the model stops asking for tools (`end_turn`), refuses (`refusal`), or
678
+ * `persona.maxSteps` (default 8) is hit (`max_steps`). Composes the persona's
679
+ * skills into its tools/system prompt, enforces per-tool taint allowlists, and
680
+ * loads/appends `persona.memory` when set. Returns `{ finalText, response,
681
+ * messages, usage, steps, toolCalls, stoppedReason }`.
682
+ */
592
683
  declare function runAgent(inference: Inference, persona: Persona, input: AgentRunInput): Promise<AgentRun>;
593
684
 
594
685
  /** One evaluation case — an input plus whatever the grader needs to judge it. */
@@ -643,6 +734,12 @@ interface EvaluateOptions {
643
734
  /** Max cases run concurrently (default 5). */
644
735
  concurrency?: number;
645
736
  }
737
+ /**
738
+ * Eval harness: run each case through a `persona` (agent loop) or a plain `model`
739
+ * chat, grade it with `grader`, and return an `EvalReport` (per-case results,
740
+ * pass/fail counts, passRate, summed usage). Cases run concurrently up to
741
+ * `concurrency` (default 5); throws if neither `persona` nor `model` is given.
742
+ */
646
743
  declare function evaluate(opts: EvaluateOptions): Promise<EvalReport>;
647
744
 
648
745
  /** Pass when trimmed output equals `case.expected` (stringified). */
@@ -888,6 +985,12 @@ interface OdlaDbMemoryOptions {
888
985
  conversation?: string;
889
986
  };
890
987
  }
988
+ /**
989
+ * A `MemoryScope` backed by odla-db. `load()` replays a session's prior turns
990
+ * (ordered by `seq`); `append()` upserts new turns by natural key under a
991
+ * deterministic `mutationId`, so a retried run never duplicates. Takes an
992
+ * injected odla-db client — odla-ai keeps zero runtime dependency on @odla-ai/db.
993
+ */
891
994
  declare class OdlaDbMemory implements MemoryScope {
892
995
  private readonly db;
893
996
  private readonly sessionId;
@@ -928,6 +1031,12 @@ interface OdlaDbKeyResolverOptions {
928
1031
  secretName?: (provider: ProviderId) => string;
929
1032
  /** Cache resolved keys in memory (default true). */
930
1033
  cache?: boolean;
1034
+ /** Maximum age for a cached secret (default 60 seconds; 0 disables caching).
1035
+ * This bounds provider-key rotation propagation in warm isolates. */
1036
+ ttlMs?: number;
1037
+ /** Version included in the cache key. Change it to invalidate a known key
1038
+ * generation immediately without waiting for the TTL. */
1039
+ cacheVersion?: string | ((provider: ProviderId) => string);
931
1040
  }
932
1041
  /** Build a KeyResolver that reads provider keys from odla-db secrets. A missing
933
1042
  * secret resolves to `undefined` (→ that provider is simply unavailable, and
@@ -951,6 +1060,8 @@ interface InitFromPlatformOptions {
951
1060
  * owned by this helper; `defaultModel` is used only when the platform
952
1061
  * config sets no model. */
953
1062
  initOptions?: Omit<InitOptions, "resolveKey">;
1063
+ /** Secret resolver cache controls. Defaults to a finite 60-second TTL. */
1064
+ keyResolverOptions?: OdlaDbKeyResolverOptions;
954
1065
  }
955
1066
  interface PlatformAi {
956
1067
  ai: Ai;
@@ -960,15 +1071,14 @@ interface PlatformAi {
960
1071
  /** Drop all cached platform configs (tests, or to force an immediate refetch). */
961
1072
  declare function clearPlatformAiCache(): void;
962
1073
  /** Build an `Ai` from the app's platform registration: provider/model from
963
- * public-config (cached ~60s), API key from the tenant's odla-db secrets at
964
- * call time. On cache refresh the existing `Ai` (and its warm key-resolver
965
- * cache) is reused unless provider/model changed. Note the first call's
966
- * `db`/`initOptions` are captured for the cache entry's lifetime. */
1074
+ * public-config (cached ~60s), API key from the supplied tenant's odla-db
1075
+ * secrets at call time. Only public config is shared globally; every call
1076
+ * builds a facade bound to its own `db` and init options. */
967
1077
  declare function initFromPlatform(opts: InitFromPlatformOptions): Promise<PlatformAi>;
968
1078
 
969
1079
  type FetchLike = typeof fetch;
970
1080
  interface ProvisionContext {
971
- /** The odla-db worker URL always human-supplied, never hardcoded. */
1081
+ /** Platform origin exposing the proxied db operator routes, normally https://odla.ai. */
972
1082
  endpoint: string;
973
1083
  /** Operator `ADMIN_SECRET` or an `odla_dev_...` developer token (owns the app). */
974
1084
  token: string;
@@ -1050,4 +1160,4 @@ interface EntityCrudSkillOptions {
1050
1160
  /** Build a CRUD Skill for one odla-db entity. */
1051
1161
  declare function entityCrudSkill(opts: EntityCrudSkillOptions): Skill;
1052
1162
 
1053
- export { AGENT_SCHEMA, ANTHROPIC_MODELS, type AgentRun, type AgentRunInput, type Ai, type AudioBlock, type AudioMediaType, type AudioSource, AuthError, type Capabilities, CapabilityError, type Catalog, type ChatInput, type ComposedPersona, ConfigError, type ContentBlockDelta, type ContentBlockDeltaEvent, type ContentBlockStartEvent, type ContentBlockStopEvent, ContextWindowError, DEFAULT_CATALOG, DEFAULT_SECRET_NAMES, type DocumentBlock, type DocumentSource, type Effort, type EntityCrudSkillOptions, type EvalCase, type EvalReport, type EvalResult, type EvaluateOptions, type ExtractCall, type ExtractTool, GOOGLE_MODELS, type GradeContext, type GradeResult, type Grader, type ImageBlock, type ImageMediaType, type ImageSource, InMemoryScope, type Inference, type InitFromPlatformOptions, type InitOptions, InvalidRequestError, type KeyMap, type KeyOptions, type KeyResolver, type MemoryScope, type MessageDeltaEvent, type MessageStartEvent, type MessageStopEvent, type ModelKind, type ModelSpec, NS, OPENAI_MODELS, OdlaAIError, type OdlaDbClient, type OdlaDbKeyResolverOptions, OdlaDbMemory, type OdlaDbMemoryOptions, type OdlaEntityRef, type OdlaLookup, type OdlaOp, type OdlaQuery, type OdlaScalar, type OracleContentBlock, type OracleErrorEvent, type OracleErrorShape, type OracleErrorType, type OracleEvent, type OracleMessage, type OracleRequest, type OracleResponse, type OracleRole, type OracleStopReason, type OracleTool, type OracleUsage, type PersistRunOptions, type Persona, type PlatformAi, type Provider, ProviderError, type ProviderFactory, type ProviderId, type ProvisionAgentAppOptions, type ProvisionContext, type ProvisionedApp, type QueryRunsOptions, RateLimitError, type ResponseFormat, type SearchCall, type Skill, type StoppedReason, TaintError, type TaintLabel, type TaintSet, type TextBlock, type ThinkingBlock, type ThinkingMode, type ToolCallRecord, type ToolChoice, type ToolContext, type ToolDef, type ToolHandler, type ToolOutput, type ToolResultBlock, type ToolUseBlock, addUsage, assertSinkAcceptsTaint, blocksOf, buildCatalog, chatCapabilities, clearPlatformAiCache, clearProviderCache, composeSkills, createApp, emptyUsage, entityCrudSkill, evaluate, exactMatch, extractText, extractToolUses, generateLlmsTxt, getProvider, includes, init, initFromPlatform, isAudioBlock, isDocumentBlock, isImageBlock, isTextBlock, isThinkingBlock, isToolResultBlock, isToolUseBlock, llmJudge, looksLikeKey, mintAppKey, normalizeError, odlaDbKeyResolver, persistRun, providersInCatalog, provisionAgentApp, pushAgentSchema, putSecret, queryRuns, redact, registerProvider, resolveModel, runAgent, structuredMatch, taint, toOracleTool, validateRequest };
1163
+ export { AGENT_SCHEMA, ANTHROPIC_MODELS, type AgentRun, type AgentRunBudget, type AgentRunInput, type Ai, type AudioBlock, type AudioMediaType, type AudioSource, AuthError, CancelledError, type Capabilities, CapabilityError, type Catalog, type ChatInput, type ComposedPersona, ConfigError, type ContentBlockDelta, type ContentBlockDeltaEvent, type ContentBlockStartEvent, type ContentBlockStopEvent, ContextWindowError, DEFAULT_CATALOG, DEFAULT_SECRET_NAMES, DeadlineExceededError, type DocumentBlock, type DocumentSource, type Effort, type EntityCrudSkillOptions, type EvalCase, type EvalReport, type EvalResult, type EvaluateOptions, type ExtractCall, type ExtractTool, GOOGLE_MODELS, type GradeContext, type GradeResult, type Grader, type ImageBlock, type ImageMediaType, type ImageSource, InMemoryScope, type Inference, type InitFromPlatformOptions, type InitOptions, InvalidRequestError, type JsonSchemaIssue, type JsonSchemaValidation, type KeyMap, type KeyOptions, type KeyResolver, type MemoryScope, type MessageDeltaEvent, type MessageStartEvent, type MessageStopEvent, type ModelKind, type ModelSpec, NS, OPENAI_MODELS, OdlaAIError, type OdlaDbClient, type OdlaDbKeyResolverOptions, OdlaDbMemory, type OdlaDbMemoryOptions, type OdlaEntityRef, type OdlaLookup, type OdlaOp, type OdlaQuery, type OdlaScalar, type OracleContentBlock, type OracleErrorEvent, type OracleErrorShape, type OracleErrorType, type OracleEvent, type OracleMessage, type OracleRequest, type OracleResponse, type OracleRole, type OracleStopReason, type OracleTool, type OracleUsage, type PersistRunOptions, type Persona, type PlatformAi, type Provider, ProviderError, type ProviderFactory, type ProviderId, type ProvisionAgentAppOptions, type ProvisionContext, type ProvisionedApp, type QueryRunsOptions, RateLimitError, type ResponseFormat, type SearchCall, type Skill, type StoppedReason, TaintError, type TaintLabel, type TaintSet, type TextBlock, type ThinkingBlock, type ThinkingMode, type ToolCallRecord, type ToolChoice, type ToolContext, type ToolDef, type ToolHandler, ToolInputError, type ToolOutput, type ToolResultBlock, type ToolUseBlock, addUsage, assertSinkAcceptsTaint, blocksOf, buildCatalog, chatCapabilities, clearPlatformAiCache, clearProviderCache, composeSkills, createApp, emptyUsage, entityCrudSkill, evaluate, exactMatch, extractText, extractToolUses, generateLlmsTxt, getProvider, includes, init, initFromPlatform, isAudioBlock, isDocumentBlock, isImageBlock, isTextBlock, isThinkingBlock, isToolResultBlock, isToolUseBlock, llmJudge, looksLikeKey, mintAppKey, normalizeError, odlaDbKeyResolver, persistRun, providersInCatalog, provisionAgentApp, pushAgentSchema, putSecret, queryRuns, redact, registerProvider, resolveModel, runAgent, structuredMatch, taint, toOracleTool, validateJsonSchema, validateRequest };