open-mem 0.14.0 → 0.14.2
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 +6 -0
- package/README.md +58 -1
- package/dist/claude-code.js +88 -87
- package/dist/cursor.js +88 -87
- package/dist/daemon/manager.d.ts +33 -5
- package/dist/daemon/manager.d.ts.map +1 -1
- package/dist/daemon/pid.d.ts +23 -0
- package/dist/daemon/pid.d.ts.map +1 -1
- package/dist/daemon.js +35 -34
- package/dist/db/advisory-lock.d.ts +40 -0
- package/dist/db/advisory-lock.d.ts.map +1 -0
- package/dist/db/database.d.ts +37 -4
- package/dist/db/database.d.ts.map +1 -1
- package/dist/doctor.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +99 -98
- package/dist/maintenance.js +48 -45
- package/dist/mcp.js +72 -71
- package/dist/platform-worker.d.ts.map +1 -1
- package/dist/runtime/queue-runtime.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/daemon/manager.d.ts
CHANGED
|
@@ -1,8 +1,39 @@
|
|
|
1
|
+
import { type KnownProcessType } from "./pid";
|
|
1
2
|
interface DaemonManagerConfig {
|
|
2
3
|
dbPath: string;
|
|
3
4
|
projectPath: string;
|
|
4
5
|
daemonScript: string;
|
|
5
6
|
}
|
|
7
|
+
export interface DaemonStatus {
|
|
8
|
+
state: "running" | "missing" | "dead";
|
|
9
|
+
running: boolean;
|
|
10
|
+
pid: number | null;
|
|
11
|
+
stalePid: number | null;
|
|
12
|
+
stalePidRemoved: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface DaemonSignalResult {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
state: "delivered" | "no-daemon" | "daemon-dead" | "unsupported-signal" | "delivery-failed";
|
|
17
|
+
via: "ipc" | "os-signal" | "none";
|
|
18
|
+
pid: number | null;
|
|
19
|
+
message: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface MaintenancePreflightProcessStatus {
|
|
23
|
+
processType: KnownProcessType;
|
|
24
|
+
state: "running" | "missing" | "dead";
|
|
25
|
+
running: boolean;
|
|
26
|
+
pidPath: string;
|
|
27
|
+
pid: number | null;
|
|
28
|
+
stalePid: number | null;
|
|
29
|
+
stalePidRemoved: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface MaintenancePreflightStatus {
|
|
32
|
+
blocked: boolean;
|
|
33
|
+
activeProcesses: MaintenancePreflightProcessStatus[];
|
|
34
|
+
checks: MaintenancePreflightProcessStatus[];
|
|
35
|
+
}
|
|
36
|
+
export declare function getMaintenancePreflightStatus(dbPath: string): MaintenancePreflightStatus;
|
|
6
37
|
/** Manages the lifecycle of a background daemon subprocess for queue processing. */
|
|
7
38
|
export declare class DaemonManager {
|
|
8
39
|
private readonly pidPath;
|
|
@@ -11,13 +42,10 @@ export declare class DaemonManager {
|
|
|
11
42
|
private subprocess;
|
|
12
43
|
constructor(config: DaemonManagerConfig);
|
|
13
44
|
start(): boolean;
|
|
14
|
-
signal(message: string):
|
|
45
|
+
signal(message: string): DaemonSignalResult;
|
|
15
46
|
stop(): void;
|
|
16
47
|
isRunning(): boolean;
|
|
17
|
-
getStatus():
|
|
18
|
-
running: boolean;
|
|
19
|
-
pid: number | null;
|
|
20
|
-
};
|
|
48
|
+
getStatus(): DaemonStatus;
|
|
21
49
|
}
|
|
22
50
|
export {};
|
|
23
51
|
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/daemon/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/daemon/manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAKN,KAAK,gBAAgB,EAGrB,MAAM,OAAO,CAAC;AAKf,UAAU,mBAAmB;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,oBAAoB,GAAG,iBAAiB,CAAC;IAC5F,GAAG,EAAE,KAAK,GAAG,WAAW,GAAG,MAAM,CAAC;IAClC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iCAAiC;IACjD,WAAW,EAAE,gBAAgB,CAAC;IAC9B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,iCAAiC,EAAE,CAAC;IACrD,MAAM,EAAE,iCAAiC,EAAE,CAAC;CAC5C;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,GAAG,0BAA0B,CAyDxF;AAED,oFAAoF;AACpF,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,UAAU,CAA6C;gBAEnD,MAAM,EAAE,mBAAmB;IAMvC,KAAK,IAAI,OAAO;IA+BhB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB;IAgF3C,IAAI,IAAI,IAAI;IAaZ,SAAS,IAAI,OAAO;IAIpB,SAAS,IAAI,YAAY;CAGzB"}
|
package/dist/daemon/pid.d.ts
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
|
+
export interface PidLivenessStatus {
|
|
2
|
+
state: "alive" | "missing" | "dead";
|
|
3
|
+
pid: number | null;
|
|
4
|
+
stalePid: number | null;
|
|
5
|
+
stalePidRemoved: boolean;
|
|
6
|
+
}
|
|
7
|
+
export type PlatformWorkerProcessKind = "claude" | "cursor";
|
|
8
|
+
export type KnownProcessType = "daemon" | "platform-worker-claude" | "platform-worker-cursor";
|
|
9
|
+
export interface KnownProcessPidFile {
|
|
10
|
+
type: KnownProcessType;
|
|
11
|
+
pidPath: string;
|
|
12
|
+
}
|
|
1
13
|
/** Write the current process PID to the given file path. */
|
|
2
14
|
export declare function writePid(pidPath: string): void;
|
|
3
15
|
/** Read a PID from file, returning null if missing or invalid. */
|
|
4
16
|
export declare function readPid(pidPath: string): number | null;
|
|
5
17
|
/** Check whether a process with the given PID is still running. */
|
|
6
18
|
export declare function isProcessAlive(pid: number): boolean;
|
|
19
|
+
/** Resolve process liveness from a PID file with optional stale cleanup. */
|
|
20
|
+
export declare function getPidLiveness(pidPath: string, removeStale: boolean): PidLivenessStatus;
|
|
7
21
|
/** Remove a PID file, ignoring errors if it doesn't exist. */
|
|
8
22
|
export declare function removePid(pidPath: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Remove a PID file only when it still belongs to the expected PID.
|
|
25
|
+
* Returns true only when a matching PID file was removed.
|
|
26
|
+
*/
|
|
27
|
+
export declare function removePidIfMatches(pidPath: string, expectedPid: number): boolean;
|
|
9
28
|
/** Derive the PID file path from the database path. */
|
|
10
29
|
export declare function getPidPath(dbPath: string): string;
|
|
30
|
+
/** Derive the platform worker PID path from the database path and worker kind. */
|
|
31
|
+
export declare function getPlatformWorkerPidPath(dbPath: string, kind: PlatformWorkerProcessKind): string;
|
|
32
|
+
/** Derive known process PID files associated with the database path. */
|
|
33
|
+
export declare function getKnownProcessPidFiles(dbPath: string): KnownProcessPidFile[];
|
|
11
34
|
//# sourceMappingURL=pid.d.ts.map
|
package/dist/daemon/pid.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pid.d.ts","sourceRoot":"","sources":["../../src/daemon/pid.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAO9C;AAED,kEAAkE;AAClE,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUtD;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWnD;AAED,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAM/C;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMjD"}
|
|
1
|
+
{"version":3,"file":"pid.d.ts","sourceRoot":"","sources":["../../src/daemon/pid.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,wBAAwB,GAAG,wBAAwB,CAAC;AAE9F,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,4DAA4D;AAC5D,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAO9C;AAED,kEAAkE;AAClE,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUtD;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWnD;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,iBAAiB,CAavF;AAED,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAM/C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAYhF;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,MAAM,CAIhG;AAED,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAM7E"}
|
package/dist/daemon.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
var A=import.meta.require;import{parseArgs as
|
|
3
|
+
var A=import.meta.require;import{parseArgs as KJ}from"util";import{generateText as XV}from"ai";function j($){if(typeof $!=="object"||$===null)return!1;let V=$,J=V.status;if(J===429||J===500||J===503)return!0;let X=V.error;if(typeof X==="object"&&X!==null&&X.type==="overloaded_error")return!0;return!1}function P($){if($&&typeof $==="object"){let V=$.status;if(typeof V==="number")return V===400||V===401||V===403}return!1}function C($){return new Promise((V)=>setTimeout(V,$))}var i$=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function U($,V){let J=new RegExp(`<${V}[^>]*>([\\s\\S]*?)</${V}>`,"i"),X=$.match(J);return X?X[1].trim():""}function _($,V){let J=new RegExp(`<${V}[^>]*>([\\s\\S]*?)</${V}>`,"gi"),X=[];for(let Z of $.matchAll(J)){let H=Z[1].trim();if(H)X.push(H)}return X}function G$($){let V=U($,"observation");if(!V)return null;let J=U(V,"type").toLowerCase(),X=i$.has(J)?J:"discovery",Z=U(V,"title")||"Untitled observation",H=U(V,"subtitle"),Y=U(V,"narrative"),K=_(U(V,"facts"),"fact"),Q=_(U(V,"concepts"),"concept"),G=_(U(V,"files_read"),"file"),F=_(U(V,"files_modified"),"file"),W=U(V,"importance"),B=Number.parseInt(W,10),N=Number.isNaN(B)?3:Math.max(1,Math.min(5,B));return{type:X,title:Z,subtitle:H,facts:K,narrative:Y,concepts:Q,filesRead:G,filesModified:F,importance:N}}function F$($){let V=U($,"session_summary");if(!V)return null;let J=U(V,"summary")||"No summary available",X=_(U(V,"key_decisions"),"decision"),Z=_(U(V,"files_modified"),"file"),H=_(U(V,"concepts"),"concept"),Y=U(V,"request")||void 0,K=U(V,"investigated")||void 0,Q=U(V,"learned")||void 0,G=U(V,"completed")||void 0,F=U(V,"next_steps")||void 0;return{summary:J,keyDecisions:X,filesModified:Z,concepts:H,request:Y,investigated:K,learned:Q,completed:G,nextSteps:F}}var r$=new Set(["new_fact","update","duplicate"]);function W$($){let V=U($,"evaluation");if(!V)return null;let J=U(V,"outcome").toLowerCase().trim();if(!r$.has(J))return null;let X=J,Z=U(V,"reason");if(!Z)return null;let H=U(V,"supersedes"),Y={outcome:X,reason:Z};if(X==="update"&&H)Y.supersedesId=H;if(X==="update"&&!Y.supersedesId)return null;return Y}var o$=new Set(["technology","library","pattern","concept","file","person","project","other"]),t$=new Set(["uses","depends_on","implements","extends","related_to","replaces","configures"]);function U$($){let V=U($,"extraction");if(!V)return null;let J=U(V,"entities"),X=U(V,"relations"),Z=_(J,"entity"),H=[];for(let Q of Z){let G=U(Q,"name");if(!G)continue;let F=U(Q,"type").toLowerCase(),W=o$.has(F)?F:"other";H.push({name:G,entityType:W})}let Y=_(X,"relation"),K=[];for(let Q of Y){let G=U(Q,"source"),F=U(Q,"target"),W=U(Q,"relationship").toLowerCase();if(!G||!F||!W)continue;if(!t$.has(W))continue;K.push({sourceName:G,targetName:F,relationship:W})}return{entities:H,relations:K}}function R($){return Math.ceil($.length/4)}function z$($,V,J,X){let Z=J?`<session_context>
|
|
4
4
|
${J}
|
|
5
5
|
</session_context>
|
|
6
6
|
|
|
7
|
-
`:"",H=X?X.observationTypes.join("|"):"decision|bugfix|feature|refactor|discovery|change",
|
|
7
|
+
`:"",H=X?X.observationTypes.join("|"):"decision|bugfix|feature|refactor|discovery|change",K=(X?X.conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"]).map((Q)=>{let F={"how-it-works":"Technical mechanisms and behaviors","why-it-exists":"Rationale and motivations","what-changed":"Modifications and their effects","problem-solution":"Issues encountered and how they were resolved",gotcha:"Surprising behaviors, edge cases, or pitfalls",pattern:"Recurring design patterns or approaches","trade-off":"Deliberate compromises between competing concerns",hypothesis:"Proposed explanations or predictions",finding:"Key results or discoveries",methodology:"Research methods and approaches",evidence:"Supporting data or observations",limitation:"Known constraints or boundaries",implication:"Consequences or downstream effects",comparison:"Similarities and differences between approaches"}[Q];return F?`- ${Q}: ${F}`:`- ${Q}`}).join(`
|
|
8
8
|
`);return`<task>
|
|
9
9
|
Analyze the following tool output and extract a structured observation.
|
|
10
10
|
</task>
|
|
@@ -15,11 +15,11 @@ Analyze the following tool output and extract a structured observation.
|
|
|
15
15
|
${V}
|
|
16
16
|
</tool_output>
|
|
17
17
|
|
|
18
|
-
${
|
|
18
|
+
${Z}<instructions>
|
|
19
19
|
Extract a structured observation from the tool output. Determine the most appropriate type and provide a concise but informative summary.
|
|
20
20
|
|
|
21
21
|
When extracting concepts, prefer established vocabulary where appropriate:
|
|
22
|
-
${
|
|
22
|
+
${K}
|
|
23
23
|
You may also use any domain-specific concepts relevant to the observation.
|
|
24
24
|
|
|
25
25
|
Respond with EXACTLY this XML format:
|
|
@@ -44,7 +44,7 @@ Respond with EXACTLY this XML format:
|
|
|
44
44
|
<file>path/to/file/modified</file>
|
|
45
45
|
</files_modified>
|
|
46
46
|
</observation>
|
|
47
|
-
</instructions>`}function
|
|
47
|
+
</instructions>`}function B$($,V){let J=$.map((X,Z)=>` <obs index="${Z+1}" type="${X.type}">
|
|
48
48
|
<title>${X.title}</title>
|
|
49
49
|
<narrative>${X.narrative}</narrative>
|
|
50
50
|
</obs>`).join(`
|
|
@@ -79,7 +79,7 @@ Respond with EXACTLY this XML format:
|
|
|
79
79
|
<concept>key-concept</concept>
|
|
80
80
|
</concepts>
|
|
81
81
|
</session_summary>
|
|
82
|
-
</instructions>`}function
|
|
82
|
+
</instructions>`}function N$($,V){let J=V.map((X)=>` <candidate id="${X.id}">
|
|
83
83
|
<title>${X.title}</title>
|
|
84
84
|
<narrative>${X.narrative}</narrative>
|
|
85
85
|
<concepts>${X.concepts.join(", ")}</concepts>
|
|
@@ -108,7 +108,7 @@ Respond with EXACTLY this XML format:
|
|
|
108
108
|
<reason>Brief explanation</reason>
|
|
109
109
|
</evaluation>
|
|
110
110
|
</instructions>
|
|
111
|
-
</conflict_evaluation>`}function
|
|
111
|
+
</conflict_evaluation>`}function M$($,V){let J=[...$.filesRead,...$.filesModified],X=V?V.entityTypes.join(", "):"technology, library, pattern, concept, file, person, project, other",Z=V?V.relationshipTypes.join(", "):"uses, depends_on, implements, extends, related_to, replaces, configures";return`<entity_extraction>
|
|
112
112
|
<observation>
|
|
113
113
|
<title>${$.title}</title>
|
|
114
114
|
<type>${$.type}</type>
|
|
@@ -123,7 +123,7 @@ Respond with EXACTLY this XML format:
|
|
|
123
123
|
Extract entities and relationships from this observation.
|
|
124
124
|
|
|
125
125
|
Entity types: ${X}
|
|
126
|
-
Relationship types: ${
|
|
126
|
+
Relationship types: ${Z}
|
|
127
127
|
|
|
128
128
|
Extract entities that are clearly mentioned or strongly implied. For example, "React hooks" implies a relationship between React and hooks. Do not extract speculative relationships.
|
|
129
129
|
Respond with EXACTLY this XML format:
|
|
@@ -137,32 +137,33 @@ Respond with EXACTLY this XML format:
|
|
|
137
137
|
</relations>
|
|
138
138
|
</extraction>
|
|
139
139
|
</instructions>
|
|
140
|
-
</entity_extraction>`}class
|
|
140
|
+
</entity_extraction>`}class m{shouldFailover($){let{error:V,attemptIndex:J,totalProviders:X}=$;if(P(V))return!1;if(J>=X-1)return!1;return j(V)}onFailover($){let V=$.error?.status??"unknown";if(!$.nextProvider)return;console.error(`[open-mem] Provider ${$.provider} failed (${V}), falling over to ${$.nextProvider}`)}}class l{specificationVersion;provider;modelId;supportedUrls;providers;policy;constructor($,V=new m){if($.length===0)throw Error("At least one provider required");let J=$[0].model;this.specificationVersion=J.specificationVersion,this.provider=J.provider,this.modelId=J.modelId,this.supportedUrls=J.supportedUrls,this.providers=$,this.policy=V}async doGenerate($){let V;for(let J=0;J<this.providers.length;J++){let X=this.providers[J];try{return this.policy.onAttempt?.({error:null,provider:X.name,nextProvider:this.providers[J+1]?.name,attemptIndex:J,totalProviders:this.providers.length}),await X.model.doGenerate($)}catch(Z){if(V=Z,P(Z))throw Z;let H=this.providers[J+1]?.name,Y={error:Z,provider:X.name,nextProvider:H,attemptIndex:J,totalProviders:this.providers.length};if(this.policy.shouldFailover(Y)){this.policy.onFailover(Y);continue}throw this.policy.onFinalFailure?.(Y),Z}}throw V}async doStream($){let V;for(let J=0;J<this.providers.length;J++){let X=this.providers[J];try{return this.policy.onAttempt?.({error:null,provider:X.name,nextProvider:this.providers[J+1]?.name,attemptIndex:J,totalProviders:this.providers.length}),await X.model.doStream($)}catch(Z){if(V=Z,P(Z))throw Z;let H=this.providers[J+1]?.name,Y={error:Z,provider:X.name,nextProvider:H,attemptIndex:J,totalProviders:this.providers.length};if(this.policy.shouldFailover(Y)){this.policy.onFailover(Y);continue}throw this.policy.onFinalFailure?.(Y),Z}}throw V}}var a$={"claude-sonnet-4-20250514":"us.anthropic.claude-sonnet-4-20250514-v1:0","claude-opus-4-20250514":"us.anthropic.claude-opus-4-20250514-v1:0","claude-3-5-sonnet-20241022":"us.anthropic.claude-3-5-sonnet-20241022-v2:0","claude-3-5-haiku-20241022":"us.anthropic.claude-3-5-haiku-20241022-v1:0","claude-3-haiku-20240307":"anthropic.claude-3-haiku-20240307-v1:0"};function e$($){if($.includes("."))return $;return a$[$]||`us.anthropic.${$}-v1:0`}function _$($){switch($.provider){case"anthropic":{let{createAnthropic:V}=A("@ai-sdk/anthropic");return V({apiKey:$.apiKey})($.model)}case"bedrock":{let{createAmazonBedrock:V}=A("@ai-sdk/amazon-bedrock");return V()(e$($.model))}case"openai":{let{createOpenAI:V}=A("@ai-sdk/openai");return V({apiKey:$.apiKey})($.model)}case"google":{let{createGoogleGenerativeAI:V}=A("@ai-sdk/google");return V({apiKey:$.apiKey})($.model)}case"openrouter":{let{createOpenRouter:V}=A("@openrouter/ai-sdk-provider");return V({apiKey:$.apiKey})($.model)}default:throw Error(`Unknown provider: ${$.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function A$($){try{switch($.provider){case"google":{let{createGoogleGenerativeAI:V}=A("@ai-sdk/google");return V({apiKey:$.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:V}=A("@ai-sdk/openai");return V({apiKey:$.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:V}=A("@ai-sdk/amazon-bedrock");return V().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var $V={google:"gemini-2.5-flash-lite",anthropic:"claude-sonnet-4-20250514",openai:"gpt-4o-mini",bedrock:"us.anthropic.claude-3-5-haiku-20241022-v1:0",openrouter:"google/gemini-2.5-flash-lite"};function VV($){switch($){case"google":return process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"openai":return process.env.OPENAI_API_KEY;case"openrouter":return process.env.OPENROUTER_API_KEY;case"bedrock":return;default:return}}function D($){if(!$.fallbackProviders||$.fallbackProviders.length===0)return[];return $.fallbackProviders.map((V)=>({provider:V,model:$V[V]??"gemini-2.5-flash-lite",apiKey:VV(V)}))}function L($,V=[],J){let X=_$($);if(V.length===0)return X;let Z=[{name:$.provider,model:X},...V.map((H)=>({name:H.provider,model:_$(H)}))];return new l(Z,J)}var JV={"gemini-2.5-flash-lite":10,"gemini-2.5-flash":10,"gemini-2.5-pro":5,"gemini-2.0-flash":15,"gemini-2.0-flash-lite":30,"gemini-3-flash":5},j$=0;async function O($,V){if(!V)return;let J=JV[$]||5,X=Math.ceil(60000/J)+100,H=Date.now()-j$;if(H<X){let Y=X-H;await new Promise((K)=>setTimeout(K,Y))}j$=Date.now()}class f{model;config;_generate=XV;constructor($){this.config=$,this.model=null;let V=$.provider!=="bedrock";if($.compressionEnabled&&(!V||$.apiKey))try{this.model=L({provider:$.provider,model:$.model,apiKey:$.apiKey},D($))}catch{}}static MAX_INPUT_LENGTH=50000;async compress($,V,J){if(!this.config.compressionEnabled||!this.model)return null;if(V.length<this.config.minOutputLength)return null;let X=R(V),Z=V.length>f.MAX_INPUT_LENGTH?`${V.substring(0,f.MAX_INPUT_LENGTH)}
|
|
141
141
|
|
|
142
|
-
[... truncated ...]`:V,H=K$($,Q,J),Z=2;for(let Y=0;Y<=Z;Y++)try{if(this.config.provider==="google")await C(this.config.model,this.config.rateLimitingEnabled);let{text:W}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:H}),K=Z$(W);if(K)K.discoveryTokens=X;return K}catch(W){if(L(W)&&Y<Z){let K=2**Y*1000;await j(K);continue}return null}return null}async compressBatch($){let V=new Map;for(let J=0;J<$.length;J++){let X=$[J],Q=await this.compress(X.toolName,X.toolOutput,X.sessionContext);if(V.set(X.callId,Q),J<$.length-1)await j(200)}return V}createFallbackObservation($,V){let J=i$(V),X=d$[$]??"discovery";return{type:X,title:`${$} execution`,subtitle:V.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${$} was executed. Output length: ${V.length} chars.`,concepts:[],filesRead:X==="discovery"?J:[],filesModified:X==="change"?J:[],discoveryTokens:R(V),importance:2}}async isAvailable(){if(!this.model)return!1;try{return await this._generate({model:this.model,maxOutputTokens:10,prompt:"ping"}),!0}catch{return!1}}}var d$={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},s$=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function i$($){let V=[];for(let J of $.matchAll(s$))V.push(J[1]);return[...new Set(V)]}import{generateText as r$}from"ai";class g{model;config;_generate=r$;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=D({provider:$.provider,model:$.model,apiKey:$.apiKey},S($))}catch{}}async evaluate($,V){if(!this.model||V.length===0)return null;let J=B$($,V),X=2;for(let Q=0;Q<=X;Q++)try{if(this.config.provider==="google")await C(this.config.model,this.config.rateLimitingEnabled);let{text:H}=await this._generate({model:this.model,maxOutputTokens:512,prompt:J});return Y$(H)}catch(H){if(L(H)&&Q<X){let Z=2**Q*1000;await j(Z);continue}return null}return null}}import{generateText as t$}from"ai";class p{model;config;_generate=t$;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=D({provider:$.provider,model:$.model,apiKey:$.apiKey},S($))}catch{}}async extract($){if(!this.model)return null;let V=F$($),J=2;for(let X=0;X<=J;X++)try{if(this.config.provider==="google")await C(this.config.model,this.config.rateLimitingEnabled);let{text:Q}=await this._generate({model:this.model,maxOutputTokens:1024,prompt:V});return W$(Q)}catch(Q){if(L(Q)&&X<J){let H=2**X*1000;await j(H);continue}return null}return null}}import{generateText as o$}from"ai";class l{model;config;_generate=o$;constructor($){this.config=$,this.model=null;let V=$.provider!=="bedrock";if($.compressionEnabled&&(!V||$.apiKey))try{this.model=D({provider:$.provider,model:$.model,apiKey:$.apiKey},S($))}catch{}}async summarize($,V){if(V.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(V);let J=z$(V.map((X)=>({type:X.type,title:X.title,narrative:X.narrative})),$);try{if(this.config.provider==="google")await C(this.config.model,this.config.rateLimitingEnabled);let{text:X}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:J}),Q=H$(X);if(!Q)return this.createFallbackSummary(V);return Q}catch{return this.createFallbackSummary(V)}}createFallbackSummary($){let V=new Set,J=new Set,X=[];for(let Y of $){for(let W of Y.filesModified)V.add(W);for(let W of Y.concepts)J.add(W);if(Y.type==="decision")X.push(Y.title)}let Q=new Map;for(let Y of $)Q.set(Y.type,(Q.get(Y.type)??0)+1);let H=Array.from(Q.entries()).map(([Y,W])=>`${W} ${Y}${W>1?"s":""}`).join(", "),Z=Array.from(J).slice(0,5).join(", ");return{summary:`Session with ${$.length} observations: ${H}. Files modified: ${V.size}. Key concepts: ${Z}.`,keyDecisions:X.slice(0,5),filesModified:Array.from(V),concepts:Array.from(J)}}shouldSummarize($){return $>=2}}import{existsSync as WV,readFileSync as KV}from"fs";import{join as QV}from"path";import{existsSync as a$,readdirSync as e$,readFileSync as $V}from"fs";import{join as VV}from"path";var P={id:"code",name:"Code",description:"Default coding workflow mode",observationTypes:["decision","bugfix","feature","refactor","discovery","change"],conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"],entityTypes:["technology","library","pattern","concept","file","person","project","other"],relationshipTypes:["uses","depends_on","implements","extends","related_to","replaces","configures"]};function k($){return{...$,observationTypes:[...$.observationTypes],conceptVocabulary:[...$.conceptVocabulary],entityTypes:[...$.entityTypes],relationshipTypes:[...$.relationshipTypes],promptOverrides:$.promptOverrides?{...$.promptOverrides}:void 0}}function JV($){if(!$||typeof $!=="object")return!1;let V=$,J=(Q)=>Array.isArray(Q)&&Q.every((H)=>typeof H==="string"),X=(Q)=>typeof Q==="object"&&Q!==null&&!Array.isArray(Q)&&Object.values(Q).every((H)=>typeof H==="string");return typeof V.id==="string"&&(V.extends===void 0||typeof V.extends==="string")&&(V.locale===void 0||typeof V.locale==="string")&&(V.name===void 0||typeof V.name==="string")&&(V.description===void 0||typeof V.description==="string")&&(V.observationTypes===void 0||J(V.observationTypes))&&(V.conceptVocabulary===void 0||J(V.conceptVocabulary))&&(V.entityTypes===void 0||J(V.entityTypes))&&(V.relationshipTypes===void 0||J(V.relationshipTypes))&&(V.promptOverrides===void 0||X(V.promptOverrides))}function XV($){return typeof $.name==="string"&&typeof $.description==="string"&&Array.isArray($.observationTypes)&&Array.isArray($.conceptVocabulary)&&Array.isArray($.entityTypes)&&Array.isArray($.relationshipTypes)}function _$($,V){return{...$,...V,id:V.id,name:V.name??$.name,description:V.description??$.description,observationTypes:V.observationTypes??$.observationTypes,conceptVocabulary:V.conceptVocabulary??$.conceptVocabulary,entityTypes:V.entityTypes??$.entityTypes,relationshipTypes:V.relationshipTypes??$.relationshipTypes,promptOverrides:{...$.promptOverrides??{},...V.promptOverrides??{}}}}class m{modesDir;constructor($){this.modesDir=$}loadAllRaw(){let $=new Map;if(!a$(this.modesDir))return $;for(let V of e$(this.modesDir)){if(!V.endsWith(".json"))continue;let J=VV(this.modesDir,V);try{let X=$V(J,"utf-8"),Q=JSON.parse(X);if(!JV(Q))continue;if($.has(Q.id))console.warn(`[open-mem] Duplicate mode id "${Q.id}" in ${J}; overriding previous definition.`);$.set(Q.id,Q)}catch{}}return $}resolveById($,V){let J=new Set,X=!1,Q=(Z)=>{if(J.has(Z))return X=!0,k(P);J.add(Z);let Y=V.get(Z);if(!Y)return k(P);if(!Y.extends){if(!XV(Y))return k(P);return _$(k(P),Y)}let W=Q(Y.extends);if(X)return k(P);return _$(W,Y)},H=Q($);return X?k(P):k(H)}}var ZV=QV(import.meta.dir,"."),HV=new m(ZV),f=null;function YV(){if(f)return f;return f=HV.loadAllRaw(),f}function N$(){return[...YV().keys()].sort()}var zV={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,folderContextMode:"dispersed",folderContextFilename:"AGENTS.md",daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1,fallbackProviders:void 0,mode:"code"};function BV(){let $={};if(process.env.OPEN_MEM_DB_PATH)$.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)$.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)$.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)$.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")$.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")$.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)$.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((V)=>V.trim());if(process.env.OPEN_MEM_BATCH_SIZE)$.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)$.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)$.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")$.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)$.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((V)=>V.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)$.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)$.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")$.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")$.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")$.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)$.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")$.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")$.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)$.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")$.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")$.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)$.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")$.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")$.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")$.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)$.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)$.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((V)=>V.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)$.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")$.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let V=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(V))$.conflictSimilarityBandLow=V}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let V=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(V))$.conflictSimilarityBandHigh=V}if(process.env.OPEN_MEM_USER_MEMORY==="true")$.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)$.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)$.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")$.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)$.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")$.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)$.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((V)=>V.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)$.mode=process.env.OPEN_MEM_MODE;return $}function FV($){let V=`${$}/.open-mem/config.json`;if(!WV(V))return{};try{let J=KV(V,"utf-8"),X=JSON.parse(J);if(!X||typeof X!=="object"||Array.isArray(X))return{};return X}catch{return{}}}function GV($){switch($){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function A$($,V){let J=FV($),X=BV(),Q={...zV,...J,...X,...V};if(!Q.dbPath.startsWith("/"))Q.dbPath=`${$}/${Q.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!V?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)Q.provider="google";else if(process.env.ANTHROPIC_API_KEY)Q.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)Q.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)Q.provider="openrouter"}if(!Q.apiKey)switch(Q.provider){case"google":Q.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":Q.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":Q.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":Q.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(Q.provider==="openrouter"&&Q.model==="gemini-2.5-flash-lite")Q.model="google/gemini-2.5-flash-lite";if(Q.embeddingDimension===void 0)Q.embeddingDimension=GV(Q.provider);if(Q.mode&&!N$().includes(Q.mode))Q.mode="code";return Q}import{existsSync as uJ,mkdirSync as UV,readFileSync as wJ,unlinkSync as MV,writeFileSync as _V}from"fs";function L$($){let V=$.lastIndexOf("/");if(V>0){let J=$.substring(0,V);UV(J,{recursive:!0})}_V($,String(process.pid),"utf-8")}function S$($){try{MV($)}catch{}}function D$($){let V=$.lastIndexOf("/");if(V>=0)return`${$.substring(0,V)}/worker.pid`;return"worker.pid"}class c{queueProcessor;pollIntervalMs;timer=null;lastActiveAt=Date.now();processing=!1;constructor($){this.queueProcessor=$.queueProcessor,this.pollIntervalMs=$.pollIntervalMs}start(){if(this.timer)return;this.lastActiveAt=Date.now(),this.timer=setInterval(async()=>{if(this.processing)return;this.processing=!0;try{if(await this.queueProcessor.processBatch()>0)this.lastActiveAt=Date.now()}catch{}finally{this.processing=!1}},this.pollIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get idleMs(){return Date.now()-this.lastActiveAt}get shouldAutoExit(){return this.idleMs>=60000&&!process.send}handleMessage($){if($==="SHUTDOWN")this.stop();else if($==="PROCESS_NOW"){if(!this.processing)this.processing=!0,this.queueProcessor.processBatch().then((V)=>{if(V>0)this.lastActiveAt=Date.now()}).catch(()=>{}).finally(()=>{this.processing=!1})}}}import{Database as C$}from"bun:sqlite";import{existsSync as n,mkdirSync as NV,unlinkSync as O$}from"fs";import*as j$ from"sqlite-vec";class u{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let $=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let V of $)try{if(n(V))return C$.setCustomSQLite(V),!0}catch{return!1}return!1}constructor($){this.dbPath=$,this.db=this.open($),this.configure()}open($){let V=$.lastIndexOf("/");if(V>0){let J=$.substring(0,V);NV(J,{recursive:!0})}return new C$($,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch($){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",$.message);try{this.db.close()}catch{}this.deleteSidecarFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after removing WAL/SHM files");return}catch(V){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",V.message);try{this.db.close()}catch{}this.deleteDatabaseFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after full database recreation");return}catch(J){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",J.message),$}}}}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{j$.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let $ of["-wal","-shm"]){let V=this.dbPath+$;try{if(n(V))O$(V)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(n(this.dbPath))O$(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
|
|
142
|
+
[... truncated ...]`:V,H=z$($,Z,J),Y=2;for(let K=0;K<=Y;K++)try{if(this.config.provider==="google")await O(this.config.model,this.config.rateLimitingEnabled);let{text:Q}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:H}),G=G$(Q);if(G)G.discoveryTokens=X;return G}catch(Q){if(j(Q)&&K<Y){let G=2**K*1000;await C(G);continue}return null}return null}async compressBatch($){let V=new Map;for(let J=0;J<$.length;J++){let X=$[J],Z=await this.compress(X.toolName,X.toolOutput,X.sessionContext);if(V.set(X.callId,Z),J<$.length-1)await C(200)}return V}createFallbackObservation($,V){let J=YV(V),X=ZV[$]??"discovery";return{type:X,title:`${$} execution`,subtitle:V.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${$} was executed. Output length: ${V.length} chars.`,concepts:[],filesRead:X==="discovery"?J:[],filesModified:X==="change"?J:[],discoveryTokens:R(V),importance:2}}async isAvailable(){if(!this.model)return!1;try{return await this._generate({model:this.model,maxOutputTokens:10,prompt:"ping"}),!0}catch{return!1}}}var ZV={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},HV=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function YV($){let V=[];for(let J of $.matchAll(HV))V.push(J[1]);return[...new Set(V)]}import{generateText as KV}from"ai";class c{model;config;_generate=KV;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=L({provider:$.provider,model:$.model,apiKey:$.apiKey},D($))}catch{}}async evaluate($,V){if(!this.model||V.length===0)return null;let J=N$($,V),X=2;for(let Z=0;Z<=X;Z++)try{if(this.config.provider==="google")await O(this.config.model,this.config.rateLimitingEnabled);let{text:H}=await this._generate({model:this.model,maxOutputTokens:512,prompt:J});return W$(H)}catch(H){if(j(H)&&Z<X){let Y=2**Z*1000;await C(Y);continue}return null}return null}}import{generateText as QV}from"ai";class d{model;config;_generate=QV;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=L({provider:$.provider,model:$.model,apiKey:$.apiKey},D($))}catch{}}async extract($){if(!this.model)return null;let V=M$($),J=2;for(let X=0;X<=J;X++)try{if(this.config.provider==="google")await O(this.config.model,this.config.rateLimitingEnabled);let{text:Z}=await this._generate({model:this.model,maxOutputTokens:1024,prompt:V});return U$(Z)}catch(Z){if(j(Z)&&X<J){let H=2**X*1000;await C(H);continue}return null}return null}}import{generateText as GV}from"ai";class n{model;config;_generate=GV;constructor($){this.config=$,this.model=null;let V=$.provider!=="bedrock";if($.compressionEnabled&&(!V||$.apiKey))try{this.model=L({provider:$.provider,model:$.model,apiKey:$.apiKey},D($))}catch{}}async summarize($,V){if(V.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(V);let J=B$(V.map((X)=>({type:X.type,title:X.title,narrative:X.narrative})),$);try{if(this.config.provider==="google")await O(this.config.model,this.config.rateLimitingEnabled);let{text:X}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:J}),Z=F$(X);if(!Z)return this.createFallbackSummary(V);return Z}catch{return this.createFallbackSummary(V)}}createFallbackSummary($){let V=new Set,J=new Set,X=[];for(let K of $){for(let Q of K.filesModified)V.add(Q);for(let Q of K.concepts)J.add(Q);if(K.type==="decision")X.push(K.title)}let Z=new Map;for(let K of $)Z.set(K.type,(Z.get(K.type)??0)+1);let H=Array.from(Z.entries()).map(([K,Q])=>`${Q} ${K}${Q>1?"s":""}`).join(", "),Y=Array.from(J).slice(0,5).join(", ");return{summary:`Session with ${$.length} observations: ${H}. Files modified: ${V.size}. Key concepts: ${Y}.`,keyDecisions:X.slice(0,5),filesModified:Array.from(V),concepts:Array.from(J)}}shouldSummarize($){return $>=2}}import{existsSync as DV,readFileSync as LV}from"fs";import{join as MV}from"path";import{existsSync as FV,readdirSync as WV,readFileSync as UV}from"fs";import{join as zV}from"path";var q={id:"code",name:"Code",description:"Default coding workflow mode",observationTypes:["decision","bugfix","feature","refactor","discovery","change"],conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"],entityTypes:["technology","library","pattern","concept","file","person","project","other"],relationshipTypes:["uses","depends_on","implements","extends","related_to","replaces","configures"]};function T($){return{...$,observationTypes:[...$.observationTypes],conceptVocabulary:[...$.conceptVocabulary],entityTypes:[...$.entityTypes],relationshipTypes:[...$.relationshipTypes],promptOverrides:$.promptOverrides?{...$.promptOverrides}:void 0}}function BV($){if(!$||typeof $!=="object")return!1;let V=$,J=(Z)=>Array.isArray(Z)&&Z.every((H)=>typeof H==="string"),X=(Z)=>typeof Z==="object"&&Z!==null&&!Array.isArray(Z)&&Object.values(Z).every((H)=>typeof H==="string");return typeof V.id==="string"&&(V.extends===void 0||typeof V.extends==="string")&&(V.locale===void 0||typeof V.locale==="string")&&(V.name===void 0||typeof V.name==="string")&&(V.description===void 0||typeof V.description==="string")&&(V.observationTypes===void 0||J(V.observationTypes))&&(V.conceptVocabulary===void 0||J(V.conceptVocabulary))&&(V.entityTypes===void 0||J(V.entityTypes))&&(V.relationshipTypes===void 0||J(V.relationshipTypes))&&(V.promptOverrides===void 0||X(V.promptOverrides))}function NV($){return typeof $.name==="string"&&typeof $.description==="string"&&Array.isArray($.observationTypes)&&Array.isArray($.conceptVocabulary)&&Array.isArray($.entityTypes)&&Array.isArray($.relationshipTypes)}function D$($,V){return{...$,...V,id:V.id,name:V.name??$.name,description:V.description??$.description,observationTypes:V.observationTypes??$.observationTypes,conceptVocabulary:V.conceptVocabulary??$.conceptVocabulary,entityTypes:V.entityTypes??$.entityTypes,relationshipTypes:V.relationshipTypes??$.relationshipTypes,promptOverrides:{...$.promptOverrides??{},...V.promptOverrides??{}}}}class s{modesDir;constructor($){this.modesDir=$}loadAllRaw(){let $=new Map;if(!FV(this.modesDir))return $;for(let V of WV(this.modesDir)){if(!V.endsWith(".json"))continue;let J=zV(this.modesDir,V);try{let X=UV(J,"utf-8"),Z=JSON.parse(X);if(!BV(Z))continue;if($.has(Z.id))console.warn(`[open-mem] Duplicate mode id "${Z.id}" in ${J}; overriding previous definition.`);$.set(Z.id,Z)}catch{}}return $}resolveById($,V){let J=new Set,X=!1,Z=(Y)=>{if(J.has(Y))return X=!0,T(q);J.add(Y);let K=V.get(Y);if(!K)return T(q);if(!K.extends){if(!NV(K))return T(q);return D$(T(q),K)}let Q=Z(K.extends);if(X)return T(q);return D$(Q,K)},H=Z($);return X?T(q):T(H)}}var _V=MV(import.meta.dir,"."),AV=new s(_V),w=null;function jV(){if(w)return w;return w=AV.loadAllRaw(),w}function L$(){return[...jV().keys()].sort()}var OV={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,folderContextMode:"single",folderContextFilename:"AGENTS.md",daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1,fallbackProviders:void 0,mode:"code"};function SV(){let $={};if(process.env.OPEN_MEM_DB_PATH)$.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)$.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)$.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)$.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")$.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")$.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)$.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((V)=>V.trim());if(process.env.OPEN_MEM_BATCH_SIZE)$.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)$.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)$.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")$.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)$.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((V)=>V.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)$.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)$.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")$.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")$.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")$.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)$.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")$.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")$.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)$.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")$.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")$.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)$.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")$.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")$.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")$.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)$.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)$.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((V)=>V.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)$.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")$.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let V=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(V))$.conflictSimilarityBandLow=V}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let V=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(V))$.conflictSimilarityBandHigh=V}if(process.env.OPEN_MEM_USER_MEMORY==="true")$.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)$.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)$.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")$.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)$.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")$.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)$.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((V)=>V.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)$.mode=process.env.OPEN_MEM_MODE;return $}function CV($){let V=`${$}/.open-mem/config.json`;if(!DV(V))return{};try{let J=LV(V,"utf-8"),X=JSON.parse(J);if(!X||typeof X!=="object"||Array.isArray(X))return{};return X}catch{return{}}}function RV($){switch($){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function O$($,V){let J=CV($),X=SV(),Z={...OV,...J,...X,...V};if(!Z.dbPath.startsWith("/"))Z.dbPath=`${$}/${Z.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!V?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)Z.provider="google";else if(process.env.ANTHROPIC_API_KEY)Z.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)Z.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)Z.provider="openrouter"}if(!Z.apiKey)switch(Z.provider){case"google":Z.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":Z.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":Z.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":Z.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(Z.provider==="openrouter"&&Z.model==="gemini-2.5-flash-lite")Z.model="google/gemini-2.5-flash-lite";if(Z.embeddingDimension===void 0)Z.embeddingDimension=RV(Z.provider);if(Z.mode&&!L$().includes(Z.mode))Z.mode="code";return Z}import{existsSync as M2,mkdirSync as TV,readFileSync as _2,unlinkSync as EV,writeFileSync as yV}from"fs";function S$($){let V=$.lastIndexOf("/");if(V>0){let J=$.substring(0,V);TV(J,{recursive:!0})}yV($,String(process.pid),"utf-8")}function C$($){try{return process.kill($,0),!0}catch(V){if(V instanceof Error&&"code"in V&&V.code==="EPERM")return!0;return!1}}function R$($){try{EV($)}catch{}}function T$($){let V=$.lastIndexOf("/");if(V>=0)return`${$.substring(0,V)}/worker.pid`;return"worker.pid"}class i{queueProcessor;pollIntervalMs;timer=null;lastActiveAt=Date.now();processing=!1;constructor($){this.queueProcessor=$.queueProcessor,this.pollIntervalMs=$.pollIntervalMs}start(){if(this.timer)return;this.lastActiveAt=Date.now(),this.timer=setInterval(async()=>{if(this.processing)return;this.processing=!0;try{if(await this.queueProcessor.processBatch()>0)this.lastActiveAt=Date.now()}catch{}finally{this.processing=!1}},this.pollIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get idleMs(){return Date.now()-this.lastActiveAt}get shouldAutoExit(){return this.idleMs>=60000&&!process.send}handleMessage($){if($==="SHUTDOWN")this.stop();else if($==="PROCESS_NOW"){if(!this.processing)this.processing=!0,this.queueProcessor.processBatch().then((V)=>{if(V>0)this.lastActiveAt=Date.now()}).catch(()=>{}).finally(()=>{this.processing=!1})}}}import{Database as f$}from"bun:sqlite";import{existsSync as gV,mkdirSync as pV}from"fs";import*as v$ from"sqlite-vec";import{closeSync as qV,fsyncSync as xV,openSync as IV,readFileSync as kV,unlinkSync as y$,writeFileSync as PV}from"fs";import{hostname as q$}from"os";var x$="plugin";class u extends Error{lockPath;role;waitDurationMs;owner;constructor($){super(`Timed out acquiring advisory write lock after ${$.waitDurationMs}ms (role=${$.role}, lockPath=${$.lockPath})`);this.name="AdvisoryLockTimeoutError",this.lockPath=$.lockPath,this.role=$.role,this.waitDurationMs=$.waitDurationMs,this.owner=$.owner}}var fV=5000,hV=50,x=new Map;function vV($){if($<=0)return;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,$)}function E$($,V){if(typeof $!=="number"||!Number.isFinite($)||$<=0)return V;return Math.floor($)}function I$($){try{let V=kV($,"utf8").trim();if(!V)return null;let J=JSON.parse(V);if(typeof J!=="object"||J===null||typeof J.pid!=="number"||typeof J.role!=="string"||typeof J.hostname!=="string"||typeof J.acquiredAt!=="string")return null;return{pid:J.pid,role:J.role,hostname:J.hostname,acquiredAt:J.acquiredAt,ownerId:typeof J.ownerId==="string"?J.ownerId:void 0}}catch{return null}}function wV($,V){if(!$||!V)return!1;return $.pid===V.pid&&$.role===V.role&&$.hostname===V.hostname&&$.acquiredAt===V.acquiredAt&&$.ownerId===V.ownerId}function uV($,V){if(!V)return!1;if(V.hostname!==q$())return!1;if(C$(V.pid))return!1;let J=I$($);if(!wV(J,V))return!1;try{return y$($),!0}catch(X){if(X.code==="ENOENT")return!1;throw X}}function r($,V){qV(V);try{y$($)}catch(J){if(J.code!=="ENOENT")throw J}}function k$($){return`${$}.write.lock`}function bV($,V){let J=V.now??Date.now,X=E$(V.timeoutMs,fV),Z=E$(V.retryIntervalMs,hV),H=x.get($);if(H){H.count+=1;let G=!1;return{lockPath:$,role:V.role,waitDurationMs:0,reentrant:!0,release:()=>{if(G)return;G=!0;let F=x.get($);if(!F)return;if(F.count-=1,F.count===0)x.delete($),r($,F.fd)}}}let Y={pid:process.pid,role:V.role,hostname:q$(),acquiredAt:new Date(J()).toISOString(),ownerId:V.ownerId},K=J(),Q=null;for(;;)try{let G=IV($,"wx");try{PV(G,JSON.stringify(Y),"utf8"),xV(G)}catch(W){throw r($,G),W}x.set($,{count:1,fd:G});let F=!1;return{lockPath:$,role:V.role,waitDurationMs:J()-K,reentrant:!1,release:()=>{if(F)return;F=!0;let W=x.get($);if(!W)return;if(W.count-=1,W.count===0)x.delete($),r($,W.fd)}}}catch(G){if(G.code!=="EEXIST")throw G;if(Q=I$($),uV($,Q))continue;let W=J()-K;if(W>=X)throw new u({lockPath:$,role:V.role,waitDurationMs:W,owner:Q});vV(Math.min(Z,X-W))}}function P$($,V,J){let X=bV($,V);try{return J()}finally{X.release()}}var mV=new Set(["SQLITE_BUSY","SQLITE_LOCKED","SQLITE_IOERR","SQLITE_IOERR_VNODE","SQLITE_IOERR_READ","SQLITE_IOERR_WRITE","SQLITE_IOERR_SHORT_READ","SQLITE_IOERR_FSYNC","SQLITE_PROTOCOL"]),lV=3,h$=50,cV=new Set(["INSERT","UPDATE","DELETE","REPLACE","CREATE","ALTER","DROP","VACUUM","REINDEX","ANALYZE","ATTACH","DETACH"]),dV=new Set(["WAL_CHECKPOINT","OPTIMIZE","INCREMENTAL_VACUUM","SHRINK_MEMORY"]),nV=/^(?:\s+|--[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)+/;function sV($){let V=$;for(;;){let J=V.replace(nV,"");if(J===V)return V.trimStart();V=J}}function iV($){let V=[],J=0,X=!1,Z=!1,H=!1,Y=!1,K=!1,Q=!1;for(let F=0;F<$.length;F+=1){let W=$[F],B=$[F+1];if(K){if(W===`
|
|
143
|
+
`)K=!1;continue}if(Q){if(W==="*"&&B==="/")Q=!1,F+=1;continue}if(X){if(W==="'")if(B==="'")F+=1;else X=!1;continue}if(Z){if(W==='"')if(B==='"')F+=1;else Z=!1;continue}if(H){if(W==="`")H=!1;continue}if(Y){if(W==="]")Y=!1;continue}if(W==="-"&&B==="-"){K=!0,F+=1;continue}if(W==="/"&&B==="*"){Q=!0,F+=1;continue}if(W==="'"){X=!0;continue}if(W==='"'){Z=!0;continue}if(W==="`"){H=!0;continue}if(W==="["){Y=!0;continue}if(W===";"){let N=$.slice(J,F).trim();if(N.length>0)V.push(N);J=F+1}}let G=$.slice(J).trim();if(G.length>0)V.push(G);return V}function rV($){let V=sV($);if(!V)return!1;let J=V.toUpperCase();if(/\bRETURNING\b/.test(J))return!0;if(J.startsWith("PRAGMA")){if(/^PRAGMA\s+(?:[A-Z0-9_]+\.)?[A-Z0-9_]+\s*=/.test(J))return!0;let Z=/^PRAGMA\s+(?:[A-Z0-9_]+\.)?([A-Z0-9_]+)/.exec(J)?.[1];if(!Z)return!1;return dV.has(Z)}let X=/^[A-Z]+/.exec(J)?.[0];if(!X)return!1;if(cV.has(X))return!0;if(X==="WITH")return/\b(INSERT|UPDATE|DELETE|REPLACE)\b/.test(J);return!1}function o($){let V=iV($);if(V.length===0)return!1;for(let J of V)if(rV(J))return!0;return!1}var oV=new Set(["PASSIVE","FULL","RESTART","TRUNCATE"]);function h($){if($ instanceof Error){let V=$.code;return{code:typeof V==="string"?V:"UNKNOWN",message:$.message}}return{code:"UNKNOWN",message:String($)}}function tV($){if($&&typeof $==="object"&&"code"in $){let V=$.code;return mV.has(V)}return!1}class b{db;dbPath;advisoryWriteLockPath;processRole;transactionDepth=0;_hasVectorExtension=!1;static enableExtensionSupport(){let $=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let V of $)try{if(gV(V))return f$.setCustomSQLite(V),!0}catch{return!1}return!1}constructor($,V={}){this.dbPath=$,this.processRole=V.processRole??x$,this.advisoryWriteLockPath=k$($),this.db=this.open($),this.configure()}open($){let V=$.lastIndexOf("/");if(V>0){let J=$.substring(0,V);pV(J,{recursive:!0})}return new f$($,{create:!0})}configure(){this.runConfigureStage("applyPragmas",()=>this.applyPragmas()),this.runConfigureStage("loadExtensions",()=>this.loadExtensions())}runConfigureStage($,V){try{V()}catch(J){this.throwConfigureFailure($,J)}}throwConfigureFailure($,V){let J=h(V);try{this.db.close()}catch{}throw console.error("[open-mem] Database configure failed (non-destructive fail-safe)",{stage:$,dbPath:this.dbPath,sqliteCode:J.code,sqliteMessage:J.message,action:"startup-abort",deletionAttempted:!1}),Error(`Database startup failed during ${$} (fail-safe, non-destructive): [${J.code}] ${J.message}`)}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{v$.load(this.db),this._hasVectorExtension=!0}catch($){let V=h($);console.warn("[open-mem] SQLite extension load skipped",{stage:"loadExtensions",dbPath:this.dbPath,sqliteCode:V.code,sqliteMessage:V.message,action:"continue-without-extension"}),this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}ensureMigrationTable(){this.db.exec(`
|
|
143
144
|
CREATE TABLE IF NOT EXISTS _migrations (
|
|
144
145
|
version INTEGER PRIMARY KEY,
|
|
145
146
|
name TEXT NOT NULL,
|
|
146
147
|
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
147
148
|
)
|
|
148
|
-
`)}migrate($){this.ensureMigrationTable();let V=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),J=new Set(V.map((
|
|
149
|
+
`)}migrate($){this.withAdvisoryWriteLock(this.processRole,()=>{this.ensureMigrationTable();let V=this.withRetry("migrate.applied_versions",()=>{return this.db.query("SELECT version FROM _migrations ORDER BY version").all()}),J=new Set(V.map((Z)=>Z.version)),X=$.filter((Z)=>!J.has(Z.version)).sort((Z,H)=>Z.version-H.version);for(let Z of X)this.transaction(()=>{this.exec(Z.up),this.run("INSERT INTO _migrations (version, name) VALUES ($version, $name)",[{$version:Z.version,$name:Z.name}])})})}withRetry($,V){let J=this.transactionDepth>0?0:lV,X;for(let Z=0;Z<=J;Z++)try{return V()}catch(H){if(X=H,!tV(H)||Z===J)throw H;let Y=h$*2**Z+Math.random()*h$;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,Y);let K=h(H);console.warn("[open-mem] Retrying after transient SQLite error",{attempt:Z+1,maxRetries:J,operation:$,role:this.processRole,dbPath:this.dbPath,sqliteCode:K.code,sqliteMessage:K.message})}throw X}run($,V){this.withAdvisoryWriteLock(this.processRole,()=>{this.withRetry("run",()=>{let J=this.db.query($);if(V)J.run(...V);else J.run()})})}get($,V){let J=()=>{let X=this.db.query($);return V?X.get(...V):X.get()};if(o($))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("get",J));return this.withRetry("get",J)}all($,V){let J=()=>{let X=this.db.query($);return V?X.all(...V):X.all()};if(o($))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("all",J));return this.withRetry("all",J)}exec($){let V=()=>this.withRetry("exec",()=>this.db.exec($));if(o($)){this.withAdvisoryWriteLock(this.processRole,V);return}V()}transaction($){return this.withAdvisoryWriteLock(this.processRole,()=>{if(this.transactionDepth>0)return $();let V=this.db.transaction($);if(typeof V.immediate==="function"){this.transactionDepth+=1;try{return V.immediate()}finally{this.transactionDepth-=1}}this.db.exec("BEGIN IMMEDIATE"),this.transactionDepth+=1;try{let J=$();return this.db.exec("COMMIT"),J}catch(J){let X=J;try{this.db.exec("ROLLBACK")}catch(Z){if(X instanceof Error){let H=X;if(H.cause===void 0)H.cause=Z;else H.suppressed=[...H.suppressed??[],Z]}console.warn("[open-mem] Transaction rollback failed after transaction error",{dbPath:this.dbPath,originalError:h(X),rollbackError:h(Z)})}throw X}finally{this.transactionDepth-=1}})}get writeLockPath(){return this.advisoryWriteLockPath}withAdvisoryWriteLock($,V,J){try{return P$(this.advisoryWriteLockPath,{...J,role:$},V)}catch(X){if(X instanceof u)console.error("[open-mem] Advisory write lock timeout",{role:$,dbPath:this.dbPath,lockPath:X.lockPath,waitDurationMs:X.waitDurationMs,owner:X.owner});throw X}}checkpointWal($="PASSIVE"){let V=typeof $==="string"?$.toUpperCase():"";if(!oV.has(V))throw Error(`Invalid wal_checkpoint mode: ${String($)}`);return this.withAdvisoryWriteLock(this.processRole,()=>{return this.withRetry("maintenance.wal_checkpoint",()=>{let J=this.db.query(`PRAGMA wal_checkpoint(${V})`).get();if(!J)throw Error("wal_checkpoint returned no result row");return{mode:V,busy:J.busy??0,logFrames:J.log??0,checkpointedFrames:J.checkpointed??0}})})}integrityCheck($=1){let V=Number.isFinite($)?Math.max(1,Math.floor($)):1;return this.withRetry("maintenance.integrity_check",()=>{let J=this.db.query(`PRAGMA integrity_check(${V})`).all();if(J.length===0)throw Error("integrity_check returned no result rows");let X=J.map((Z)=>Object.values(Z).find((H)=>typeof H==="string")).filter((Z)=>typeof Z==="string").map((Z)=>Z.trim()).filter((Z)=>Z.length>0);if(X.length===0)throw Error("integrity_check returned no diagnostic messages");return{ok:X.length===1&&X[0].toLowerCase()==="ok",messages:X,maxErrors:V}})}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function w$($,V){return new b($,V)}import{randomUUID as u$}from"crypto";class t{db;constructor($){this.db=$}upsertEntity($,V){let J=u$(),X=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
|
|
149
150
|
VALUES (?, ?, ?, ?, ?, 1)
|
|
150
151
|
ON CONFLICT(name, entity_type) DO UPDATE SET
|
|
151
152
|
mention_count = mention_count + 1,
|
|
152
|
-
last_seen_at = ?`,[J,$,V,X,X,X]);let
|
|
153
|
+
last_seen_at = ?`,[J,$,V,X,X,X]);let Z=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[$,V]);if(!Z)throw Error(`Failed to upsert entity: ${$} (${V})`);return this.mapEntityRow(Z)}createRelation($,V,J,X){let Z=u$(),H=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
|
|
153
154
|
(id, source_entity_id, target_entity_id, relationship, observation_id, created_at)
|
|
154
|
-
VALUES (?, ?, ?, ?, ?, ?)`,[
|
|
155
|
-
WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[$,V,J]);return
|
|
155
|
+
VALUES (?, ?, ?, ?, ?, ?)`,[Z,$,V,J,X,H])}catch{return null}let Y=this.db.get(`SELECT * FROM entity_relations
|
|
156
|
+
WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[$,V,J]);return Y?this.mapRelationRow(Y):null}linkObservation($,V){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[$,V])}findByName($){try{return this.db.all(`SELECT e.*
|
|
156
157
|
FROM entities e
|
|
157
158
|
JOIN entities_fts fts ON e._rowid = fts.rowid
|
|
158
159
|
WHERE entities_fts MATCH ?
|
|
159
160
|
ORDER BY rank`,[$]).map((J)=>this.mapEntityRow(J))}catch{return[]}}getRelationsFor($){return this.db.all(`SELECT * FROM entity_relations
|
|
160
|
-
WHERE source_entity_id = ? OR target_entity_id = ?`,[$,$]).map((J)=>this.mapRelationRow(J))}traverseRelations($,V=1){let J=Math.min(V,2),X=100,
|
|
161
|
-
`)}function
|
|
161
|
+
WHERE source_entity_id = ? OR target_entity_id = ?`,[$,$]).map((J)=>this.mapRelationRow(J))}traverseRelations($,V=1){let J=Math.min(V,2),X=100,Z=new Set,H=[{id:$,currentDepth:0}];Z.add($);while(H.length>0){if(Z.size>=100)break;let Y=H.shift();if(!Y)continue;if(Y.currentDepth>=J)continue;let K=this.getRelationsFor(Y.id);for(let Q of K){let G=Q.sourceEntityId===Y.id?Q.targetEntityId:Q.sourceEntityId;if(!Z.has(G))Z.add(G),H.push({id:G,currentDepth:Y.currentDepth+1})}}return Z}getObservationsForEntity($){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[$]).map((J)=>J.observation_id)}getById($){let V=this.db.get("SELECT * FROM entities WHERE id = ?",[$]);return V?this.mapEntityRow(V):null}mapEntityRow($){return{id:$.id,name:$.name,entityType:$.entity_type,firstSeenAt:$.first_seen_at,lastSeenAt:$.last_seen_at,mentionCount:$.mention_count}}mapRelationRow($){return{id:$.id,sourceEntityId:$.source_entity_id,targetEntityId:$.target_entity_id,relationship:$.relationship,observationId:$.observation_id,createdAt:$.created_at}}}import{randomUUID as eV}from"crypto";import{embed as aV}from"ai";async function a($,V){try{let{embedding:J}=await aV({model:$,value:V});return J}catch{return null}}function b$($,V){if($.length!==V.length||$.length===0)return 0;let J=0,X=0,Z=0;for(let Y=0;Y<$.length;Y++)J+=$[Y]*V[Y],X+=$[Y]*$[Y],Z+=V[Y]*V[Y];let H=Math.sqrt(X)*Math.sqrt(Z);if(H===0)return 0;return J/H}function e($){let V=[$.title,$.narrative];if($.concepts.length>0)V.push($.concepts.join(", "));return V.join(`
|
|
162
|
+
`)}function $J($){return $.replace(/[%_\\]/g,"\\$&")}class $${db;constructor($){this.db=$}create($){let V=eV(),J=new Date().toISOString(),X=$.discoveryTokens??0,Z=$.importance??3,H=$.scope??"project";return this.db.run(`INSERT INTO observations
|
|
162
163
|
(id, session_id, scope, type, title, subtitle, facts, narrative,
|
|
163
164
|
concepts, files_read, files_modified, raw_tool_output,
|
|
164
165
|
tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
|
|
165
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[V,$.sessionId,H,$.type,$.title,$.subtitle,JSON.stringify($.facts),$.narrative,JSON.stringify($.concepts),JSON.stringify($.filesRead),JSON.stringify($.filesModified),$.rawToolOutput,$.toolName,J,$.tokenCount,X,
|
|
166
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[V,$.sessionId,H,$.type,$.title,$.subtitle,JSON.stringify($.facts),$.narrative,JSON.stringify($.concepts),JSON.stringify($.filesRead),JSON.stringify($.filesModified),$.rawToolOutput,$.toolName,J,$.tokenCount,X,Z,null,null]),{...$,id:V,scope:H,createdAt:J,discoveryTokens:X,importance:Z,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation($){this.db.run(`INSERT INTO observations
|
|
166
167
|
(id, session_id, scope, type, title, subtitle, facts, narrative,
|
|
167
168
|
concepts, files_read, files_modified, raw_tool_output,
|
|
168
169
|
tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
|
|
@@ -171,7 +172,7 @@ Respond with EXACTLY this XML format:
|
|
|
171
172
|
JOIN sessions s ON o.session_id = s.id
|
|
172
173
|
WHERE s.project_path = ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
173
174
|
ORDER BY o.created_at DESC
|
|
174
|
-
LIMIT ?`,[$,V]).map((J)=>({id:J.id,sessionId:J.session_id,type:J.type,title:J.title,tokenCount:J.token_count,discoveryTokens:J.discovery_tokens??0,createdAt:J.created_at,importance:J.importance??3}))}getAroundTimestamp($,V,J,X){let
|
|
175
|
+
LIMIT ?`,[$,V]).map((J)=>({id:J.id,sessionId:J.session_id,type:J.type,title:J.title,tokenCount:J.token_count,discoveryTokens:J.discovery_tokens??0,createdAt:J.created_at,importance:J.importance??3}))}getAroundTimestamp($,V,J,X){let Z=V>0?this.db.all(`SELECT o.*
|
|
175
176
|
FROM observations o
|
|
176
177
|
JOIN sessions s ON o.session_id = s.id
|
|
177
178
|
WHERE s.project_path = ? AND o.created_at < ?
|
|
@@ -183,17 +184,17 @@ Respond with EXACTLY this XML format:
|
|
|
183
184
|
WHERE s.project_path = ? AND o.created_at > ?
|
|
184
185
|
AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
185
186
|
ORDER BY o.created_at ASC
|
|
186
|
-
LIMIT ?`,[X,$,J]):[];return[...
|
|
187
|
+
LIMIT ?`,[X,$,J]):[];return[...Z,...H].map((Y)=>this.mapRow(Y))}listByProject($,V={}){let{limit:J=50,offset:X=0,type:Z,state:H,sessionId:Y}=V,K=`SELECT o.*
|
|
187
188
|
FROM observations o
|
|
188
189
|
JOIN sessions s ON o.session_id = s.id
|
|
189
|
-
WHERE s.project_path = ?`,
|
|
190
|
+
WHERE s.project_path = ?`,Q=[$];if(Y)K+=" AND o.session_id = ?",Q.push(Y);if(Z)K+=" AND o.type = ?",Q.push(Z);if(H==="current")K+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(H==="superseded")K+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(H==="tombstoned")K+=" AND o.deleted_at IS NOT NULL";else K+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return K+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",Q.push(J,X),this.db.all(K,Q).map((G)=>this.mapRow(G))}search($){let V=!!$.projectPath,J=`
|
|
190
191
|
SELECT o.*, rank
|
|
191
192
|
FROM observations o
|
|
192
193
|
JOIN observations_fts fts ON o._rowid = fts.rowid
|
|
193
194
|
${V?"JOIN sessions s ON o.session_id = s.id":""}
|
|
194
195
|
WHERE observations_fts MATCH ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
195
|
-
`,X=[$.query];if(V&&$.projectPath)J+=" AND s.project_path = ?",X.push($.projectPath);if($.sessionId)J+=" AND o.session_id = ?",X.push($.sessionId);if($.type)J+=" AND o.type = ?",X.push($.type);if($.importanceMin!==void 0)J+=" AND o.importance >= ?",X.push($.importanceMin);if($.importanceMax!==void 0)J+=" AND o.importance <= ?",X.push($.importanceMax);if($.createdAfter)J+=" AND o.created_at >= ?",X.push($.createdAfter);if($.createdBefore)J+=" AND o.created_at <= ?",X.push($.createdBefore);if($.concepts&&$.concepts.length>0){let
|
|
196
|
-
OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);J+=` AND (${
|
|
196
|
+
`,X=[$.query];if(V&&$.projectPath)J+=" AND s.project_path = ?",X.push($.projectPath);if($.sessionId)J+=" AND o.session_id = ?",X.push($.sessionId);if($.type)J+=" AND o.type = ?",X.push($.type);if($.importanceMin!==void 0)J+=" AND o.importance >= ?",X.push($.importanceMin);if($.importanceMax!==void 0)J+=" AND o.importance <= ?",X.push($.importanceMax);if($.createdAfter)J+=" AND o.created_at >= ?",X.push($.createdAfter);if($.createdBefore)J+=" AND o.created_at <= ?",X.push($.createdBefore);if($.concepts&&$.concepts.length>0){let Z=$.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");J+=` AND (${Z.join(" OR ")})`;for(let H of $.concepts)X.push(H)}if($.files&&$.files.length>0){let Z=$.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
|
|
197
|
+
OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);J+=` AND (${Z.join(" OR ")})`;for(let H of $.files){let Y=`%${$J(H)}%`;X.push(Y,Y)}}return J+=" ORDER BY rank LIMIT ? OFFSET ?",X.push($.limit??10),X.push($.offset??0),this.db.all(J,X).map((Z)=>({observation:this.mapRow(Z),rank:Z.rank,snippet:Z.title}))}searchByConcept($,V=10,J){let X=!!J,Z=`SELECT o.*
|
|
197
198
|
FROM observations o
|
|
198
199
|
JOIN observations_fts fts ON o._rowid = fts.rowid
|
|
199
200
|
${X?"JOIN sessions s ON o.session_id = s.id":""}
|
|
@@ -201,7 +202,7 @@ Respond with EXACTLY this XML format:
|
|
|
201
202
|
AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
202
203
|
${X?"AND s.project_path = ?":""}
|
|
203
204
|
ORDER BY rank
|
|
204
|
-
LIMIT ?`,
|
|
205
|
+
LIMIT ?`,Y=[`concepts:"${$.replace(/"/g,'""')}"`];if(X&&J)Y.push(J);return Y.push(V),this.db.all(Z,Y).map((K)=>this.mapRow(K))}searchByFile($,V=10,J){let X=!!J,Z=`SELECT o.*
|
|
205
206
|
FROM observations o
|
|
206
207
|
JOIN observations_fts fts ON o._rowid = fts.rowid
|
|
207
208
|
${X?"JOIN sessions s ON o.session_id = s.id":""}
|
|
@@ -209,22 +210,22 @@ Respond with EXACTLY this XML format:
|
|
|
209
210
|
AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
210
211
|
${X?"AND s.project_path = ?":""}
|
|
211
212
|
ORDER BY rank
|
|
212
|
-
LIMIT ?`,H=[`files_read:"${$.replace(/"/g,'""')}" OR files_modified:"${$.replace(/"/g,'""')}"`];if(X&&J)H.push(J);return H.push(V),this.db.all(
|
|
213
|
+
LIMIT ?`,H=[`files_read:"${$.replace(/"/g,'""')}" OR files_modified:"${$.replace(/"/g,'""')}"`];if(X&&J)H.push(J);return H.push(V),this.db.all(Z,H).map((Y)=>this.mapRow(Y))}setEmbedding($,V){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(V),$])}getWithEmbeddings($,V){return this.db.all(`SELECT o.id, o.embedding, o.title
|
|
213
214
|
FROM observations o
|
|
214
215
|
JOIN sessions s ON o.session_id = s.id
|
|
215
216
|
WHERE s.project_path = ? AND o.embedding IS NOT NULL AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
216
217
|
ORDER BY o.created_at DESC
|
|
217
|
-
LIMIT ?`,[$,V]).map((J)=>{try{return{id:J.id,embedding:JSON.parse(J.embedding),title:J.title}}catch{return null}}).filter((J)=>J!==null)}findSimilar($,V,J,X){let
|
|
218
|
+
LIMIT ?`,[$,V]).map((J)=>{try{return{id:J.id,embedding:JSON.parse(J.embedding),title:J.title}}catch{return null}}).filter((J)=>J!==null)}findSimilar($,V,J,X){let Z=this.db.all(`SELECT id, embedding FROM observations
|
|
218
219
|
WHERE embedding IS NOT NULL AND type = ? AND superseded_by IS NULL AND deleted_at IS NULL
|
|
219
220
|
ORDER BY created_at DESC
|
|
220
|
-
LIMIT 200`,[V]),H=[];for(let
|
|
221
|
+
LIMIT 200`,[V]),H=[];for(let Y of Z)try{let K=JSON.parse(Y.embedding);if(!Array.isArray(K)||K.length!==$.length)continue;let Q=b$($,K);if(Q>=J)H.push({id:Y.id,similarity:Q})}catch{}return H.sort((Y,K)=>K.similarity-Y.similarity).slice(0,X)}insertVecEmbedding($,V){let J=new Float32Array(V);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[$]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[$,J]),this.db.run("COMMIT")}catch(X){throw this.db.run("ROLLBACK"),X}}migrateExistingEmbeddings($){let V=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),J=0,X=0;for(let Z of V)try{let H=JSON.parse(Z.embedding);if(!Array.isArray(H)||H.length!==$){X++;continue}this.insertVecEmbedding(Z.id,H),J++}catch{X++}return{migrated:J,skipped:X}}getVecEmbeddingMatches($,V){try{let J=new Float32Array($);return this.db.all(`SELECT observation_id, distance
|
|
221
222
|
FROM observation_embeddings
|
|
222
|
-
WHERE embedding MATCH ? AND k = ?`,[J,V]).map((X)=>({observationId:X.observation_id,distance:X.distance}))}catch{return[]}}searchVecSubset($,V,J){if(V.length===0)return[];try{let X=new Float32Array($),
|
|
223
|
+
WHERE embedding MATCH ? AND k = ?`,[J,V]).map((X)=>({observationId:X.observation_id,distance:X.distance}))}catch{return[]}}searchVecSubset($,V,J){if(V.length===0)return[];try{let X=new Float32Array($),Z=Math.max(J*5,V.length),H=this.db.all(`SELECT observation_id, distance
|
|
223
224
|
FROM observation_embeddings
|
|
224
|
-
WHERE embedding MATCH ? AND k = ?`,[X,
|
|
225
|
+
WHERE embedding MATCH ? AND k = ?`,[X,Z]),Y=new Set(V);return H.filter((K)=>Y.has(K.observation_id)).slice(0,J).map((K)=>({observationId:K.observation_id,distance:K.distance}))}catch{return[]}}update($,V){let J=this.getById($);if(!J)return null;if(Object.keys(V).length===0)return J;let X=this.create({sessionId:J.sessionId,scope:J.scope??"project",type:V.type??J.type,title:V.title??J.title,subtitle:V.subtitle??J.subtitle,facts:V.facts??J.facts,narrative:V.narrative??J.narrative,concepts:V.concepts??J.concepts,filesRead:V.filesRead??J.filesRead,filesModified:V.filesModified??J.filesModified,rawToolOutput:J.rawToolOutput,toolName:"mem-revise",tokenCount:J.tokenCount,discoveryTokens:J.discoveryTokens,importance:V.importance??J.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[$,X.id]),this.supersede($,X.id),this.getById(X.id)}supersede($,V){let J=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[V,J,$])}delete($){if(this.db.all("SELECT id FROM observations WHERE id = ?",[$]).length===0)return!1;let J=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[J,$]),this.deleteEmbeddingsForObservations([$]),!0}getLineage($){let V=this.getByIdIncludingArchived($);if(!V)return[];let J=new Set([V.id]),X=[V];while(X[0].revisionOf){let Z=this.getByIdIncludingArchived(X[0].revisionOf);if(!Z||J.has(Z.id))break;X.unshift(Z),J.add(Z.id)}while(X[X.length-1].supersededBy){let Z=X[X.length-1].supersededBy;if(!Z)break;let H=this.getByIdIncludingArchived(Z);if(!H||J.has(H.id))break;X.push(H),J.add(H.id)}return X}deleteOlderThan($){return this.db.all(`DELETE FROM observations
|
|
225
226
|
WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
|
|
226
227
|
AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
|
|
227
|
-
RETURNING id`,[$]).length}deleteEmbeddingsForObservations($){if($.length===0)return;let V=$.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${V})`,$)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${V})`,$)}mapRow($){return{id:$.id,sessionId:$.session_id,scope:$.scope??"project",type:$.type,title:$.title,subtitle:$.subtitle,facts:JSON.parse($.facts),narrative:$.narrative,concepts:JSON.parse($.concepts),filesRead:JSON.parse($.files_read),filesModified:JSON.parse($.files_modified),rawToolOutput:$.raw_tool_output,toolName:$.tool_name,createdAt:$.created_at,tokenCount:$.token_count,discoveryTokens:$.discovery_tokens??0,importance:$.importance??3,revisionOf:$.revision_of??null,deletedAt:$.deleted_at??null,supersededBy:$.superseded_by??null,supersededAt:$.superseded_at??null}}}import{randomUUID as
|
|
228
|
+
RETURNING id`,[$]).length}deleteEmbeddingsForObservations($){if($.length===0)return;let V=$.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${V})`,$)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${V})`,$)}mapRow($){return{id:$.id,sessionId:$.session_id,scope:$.scope??"project",type:$.type,title:$.title,subtitle:$.subtitle,facts:JSON.parse($.facts),narrative:$.narrative,concepts:JSON.parse($.concepts),filesRead:JSON.parse($.files_read),filesModified:JSON.parse($.files_modified),rawToolOutput:$.raw_tool_output,toolName:$.tool_name,createdAt:$.created_at,tokenCount:$.token_count,discoveryTokens:$.discovery_tokens??0,importance:$.importance??3,revisionOf:$.revision_of??null,deletedAt:$.deleted_at??null,supersededBy:$.superseded_by??null,supersededAt:$.superseded_at??null}}}import{randomUUID as VJ}from"crypto";class V${db;constructor($){this.db=$}create($){let V=VJ(),J=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
|
|
228
229
|
(id, session_id, tool_name, tool_output, call_id, created_at)
|
|
229
230
|
VALUES (?, ?, ?, ?, ?, ?)`,[V,$.sessionId,$.toolName,$.toolOutput,$.callId,J]),{...$,id:V,createdAt:J,status:"pending",retryCount:0,error:null}}getPending($=10){return this.db.all("SELECT * FROM pending_messages WHERE status = 'pending' ORDER BY created_at ASC LIMIT ?",[$]).map((V)=>this.mapRow(V))}getByStatus($){return this.db.all("SELECT * FROM pending_messages WHERE status = ? ORDER BY created_at ASC",[$]).map((V)=>this.mapRow(V))}markProcessing($){this.db.run("UPDATE pending_messages SET status = 'processing' WHERE id = ?",[$])}markCompleted($){this.db.run("UPDATE pending_messages SET status = 'completed' WHERE id = ?",[$])}markFailed($,V){this.db.run("UPDATE pending_messages SET status = 'failed', error = ?, retry_count = retry_count + 1 WHERE id = ?",[V,$])}resetStale($=5){return this.db.all(`UPDATE pending_messages SET status = 'pending'
|
|
230
231
|
WHERE status = 'processing'
|
|
@@ -232,7 +233,7 @@ Respond with EXACTLY this XML format:
|
|
|
232
233
|
RETURNING id`,[`-${$}`]).length}deleteCompletedOlderThan($){return this.db.all(`DELETE FROM pending_messages
|
|
233
234
|
WHERE status = 'completed'
|
|
234
235
|
AND created_at < datetime('now', '-' || ? || ' days')
|
|
235
|
-
RETURNING id`,[$]).length}mapRow($){return{id:$.id,sessionId:$.session_id,toolName:$.tool_name,toolOutput:$.tool_output,callId:$.call_id,createdAt:$.created_at,status:$.status,retryCount:$.retry_count,error:$.error??null}}}var
|
|
236
|
+
RETURNING id`,[$]).length}mapRow($){return{id:$.id,sessionId:$.session_id,toolName:$.tool_name,toolOutput:$.tool_output,callId:$.call_id,createdAt:$.created_at,status:$.status,retryCount:$.retry_count,error:$.error??null}}}var JJ=[{version:1,name:"create-schema",up:`
|
|
236
237
|
-- Sessions table
|
|
237
238
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
238
239
|
_rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -526,11 +527,11 @@ Respond with EXACTLY this XML format:
|
|
|
526
527
|
INSERT INTO entities_fts(rowid, name, entity_type)
|
|
527
528
|
VALUES (new._rowid, new.name, new.entity_type);
|
|
528
529
|
END;
|
|
529
|
-
`}];function
|
|
530
|
+
`}];function g$($,V){if($.migrate(JJ),V?.hasVectorExtension&&V?.embeddingDimension&&V.embeddingDimension>0)XJ($,V.embeddingDimension)}function XJ($,V){if($.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let X=$.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(X&&Number(X.value)!==V){console.warn(`[open-mem] vec0 table exists with dimension ${X.value}, but config specifies ${V}. Drop observation_embeddings to re-create with new dimension.`);return}}else $.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
|
|
530
531
|
observation_id TEXT PRIMARY KEY,
|
|
531
532
|
embedding float[${V}] distance_metric=cosine
|
|
532
|
-
)`);$.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(V)])}class
|
|
533
|
-
VALUES (?, ?, ?, 'active')`,[$,V,J]),this.getById($)}getOrCreate($,V){let J=this.getById($);if(J)return J;return this.create($,V)}getById($){let V=this.db.get("SELECT * FROM sessions WHERE id = ?",[$]);return V?this.mapRow(V):null}getRecent($,V=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[$,V]).map((J)=>this.mapRow(J))}getAll($){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[$]).map((V)=>this.mapRow(V))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map(($)=>this.mapRow($))}updateStatus($,V){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[V,$])}markCompleted($){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[$])}incrementObservationCount($){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[$])}setSummary($,V){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[V,$])}mapRow($){return{id:$.id,projectPath:$.project_path,startedAt:$.started_at,endedAt:$.ended_at??null,status:$.status,observationCount:$.observation_count,summaryId:$.summary_id??null}}}import{randomUUID as
|
|
533
|
+
)`);$.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(V)])}class J${db;constructor($){this.db=$}create($,V){let J=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
|
|
534
|
+
VALUES (?, ?, ?, 'active')`,[$,V,J]),this.getById($)}getOrCreate($,V){let J=this.getById($);if(J)return J;return this.create($,V)}getById($){let V=this.db.get("SELECT * FROM sessions WHERE id = ?",[$]);return V?this.mapRow(V):null}getRecent($,V=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[$,V]).map((J)=>this.mapRow(J))}getAll($){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[$]).map((V)=>this.mapRow(V))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map(($)=>this.mapRow($))}updateStatus($,V){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[V,$])}markCompleted($){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[$])}incrementObservationCount($){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[$])}setSummary($,V){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[V,$])}mapRow($){return{id:$.id,projectPath:$.project_path,startedAt:$.started_at,endedAt:$.ended_at??null,status:$.status,observationCount:$.observation_count,summaryId:$.summary_id??null}}}import{randomUUID as ZJ}from"crypto";class X${db;constructor($){this.db=$}create($){let V=ZJ(),J=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
|
|
534
535
|
(id, session_id, summary, key_decisions, files_modified,
|
|
535
536
|
concepts, created_at, token_count,
|
|
536
537
|
request, investigated, learned, completed, next_steps)
|
|
@@ -543,4 +544,4 @@ Respond with EXACTLY this XML format:
|
|
|
543
544
|
JOIN summaries_fts fts ON ss._rowid = fts.rowid
|
|
544
545
|
WHERE summaries_fts MATCH ?
|
|
545
546
|
ORDER BY rank
|
|
546
|
-
LIMIT ?`,[$,V]).map((J)=>this.mapRow(J))}mapRow($){return{id:$.id,sessionId:$.session_id,summary:$.summary,keyDecisions:JSON.parse($.key_decisions),filesModified:JSON.parse($.files_modified),concepts:JSON.parse($.concepts),createdAt:$.created_at,tokenCount:$.token_count,request:$.request||void 0,investigated:$.investigated||void 0,learned:$.learned||void 0,completed:$.completed||void 0,nextSteps:$.next_steps||void 0}}}class
|
|
547
|
+
LIMIT ?`,[$,V]).map((J)=>this.mapRow(J))}mapRow($){return{id:$.id,sessionId:$.session_id,summary:$.summary,keyDecisions:JSON.parse($.key_decisions),filesModified:JSON.parse($.files_modified),concepts:JSON.parse($.concepts),createdAt:$.created_at,tokenCount:$.token_count,request:$.request||void 0,investigated:$.investigated||void 0,learned:$.learned||void 0,completed:$.completed||void 0,nextSteps:$.next_steps||void 0}}}class Z${config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;conflictEvaluator;entityExtractor;entityRepo;observer;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor($,V,J,X,Z,H,Y,K=null,Q=null,G=null,F=null,W=null){this.config=$;this.compressor=V;this.summarizer=J;this.pendingRepo=X;this.observationRepo=Z;this.sessionRepo=H;this.summaryRepo=Y;this.embeddingModel=K;this.conflictEvaluator=Q;this.entityExtractor=G;this.entityRepo=F;this.observer=W}setMode($){if(this.mode=$,$==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue($){this.onEnqueue=$}enqueue($,V,J,X){if(this.pendingRepo.create({sessionId:$,toolName:V,toolOutput:J,callId:X}),this.observer?.onEnqueue?.({sessionId:$,toolName:V,createdAt:new Date().toISOString()}),this.mode==="enqueue-only")this.onEnqueue?.()}async processBatch(){if(this.mode==="enqueue-only")return 0;if(this.processing)return 0;this.processing=!0;let $=0,V=0,J=Date.now();try{this.pendingRepo.resetStale(5);let X=this.pendingRepo.getPending(this.config.batchSize);if(this.observer?.onBatchStart?.({pending:X.length,mode:this.mode,startedAt:new Date(J).toISOString()}),X.length===0)return 0;for(let Z of X)try{this.pendingRepo.markProcessing(Z.id);let Y=await this.compressor.compress(Z.toolName,Z.toolOutput)??this.compressor.createFallbackObservation(Z.toolName,Z.toolOutput),K=!1,Q=null;if(this.embeddingModel)try{let F=e({title:Y.title,narrative:Y.narrative,concepts:Y.concepts}),W=await a(this.embeddingModel,F);if(W){let B=this.config.conflictResolutionEnabled&&this.conflictEvaluator,N=this.config.conflictSimilarityBandLow??0.7,I=this.config.conflictSimilarityBandHigh??0.92;if(B){let E=this.observationRepo.findSimilar(W,Y.type,N,5),p=E.find((v)=>v.similarity>I);if(p)console.log(`[open-mem] Dedup: skipping duplicate of ${p.id} (similarity: ${p.similarity.toFixed(3)})`),K=!0;else{let v=E.filter((k)=>k.similarity>=N&&k.similarity<=I);if(v.length>0)try{let k=v.map((M)=>{let y=this.observationRepo.getById(M.id);return y?{id:y.id,title:y.title,narrative:y.narrative,concepts:y.concepts,type:y.type}:null}).filter((M)=>M!==null);if(k.length>0&&this.conflictEvaluator){let M=await this.conflictEvaluator.evaluate({title:Y.title,narrative:Y.narrative,concepts:Y.concepts,type:Y.type},k);if(M&&M.outcome==="duplicate")console.log(`[open-mem] Conflict eval: duplicate (${M.reason})`),K=!0;else if(M&&M.outcome==="update"&&M.supersedesId)console.log(`[open-mem] Conflict eval: update supersedes ${M.supersedesId} (${M.reason})`),Q=M.supersedesId}}catch{}}}else{let E=this.observationRepo.findSimilar(W,Y.type,0.92,1);if(E.length>0)console.log(`[open-mem] Dedup: skipping duplicate of ${E[0].id} (similarity: ${E[0].similarity.toFixed(3)})`),K=!0}}}catch{}if(K){this.pendingRepo.markCompleted(Z.id);continue}let G=this.observationRepo.create({sessionId:Z.sessionId,type:Y.type,title:Y.title,subtitle:Y.subtitle,facts:Y.facts,narrative:Y.narrative,concepts:Y.concepts,filesRead:Y.filesRead,filesModified:Y.filesModified,rawToolOutput:Z.toolOutput,toolName:Z.toolName,tokenCount:R(`${Y.title} ${Y.narrative} ${Y.facts.join(" ")}`),discoveryTokens:Y.discoveryTokens??R(Z.toolOutput),importance:Y.importance??3});if(this.embeddingModel)try{let F=e({title:G.title,narrative:G.narrative,concepts:G.concepts}),W=await a(this.embeddingModel,F);if(W)this.observationRepo.setEmbedding(G.id,W)}catch{}if(Q)try{this.observationRepo.supersede(Q,G.id),console.log(`[open-mem] Superseded observation ${Q} with ${G.id}`)}catch(F){console.error(`[open-mem] Failed to supersede ${Q}:`,F)}if(this.config.entityExtractionEnabled&&this.entityExtractor&&this.entityRepo)try{let F=await this.entityExtractor.extract({title:G.title,narrative:G.narrative,concepts:G.concepts,facts:G.facts,filesRead:G.filesRead,filesModified:G.filesModified,type:G.type});if(F){let W=new Map;for(let B of F.entities){let N=this.entityRepo.upsertEntity(B.name,B.entityType);W.set(B.name,N.id),this.entityRepo.linkObservation(N.id,G.id)}for(let B of F.relations){let N=W.get(B.sourceName),I=W.get(B.targetName);if(N&&I)this.entityRepo.createRelation(N,I,B.relationship,G.id)}}}catch{}this.sessionRepo.incrementObservationCount(Z.sessionId),this.pendingRepo.markCompleted(Z.id),$++}catch(H){this.pendingRepo.markFailed(Z.id,String(H)),V++,this.observer?.onItemFailed?.({pendingId:Z.id,error:String(H),failedAt:new Date().toISOString()})}return $}finally{this.observer?.onBatchEnd?.({processed:$,failed:V,durationMs:Date.now()-J,finishedAt:new Date().toISOString()}),this.processing=!1}}async summarizeSession($){let V=this.observationRepo.getBySession($);if(!this.summarizer.shouldSummarize(V.length))return;if(this.summaryRepo.getBySessionId($))return;let X=await this.summarizer.summarize($,V);if(!X)return;let Z=this.summaryRepo.create({sessionId:$,summary:X.summary,keyDecisions:X.keyDecisions,filesModified:X.filesModified,concepts:X.concepts,tokenCount:R(X.summary)});this.sessionRepo.setSummary($,Z.id)}start(){if(this.mode==="enqueue-only")return;if(this.timer)return;this.timer=setInterval(async()=>{try{await this.processBatch()}catch{}},this.config.batchIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get isProcessing(){return this.processing}getStats(){return{pending:this.pendingRepo.getPending(1000).length,processing:this.processing}}}import{spawnSync as p$}from"child_process";import{dirname as HJ,resolve as m$}from"path";function YJ($){try{let V=p$("git",["rev-parse","--git-common-dir"],{cwd:$,encoding:"utf-8",timeout:5000});if(V.status!==0||!V.stdout)return null;let J=V.stdout.trim();if(J===".git")return null;let X=p$("git",["rev-parse","--git-dir"],{cwd:$,encoding:"utf-8",timeout:5000});if(X.status!==0||!X.stdout)return null;let Z=X.stdout.trim(),H=m$($,J),Y=m$($,Z);if(H===Y)return null;let K=HJ(H);if(K===H||K==="/")return null;return K}catch{return null}}function l$($){return YJ($)??$}var QJ=5000,{values:H$}=KJ({options:{project:{type:"string",short:"p"},"poll-interval":{type:"string"}},strict:!1}),n$=typeof H$.project==="string"?H$.project:null;if(!n$)console.error("Usage: open-mem-daemon --project <path> [--poll-interval <ms>]"),process.exit(1);var c$=H$["poll-interval"],Y$=typeof c$==="string"?Number.parseInt(c$,10):QJ;if(Number.isNaN(Y$)||Y$<100)console.error("--poll-interval must be a number >= 100"),process.exit(1);var GJ=l$(n$),z=O$(GJ);b.enableExtensionSupport();var S=w$(z.dbPath,{processRole:"daemon"});g$(S,{hasVectorExtension:S.hasVectorExtension,embeddingDimension:z.embeddingDimension});var FJ=new V$(S),WJ=new $$(S),UJ=new J$(S),zJ=new X$(S),BJ=new f(z),NJ=new n(z),K$=z.provider!=="bedrock",MJ=z.compressionEnabled&&(!K$||z.apiKey)?A$({provider:z.provider,model:z.model,apiKey:z.apiKey}):null,_J=z.conflictResolutionEnabled&&(!K$||z.apiKey)?new c({provider:z.provider,apiKey:z.apiKey,model:z.model,rateLimitingEnabled:z.rateLimitingEnabled}):null,AJ=z.entityExtractionEnabled&&(!K$||z.apiKey)?new d({provider:z.provider,apiKey:z.apiKey,model:z.model,rateLimitingEnabled:z.rateLimitingEnabled}):null,jJ=new t(S),DJ=new Z$(z,BJ,NJ,FJ,WJ,UJ,zJ,MJ,_J,AJ,jJ),s$=T$(z.dbPath);S$(s$);var g=new i({queueProcessor:DJ,pollIntervalMs:Y$});if(process.send)process.on("message",($)=>{g.handleMessage($)});process.on("SIGUSR1",()=>{g.handleMessage("PROCESS_NOW")});var d$=!1,Q$=()=>{if(d$)return;d$=!0,g.stop(),R$(s$),S.close()};process.on("SIGTERM",()=>{Q$(),process.exit(0)});process.on("SIGINT",()=>{Q$(),process.exit(0)});process.on("beforeExit",Q$);g.start();
|