{"version":3,"file":"retrievable.mjs","names":[],"sources":["../../../src/batteries/vector/retrievable_glue.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/retrievable\n */\n\nimport { Retrievable } from '@nhtio/adk'\nimport type { VectorFilter } from './filters'\nimport type { CallableVectorStore } from './contract'\nimport type { VectorMatch, VectorMetadata } from './types'\nimport type { RawRetrievable, RetrievableTrustTier } from '@nhtio/adk/common'\nimport type {\n  TurnContext,\n  RetrievableRetrievalFn,\n  RetrievableStoreFn,\n  RetrievableMutateFn,\n  RetrievableDeleteFn,\n} from '@nhtio/adk'\n\n/** Configuration for wiring a vector store to the ADK's retrievable lifecycle callbacks. */\nexport interface VectorRetrievableGlueOptions {\n  /** The callable vector store the callbacks query and write to. */\n  store: CallableVectorStore\n  /** Collection the retrievables live in. */\n  collection: string\n  /** Trust tier for fetched matches — a fixed tier, or a per-match function. */\n  trustTier: RetrievableTrustTier | ((m: VectorMatch) => RetrievableTrustTier)\n  /** Maximum number of retrievables to fetch per turn (default 5). */\n  topK?: number\n  /** Optional filter applied to every retrieval query. */\n  filter?: VectorFilter\n  /** Derives the retrieval query from the turn context; defaults to the last user message. */\n  deriveQuery?: (\n    ctx: TurnContext\n  ) => string | number[] | undefined | Promise<string | number[] | undefined>\n  /** Maps a {@link VectorMatch} to a raw retrievable (trust tier applied separately). */\n  toRetrievable?: (m: VectorMatch) => Omit<RawRetrievable, 'trustTier'>\n}\n\n/** The four retrievable-lifecycle callbacks produced by {@link createVectorRetrievableCallbacks}. */\nexport interface VectorRetrievableCallbacks {\n  /** Fetches retrievables relevant to the current turn. */\n  fetchRetrievablesCallback: RetrievableRetrievalFn\n  /** Persists a new retrievable into the store. */\n  storeRetrievableCallback: RetrievableStoreFn\n  /** Replaces an existing retrievable (upsert). */\n  mutateRetrievableCallback: RetrievableMutateFn\n  /** Deletes a retrievable by id. */\n  deleteRetrievableCallback: RetrievableDeleteFn\n}\n\n/**\n * Build the retrievable-lifecycle callbacks (fetch/store/mutate/delete) that bridge a callable\n * vector store to the ADK's retrievable subsystem, applying the supplied query derivation,\n * match-to-retrievable mapping, and trust-tier assignment.\n *\n * @param opts - The store, collection, and behaviour overrides.\n * @returns The four wired {@link VectorRetrievableCallbacks}.\n */\nexport const createVectorRetrievableCallbacks = (\n  opts: VectorRetrievableGlueOptions\n): VectorRetrievableCallbacks => {\n  const topK = opts.topK ?? 5\n  const tierFor = (m: VectorMatch): RetrievableTrustTier =>\n    typeof opts.trustTier === 'function' ? opts.trustTier(m) : opts.trustTier\n\n  // default deriveQuery: last user message text, else undefined\n  const deriveQuery =\n    opts.deriveQuery ??\n    (async (ctx: TurnContext) => {\n      const msgs = await ctx.fetchMessages()\n      for (let i = msgs.length - 1; i >= 0; i--) {\n        if (msgs[i].role === 'user') return msgs[i].content?.toString() ?? ''\n      }\n      return undefined\n    })\n\n  // default mapping VectorMatch -> RawRetrievable (minus trustTier)\n  const toRetrievable =\n    opts.toRetrievable ??\n    ((m: VectorMatch): Omit<RawRetrievable, 'trustTier'> => {\n      const md = (m.metadata ?? {}) as Record<string, unknown>\n      const now = new Date()\n      return {\n        id: m.id ?? String(md.id ?? ''),\n        content: m.document ?? String(md.content ?? ''),\n        source: typeof md.source === 'string' ? md.source : undefined,\n        kind: typeof md.kind === 'string' ? md.kind : undefined,\n        score: typeof m.score === 'number' ? m.score : undefined,\n        createdAt: (md.createdAt as any) ?? now,\n        updatedAt: (md.updatedAt as any) ?? now,\n      }\n    })\n\n  const fetchRetrievablesCallback: RetrievableRetrievalFn = async (ctx) => {\n    const q = await deriveQuery(ctx)\n    if (q === undefined) return []\n    let b = opts.store(opts.collection)\n    b = Array.isArray(q) ? b.nearVector(q) : b.nearText(q)\n    if (opts.filter) b = b.whereRaw(opts.filter as any)\n    const matches = await b.select('id', 'document', 'metadata').limit(topK)\n    return matches.map((m) => new Retrievable({ ...toRetrievable(m), trustTier: tierFor(m) }))\n  }\n\n  const storeRetrievableCallback: RetrievableStoreFn = async (_ctx, r) => {\n    const content = await r.contentString()\n    const metadata: VectorMetadata = {\n      trustTier: r.trustTier,\n      createdAt: r.createdAt?.toISO?.() ?? String(r.createdAt),\n      updatedAt: r.updatedAt?.toISO?.() ?? String(r.updatedAt),\n    }\n    if (r.source !== undefined) metadata.source = r.source\n    if (r.kind !== undefined) metadata.kind = r.kind\n    await opts.store(opts.collection).upsert([{ id: r.id, document: content, metadata }])\n  }\n  const mutateRetrievableCallback: RetrievableMutateFn = storeRetrievableCallback // upsert == replace\n  const deleteRetrievableCallback: RetrievableDeleteFn = async (_ctx, id) => {\n    await opts.store(opts.collection).whereIn('id', [id]).delete()\n  }\n\n  return {\n    fetchRetrievablesCallback,\n    storeRetrievableCallback,\n    mutateRetrievableCallback,\n    deleteRetrievableCallback,\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;AAyDA,IAAa,oCACX,SAC+B;CAC/B,MAAM,OAAO,KAAK,QAAQ;CAC1B,MAAM,WAAW,MACf,OAAO,KAAK,cAAc,aAAa,KAAK,UAAU,CAAC,IAAI,KAAK;CAGlE,MAAM,cACJ,KAAK,gBACJ,OAAO,QAAqB;EAC3B,MAAM,OAAO,MAAM,IAAI,cAAc;EACrC,KAAK,IAAI,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KACpC,IAAI,KAAK,GAAG,SAAS,QAAQ,OAAO,KAAK,GAAG,SAAS,SAAS,KAAK;CAGvE;CAGF,MAAM,gBACJ,KAAK,mBACH,MAAsD;EACtD,MAAM,KAAM,EAAE,YAAY,CAAC;EAC3B,MAAM,sBAAM,IAAI,KAAK;EACrB,OAAO;GACL,IAAI,EAAE,MAAM,OAAO,GAAG,MAAM,EAAE;GAC9B,SAAS,EAAE,YAAY,OAAO,GAAG,WAAW,EAAE;GAC9C,QAAQ,OAAO,GAAG,WAAW,WAAW,GAAG,SAAS,KAAA;GACpD,MAAM,OAAO,GAAG,SAAS,WAAW,GAAG,OAAO,KAAA;GAC9C,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,KAAA;GAC/C,WAAY,GAAG,aAAqB;GACpC,WAAY,GAAG,aAAqB;EACtC;CACF;CAEF,MAAM,4BAAoD,OAAO,QAAQ;EACvE,MAAM,IAAI,MAAM,YAAY,GAAG;EAC/B,IAAI,MAAM,KAAA,GAAW,OAAO,CAAC;EAC7B,IAAI,IAAI,KAAK,MAAM,KAAK,UAAU;EAClC,IAAI,MAAM,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC;EACrD,IAAI,KAAK,QAAQ,IAAI,EAAE,SAAS,KAAK,MAAa;EAElD,QAAO,MADe,EAAE,OAAO,MAAM,YAAY,UAAU,EAAE,MAAM,IAAI,GACxD,KAAK,MAAM,IAAI,YAAY;GAAE,GAAG,cAAc,CAAC;GAAG,WAAW,QAAQ,CAAC;EAAE,CAAC,CAAC;CAC3F;CAEA,MAAM,2BAA+C,OAAO,MAAM,MAAM;EACtE,MAAM,UAAU,MAAM,EAAE,cAAc;EACtC,MAAM,WAA2B;GAC/B,WAAW,EAAE;GACb,WAAW,EAAE,WAAW,QAAQ,KAAK,OAAO,EAAE,SAAS;GACvD,WAAW,EAAE,WAAW,QAAQ,KAAK,OAAO,EAAE,SAAS;EACzD;EACA,IAAI,EAAE,WAAW,KAAA,GAAW,SAAS,SAAS,EAAE;EAChD,IAAI,EAAE,SAAS,KAAA,GAAW,SAAS,OAAO,EAAE;EAC5C,MAAM,KAAK,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;GAAE,IAAI,EAAE;GAAI,UAAU;GAAS;EAAS,CAAC,CAAC;CACtF;CACA,MAAM,4BAAiD;CACvD,MAAM,4BAAiD,OAAO,MAAM,OAAO;EACzE,MAAM,KAAK,MAAM,KAAK,UAAU,EAAE,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO;CAC/D;CAEA,OAAO;EACL;EACA;EACA;EACA;CACF;AACF"}