@gencode/agents 0.7.2 → 0.7.4
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/CHANGELOG.md +13 -0
- package/dist/builtin-provider-Bhzb_o53.js +66 -0
- package/dist/{goal-events-PYGTADzY.js → goal-events-Bdf1BDep.js} +1 -1
- package/dist/{goal-store-B36KsoVO.js → goal-store-DxaeZmiE.js} +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +91 -91
- package/dist/{session-BDGOSbwC.js → session-CiekMEUQ.js} +2 -2
- package/dist/{session-store-CClsJSJO.js → session-store-DjXWnxJY.js} +1 -1
- package/package.json +1 -1
- package/dist/builtin-provider-CXE7L9HO.js +0 -66
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import e from"node:fs/promises";import t from"node:path";import{randomUUID as n}from"node:crypto";async function r(t){try{return await e.readFile(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async function i(t,n,r){await e.writeFile(t,n,`utf-8`)}async function a(t,n,a){if(!a){await e.appendFile(t,n,`utf-8`);return}let o=await r(t);await i(t,o?o+n:n,!0)}async function o(t,n,r){let i=`${t}.${process.pid}.${Date.now()}.tmp`;await e.writeFile(i,n,`utf-8`),await e.rename(i,t)}async function s(e){return r(e)}const c=`sessions`,l=2e3,u=new Map;function d(e){let t=e?.trim()||c;if(!/^[A-Za-z0-9_-]+$/.test(t))throw Error(`Invalid session store name: ${e}. Must match /^[A-Za-z0-9_-]+$/`);return t}function f(e,t){let n=t.trim();if(!/^[A-Za-z0-9_-]+$/.test(n))throw Error(`Invalid ${e}: ${t}. Must match /^[A-Za-z0-9_-]+$/`);return n}function p(e,n){return t.join(e,`.aimax`,d(n?.storeName))}function m(e,n,r){let i=r?.subagent?f(`subagent session id`,n):n;if(r?.subagent){if(r.subagent.parentDir)return t.join(r.subagent.parentDir,`subagents`,i);let n=f(`parent session id`,r.subagent.parentSessionId);return t.join(p(e,r),n,`subagents`,i)}return t.join(p(e,r),i)}function h(e,n,r){return t.join(m(e,n,r),`transcript.jsonl`)}function g(e,n,r){return t.join(m(e,n,r),`artifacts.json`)}function _(e,n,r){return t.join(m(e,n,r),`session.json`)}function v(e,n,r){return t.join(m(e,n,r),`context.json`)}function y(e,n,r){return t.join(m(e,n,r),`session-memory.json`)}function b(e,n,r){return t.join(m(e,n,r),`collapse-log.jsonl`)}function x(e,n,r){return t.join(m(e,n,r),`tool-results`)}function S(e,n,r){return t.join(m(e,n,r),`cron-executions.jsonl`)}const C={version:2,updatedAt:new Date(0).toISOString(),readStates:[],toolResults:[],compaction:{budgets:[],snips:[],collapseSpans:[],consecutiveAutocompactFailures:0}};async function w(r,i,a){let o=a?.sessionId??n(),s=m(r,o,a);await e.mkdir(s,{recursive:!0});let c=t.join(s,`.channel`);return await e.writeFile(c,i,`utf-8`),o}async function T(t,n,r){let i=m(t,n,r);await e.mkdir(i,{recursive:!0})}async function E(e,t,n){let i=await r(h(e,t,n));if(i===null)return[];let a=[];for(let e of i.split(`
|
|
2
2
|
`)){let t=e.trim();if(t)try{a.push(JSON.parse(t))}catch{}}return a}async function D(e,t,n,r){await T(e,t,r);let i=g(e,t,r),a=r?.encryptSessions??!1;await N(i,async()=>{let e=await A(i);await M(i,{version:1,updatedAt:new Date().toISOString(),operations:[...e.operations,k(n)]},a)})}async function O(e,t,n){return(await A(g(e,t,n))).operations}function k(e){let t=e.content.length,n=t>l;return{...e,content:n?`${e.content.slice(0,Math.max(0,l-3))}...`:e.content,timestamp:new Date().toISOString(),truncated:n,originalChars:t}}async function A(e){let t=await r(e);if(t===null)return j();try{let e=JSON.parse(t);return e.version!==1||!Array.isArray(e.operations)?j():{version:1,updatedAt:typeof e.updatedAt==`string`?e.updatedAt:new Date(0).toISOString(),operations:e.operations}}catch{return j()}}function j(){return{version:1,updatedAt:new Date(0).toISOString(),operations:[]}}async function M(n,r,i){await e.mkdir(t.dirname(n),{recursive:!0}),await o(n,`${JSON.stringify(r,null,2)}\n`,i)}async function N(e,t){let n=(u.get(e)??Promise.resolve()).catch(()=>{}).then(t);u.set(e,n);try{await n}finally{u.get(e)===n&&u.delete(e)}}async function P(e,n,r,i){await T(e,n,i);let o=h(e,n,i);await a(o,JSON.stringify(r)+`
|
|
3
|
-
`,i?.encryptSessions??!1);try{let{resolveMemoryProvider:n}=await import(`./provider-registry-Kh5nNG84.js`).then(e=>e.t),{createBuiltinMemoryProvider:r}=await import(`./builtin-provider-
|
|
4
|
-
`),l=a?.encryptSessions??!1;await i(o,c.length>0?`${c}\n`:``,l);try{let{resolveMemoryProvider:n}=await import(`./provider-registry-Kh5nNG84.js`).then(e=>e.t),{createBuiltinMemoryProvider:r}=await import(`./builtin-provider-
|
|
3
|
+
`,i?.encryptSessions??!1);try{let{resolveMemoryProvider:n}=await import(`./provider-registry-Kh5nNG84.js`).then(e=>e.t),{createBuiltinMemoryProvider:r}=await import(`./builtin-provider-Bhzb_o53.js`).then(e=>e.t),a=t.join(e,`.aimax`),s=n({providerId:i?.providerId,pluginId:i?.pluginId,dataDir:e,memoryDir:a,sessionStoreName:i?.storeName})?.provider??r({dataDir:e,memoryDir:a,sessionStoreName:i?.storeName});s.noteSessionUpdate&&s.noteSessionUpdate(o)}catch{}i?.onMemoryChanged&&await Promise.resolve(i.onMemoryChanged({reason:`transcript-append`,files:[t.join(d(i.storeName),n,`transcript.jsonl`).replace(/\\/g,`/`)],source:`sessions`,sessionId:n,providerId:i.providerId??i.pluginId,timestamp:new Date().toISOString()})).catch(()=>{})}async function F(e,n,r,a){await T(e,n,a);let o=h(e,n,a),s=r(await E(e,n,a)),c=s.map(e=>JSON.stringify(e)).join(`
|
|
4
|
+
`),l=a?.encryptSessions??!1;await i(o,c.length>0?`${c}\n`:``,l);try{let{resolveMemoryProvider:n}=await import(`./provider-registry-Kh5nNG84.js`).then(e=>e.t),{createBuiltinMemoryProvider:r}=await import(`./builtin-provider-Bhzb_o53.js`).then(e=>e.t),i=t.join(e,`.aimax`),s=n({providerId:a?.providerId,pluginId:a?.pluginId,dataDir:e,memoryDir:i,sessionStoreName:a?.storeName})?.provider??r({dataDir:e,memoryDir:i,sessionStoreName:a?.storeName});s.noteSessionUpdate&&s.noteSessionUpdate(o)}catch{}return a?.onMemoryChanged&&await Promise.resolve(a.onMemoryChanged({reason:`transcript-rewrite`,files:[t.join(d(a.storeName),n,`transcript.jsonl`).replace(/\\/g,`/`)],source:`sessions`,sessionId:n,providerId:a.providerId??a.pluginId,timestamp:new Date().toISOString()})).catch(()=>{}),s}async function I(e,t,n,r){await T(e,t,r),await a(S(e,t,r),JSON.stringify(n)+`
|
|
5
5
|
`,r?.encryptSessions??!1)}async function L(e,t,n){let i=await r(S(e,t,n));if(i===null)return[];let a=[];for(let e of i.split(`
|
|
6
6
|
`)){let t=e.trim();if(t)try{a.push(JSON.parse(t))}catch{}}return a}async function R(t,n){let r=p(t,n);try{return(await e.readdir(r,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name).sort()}catch(e){if(e.code===`ENOENT`)return[];throw e}}async function z(e,t,n){await T(e,t.id,n);let r=_(e,t.id,n),a=n?.encryptSessions??!1;await i(r,JSON.stringify(t,null,2),a)}async function B(e,t,n,r){let i=await V(e,t,r);if(!i)return null;let a={...i,...n,id:i.id,createdAt:i.createdAt,updatedAt:new Date().toISOString()};return await z(e,a,r),a}async function V(n,i,a){let o=await r(_(n,i,a));if(o===null)return null;try{let r=JSON.parse(o);if(!r.channel){let o=t.join(m(n,i,a),`.channel`);try{r.channel=(await e.readFile(o,`utf-8`)).trim()}catch{r.channel=`WEB`}}return r}catch{return null}}async function H(e,t,n){let r=await R(e,n),i=await Promise.all(r.map(async t=>{let r=await V(e,t,n);return{id:t,title:r?.title??t,channel:r?.channel??`WEB`,createdAt:r?.createdAt??``,updatedAt:r?.updatedAt??``}}));return t?i.filter(e=>e.channel===t):i}async function U(e,t,n){let i=await r(v(e,t,n));if(i===null)return C;try{let e=JSON.parse(i),t=typeof e.version==`number`?e.version:void 0;return t!==1&&t!==2?C:{version:2,updatedAt:typeof e.updatedAt==`string`?e.updatedAt:C.updatedAt,readStates:Array.isArray(e.readStates)?e.readStates:[],toolResults:Array.isArray(e.toolResults)?e.toolResults:[],compaction:{sessionMemory:e.compaction?.sessionMemory,modelUsage:e.compaction?.modelUsage,budgets:Array.isArray(e.compaction?.budgets)?e.compaction.budgets:[],snips:Array.isArray(e.compaction?.snips)?e.compaction.snips:[],collapseSpans:Array.isArray(e.compaction?.collapseSpans)?e.compaction.collapseSpans:[],consecutiveAutocompactFailures:typeof e.compaction?.consecutiveAutocompactFailures==`number`?e.compaction.consecutiveAutocompactFailures:0,lastCompactionAt:typeof e.compaction?.lastCompactionAt==`string`?e.compaction.lastCompactionAt:void 0,lastCompactionLayer:e.compaction?.lastCompactionLayer===`L1`||e.compaction?.lastCompactionLayer===`L2`||e.compaction?.lastCompactionLayer===`L3`||e.compaction?.lastCompactionLayer===`L4`||e.compaction?.lastCompactionLayer===`L5`||e.compaction?.lastCompactionLayer===`L6`?e.compaction.lastCompactionLayer:void 0}}}catch{return C}}async function W(t,n,r){let i=m(t,n,r);try{return(await e.stat(i)).isDirectory()}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function G(e,t,n){let[r,i,a]=await Promise.all([V(e,t,n),E(e,t,n),U(e,t,n)]);return{id:t,metadata:r,transcriptPath:h(e,t,n),contextSnapshotPath:v(e,t,n),sessionMemoryPath:y(e,t,n),collapseLogPath:b(e,t,n),toolResultsDir:x(e,t,n),transcriptEntryCount:i.length,readStateCount:a.readStates.length,toolResultRefCount:a.toolResults.length,transcriptEntries:i,context:a}}async function K(e,t,n){let r=await G(e,t,n);return{id:r.id,metadata:r.metadata,transcript:r.transcriptEntries,context:r.context,paths:{transcriptPath:r.transcriptPath,contextSnapshotPath:r.contextSnapshotPath,sessionMemoryPath:r.sessionMemoryPath,collapseLogPath:r.collapseLogPath,toolResultsDir:r.toolResultsDir}}}export{h as A,F as C,y as D,W as E,s as F,i as I,a as M,o as N,p as O,r as P,d as S,m as T,L as _,P as a,E as b,v as c,T as d,K as f,O as g,R as h,I as i,B as j,x as k,w as l,H as m,l as n,g as o,G as p,D as r,b as s,c as t,S as u,U as v,z as w,_ as x,V as y};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{I as t,M as n,P as r,T as i}from"./session-
|
|
1
|
+
import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{I as t,M as n,P as r,T as i}from"./session-CiekMEUQ.js";import a from"node:fs/promises";import o from"node:path";var s=e({appendHitlHistory:()=>d,clearPendingHitl:()=>_,createPendingHitl:()=>m,findResolvedHitlState:()=>g,hitlHistoryPath:()=>l,pendingHitlPath:()=>c,readHitlHistory:()=>p,readPendingHitl:()=>f,transitionHitlStatus:()=>h,writePendingHitl:()=>u});function c(e,t,n){return o.join(i(e,t,n),`pending-hitl.json`)}function l(e,t,n){return o.join(i(e,t,n),`hitl-history.jsonl`)}async function u(e,n,r,o){let s=i(e,n,o);await a.mkdir(s,{recursive:!0});let l=c(e,n,o),u=o?.encryptSessions??!1;await t(l,JSON.stringify(r,null,2),u)}async function d(e,t,r,o){let s=i(e,t,o);await a.mkdir(s,{recursive:!0}),await n(l(e,t,o),JSON.stringify(r)+`
|
|
2
2
|
`,o?.encryptSessions??!1)}async function f(e,t,n){let i=await r(c(e,t,n));if(i===null)return null;try{return JSON.parse(i)}catch{return null}}async function p(e,t,n){let i=await r(l(e,t,n));if(i===null)return[];let a=[];for(let e of i.split(`
|
|
3
3
|
`)){let t=e.trim();if(t)try{a.push(JSON.parse(t))}catch{}}return a}async function m(e,t,n,r,i,a,o){let s=new Date().toISOString(),c={version:1,sessionId:t,request:n,status:`pending`,checkpoint:r,context:i,toolContext:a,createdAt:s,updatedAt:s};return await u(e,t,c,o),await d(e,t,{requestId:n.requestId,sessionId:t,action:`requested`,payload:n,timestamp:s},o),c}async function h(e,t,n,r,i,a){let o=await f(e,t,a);if(!o||o.request.requestId!==n||o.status!==`pending`)return null;let s=new Date().toISOString(),c={...o,status:r,resolution:i,updatedAt:s};await u(e,t,c,a);let l={resolved:`resolved`,expired:`expired`,cancelled:`cancelled`}[r];return await d(e,t,{requestId:n,sessionId:t,action:l,payload:i??o.request,timestamp:s},a),c}async function g(e,t,n,r){let i=await f(e,t,r);return!i||i.request.requestId!==n?null:i.status===`resolved`?i:null}async function _(e,t,n){let r=c(e,t,n);try{await a.unlink(r)}catch(e){if(e.code===`ENOENT`)return;throw e}}export{c as a,s as c,l as i,h as l,m as n,p as o,g as r,f as s,_ as t};
|
package/package.json
CHANGED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{O as t,P as n,S as r}from"./session-BDGOSbwC.js";import{createRequire as i}from"node:module";import a from"node:fs/promises";import o,{basename as s}from"node:path";import c from"node:crypto";import l from"node:fs";function u(e){return!!(e&&typeof e==`object`&&`code`in e&&e.code===`ENOENT`)}async function d(e){let t;try{t=await a.lstat(e)}catch(e){if(u(e))return{missing:!0};throw e}if(t.isSymbolicLink()||!t.isFile())throw Error(`path required`);return{missing:!1,stat:t}}function f(e){try{l.mkdirSync(e,{recursive:!0})}catch{}return e}function p(e){return e.trim().replace(/^[./]+/,``).replace(/\\/g,`/`)}function m(e){let t=p(e);return t?t===`MEMORY.md`||t===`memory.md`?!0:t.startsWith(`memory/`):!1}async function h(e,t){let n=await a.readdir(e,{withFileTypes:!0});for(let r of n){let n=o.join(e,r.name);if(!r.isSymbolicLink()){if(r.isDirectory()){await h(n,t);continue}r.isFile()&&r.name.endsWith(`.md`)&&t.push(n)}}}async function g(e){let t=[],n=o.join(e,`MEMORY.md`),r=o.join(e,`memory.md`),i=o.join(e,`memory`),s=async e=>{try{let n=await a.lstat(e);if(n.isSymbolicLink()||!n.isFile()||!e.endsWith(`.md`))return;t.push(e)}catch{}};await s(n),await s(r);try{let e=await a.lstat(i);!e.isSymbolicLink()&&e.isDirectory()&&await h(i,t)}catch{}if(t.length<=1)return t;let c=new Set,l=[];for(let e of t){let t=e;try{t=await a.realpath(e)}catch{}c.has(t)||(c.add(t),l.push(e))}return l}function _(e){return c.createHash(`sha256`).update(e).digest(`hex`)}async function v(e,t){let n;try{n=await a.stat(e)}catch(e){if(u(e))return null;throw e}let r;try{r=await a.readFile(e,`utf-8`)}catch(e){if(u(e))return null;throw e}let i=_(r);return{path:o.relative(t,e).replace(/\\/g,`/`),absPath:e,mtimeMs:n.mtimeMs,size:n.size,hash:i}}function y(e,t){let n=e.split(`
|
|
2
|
-
`);if(n.length===0)return[];let r=Math.max(32,t.tokens*4),i=Math.max(0,t.overlap*4),a=[],o=[],s=0,c=()=>{if(o.length===0)return;let e=o[0],t=o[o.length-1];if(!e||!t)return;let n=o.map(e=>e.line).join(`
|
|
3
|
-
`),r=e.lineNo,i=t.lineNo;a.push({startLine:r,endLine:i,text:n,hash:_(n)})},l=()=>{if(i<=0||o.length===0){o=[],s=0;return}let e=0,t=[];for(let n=o.length-1;n>=0;--n){let r=o[n];if(r&&(e+=r.line.length+1,t.unshift(r),e>=i))break}o=t,s=t.reduce((e,t)=>e+t.line.length+1,0)};for(let e=0;e<n.length;e+=1){let t=n[e]??``,i=e+1,a=[];if(t.length===0)a.push(``);else for(let e=0;e<t.length;e+=r)a.push(t.slice(e,e+r));for(let e of a){let t=e.length+1;s+t>r&&o.length>0&&(c(),l()),o.push({line:e,lineNo:i}),s+=t}}return c(),a}function ee(e,t){if(!(!t||t.length===0))for(let n of e)n.startLine=t[n.startLine-1]??n.startLine,n.endLine=t[n.endLine-1]??n.endLine}function b(e){try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function te(e,t){if(e.length===0||t.length===0)return 0;let n=Math.min(e.length,t.length),r=0,i=0,a=0;for(let o=0;o<n;o+=1){let n=e[o]??0,s=t[o]??0;r+=n*s,i+=n*n,a+=s*s}return i===0||a===0?0:r/(Math.sqrt(i)*Math.sqrt(a))}function ne(e){return(e.toLowerCase().match(/[\p{L}\p{N}_]+/gu)??[]).filter(Boolean)}function re(e){return c.createHash(`sha256`).update(e).digest().readUInt32BE(0)}function x(e,t=384){let n=Array(t).fill(0),r=ne(e);if(r.length===0)return n;for(let e of r){let r=re(e)%t;n[r]+=1}let i=Math.sqrt(n.reduce((e,t)=>e+t*t,0));if(i>0)for(let e=0;e<n.length;e+=1)n[e]=n[e]/i;return n}function S(e){let t=e?.model?.trim()||`mock-embedding-v1`,n=e?.dimensions??384;return{id:`external-mock`,model:t,embedQuery:async e=>x(e,n),embedBatch:async e=>e.map(e=>x(e,n))}}const C=new class{providers=new Map;byPluginId=new Map;register(e){this.providers.set(e.id,e),e.pluginId&&this.byPluginId.set(e.pluginId,e.id)}getById(e){return this.providers.get(e)}getByPluginId(e){let t=this.byPluginId.get(e);return t?this.providers.get(t):void 0}clear(){this.providers.clear(),this.byPluginId.clear()}};function ie(e){let t=e.id?.trim()||e.pluginId;return C.register({id:t,pluginId:e.pluginId,create:e.create,config:e.config,rootDir:e.rootDir,source:e.source}),t}function w(e){let t=e.providerId?.trim(),n=e.pluginId?.trim(),r=(t?C.getById(t):void 0)??(n?C.getByPluginId(n):void 0);return r?{provider:r.create({dataDir:e.dataDir,memoryDir:e.memoryDir,pluginId:r.pluginId,config:r.config,rootDir:r.rootDir,source:r.source}),registration:r}:null}function ae(){C.clear()}const T={enabled:!1,lambda:.7};function E(e){let t=e.toLowerCase().match(/[a-z0-9_]+/g)??[];return new Set(t)}function oe(e,t){if(e.size===0&&t.size===0)return 1;if(e.size===0||t.size===0)return 0;let n=0,r=e.size<=t.size?e:t,i=e.size<=t.size?t:e;for(let e of r)i.has(e)&&n++;let a=e.size+t.size-n;return a===0?0:n/a}function se(e,t,n){if(t.length===0)return 0;let r=0,i=n.get(e.id)??E(e.content);for(let e of t){let t=oe(i,n.get(e.id)??E(e.content));t>r&&(r=t)}return r}function ce(e,t,n){return n*e-(1-n)*t}function le(e,t={}){let{enabled:n=T.enabled,lambda:r=T.lambda}=t;if(!n||e.length<=1)return[...e];let i=Math.max(0,Math.min(1,r));if(i===1)return e.slice().sort((e,t)=>t.score-e.score);let a=new Map;for(let t of e)a.set(t.id,E(t.content));let o=Math.max(...e.map(e=>e.score)),s=Math.min(...e.map(e=>e.score)),c=o-s,l=e=>c===0?1:(e-s)/c,u=[],d=new Set(e);for(;d.size>0;){let e=null,t=-1/0;for(let n of d){let r=ce(l(n.score),se(n,u,a),i);(r>t||r===t&&n.score>(e?.score??-1/0))&&(t=r,e=n)}if(e)u.push(e),d.delete(e);else break}return u}function ue(e,t={}){if(e.length===0)return e;let n=new Map;return le(e.map((e,t)=>{let r=`${e.path}:${e.startLine}:${t}`;return n.set(r,e),{id:r,score:e.score,content:e.snippet}}),t).map(e=>n.get(e.id))}const D={enabled:!1,halfLifeDays:30},O=/(?:^|\/)(?:memory)\/(\d{4})-(\d{2})-(\d{2})\.md$/;function de(e){return!Number.isFinite(e)||e<=0?0:Math.LN2/e}function k(e){let t=de(e.halfLifeDays),n=Math.max(0,e.ageInDays);return t<=0||!Number.isFinite(n)?1:Math.exp(-t*n)}function A(e){return e.score*k(e)}function j(e){let t=e.replaceAll(`\\`,`/`).replace(/^\.\//,``),n=O.exec(t);if(!n)return null;let r=Number(n[1]),i=Number(n[2]),a=Number(n[3]);if(!Number.isInteger(r)||!Number.isInteger(i)||!Number.isInteger(a))return null;let o=Date.UTC(r,i-1,a),s=new Date(o);return s.getUTCFullYear()!==r||s.getUTCMonth()!==i-1||s.getUTCDate()!==a?null:s}function M(e){let t=e.replaceAll(`\\`,`/`).replace(/^\.\//,``);return t===`MEMORY.md`||t===`memory.md`?!0:t.startsWith(`memory/`)?!O.test(t):!1}async function N(e){let t=j(e.filePath);if(t)return t;if(e.source===`memory`&&M(e.filePath)||!e.memoryRoot)return null;let n=o.isAbsolute(e.filePath)?e.filePath:o.resolve(e.memoryRoot,e.filePath);try{let e=await a.stat(n);return Number.isFinite(e.mtimeMs)?new Date(e.mtimeMs):null}catch{return null}}function P(e,t){return Math.max(0,t-e.getTime())/864e5}async function F(e){let t={...D,...e.temporalDecay};if(!t.enabled)return[...e.results];let n=e.nowMs??Date.now(),r=new Map;return Promise.all(e.results.map(async i=>{let a=`${i.source}:${i.path}`,o=r.get(a);o||(o=N({filePath:i.path,source:i.source,memoryRoot:e.memoryRoot}),r.set(a,o));let s=await o;if(!s)return i;let c=A({score:i.score,ageInDays:P(s,n),halfLifeDays:t.halfLifeDays});return{...i,score:c}}))}function I(e){let t=e.match(/[\p{L}\p{N}_]+/gu)?.map(e=>e.trim()).filter(Boolean)??[];return t.length===0?null:t.map(e=>`"${e.replaceAll(`"`,``)}"`).join(` AND `)}function L(e){return 1/(1+(Number.isFinite(e)?Math.max(0,e):999))}async function R(e){let t=new Map;for(let n of e.vector)t.set(n.id,{id:n.id,path:n.path,startLine:n.startLine,endLine:n.endLine,source:n.source,snippet:n.snippet,vectorScore:n.vectorScore,textScore:0});for(let n of e.keyword){let e=t.get(n.id);e?(e.textScore=n.textScore,n.snippet&&n.snippet.length>0&&(e.snippet=n.snippet)):t.set(n.id,{id:n.id,path:n.path,startLine:n.startLine,endLine:n.endLine,source:n.source,snippet:n.snippet,vectorScore:0,textScore:n.textScore})}let n=(await F({results:Array.from(t.values()).map(t=>{let n=e.vectorWeight*t.vectorScore+e.textWeight*t.textScore;return{path:t.path,startLine:t.startLine,endLine:t.endLine,score:n,snippet:t.snippet,source:t.source}}),temporalDecay:{...D,...e.temporalDecay},memoryRoot:e.memoryRoot,nowMs:e.nowMs})).slice().sort((e,t)=>t.score-e.score),r={...T,...e.mmr};return r.enabled?ue(n,r):n}function z(e){e.db.exec(`
|
|
4
|
-
CREATE TABLE IF NOT EXISTS meta (
|
|
5
|
-
key TEXT PRIMARY KEY,
|
|
6
|
-
value TEXT NOT NULL
|
|
7
|
-
);
|
|
8
|
-
`),e.db.exec(`
|
|
9
|
-
CREATE TABLE IF NOT EXISTS files (
|
|
10
|
-
path TEXT PRIMARY KEY,
|
|
11
|
-
source TEXT NOT NULL DEFAULT 'memory',
|
|
12
|
-
hash TEXT NOT NULL,
|
|
13
|
-
mtime INTEGER NOT NULL,
|
|
14
|
-
size INTEGER NOT NULL
|
|
15
|
-
);
|
|
16
|
-
`),e.db.exec(`
|
|
17
|
-
CREATE TABLE IF NOT EXISTS chunks (
|
|
18
|
-
id TEXT PRIMARY KEY,
|
|
19
|
-
path TEXT NOT NULL,
|
|
20
|
-
source TEXT NOT NULL DEFAULT 'memory',
|
|
21
|
-
start_line INTEGER NOT NULL,
|
|
22
|
-
end_line INTEGER NOT NULL,
|
|
23
|
-
hash TEXT NOT NULL,
|
|
24
|
-
model TEXT NOT NULL,
|
|
25
|
-
text TEXT NOT NULL,
|
|
26
|
-
embedding TEXT NOT NULL,
|
|
27
|
-
updated_at INTEGER NOT NULL
|
|
28
|
-
);
|
|
29
|
-
`),e.db.exec(`
|
|
30
|
-
CREATE TABLE IF NOT EXISTS ${e.embeddingCacheTable} (
|
|
31
|
-
provider TEXT NOT NULL,
|
|
32
|
-
model TEXT NOT NULL,
|
|
33
|
-
provider_key TEXT NOT NULL,
|
|
34
|
-
hash TEXT NOT NULL,
|
|
35
|
-
embedding TEXT NOT NULL,
|
|
36
|
-
dims INTEGER,
|
|
37
|
-
updated_at INTEGER NOT NULL,
|
|
38
|
-
PRIMARY KEY (provider, model, provider_key, hash)
|
|
39
|
-
);
|
|
40
|
-
`),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_embedding_cache_updated_at ON ${e.embeddingCacheTable}(updated_at);`);let t=!1,n;if(e.ftsEnabled)try{e.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${e.ftsTable} USING fts5(\n text,\n id UNINDEXED,\n path UNINDEXED,\n source UNINDEXED,\n model UNINDEXED,\n start_line UNINDEXED,\n end_line UNINDEXED\n);`),t=!0}catch(e){let r=e instanceof Error?e.message:String(e);t=!1,n=r}return B(e.db,`files`,`source`,`TEXT NOT NULL DEFAULT 'memory'`),B(e.db,`chunks`,`source`,`TEXT NOT NULL DEFAULT 'memory'`),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_path ON chunks(path);`),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_source ON chunks(source);`),{ftsAvailable:t,...n?{ftsError:n}:{}}}function B(e,t,n,r){e.prepare(`PRAGMA table_info(${t})`).all().some(e=>e.name===n)||e.exec(`ALTER TABLE ${t} ADD COLUMN ${n} ${r}`)}function V(e,t){return e.length<=t?e:e.slice(0,t)}const H=e=>Buffer.from(new Float32Array(e).buffer);async function U(e){return e.queryVec.length===0||e.limit<=0?[]:await e.ensureVectorReady(e.queryVec.length)?e.db.prepare(`SELECT c.id, c.path, c.start_line, c.end_line, c.text,
|
|
41
|
-
c.source,
|
|
42
|
-
vec_distance_cosine(v.embedding, ?) AS dist
|
|
43
|
-
FROM ${e.vectorTable} v\n JOIN chunks c ON c.id = v.id\n WHERE c.model = ?${e.sourceFilterVec.sql}\n ORDER BY dist ASC\n LIMIT ?`).all(H(e.queryVec),e.providerModel,...e.sourceFilterVec.params,e.limit).map(t=>({id:t.id,path:t.path,startLine:t.start_line,endLine:t.end_line,score:1-t.dist,snippet:V(t.text,e.snippetMaxChars),source:t.source})):fe({db:e.db,providerModel:e.providerModel,sourceFilter:e.sourceFilterChunks}).map(t=>({chunk:t,score:te(e.queryVec,t.embedding)})).filter(e=>Number.isFinite(e.score)).slice().sort((e,t)=>t.score-e.score).slice(0,e.limit).map(t=>({id:t.chunk.id,path:t.chunk.path,startLine:t.chunk.startLine,endLine:t.chunk.endLine,score:t.score,snippet:V(t.chunk.text,e.snippetMaxChars),source:t.chunk.source}))}function fe(e){return e.db.prepare(`SELECT id, path, start_line, end_line, text, embedding, source
|
|
44
|
-
FROM chunks
|
|
45
|
-
WHERE model = ?${e.sourceFilter.sql}`).all(e.providerModel,...e.sourceFilter.params).map(e=>({id:e.id,path:e.path,startLine:e.start_line,endLine:e.end_line,text:e.text,embedding:b(e.embedding),source:e.source}))}async function pe(e){if(e.limit<=0)return[];let t=e.buildFtsQuery(e.query);if(!t)return[];let n=e.providerModel?` AND model = ?`:``,r=e.providerModel?[e.providerModel]:[];return e.db.prepare(`SELECT id, path, source, start_line, end_line, text,\n bm25(${e.ftsTable}) AS rank\n FROM ${e.ftsTable}\n WHERE ${e.ftsTable} MATCH ?${n}${e.sourceFilter.sql}\n ORDER BY rank ASC\n LIMIT ?`).all(t,...r,...e.sourceFilter.params,e.limit).map(t=>{let n=e.bm25RankToScore(t.rank);return{id:t.id,path:t.path,startLine:t.start_line,endLine:t.end_line,score:n,textScore:n,snippet:V(t.text,e.snippetMaxChars),source:t.source}})}const me=i(import.meta.url);function he(){try{return me(`node:sqlite`)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`SQLite support is unavailable in this Node runtime (missing node:sqlite). ${t}`,{cause:e})}}const W={chunkTokens:400,chunkOverlap:80,maxResults:6,minScore:.2,fallback:{enabled:!0},embedding:{},experimental:{sessionMemory:!1},sources:[`memory`],store:{sessionStoreName:void 0,vector:{enabled:!0}},hybrid:{enabled:!0,vectorWeight:.7,textWeight:.3,candidateMultiplier:4,mmr:{enabled:!1,lambda:.7},temporalDecay:{enabled:!1,halfLifeDays:30}},cache:{enabled:!0,maxEntries:5e4},sync:{onSessionStart:!0,onSearch:!0,watch:!0,watchDebounceMs:1500,sessions:{deltaBytes:1e5,deltaMessages:50}},citations:`auto`};async function ge(e){try{let t=await import(`sqlite-vec`),n=e.extensionPath?.trim()?e.extensionPath.trim():void 0,r=n??t.getLoadablePath();return n?e.db.loadExtension(r):t.load(e.db),{ok:!0,extensionPath:r}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}function _e(e,n,r){let i=t(e,{storeName:r});return o.relative(i,n).replace(/\\/g,`/`)}async function ve(e,n){let r=t(e,{storeName:n});try{let e=await a.readdir(r,{withFileTypes:!0}),t=[];for(let n of e){if(!n.isDirectory())continue;let e=o.join(r,n.name,`transcript.jsonl`);try{(await a.stat(e)).isFile()&&t.push(e)}catch{}}return t}catch(e){if(u(e))return[];throw e}}function ye(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>typeof e==`string`?e:e&&typeof e==`object`&&`text`in e?String(e.text??``):``).filter(Boolean).join(` `):e?String(e):``}async function be(e,t,i){let s;try{s=await a.stat(t)}catch(e){if(u(e))return null;throw e}let c;try{let e=await n(t);if(e===null)return null;c=e}catch(e){if(u(e))return null;throw e}let l=[],d=[],f=c.split(`
|
|
46
|
-
`);for(let e=0;e<f.length;e+=1){let t=f[e]?.trim();if(t)try{let n=JSON.parse(t),r=n.role??`unknown`,i=ye(n.content);if(!i)continue;let a=i.split(`
|
|
47
|
-
`);for(let t of a)l.push(`[${r}] ${t}`),d.push(e+1)}catch{}}let p=l.join(`
|
|
48
|
-
`),m=_(p);return{path:o.join(r(i),_e(e,t,i)).replace(/\\/g,`/`),absPath:t,mtimeMs:s.mtimeMs,size:s.size,hash:m,content:p,lineMap:d}}const G=`chunks_vec`,K=`chunks_fts`,q=`embedding_cache`,J=`memory_index_meta_v1`,Y=3e4;function xe(e,t,n){let r=t.split(`
|
|
49
|
-
`);for(let t of r){let n=t.match(/^##\s+(.+)$/);if(n?.[1])return`${e}#${n[1].trim()}`}return`${e}#L${n}`}const X=new Map;function Z(e,t){let n={...e,...t,hybrid:{...e.hybrid,...t?.hybrid??{}},cache:{...e.cache,...t?.cache??{}},sync:{...e.sync,...t?.sync??{}},experimental:{...e.experimental,...t?.experimental??{}},sources:t?.sources??e.sources,embedding:{...e.embedding,...t?.embedding??{}},store:{...e.store,...t?.store??{},vector:{...e.store.vector,...t?.store?.vector??{}}}};return n.experimental.sessionMemory&&!n.sources.includes(`sessions`)&&(n.sources=[...n.sources,`sessions`]),n}var Q=class e{dataDir;memoryRoot;storePath;config;sessionStoreName;provider;providerKey;embeddingProviderId;db;dirty=!0;ftsAvailable=!1;ftsError;vector={enabled:!0,available:null,extensionPath:void 0,loadError:void 0,dims:void 0};vectorReady=null;watchers=[];watchTimer=null;sessionWatchTimer=null;sessionsDirty=!1;sessionsDirtyFiles=new Set;sessionPendingFiles=new Set;searchFallbackOnly=!1;lastRebuildSummary;sessionDeltas=new Map;static get(t,n){let i=o.join(t,`.aimax`),a=Z(W,n),s=`${i}::${r(a.store.sessionStoreName)}`,c=X.get(s);if(c)return n&&c.applyConfig(n),c;let l=new e(t,i,a);return X.set(s,l),l}constructor(e,t,n){this.dataDir=e,this.memoryRoot=t,this.storePath=o.join(t,`.index.sqlite`),this.config=Z(W,n),this.sessionStoreName=r(this.config.store.sessionStoreName),this.provider=S(),this.providerKey=this.computeProviderKey(),this.applyEmbeddingProvider(),this.vector.enabled=this.config.store.vector.enabled,this.vector.extensionPath=this.config.store.vector.extensionPath,this.db=this.openDatabase(),this.ensureSchema(),this.ensureWatcher(),this.ensureSessionListener(),this.dirty=!0}applyConfig(e){this.config=Z(this.config,e),this.sessionStoreName=r(this.config.store.sessionStoreName),this.applyEmbeddingProvider(),this.vector.enabled=this.config.store.vector.enabled,this.vector.extensionPath=this.config.store.vector.extensionPath,this.ensureWatcher(),this.ensureSessionListener()}warmSession(){this.config.sync.onSessionStart&&this.sync({reason:`session-start`}).catch(()=>{})}noteSessionUpdate(e){this.scheduleSessionDirty(e)}status(){let e=this.buildSourceFilter(),t=this.db.prepare(`SELECT COUNT(*) as c FROM files WHERE 1=1${e.sql}`).get(...e.params),n=this.db.prepare(`SELECT COUNT(*) as c FROM chunks WHERE 1=1${e.sql}`).get(...e.params),r=(()=>{let t=Array.from(this.config.sources);if(t.length===0)return[];let n=new Map;for(let e of t)n.set(e,{files:0,chunks:0});let r=this.db.prepare(`SELECT source, COUNT(*) as c FROM files WHERE 1=1${e.sql} GROUP BY source`).all(...e.params);for(let e of r){let t=n.get(e.source)??{files:0,chunks:0};t.files=e.c??0,n.set(e.source,t)}let i=this.db.prepare(`SELECT source, COUNT(*) as c FROM chunks WHERE 1=1${e.sql} GROUP BY source`).all(...e.params);for(let e of i){let t=n.get(e.source)??{files:0,chunks:0};t.chunks=e.c??0,n.set(e.source,t)}return t.map(e=>Object.assign({source:e},n.get(e)))})(),i=this.provider?`hybrid`:`fts-only`,a=this.config.cache.enabled?this.db.prepare(`SELECT COUNT(*) as c FROM ${q}`).get()?.c??0:void 0;return{backend:`builtin`,files:t?.c??0,chunks:n?.c??0,dirty:this.dirty||this.sessionsDirty,workspaceDir:this.memoryRoot,dbPath:this.storePath,provider:this.provider.id,model:this.provider.model,sources:Array.from(this.config.sources),sourceCounts:r,cache:this.config.cache.enabled?{enabled:!0,entries:a,maxEntries:this.config.cache.maxEntries}:{enabled:!1,maxEntries:this.config.cache.maxEntries},fts:{enabled:this.config.hybrid.enabled,available:this.ftsAvailable,error:this.ftsError,rows:this.getFtsRowCount()},vector:{enabled:this.vector.enabled,available:this.vector.available??void 0,extensionPath:this.vector.extensionPath,loadError:this.vector.loadError,dims:this.vector.dims},custom:{searchMode:i,fallbackActive:this.searchFallbackOnly,lastRebuildSummary:this.lastRebuildSummary}}}async probeEmbeddingAvailability(){try{return await this.provider.embedBatch([`ping`]),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async probeVectorAvailability(){return this.vector.enabled?await this.ensureVectorReady():!1}async search(e){let t=e.trim();if(!t)return[];if(this.readMeta()?this.config.sync.onSearch&&(this.dirty||this.sessionsDirty)&&this.sync({reason:`search`}).catch(()=>{this.searchFallbackOnly=!0}):await this.sync({reason:`boot`}).catch(()=>{this.searchFallbackOnly=!0}),this.searchFallbackOnly)return this.decorateCitations(await this.fileScanSearch(t));let n=this.config.hybrid,r=Math.min(200,Math.max(1,Math.floor(this.config.maxResults*n.candidateMultiplier))),i=n.enabled&&this.ftsAvailable?await this.searchKeyword(t,r).catch(()=>[]):[],a=await this.provider.embedQuery(t).catch(()=>[]),o=a.some(e=>e!==0)?await this.searchVector(a,r).catch(()=>[]):[],s=[];if(!n.enabled||!this.ftsAvailable)s=o.filter(e=>e.score>=this.config.minScore).slice(0,this.config.maxResults);else{let e=await R({vector:o.map(e=>({id:`${e.path}:${e.startLine}:${e.endLine}:${e.source}`,path:e.path,startLine:e.startLine,endLine:e.endLine,source:e.source,snippet:e.snippet,vectorScore:e.score})),keyword:i.map(e=>({id:`${e.path}:${e.startLine}:${e.endLine}:${e.source}`,path:e.path,startLine:e.startLine,endLine:e.endLine,source:e.source,snippet:e.snippet,textScore:e.textScore})),vectorWeight:n.vectorWeight,textWeight:n.textWeight,mmr:n.mmr,temporalDecay:n.temporalDecay,memoryRoot:this.memoryRoot}),t=e.filter(e=>e.score>=this.config.minScore);if(t.length>0||i.length===0)s=t.slice(0,this.config.maxResults);else{let t=Math.min(this.config.minScore,n.textWeight);s=e.filter(e=>e.score>=t).slice(0,this.config.maxResults)}}return s.length>0?this.decorateCitations(this.decorateEntryIds(s)):this.config.fallback.enabled?(this.searchFallbackOnly=!0,this.decorateCitations(this.decorateEntryIds(await this.fileScanSearch(t)))):[]}async readFile(e){let{absPath:t,relPath:n}=this.resolveMemoryFilePath(e.relPath);if((await d(t)).missing)return{text:``,path:n};let r;try{r=await a.readFile(t,`utf-8`)}catch(e){if(u(e))return{text:``,path:n};throw e}if(!e.from&&!e.lines)return{text:r,path:n};let i=r.split(`
|
|
50
|
-
`),o=Math.max(1,e.from??1),s=Math.max(1,e.lines??i.length);return{text:i.slice(o-1,o-1+s).join(`
|
|
51
|
-
`),path:n}}async replaceFile(e){let{absPath:t}=this.resolveMemoryFilePath(e.relPath);await a.mkdir(o.dirname(t),{recursive:!0}),await a.writeFile(t,e.content,`utf-8`),this.dirty=!0,await this.syncAndPostCheck(`replace`)}async deleteFile(e){let{absPath:t}=this.resolveMemoryFilePath(e);try{await a.unlink(t)}catch(e){if(u(e))return;throw e}this.dirty=!0,await this.syncAndPostCheck(`delete`)}async appendToMemory(e){let t=this.memoryRoot;await a.mkdir(t,{recursive:!0});let n=o.join(t,`MEMORY.md`),r=e.endsWith(`
|
|
52
|
-
`)?e:`${e}\n`;await a.appendFile(n,r,`utf-8`),this.dirty=!0,await this.syncAndPostCheck(`append`)}openDatabase(){f(o.dirname(this.storePath));let{DatabaseSync:e}=he();return new e(this.storePath,{allowExtension:this.vector.enabled})}ensureSchema(){let e=z({db:this.db,embeddingCacheTable:q,ftsTable:K,ftsEnabled:this.config.hybrid.enabled});this.ftsAvailable=e.ftsAvailable,e.ftsError&&(this.ftsError=e.ftsError)}async ensureVectorReady(e){if(!this.vector.enabled)return!1;this.vectorReady||=this.withTimeout(this.loadVectorExtension(),Y,`sqlite-vec load timed out after ${Math.round(Y/1e3)}s`);let t=!1;try{t=await this.vectorReady||!1}catch(e){let t=e instanceof Error?e.message:String(e);return this.vector.available=!1,this.vector.loadError=t,this.vectorReady=null,!1}return t&&typeof e==`number`&&e>0&&this.ensureVectorTable(e),t}async loadVectorExtension(){if(this.vector.available!==null)return this.vector.available;if(!this.vector.enabled)return this.vector.available=!1,!1;try{let e=this.vector.extensionPath?.trim()?this.vector.extensionPath.trim():void 0,t=await ge({db:this.db,extensionPath:e});if(!t.ok)throw Error(t.error??`unknown sqlite-vec load error`);return this.vector.extensionPath=t.extensionPath,this.vector.available=!0,!0}catch(e){let t=e instanceof Error?e.message:String(e);return this.vector.available=!1,this.vector.loadError=t,!1}}ensureVectorTable(e){this.vector.dims!==e&&(this.vector.dims&&this.vector.dims!==e&&this.dropVectorTable(),this.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${G} USING vec0(\n id TEXT PRIMARY KEY,\n embedding FLOAT[${e}]\n)`),this.vector.dims=e)}dropVectorTable(){try{this.db.exec(`DROP TABLE IF EXISTS ${G}`)}catch{}}async withTimeout(e,t,n){if(!Number.isFinite(t)||t<=0)return await e;let r=null,i=new Promise((e,i)=>{r=setTimeout(()=>i(Error(n)),t)});try{return await Promise.race([e,i])}finally{r&&clearTimeout(r)}}ensureWatcher(){if(!this.config.sync.watch||this.watchers.length>0)return;let e=[o.join(this.memoryRoot,`MEMORY.md`),o.join(this.memoryRoot,`memory.md`),o.join(this.memoryRoot,`memory`)],t=()=>{this.dirty=!0,this.scheduleWatchSync()};for(let n of e)try{let e=l.watch(n,{recursive:!1},t);e.on(`error`,()=>{try{e.close()}catch{}}),this.watchers.push(e)}catch{}}scheduleWatchSync(){this.config.sync.watch&&(this.watchTimer&&clearTimeout(this.watchTimer),this.watchTimer=setTimeout(()=>{this.watchTimer=null,this.sync({reason:`watch`}).catch(()=>{})},this.config.sync.watchDebounceMs))}ensureSessionListener(){if(!this.config.experimental.sessionMemory)return;let e=t(this.dataDir,{storeName:this.sessionStoreName});try{let t=l.watch(e,{recursive:!0},(t,n)=>{if(!n||!n.endsWith(`transcript.jsonl`))return;let r=o.join(e,n);this.scheduleSessionDirty(r)});this.watchers.push(t)}catch{}}scheduleSessionDirty(e){this.config.experimental.sessionMemory&&(this.sessionPendingFiles.add(e),!this.sessionWatchTimer&&(this.sessionWatchTimer=setTimeout(()=>{this.sessionWatchTimer=null,this.processSessionDeltaBatch().catch(()=>{})},5e3)))}async processSessionDeltaBatch(){if(this.sessionPendingFiles.size===0)return;let e=Array.from(this.sessionPendingFiles);this.sessionPendingFiles.clear();let t=!1;for(let n of e){let e=await this.updateSessionDelta(n);if(!e)continue;let r=e.deltaBytes,i=e.deltaMessages,a=r<=0?e.pendingBytes>0:e.pendingBytes>=r,o=i<=0?e.pendingMessages>0:e.pendingMessages>=i;!a&&!o||(this.sessionsDirtyFiles.add(n),this.sessionsDirty=!0,e.pendingBytes=r>0?Math.max(0,e.pendingBytes-r):0,e.pendingMessages=i>0?Math.max(0,e.pendingMessages-i):0,t=!0)}t&&this.sync({reason:`session-delta`}).catch(()=>{})}async updateSessionDelta(e){let t=this.config.sync.sessions;if(!t)return null;let n;try{n=await a.stat(e)}catch{return null}let r=n.size,i=this.sessionDeltas.get(e);i||(i={lastSize:0,pendingBytes:0,pendingMessages:0},this.sessionDeltas.set(e,i));let o=Math.max(0,r-i.lastSize);return o===0&&r===i.lastSize?{deltaBytes:t.deltaBytes,deltaMessages:t.deltaMessages,pendingBytes:i.pendingBytes,pendingMessages:i.pendingMessages}:(r<i.lastSize?(i.lastSize=r,i.pendingBytes+=r,t.deltaMessages>0&&(t.deltaBytes<=0||i.pendingBytes<t.deltaBytes)&&(i.pendingMessages+=await this.countNewlines(e,0,r))):(i.pendingBytes+=o,t.deltaMessages>0&&(t.deltaBytes<=0||i.pendingBytes<t.deltaBytes)&&(i.pendingMessages+=await this.countNewlines(e,i.lastSize,r)),i.lastSize=r),this.sessionDeltas.set(e,i),{deltaBytes:t.deltaBytes,deltaMessages:t.deltaMessages,pendingBytes:i.pendingBytes,pendingMessages:i.pendingMessages})}async countNewlines(e,t,n){if(n<=t)return 0;let r;try{r=await a.open(e,`r`)}catch{return 0}try{let e=t,i=0,a=Buffer.alloc(64*1024);for(;e<n;){let t=Math.min(a.length,n-e),{bytesRead:o}=await r.read(a,0,t,e);if(o<=0)break;for(let e=0;e<o;e+=1)a[e]===10&&(i+=1);e+=o}return i}finally{await r.close()}}computeProviderKey(){return _(JSON.stringify({provider:this.provider.id,model:this.provider.model}))}resolveMemoryFilePath(e){let t=e.trim();if(!t)throw Error(`path required`);let n=o.isAbsolute(t)?o.resolve(t):o.resolve(this.memoryRoot,t),r=o.relative(this.memoryRoot,n).replace(/\\/g,`/`);if(!(r.length>0&&!r.startsWith(`..`)&&!o.isAbsolute(r)&&m(r))||!n.endsWith(`.md`))throw Error(`path required`);return{absPath:n,relPath:r}}applyEmbeddingProvider(){let e=this.config.embedding?.providerId?.trim();if(e){let t=w({providerId:e,dataDir:this.dataDir,memoryDir:this.memoryRoot});if(!t)throw Error(`Embedding provider not found: ${e}`);this.provider=t.provider,this.embeddingProviderId=e,this.providerKey=this.computeProviderKey(),this.dirty=!0;return}this.embeddingProviderId&&(this.provider=S(),this.embeddingProviderId=void 0,this.providerKey=this.computeProviderKey(),this.dirty=!0)}readMeta(){let e=this.db.prepare(`SELECT value FROM meta WHERE key = ?`).get(J);if(!e?.value)return null;try{return JSON.parse(e.value)}catch{return null}}writeMeta(e){let t=JSON.stringify(e);this.db.prepare(`INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(J,t)}loadEmbeddingCache(e){if(!this.config.cache.enabled||e.length===0)return new Map;let t=Array.from(new Set(e.filter(Boolean)));if(t.length===0)return new Map;let n=new Map,r=[this.provider.id,this.provider.model,this.providerKey];for(let e=0;e<t.length;e+=400){let i=t.slice(e,e+400),a=i.map(()=>`?`).join(`, `),o=this.db.prepare(`SELECT hash, embedding FROM ${q}\n WHERE provider = ? AND model = ? AND provider_key = ? AND hash IN (${a})`).all(...r,...i);for(let e of o)n.set(e.hash,b(e.embedding))}return n}upsertEmbeddingCache(e){if(!this.config.cache.enabled||e.length===0)return;let t=Date.now(),n=this.db.prepare(`INSERT INTO ${q} (provider, model, provider_key, hash, embedding, dims, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(provider, model, provider_key, hash) DO UPDATE SET\n embedding=excluded.embedding,\n dims=excluded.dims,\n updated_at=excluded.updated_at`);for(let r of e){let e=r.embedding??[];n.run(this.provider.id,this.provider.model,this.providerKey,r.hash,JSON.stringify(e),e.length,t)}}async embedChunks(e){if(e.length===0)return[];let t=this.loadEmbeddingCache(e.map(e=>e.hash)),n=Array.from({length:e.length},()=>[]),r=[];for(let i=0;i<e.length;i+=1){let a=e[i],o=a?.hash?t.get(a.hash):void 0;o&&o.length>0?n[i]=o:a&&r.push({index:i,chunk:a})}if(r.length===0)return n;let i=await this.provider.embedBatch(r.map(e=>e.chunk.text)),a=[];for(let e=0;e<r.length;e+=1){let t=r[e],o=i[e]??[];n[t.index]=o,a.push({hash:t.chunk.hash,embedding:o})}return this.upsertEmbeddingCache(a),n}async indexFile(e,t){let n=y(t.content??await a.readFile(e.absPath,`utf-8`),{tokens:this.config.chunkTokens,overlap:this.config.chunkOverlap}).filter(e=>e.text.trim().length>0);t.source===`sessions`&&ee(n,t.lineMap);let r=await this.embedChunks(n),i=r.find(e=>e.length>0),o=i?await this.ensureVectorReady(i.length):!1,s=Date.now();if(o)try{this.db.prepare(`DELETE FROM ${G} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,t.source)}catch{}if(this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${K} WHERE path = ? AND source = ? AND model = ?`).run(e.path,t.source,this.provider.model)}catch{}this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,t.source);for(let i=0;i<n.length;i+=1){let a=n[i],c=r[i]??[],l=_(`${t.source}:${e.path}:${a.startLine}:${a.endLine}:${a.hash}:${this.provider.model}`);if(this.db.prepare(`INSERT INTO chunks (id, path, source, start_line, end_line, hash, model, text, embedding, updated_at)
|
|
53
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
54
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
55
|
-
hash=excluded.hash,
|
|
56
|
-
model=excluded.model,
|
|
57
|
-
text=excluded.text,
|
|
58
|
-
embedding=excluded.embedding,
|
|
59
|
-
updated_at=excluded.updated_at`).run(l,e.path,t.source,a.startLine,a.endLine,a.hash,this.provider.model,a.text,JSON.stringify(c),s),o&&c.length>0){try{this.db.prepare(`DELETE FROM ${G} WHERE id = ?`).run(l)}catch{}this.db.prepare(`INSERT INTO ${G} (id, embedding) VALUES (?, ?)`).run(l,Buffer.from(new Float32Array(c).buffer))}this.ftsAvailable&&this.db.prepare(`INSERT INTO ${K} (text, id, path, source, model, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?, ?)`).run(a.text,l,e.path,t.source,this.provider.model,a.startLine,a.endLine)}this.db.prepare(`INSERT INTO files (path, source, hash, mtime, size) VALUES (?, ?, ?, ?, ?)
|
|
60
|
-
ON CONFLICT(path) DO UPDATE SET
|
|
61
|
-
source=excluded.source,
|
|
62
|
-
hash=excluded.hash,
|
|
63
|
-
mtime=excluded.mtime,
|
|
64
|
-
size=excluded.size`).run(e.path,t.source,e.hash,e.mtimeMs,e.size)}buildSourceFilter(){let e=this.config.sources;return e.length?{sql:` AND source IN (${e.map(()=>`?`).join(`, `)})`,params:e}:{sql:``,params:[]}}async searchVector(e,t){return await U({db:this.db,vectorTable:G,providerModel:this.provider.model,queryVec:e,limit:t,snippetMaxChars:700,ensureVectorReady:async e=>await this.ensureVectorReady(e),sourceFilterVec:this.buildSourceFilter(),sourceFilterChunks:this.buildSourceFilter()})}async searchKeyword(e,t){return this.ftsAvailable?await pe({db:this.db,ftsTable:K,providerModel:this.provider.model,query:e,limit:t,snippetMaxChars:700,sourceFilter:this.buildSourceFilter(),buildFtsQuery:e=>I(e),bm25RankToScore:L}):[]}resetIndex(){if(this.db.exec(`DELETE FROM files`),this.db.exec(`DELETE FROM chunks`),this.ftsAvailable)try{this.db.exec(`DELETE FROM ${K}`)}catch{}this.dropVectorTable(),this.vector.dims=void 0,this.sessionsDirtyFiles.clear()}async syncAndPostCheck(e){try{await this.sync({reason:`mutation-postcheck`})}catch{this.searchFallbackOnly=!0;return}this.searchFallbackOnly=!this.indexHasSearchableData()}indexHasSearchableData(){try{if((this.db.prepare(`SELECT COUNT(*) as c FROM chunks`).get()?.c??0)>0)return!0}catch{}try{if(l.readdirSync(this.memoryRoot).filter(e=>e.endsWith(`.md`)).length>0)return!1;let e=o.join(this.memoryRoot,`memory`);return l.existsSync(e)?l.readdirSync(e).filter(e=>e.endsWith(`.md`)).length===0:!0}catch{return!1}}async fileScanSearch(e){let t=e.trim().toLowerCase();if(!t)return[];let n=await g(this.memoryRoot),r=[];for(let e of n){let n=``;try{n=await a.readFile(e,`utf-8`)}catch{continue}let i=o.relative(this.memoryRoot,e).replace(/\\/g,`/`);i.startsWith(`memory/`);let c=n.split(`
|
|
65
|
-
`);for(let n=0;n<c.length;n+=1){let a=c[n]??``,o=a.toLowerCase();if(!o.includes(t))continue;let l=o===t?1:Math.max(.2,t.length/Math.max(a.length,t.length));r.push({path:i||s(e),startLine:n+1,endLine:n+1,score:Number(l.toFixed(4)),snippet:a.slice(0,700),source:`memory`})}}return r.sort((e,t)=>t.score-e.score||e.path.localeCompare(t.path)||e.startLine-t.startLine),r.slice(0,this.config.maxResults)}getFtsRowCount(){if(this.ftsAvailable)try{return this.db.prepare(`SELECT COUNT(*) as c FROM ${K}`).get()?.c??0}catch{return}}buildRebuildSummary(e){let t=this.db.prepare(`SELECT COUNT(*) as c FROM chunks`).get();return{reason:e.reason,memoryFilesIndexed:e.memoryFilesIndexed,sessionFilesIndexed:e.sessionFilesIndexed,staleMemoryFilesRemoved:e.staleMemoryFilesRemoved,staleSessionFilesRemoved:e.staleSessionFilesRemoved,chunks:t?.c??0,ftsRows:this.getFtsRowCount(),fallbackActive:this.searchFallbackOnly,needsFullReindex:e.needsFullReindex}}async rebuild(e=`manual-rebuild`){return this.resetIndex(),this.dirty=!0,this.sessionsDirty=!0,await this.sync({reason:e,forceFullReindex:!0}),this.lastRebuildSummary??this.buildRebuildSummary({reason:e,memoryFilesIndexed:0,sessionFilesIndexed:0,staleMemoryFilesRemoved:0,staleSessionFilesRemoved:0,needsFullReindex:!0})}async sync(e){let t=this.readMeta(),n=e?.forceFullReindex||!t||t.model!==this.provider.model||t.provider!==this.provider.id||t.providerKey!==this.providerKey||t.chunkTokens!==this.config.chunkTokens||t.chunkOverlap!==this.config.chunkOverlap||this.vector.available&&!t?.vectorDims;n&&this.resetIndex();let r=await g(this.memoryRoot),i=(await Promise.all(r.map(async e=>v(e,this.memoryRoot)))).filter(e=>e!==null),a=new Set(i.map(e=>e.path)),o=0,s=i.map(e=>async()=>{let t=this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(e.path,`memory`);!n&&t?.hash===e.hash||(await this.indexFile(e,{source:`memory`}),o+=1)});for(let e of s)await e();let c=0,l=this.db.prepare(`SELECT path FROM files WHERE source = ?`).all(`memory`);for(let e of l)if(!a.has(e.path)){this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(e.path,`memory`),c+=1;try{this.db.prepare(`DELETE FROM ${G} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,`memory`)}catch{}if(this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,`memory`),this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${K} WHERE path = ? AND source = ? AND model = ?`).run(e.path,`memory`,this.provider.model)}catch{}}let u={indexed:0,staleRemoved:0};this.config.experimental.sessionMemory&&(n||this.sessionsDirty)&&(u=await this.syncSessionFiles(n)),this.writeMeta({model:this.provider.model,provider:this.provider.id,providerKey:this.providerKey,chunkTokens:this.config.chunkTokens,chunkOverlap:this.config.chunkOverlap,...this.vector.available&&this.vector.dims?{vectorDims:this.vector.dims}:{}}),this.dirty=!1,this.searchFallbackOnly=!this.indexHasSearchableData(),this.lastRebuildSummary=this.buildRebuildSummary({reason:e?.reason??`sync`,memoryFilesIndexed:o,sessionFilesIndexed:u.indexed,staleMemoryFilesRemoved:c,staleSessionFilesRemoved:u.staleRemoved,needsFullReindex:!!n})}async syncSessionFiles(e){let t=await ve(this.dataDir,this.sessionStoreName),n=(await Promise.all(t.map(async e=>be(this.dataDir,e,this.sessionStoreName)))).filter(e=>e!==null),r=new Set(n.map(e=>e.path)),i=e||this.sessionsDirtyFiles.size===0,a=0;for(let t of n){if(!i&&!this.sessionsDirtyFiles.has(t.absPath))continue;let n=this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(t.path,`sessions`);if(!e&&n?.hash===t.hash){this.resetSessionDelta(t.absPath,t.size);continue}await this.indexFile(t,{source:`sessions`,content:t.content,lineMap:t.lineMap}),a+=1,this.resetSessionDelta(t.absPath,t.size)}let o=0,s=this.db.prepare(`SELECT path FROM files WHERE source = ?`).all(`sessions`);for(let e of s)if(!r.has(e.path)){this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(e.path,`sessions`),o+=1;try{this.db.prepare(`DELETE FROM ${G} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,`sessions`)}catch{}if(this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,`sessions`),this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${K} WHERE path = ? AND source = ? AND model = ?`).run(e.path,`sessions`,this.provider.model)}catch{}}return this.sessionsDirty=!1,this.sessionsDirtyFiles.clear(),{indexed:a,staleRemoved:o}}resetSessionDelta(e,t){let n=this.sessionDeltas.get(e);n&&(n.lastSize=t,n.pendingBytes=0,n.pendingMessages=0)}decorateCitations(e){return this.config.citations===`off`?e:e.map(e=>{let t=`Source: ${e.path}#L${e.startLine}-L${e.endLine}`;return this.config.citations===`on`?{...e,citation:t,snippet:`${e.snippet}\n\n${t}`}:{...e,citation:t}})}decorateEntryIds(e){return e.map(e=>{if(e.id)return e;let t=xe(e.path,e.snippet,e.startLine);return{...e,id:t}})}},Se=e({createBuiltinMemoryProvider:()=>$});function $(e,t){let n=Q.get(e.dataDir,t?.includeSessions?{experimental:{sessionMemory:!0},sources:[`memory`,`sessions`],store:{sessionStoreName:e.sessionStoreName,vector:{enabled:!0}}}:e.sessionStoreName?{store:{sessionStoreName:e.sessionStoreName,vector:{enabled:!0}}}:void 0),r=e.memoryDir;return{id:`builtin-memory`,name:`Builtin Memory Provider`,status:()=>n.status(),search:async(e,t)=>n.search(e),getLines:async(e,t,r)=>{let i=Math.max(1,r-t+1),a=await n.readFile({relPath:e,from:t,lines:i});return a.text?a.text.split(`
|
|
66
|
-
`):[]},listFiles:async()=>g(r),append:async e=>n.appendToMemory(e),updateFile:async(e,t)=>{await n.replaceFile({relPath:e,content:t})},deleteFile:async e=>{await n.deleteFile(e)},sync:async e=>{if(e===`cli-rebuild`){await n.rebuild(e);return}await n.sync({reason:e??`provider-sync`})},noteSessionUpdate:e=>{let t=o.isAbsolute(e)?e:o.resolve(e);n.noteSessionUpdate(t)}}}export{ae as a,ie as i,$ as n,w as o,Q as r,g as s,Se as t};
|