@odla-ai/ai 0.1.4 → 0.2.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
@@ -924,6 +924,38 @@ interface OdlaDbKeyResolverOptions {
924
924
  * odla-ai throws its own ConfigError) rather than surfacing odla-db's 404. */
925
925
  declare function odlaDbKeyResolver(db: OdlaDbClient, opts?: OdlaDbKeyResolverOptions): KeyResolver;
926
926
 
927
+ interface InitFromPlatformOptions {
928
+ /** Platform base URL (e.g. "https://odla.ai"). */
929
+ platform: string;
930
+ /** The REGISTRY app id — not the env's tenant id. */
931
+ appId: string;
932
+ /** Which environment's config to use ("dev", "prod", …). */
933
+ env: string;
934
+ /** The app's own tenant client — key reads go through `db.secrets.get`. */
935
+ db: OdlaDbClient;
936
+ /** Transport override (tests / non-global fetch). */
937
+ fetch?: typeof fetch;
938
+ /** public-config cache TTL in ms (default 60s; 0 disables caching). */
939
+ ttlMs?: number;
940
+ /** Extra init() options (catalog, injected providers, …). `resolveKey` is
941
+ * owned by this helper; `defaultModel` is used only when the platform
942
+ * config sets no model. */
943
+ initOptions?: Omit<InitOptions, "resolveKey">;
944
+ }
945
+ interface PlatformAi {
946
+ ai: Ai;
947
+ provider: ProviderId;
948
+ model?: string;
949
+ }
950
+ /** Drop all cached platform configs (tests, or to force an immediate refetch). */
951
+ declare function clearPlatformAiCache(): void;
952
+ /** Build an `Ai` from the app's platform registration: provider/model from
953
+ * public-config (cached ~60s), API key from the tenant's odla-db secrets at
954
+ * call time. On cache refresh the existing `Ai` (and its warm key-resolver
955
+ * cache) is reused unless provider/model changed. Note the first call's
956
+ * `db`/`initOptions` are captured for the cache entry's lifetime. */
957
+ declare function initFromPlatform(opts: InitFromPlatformOptions): Promise<PlatformAi>;
958
+
927
959
  type FetchLike = typeof fetch;
928
960
  interface ProvisionContext {
929
961
  /** The odla-db worker URL — always human-supplied, never hardcoded. */
@@ -1008,4 +1040,4 @@ interface EntityCrudSkillOptions {
1008
1040
  /** Build a CRUD Skill for one odla-db entity. */
1009
1041
  declare function entityCrudSkill(opts: EntityCrudSkillOptions): Skill;
1010
1042
 
1011
- 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 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 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, clearProviderCache, composeSkills, createApp, emptyUsage, entityCrudSkill, evaluate, exactMatch, extractText, extractToolUses, generateLlmsTxt, getProvider, includes, init, 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 };
1043
+ 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 };
package/dist/index.d.ts CHANGED
@@ -924,6 +924,38 @@ interface OdlaDbKeyResolverOptions {
924
924
  * odla-ai throws its own ConfigError) rather than surfacing odla-db's 404. */
925
925
  declare function odlaDbKeyResolver(db: OdlaDbClient, opts?: OdlaDbKeyResolverOptions): KeyResolver;
926
926
 
927
+ interface InitFromPlatformOptions {
928
+ /** Platform base URL (e.g. "https://odla.ai"). */
929
+ platform: string;
930
+ /** The REGISTRY app id — not the env's tenant id. */
931
+ appId: string;
932
+ /** Which environment's config to use ("dev", "prod", …). */
933
+ env: string;
934
+ /** The app's own tenant client — key reads go through `db.secrets.get`. */
935
+ db: OdlaDbClient;
936
+ /** Transport override (tests / non-global fetch). */
937
+ fetch?: typeof fetch;
938
+ /** public-config cache TTL in ms (default 60s; 0 disables caching). */
939
+ ttlMs?: number;
940
+ /** Extra init() options (catalog, injected providers, …). `resolveKey` is
941
+ * owned by this helper; `defaultModel` is used only when the platform
942
+ * config sets no model. */
943
+ initOptions?: Omit<InitOptions, "resolveKey">;
944
+ }
945
+ interface PlatformAi {
946
+ ai: Ai;
947
+ provider: ProviderId;
948
+ model?: string;
949
+ }
950
+ /** Drop all cached platform configs (tests, or to force an immediate refetch). */
951
+ declare function clearPlatformAiCache(): void;
952
+ /** Build an `Ai` from the app's platform registration: provider/model from
953
+ * public-config (cached ~60s), API key from the tenant's odla-db secrets at
954
+ * call time. On cache refresh the existing `Ai` (and its warm key-resolver
955
+ * cache) is reused unless provider/model changed. Note the first call's
956
+ * `db`/`initOptions` are captured for the cache entry's lifetime. */
957
+ declare function initFromPlatform(opts: InitFromPlatformOptions): Promise<PlatformAi>;
958
+
927
959
  type FetchLike = typeof fetch;
928
960
  interface ProvisionContext {
929
961
  /** The odla-db worker URL — always human-supplied, never hardcoded. */
@@ -1008,4 +1040,4 @@ interface EntityCrudSkillOptions {
1008
1040
  /** Build a CRUD Skill for one odla-db entity. */
1009
1041
  declare function entityCrudSkill(opts: EntityCrudSkillOptions): Skill;
1010
1042
 
1011
- 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 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 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, clearProviderCache, composeSkills, createApp, emptyUsage, entityCrudSkill, evaluate, exactMatch, extractText, extractToolUses, generateLlmsTxt, getProvider, includes, init, 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 };
1043
+ 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 };
package/dist/index.js CHANGED
@@ -472,6 +472,27 @@ Secrets are read-only from the app key (odlaDbKeyResolver \u2192 db.secrets.get)
472
472
  are WRITTEN only with the operator/dev token via provisionAgentApp/putSecret. Keys
473
473
  are AES-GCM-encrypted at rest in odla-db and never returned to browser clients.
474
474
 
475
+ ## Platform wiring (odla.ai apps registry)
476
+
477
+ Apps registered on the odla platform get LLM access as an APP SETTING \u2014
478
+ never put provider keys in your Worker's wrangler vars/secrets. Provider +
479
+ default model are per-environment registry config (set in Studio's AI card
480
+ or \`@odla-ai/apps\` setAi); the API key lives in the platform vault (the
481
+ env's odla-db tenant secrets, write-only for operators). One call reads both:
482
+
483
+ import { initFromPlatform } from "@odla-ai/ai";
484
+ import { init as odlaInit } from "@odla-ai/db";
485
+
486
+ const db = odlaInit({ appId: TENANT, adminToken: env.ODLA_API_KEY, endpoint: "https://db.odla.ai" });
487
+ const { ai, provider, model } = await initFromPlatform({
488
+ platform: "https://odla.ai", appId: APP_ID, env: "prod", db });
489
+ // ai.chat / ai.stream / ai.extract \u2014 provider/model from public-config
490
+ // (cached ~60s, so Studio changes apply without redeploys); the key is
491
+ // fetched from the vault at call time via odlaDbKeyResolver.
492
+
493
+ The only secret the Worker carries is its odla-db app key. Rotating the LLM
494
+ key = writing the secret again; switching provider/model = a Studio edit.
495
+
475
496
  ## Errors
476
497
 
477
498
  Every error is an OdlaAIError subclass with a stable \`code\` \u2014 branch on err.code:
@@ -899,15 +920,15 @@ var DEFAULT_SECRET_NAMES = {
899
920
  function odlaDbKeyResolver(db, opts = {}) {
900
921
  const nameFor = opts.secretName ?? ((p) => DEFAULT_SECRET_NAMES[p]);
901
922
  const useCache = opts.cache ?? true;
902
- const cache2 = /* @__PURE__ */ new Map();
923
+ const cache3 = /* @__PURE__ */ new Map();
903
924
  return async (provider) => {
904
925
  if (useCache) {
905
- const hit = cache2.get(provider);
926
+ const hit = cache3.get(provider);
906
927
  if (hit !== void 0) return hit;
907
928
  }
908
929
  try {
909
930
  const key = await db.secrets.get(nameFor(provider));
910
- if (useCache) cache2.set(provider, key);
931
+ if (useCache) cache3.set(provider, key);
911
932
  return key;
912
933
  } catch {
913
934
  return void 0;
@@ -915,6 +936,51 @@ function odlaDbKeyResolver(db, opts = {}) {
915
936
  };
916
937
  }
917
938
 
939
+ // src/store/platform.ts
940
+ var cache2 = /* @__PURE__ */ new Map();
941
+ function clearPlatformAiCache() {
942
+ cache2.clear();
943
+ }
944
+ async function fetchAiConfig(opts) {
945
+ const doFetch = opts.fetch ?? fetch;
946
+ const base = opts.platform.replace(/\/$/, "");
947
+ const url = `${base}/registry/apps/${encodeURIComponent(opts.appId)}/public-config?env=${encodeURIComponent(opts.env)}`;
948
+ const res = await doFetch(url);
949
+ if (!res.ok) throw new ProviderError(`platform public-config fetch failed: ${res.status} for ${opts.appId}/${opts.env}`);
950
+ const cfg = await res.json();
951
+ const ai = cfg.ai;
952
+ if (!ai || typeof ai.provider !== "string") {
953
+ throw new ConfigError(
954
+ `ai service is not enabled/configured for "${opts.appId}" (${opts.env}) \u2014 enable it in Studio or via @odla-ai/apps setAi(appId, env, { provider }).`
955
+ );
956
+ }
957
+ if (!(ai.provider in DEFAULT_SECRET_NAMES)) {
958
+ throw new ConfigError(`platform ai config names unknown provider "${ai.provider}" for "${opts.appId}" (${opts.env}).`);
959
+ }
960
+ const model = typeof ai.model === "string" && ai.model ? ai.model : void 0;
961
+ return { provider: ai.provider, ...model ? { model } : {} };
962
+ }
963
+ async function initFromPlatform(opts) {
964
+ const ttl = opts.ttlMs ?? 6e4;
965
+ const key = `${opts.platform}|${opts.appId}|${opts.env}`;
966
+ const now = Date.now();
967
+ const hit = ttl > 0 ? cache2.get(key) : void 0;
968
+ if (hit && hit.expiresAt > now) return hit.value;
969
+ const { provider, model } = await fetchAiConfig(opts);
970
+ if (hit && hit.value.provider === provider && hit.value.model === model) {
971
+ hit.expiresAt = now + ttl;
972
+ return hit.value;
973
+ }
974
+ const ai = init({
975
+ ...opts.initOptions,
976
+ resolveKey: odlaDbKeyResolver(opts.db),
977
+ defaultModel: model ?? opts.initOptions?.defaultModel
978
+ });
979
+ const value = { ai, provider, ...model ? { model } : {} };
980
+ if (ttl > 0) cache2.set(key, { value, expiresAt: now + ttl });
981
+ return value;
982
+ }
983
+
918
984
  // src/store/provision.ts
919
985
  async function post(ctx, path, body) {
920
986
  const f = ctx.fetch ?? fetch;
@@ -1124,6 +1190,7 @@ export {
1124
1190
  blocksOf,
1125
1191
  buildCatalog,
1126
1192
  chatCapabilities,
1193
+ clearPlatformAiCache,
1127
1194
  clearProviderCache,
1128
1195
  composeSkills,
1129
1196
  createApp,
@@ -1137,6 +1204,7 @@ export {
1137
1204
  getProvider,
1138
1205
  includes,
1139
1206
  init,
1207
+ initFromPlatform,
1140
1208
  isAudioBlock,
1141
1209
  isDocumentBlock,
1142
1210
  isImageBlock,