@lunora/ai 1.0.0-alpha.127 → 1.0.0-alpha.129
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/packem_shared/{defineRag-BzrVmcfR.mjs → defineRag-CJudmmcj.mjs} +1 -1
- package/dist/packem_shared/ragSyncTriggers-D933fCwt.mjs +1 -0
- package/dist/packem_shared/sqliteVectorStore-f24ySqtJ.mjs +1 -0
- package/dist/rag/index.mjs +1 -1
- package/package.json +2 -1
- package/dist/packem_shared/ragSyncTriggers-hgMcA4f2.mjs +0 -1
- package/dist/packem_shared/sqliteVectorStore-Dyv1x3eC.mjs +0 -1
- package/dist/packem_shared/stable-key-B_BlboiY.mjs +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{tool as Re,jsonSchema as De}from"@ai-sdk/provider-utils";import{LunoraError as w,isLunoraError as Ce}from"@lunora/errors";import{
|
|
1
|
+
import{tool as Re,jsonSchema as De}from"@ai-sdk/provider-utils";import{LunoraError as w,isLunoraError as Ce}from"@lunora/errors";import{stableStringify as Be}from"@lunora/wire";import{r as de,m as L}from"./usage-GPnTSqR8.mjs";import $e from"./fixedWindowChunks-C461ahRE.mjs";import{c as Oe,I as Ke}from"./concurrent-C6nqBv41.mjs";import{contentHash as Ue}from"./contentHash-BIn6ECP8.mjs";import{hybridRank as Qe}from"./hybridRank-B4skyCLx.mjs";import{VECTORIZE_CAPABILITIES as le,vectorizeStore as Ve}from"./VECTORIZE_CAPABILITIES-l9ceRO5j.mjs";const Fe=1e3,Le=200,ze=5,ue=1e3,Pe=4,me=le.maxMetadataBytes===!1?Number.POSITIVE_INFINITY:le.maxMetadataBytes,je=2*1024,we="__ragChunk",be="__ragSource",K="__ragText",q="__ragHash",W="__ragChunks",V="__ragImportance",ve="__ragModel",He=new Set([we,W,q,V,ve,be,K]),Ye=async(e,c,u,m)=>{if(c.length===0)return;const h=c.slice(1);if(!e.upsertMany){await Oe(h,Ke,async(E,A)=>{await e.upsert(E,m),u(A+1)}),await e.upsert(c[0],m),u(0);return}for(let E=0;E<h.length;E+=ue){const A=Math.min(E+ue,h.length);await e.upsertMany(h.slice(E,A),m);for(let U=E;U<A;U+=1)u(U+1)}await e.upsertMany([c[0]],m),u(0)},qe=(e,c,u,m)=>{if(m===!1)return;const h=new TextEncoder().encode(JSON.stringify(e)).length;if(h<=m)return;const A=(typeof e[K]=="string"?new TextEncoder().encode(e[K]).length:0)*2>h?"lower `chunkSize` (it counts characters, not bytes — multibyte text costs up to 3 bytes each), or supply `textStore` to move chunk text out of metadata entirely":"attach less per-source `metadata`";throw new w("BAD_REQUEST",`@lunora/ai/rag: chunk ${String(c)} of "${u}" carries ${String(h)} bytes of metadata, over the store's ${String(m)}-byte per-vector ceiling — ${A}`)},We=(e,c,u)=>{if(u===!1)return;const m=new TextEncoder().encode(e).length;if(!(m<=u))throw new w("BAD_REQUEST",`@lunora/ai/rag: chunk id "${e}" for source "${c}" is ${String(m)} bytes, over the store's ${String(u)}-byte per-vector id ceiling — shorten the source id (hash long keys before indexing them) or shorten the \`namespace\`, which is prefixed onto every chunk id`)},Ze=/^[\w.-]{1,40}$/,ye=e=>e===void 0?"":`${encodeURIComponent(e)}#`,O=(e,c,u)=>`${ye(e)}${c}#${String(u)}`,he=(e,c)=>{const u=ye(c),m=u!==""&&e.startsWith(u)?e.slice(u.length):e,h=m.lastIndexOf("#"),E=h===-1?Number.NaN:Number(m.slice(h+1));return h===-1||!Number.isInteger(E)||E<0?{chunkIndex:0,sourceId:m}:{chunkIndex:E,sourceId:m.slice(0,h)}},Xe=async e=>Ue(new TextEncoder().encode(e)),Je=e=>{try{return Be([e.text,e.metadata,e.importance])}catch{return}},Ge=(e,c)=>{const u=[],m=[];for(const h of e)h.score>=c?u.push(h):m.push(h.id);return{kept:u,rejectedIds:m}},et=e=>e!==void 0&&Object.keys(e).length>0,H=e=>{if(!e)return;const c=Object.entries(e).filter(([u])=>!He.has(u));return c.length>0?Object.fromEntries(c):void 0},pe=new Set,tt=e=>{pe.has(e)||(pe.add(e),console.warn(`[@lunora/ai/rag] index "${e}" is used without a namespace — in a multi-tenant/sharded
|
|
2
2
|
app this shares one tenant's chunks (text included) with every other tenant, since
|
|
3
3
|
Vectorize indexes are account-global. Pass \`namespace\` (the shard/tenant key) on both
|
|
4
4
|
index() and retrieve(). Single-tenant apps suppress this via { allowSharedNamespace: true }.`))},nt=e=>e.map(c=>`[source:${c.sourceId}#${String(c.chunkIndex)}]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{stableStringify as l}from"@lunora/wire";const v=c=>{const m=c.delayMs??0,y=(d,a)=>c.id===void 0?a:c.id(d),e=d=>d===void 0?void 0:c.text(d),u=d=>c.metadata?.(d),p=d=>c.namespace?.(d),o=(d,a)=>{const t=p(d);return{id:y(d,a),...t===void 0?{}:{namespace:t}}},f=(d,a,t)=>{const i=u(d);return{...o(d,a),...i===void 0?{}:{metadata:i},text:t}},g=(d,a)=>{try{return l(u(d))===l(u(a))}catch{return!1}},r=async(d,a)=>{await d.scheduler.runAfter(m,c.action,a)};return{afterDelete:async(d,a)=>{const t=a.previous??a.doc;await r(d,{deleted:!0,...t===void 0?{id:a.id}:o(t,a.id)})},afterInsert:async(d,a)=>{const t=e(a.doc);t===void 0||a.doc===void 0||await r(d,f(a.doc,a.id,t))},afterUpdate:async(d,a)=>{if(a.doc===void 0)return;const t=e(a.doc),i=e(a.previous),s=o(a.doc,a.id),n=a.previous===void 0?s:o(a.previous,a.id),w=n.id!==s.id||n.namespace!==s.namespace,h=c.metadata!==void 0&&a.previous!==void 0&&!g(a.doc,a.previous);if(w)await r(d,{deleted:!0,...n});else if(t===i&&!h)return;await(t===void 0?r(d,{deleted:!0,...s}):r(d,f(a.doc,a.id,t)))}}};export{v as ragSyncTriggers};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import M from"./matchesMetadataFilter-BbIOyA5g.mjs";import{p as I,a as D,r as R,c as V,i as x}from"./sql-D5aqEMCY.mjs";import{LunoraError as B}from"@lunora/errors";const q=500,_=4096,A=(T,i)=>JSON.stringify([T,i]),U=T=>{const{dimensions:i,exec:c,table:w}=T,E=`${w}_ann`,f=`${w}_ann_ready`,u=(r,t)=>{if(r!==i)throw new B("RAG_DIMENSION_MISMATCH",`@lunora/ai/rag: ${t} is ${String(r)}-dimension but the \`ann\` index is ${String(i)}-dimension — set \`ann.dimensions\` to the embedding model's width, or reindex into a new \`table\` after changing models`)},g=async(r,t,o)=>{await c(`INSERT INTO ${E} (ref, namespace, embedding, id) VALUES (?, ?, ?, ?)`,[A(r,t),r,o,t])},S=async()=>{let r=0;for(;;){const t=await c(`SELECT rowid, id, namespace, vector FROM ${w} WHERE rowid > ? ORDER BY rowid LIMIT ?`,[r,q]);for(const o of t)u(JSON.parse(String(o.vector)).length,`stored vector "${String(o.id)}"`),await g(String(o.namespace),String(o.id),String(o.vector));if(t.length<q)return;r=Number(t.at(-1)?.rowid)}};return{ensure:async()=>{if((await c("SELECT name FROM sqlite_master WHERE name = ?",[f])).length>0){const[t]=await c(`SELECT dimensions FROM ${f}`,[]);u(Number(t?.dimensions),"the existing index");return}await c(`DROP TABLE IF EXISTS ${E}`,[]);try{await c(`CREATE VIRTUAL TABLE ${E} USING vec0(ref TEXT PRIMARY KEY, namespace TEXT PARTITION KEY, embedding FLOAT[${String(i)}] distance_metric=cosine, +id TEXT)`,[])}catch(t){throw t instanceof Error&&t.message.includes("no such module: vec0")?new Error("@lunora/ai/rag: sqliteVectorStore `ann` needs the sqlite-vec extension in this SQLite (`no such module: vec0`) — on celld set the `sqlite_vec` compatibility flag, on node:sqlite load the extension",{cause:t}):t}await S(),await c(`CREATE TABLE ${f} (dimensions INTEGER NOT NULL)`,[]),await c(`INSERT INTO ${f} (dimensions) VALUES (?)`,[i])},nearest:async(r,t,o)=>(u(t.length,"the query embedding"),(await c(`SELECT id, distance FROM ${E} WHERE embedding MATCH ? AND k = ? AND namespace = ?`,[JSON.stringify([...t]),Math.min(o,_),r])).map(v=>({distance:Number(v.distance),id:String(v.id)}))),put:async(r,t,o)=>{u(o.length,`the embedding for "${t}"`),await c(`DELETE FROM ${E} WHERE ref = ?`,[A(r,t)]),await g(r,t,JSON.stringify([...o]))},remove:async(r,t)=>{await c(`DELETE FROM ${E} WHERE ref IN (${I(t.length)})`,t.map(o=>A(r,o)))}}},X="lunora_rag_vectors",K=5e4,F=100,H=[4,16],W=null,h=T=>T??"",k=T=>{if(typeof T.exec!="function")throw new TypeError("@lunora/ai/rag: sqliteVectorStore requires an `exec` function");const i=D(T.table??X,"sqliteVectorStore `table`"),c=T.maxScan??K,{ann:w,exec:E}=T;if(w!==void 0&&(!Number.isInteger(w.dimensions)||w.dimensions<=0))throw new TypeError("@lunora/ai/rag: sqliteVectorStore `ann.dimensions` must be a positive integer");const f=w===void 0?void 0:U({dimensions:w.dimensions,exec:E,table:i}),u={deferredDelete:!0,maxDimensions:T.maxDimensions??w?.dimensions??!1,maxIdBytes:!1,maxMetadataBytes:!1,maxTopK:F,maxTopKWithMetadata:F};let g;const S=async()=>{g??=(async()=>{await E(`CREATE TABLE IF NOT EXISTS ${i} (id TEXT NOT NULL, namespace TEXT NOT NULL DEFAULT '', vector TEXT NOT NULL, metadata TEXT, PRIMARY KEY (namespace, id))`,[]),await E(`CREATE INDEX IF NOT EXISTS ${i}_namespace ON ${i} (namespace)`,[]),await f?.ensure()})().catch(e=>{throw g=void 0,e}),await g},O=async e=>{if(await S(),!e.embed)throw new TypeError("@lunora/ai/rag: sqliteVectorStore requires an `embed` function on upsert");const s=await e.embed(e.input),a=h(e.namespace);await f?.put(a,e.id,s),await E(`INSERT INTO ${i} (id, namespace, vector, metadata) VALUES (${I(4)}) ON CONFLICT(namespace, id) DO UPDATE SET vector = excluded.vector, metadata = excluded.metadata`,[e.id,a,JSON.stringify([...s]),e.metadata===void 0?W:JSON.stringify(e.metadata)])},r=async(e,s)=>{if(await S(),e.length===0)return[];const a=[];for(const d of x(e)){const m=await E(`SELECT id, metadata FROM ${i} WHERE namespace = ? AND id IN (${I(d.length)})`,[h(s),...d]);for(const n of m){const l=R(n.metadata);a.push({id:String(n.id),...l===void 0?{}:{metadata:l}})}}return a},t=async(e,s,a,d)=>{const m=h(a.namespace),n=await e.nearest(m,s,d),l=await r(n.map(L=>L.id),m),N=new Map(l.map(L=>[L.id,L])),b=[];for(const{distance:L,id:$}of n){const y=N.get($);y===void 0||!M(y.metadata,a.filter)||b.push({id:$,score:1-L,...a.returnMetadata==="none"||y.metadata===void 0?{}:{metadata:y.metadata}})}const p=b.slice(0,a.topK??10);return{count:p.length,exhausted:n.length<Math.min(d,_),matches:p}},o=async(e,s,a)=>{const d=a.topK??10;if(a.filter===void 0){const{count:m,matches:n}=await t(e,s,a,d);return{count:m,matches:n}}for(const m of H){const{count:n,exhausted:l,matches:N}=await t(e,s,a,d*m);if(n>=d||l)return{count:n,matches:N}}};return{capabilities:u,deleteByIds:async(e,s,a,d)=>{if(await S(),e.length===0){await d?.();return}for(const m of x(e))await E(`DELETE FROM ${i} WHERE namespace = ? AND id IN (${I(m.length)})`,[h(s),...m]),await f?.remove(h(s),m);await d?.()},getByIds:r,query:async e=>{await S();let s;if(e.embed&&e.input!==void 0)s=await e.embed(e.input);else throw new TypeError("@lunora/ai/rag: sqliteVectorStore query requires both `input` and `embed`");if(f!==void 0){const n=await o(f,s,e);if(n!==void 0)return n}const a=await E(`SELECT id, vector, metadata FROM ${i} WHERE namespace = ? LIMIT ?`,[h(e.namespace),c+1]);if(a.length>c)throw new RangeError(`@lunora/ai/rag: sqliteVectorStore scanned ${String(a.length)} vectors in namespace "${h(e.namespace)}", over the ${String(c)} limit — search here is brute force and linear, so this namespace has outgrown it. Shard it further, or move this index to Vectorize or a pgvector backend`);const d=[];for(const n of a){const l=R(n.metadata);if(!M(l,e.filter))continue;const N=R(n.vector);N!==void 0&&d.push({id:String(n.id),score:V(s,N),...e.returnMetadata==="none"||l===void 0?{}:{metadata:l}})}const m=d.toSorted((n,l)=>l.score-n.score).slice(0,e.topK??10);return{count:m.length,matches:m}},upsert:O}};export{k as sqliteVectorStore};
|
package/dist/rag/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as o}from"../packem_shared/fixedWindowChunks-C461ahRE.mjs";import{markdownChunker as a,sentenceChunker as f,tokenChunker as n}from"../packem_shared/markdownChunker-iW8V4klY.mjs";import{default as x}from"../packem_shared/defineRag-
|
|
1
|
+
import{default as o}from"../packem_shared/fixedWindowChunks-C461ahRE.mjs";import{markdownChunker as a,sentenceChunker as f,tokenChunker as n}from"../packem_shared/markdownChunker-iW8V4klY.mjs";import{default as x}from"../packem_shared/defineRag-CJudmmcj.mjs";import{contentHash as p,guessMimeTypeFromExtension as i}from"../packem_shared/contentHash-BIn6ECP8.mjs";import{hybridRank as d}from"../packem_shared/hybridRank-B4skyCLx.mjs";import{default as k}from"../packem_shared/bm25LexicalStore-DMUzAL0O.mjs";import{default as h}from"../packem_shared/matchesMetadataFilter-BbIOyA5g.mjs";import{batchReranker as g,scoreReranker as C}from"../packem_shared/batchReranker-Bc38FBLH.mjs";import{defineRagSource as E}from"../packem_shared/defineRagSource-Q3f3niU8.mjs";import{sqlLexicalStore as T}from"../packem_shared/sqlLexicalStore-4C_cIwef.mjs";import{sqliteVectorStore as y}from"../packem_shared/sqliteVectorStore-f24ySqtJ.mjs";import{ragSyncTriggers as q}from"../packem_shared/ragSyncTriggers-D933fCwt.mjs";import{VECTORIZE_CAPABILITIES as A,vectorizeStore as F}from"../packem_shared/VECTORIZE_CAPABILITIES-l9ceRO5j.mjs";export{A as VECTORIZE_CAPABILITIES,g as batchReranker,k as bm25LexicalStore,p as contentHash,x as defineRag,E as defineRagSource,o as fixedWindowChunks,i as guessMimeTypeFromExtension,d as hybridRank,a as markdownChunker,h as matchesMetadataFilter,q as ragSyncTriggers,C as scoreReranker,f as sentenceChunker,T as sqlLexicalStore,y as sqliteVectorStore,n as tokenChunker,F as vectorizeStore};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/ai",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.129",
|
|
4
4
|
"description": "Workers AI helper for Lunora: provider-agnostic AI SDK access from functions, Workers AI by default",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"@ai-sdk/openai": "4.0.83",
|
|
62
62
|
"@ai-sdk/provider-utils": "5.0.53",
|
|
63
63
|
"@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
|
|
64
|
+
"@lunora/wire": "1.0.0-alpha.1",
|
|
64
65
|
"ai": "7.0.127",
|
|
65
66
|
"workers-ai-provider": "4.0.0"
|
|
66
67
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as l}from"./stable-key-B_BlboiY.mjs";const v=c=>{const m=c.delayMs??0,y=(d,a)=>c.id===void 0?a:c.id(d),e=d=>d===void 0?void 0:c.text(d),u=d=>c.metadata?.(d),p=d=>c.namespace?.(d),o=(d,a)=>{const t=p(d);return{id:y(d,a),...t===void 0?{}:{namespace:t}}},f=(d,a,t)=>{const s=u(d);return{...o(d,a),...s===void 0?{}:{metadata:s},text:t}},g=(d,a)=>{try{return l(u(d))===l(u(a))}catch{return!1}},r=async(d,a)=>{await d.scheduler.runAfter(m,c.action,a)};return{afterDelete:async(d,a)=>{const t=a.previous??a.doc;await r(d,{deleted:!0,...t===void 0?{id:a.id}:o(t,a.id)})},afterInsert:async(d,a)=>{const t=e(a.doc);t===void 0||a.doc===void 0||await r(d,f(a.doc,a.id,t))},afterUpdate:async(d,a)=>{if(a.doc===void 0)return;const t=e(a.doc),s=e(a.previous),i=o(a.doc,a.id),n=a.previous===void 0?i:o(a.previous,a.id),w=n.id!==i.id||n.namespace!==i.namespace,h=c.metadata!==void 0&&a.previous!==void 0&&!g(a.doc,a.previous);if(w)await r(d,{deleted:!0,...n});else if(t===s&&!h)return;await(t===void 0?r(d,{deleted:!0,...i}):r(d,f(a.doc,a.id,t)))}}};export{v as ragSyncTriggers};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import x from"./matchesMetadataFilter-BbIOyA5g.mjs";import{p as I,a as q,r as y,c as F,i as A}from"./sql-D5aqEMCY.mjs";import{LunoraError as _}from"@lunora/errors";const O=500,C=4096,R=(d,n)=>JSON.stringify([d,n]),D=d=>{const{dimensions:n,exec:r,table:l}=d,i=`${l}_ann`,T=`${l}_ann_ready`,u=(a,t)=>{if(a!==n)throw new _("RAG_DIMENSION_MISMATCH",`@lunora/ai/rag: ${t} is ${String(a)}-dimension but the \`ann\` index is ${String(n)}-dimension — set \`ann.dimensions\` to the embedding model's width, or reindex into a new \`table\` after changing models`)},g=async(a,t,o)=>{await r(`INSERT INTO ${i} (ref, namespace, embedding, id) VALUES (?, ?, ?, ?)`,[R(a,t),a,o,t])},S=async()=>{let a=0;for(;;){const t=await r(`SELECT rowid, id, namespace, vector FROM ${l} WHERE rowid > ? ORDER BY rowid LIMIT ?`,[a,O]);for(const o of t)u(JSON.parse(String(o.vector)).length,`stored vector "${String(o.id)}"`),await g(String(o.namespace),String(o.id),String(o.vector));if(t.length<O)return;a=Number(t.at(-1)?.rowid)}};return{ensure:async()=>{if((await r("SELECT name FROM sqlite_master WHERE name = ?",[T])).length>0){const[t]=await r(`SELECT dimensions FROM ${T}`,[]);u(Number(t?.dimensions),"the existing index");return}await r(`DROP TABLE IF EXISTS ${i}`,[]);try{await r(`CREATE VIRTUAL TABLE ${i} USING vec0(ref TEXT PRIMARY KEY, namespace TEXT PARTITION KEY, embedding FLOAT[${String(n)}] distance_metric=cosine, +id TEXT)`,[])}catch(t){throw t instanceof Error&&t.message.includes("no such module: vec0")?new Error("@lunora/ai/rag: sqliteVectorStore `ann` needs the sqlite-vec extension in this SQLite (`no such module: vec0`) — on celld set the `sqlite_vec` compatibility flag, on node:sqlite load the extension",{cause:t}):t}await S(),await r(`CREATE TABLE ${T} (dimensions INTEGER NOT NULL)`,[]),await r(`INSERT INTO ${T} (dimensions) VALUES (?)`,[n])},nearest:async(a,t,o)=>(u(t.length,"the query embedding"),(await r(`SELECT id, distance FROM ${i} WHERE embedding MATCH ? AND k = ? AND namespace = ?`,[JSON.stringify([...t]),Math.min(o,C),a])).map(e=>({distance:Number(e.distance),id:String(e.id)}))),put:async(a,t,o)=>{u(o.length,`the embedding for "${t}"`),await r(`DELETE FROM ${i} WHERE ref = ?`,[R(a,t)]),await g(a,t,JSON.stringify([...o]))},remove:async(a,t)=>{await r(`DELETE FROM ${i} WHERE ref IN (${I(t.length)})`,t.map(o=>R(a,o)))}}},B="lunora_rag_vectors",U=5e4,$=100,V=null,h=d=>d??"",W=d=>{if(typeof d.exec!="function")throw new TypeError("@lunora/ai/rag: sqliteVectorStore requires an `exec` function");const n=q(d.table??B,"sqliteVectorStore `table`"),r=d.maxScan??U,{ann:l,exec:i}=d;if(l!==void 0&&(!Number.isInteger(l.dimensions)||l.dimensions<=0))throw new TypeError("@lunora/ai/rag: sqliteVectorStore `ann.dimensions` must be a positive integer");const T=l===void 0?void 0:D({dimensions:l.dimensions,exec:i,table:n}),u={deferredDelete:!0,maxDimensions:d.maxDimensions??l?.dimensions??!1,maxIdBytes:!1,maxMetadataBytes:!1,maxTopK:$,maxTopKWithMetadata:$};let g;const S=async()=>{g??=(async()=>{await i(`CREATE TABLE IF NOT EXISTS ${n} (id TEXT NOT NULL, namespace TEXT NOT NULL DEFAULT '', vector TEXT NOT NULL, metadata TEXT, PRIMARY KEY (namespace, id))`,[]),await i(`CREATE INDEX IF NOT EXISTS ${n}_namespace ON ${n} (namespace)`,[]),await T?.ensure()})().catch(e=>{throw g=void 0,e}),await g},b=async e=>{if(await S(),!e.embed)throw new TypeError("@lunora/ai/rag: sqliteVectorStore requires an `embed` function on upsert");const c=await e.embed(e.input),s=h(e.namespace);await T?.put(s,e.id,c),await i(`INSERT INTO ${n} (id, namespace, vector, metadata) VALUES (${I(4)}) ON CONFLICT(namespace, id) DO UPDATE SET vector = excluded.vector, metadata = excluded.metadata`,[e.id,s,JSON.stringify([...c]),e.metadata===void 0?V:JSON.stringify(e.metadata)])},a=async(e,c)=>{if(await S(),e.length===0)return[];const s=[];for(const m of A(e)){const E=await i(`SELECT id, metadata FROM ${n} WHERE namespace = ? AND id IN (${I(m.length)})`,[h(c),...m]);for(const w of E){const f=y(w.metadata);s.push({id:String(w.id),...f===void 0?{}:{metadata:f}})}}return s},t=async(e,c,s)=>{const m=h(s.namespace),E=await e.nearest(m,c,s.topK??10),w=await a(E.map(L=>L.id),m),f=new Map(w.map(L=>[L.id,L])),N=[];for(const{distance:L,id:p}of E){const v=f.get(p);v!==void 0&&N.push({id:p,score:1-L,...s.returnMetadata==="none"||v.metadata===void 0?{}:{metadata:v.metadata}})}return{count:N.length,matches:N}};return{capabilities:u,deleteByIds:async(e,c,s,m)=>{if(await S(),e.length===0){await m?.();return}for(const E of A(e))await i(`DELETE FROM ${n} WHERE namespace = ? AND id IN (${I(E.length)})`,[h(c),...E]),await T?.remove(h(c),E);await m?.()},getByIds:a,query:async e=>{await S();let c;if(e.embed&&e.input!==void 0)c=await e.embed(e.input);else throw new TypeError("@lunora/ai/rag: sqliteVectorStore query requires both `input` and `embed`");if(T!==void 0&&e.filter===void 0)return t(T,c,e);const s=await i(`SELECT id, vector, metadata FROM ${n} WHERE namespace = ? LIMIT ?`,[h(e.namespace),r+1]);if(s.length>r)throw new RangeError(`@lunora/ai/rag: sqliteVectorStore scanned ${String(s.length)} vectors in namespace "${h(e.namespace)}", over the ${String(r)} limit — search here is brute force and linear, so this namespace has outgrown it. Shard it further, or move this index to Vectorize or a pgvector backend`);const m=[];for(const w of s){const f=y(w.metadata);if(!x(f,e.filter))continue;const N=y(w.vector);N!==void 0&&m.push({id:String(w.id),score:F(c,N),...e.returnMetadata==="none"||f===void 0?{}:{metadata:f}})}const E=m.toSorted((w,f)=>f.score-w.score).slice(0,e.topK??10);return{count:E.length,matches:E}},upsert:b}};export{W as sqliteVectorStore};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const a=/["\\\u0000-\u001F\uD800-\uDFFF]/,f=t=>a.test(t)?JSON.stringify(t):`"${t}"`,y=t=>{if(t===void 0)return"null";if(typeof t=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof t=="number"){if(Number.isNaN(t))return"nan";if(t===1/0)return"inf";if(t===-1/0)return"-inf";if(Object.is(t,-0))return"-0"}if(typeof t=="string")return f(t);if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t)){let r="[";for(let n=0;n<t.length;n++)n>0&&(r+=","),r+=y(t[n]);return r+"]"}const i=Object.getPrototypeOf(t);if(i!==null&&i!==Object.prototype){const r=t.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${r} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const o=t,c=Object.keys(o).sort();let e="{",s=!0;for(const r of c){const n=o[r];n!==void 0&&(s?s=!1:e+=",",e+=f(r),e+=":",e+=y(n))}return e+"}"};export{y as s};
|