@hasna/mementos 0.10.9 → 0.10.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +166 -2
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/memories.d.ts +20 -0
- package/dist/db/memories.d.ts.map +1 -1
- package/dist/index.js +34 -1
- package/dist/lib/built-in-hooks.d.ts.map +1 -1
- package/dist/lib/embeddings.d.ts +20 -0
- package/dist/lib/embeddings.d.ts.map +1 -0
- package/dist/mcp/index.js +221 -9
- package/dist/server/index.js +166 -2
- package/dist/types/index.d.ts +11 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2584,12 +2584,23 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_resource_locks_exclusive
|
|
|
2584
2584
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_agent ON resource_locks(agent_id);
|
|
2585
2585
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_expires ON resource_locks(expires_at);
|
|
2586
2586
|
INSERT OR IGNORE INTO _migrations (id) VALUES (14);
|
|
2587
|
+
`,
|
|
2588
|
+
`
|
|
2589
|
+
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
2590
|
+
memory_id TEXT PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
2591
|
+
embedding TEXT NOT NULL,
|
|
2592
|
+
model TEXT NOT NULL DEFAULT 'tfidf-512',
|
|
2593
|
+
dimensions INTEGER NOT NULL DEFAULT 512,
|
|
2594
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
2595
|
+
);
|
|
2596
|
+
CREATE INDEX IF NOT EXISTS idx_memory_embeddings_model ON memory_embeddings(model);
|
|
2597
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (15);
|
|
2587
2598
|
`
|
|
2588
2599
|
];
|
|
2589
2600
|
});
|
|
2590
2601
|
|
|
2591
2602
|
// src/types/index.ts
|
|
2592
|
-
var AgentConflictError, EntityNotFoundError, MemoryNotFoundError, VersionConflictError;
|
|
2603
|
+
var AgentConflictError, EntityNotFoundError, MemoryNotFoundError, VersionConflictError, MemoryConflictError;
|
|
2593
2604
|
var init_types = __esm(() => {
|
|
2594
2605
|
AgentConflictError = class AgentConflictError extends Error {
|
|
2595
2606
|
conflict = true;
|
|
@@ -2631,8 +2642,92 @@ var init_types = __esm(() => {
|
|
|
2631
2642
|
this.actual = actual;
|
|
2632
2643
|
}
|
|
2633
2644
|
};
|
|
2645
|
+
MemoryConflictError = class MemoryConflictError extends Error {
|
|
2646
|
+
existingId;
|
|
2647
|
+
existingAgentId;
|
|
2648
|
+
existingUpdatedAt;
|
|
2649
|
+
constructor(key, existing) {
|
|
2650
|
+
super(`Memory conflict: key "${key}" already exists (last written by ${existing.agent_id ?? "unknown"} at ${existing.updated_at}). Use conflict:"overwrite" to replace it.`);
|
|
2651
|
+
this.name = "MemoryConflictError";
|
|
2652
|
+
this.existingId = existing.id;
|
|
2653
|
+
this.existingAgentId = existing.agent_id;
|
|
2654
|
+
this.existingUpdatedAt = existing.updated_at;
|
|
2655
|
+
}
|
|
2656
|
+
};
|
|
2634
2657
|
});
|
|
2635
2658
|
|
|
2659
|
+
// src/lib/embeddings.ts
|
|
2660
|
+
function cosineSimilarity(a, b) {
|
|
2661
|
+
if (a.length !== b.length || a.length === 0)
|
|
2662
|
+
return 0;
|
|
2663
|
+
let dot = 0, magA = 0, magB = 0;
|
|
2664
|
+
for (let i = 0;i < a.length; i++) {
|
|
2665
|
+
dot += a[i] * b[i];
|
|
2666
|
+
magA += a[i] * a[i];
|
|
2667
|
+
magB += b[i] * b[i];
|
|
2668
|
+
}
|
|
2669
|
+
const denom = Math.sqrt(magA) * Math.sqrt(magB);
|
|
2670
|
+
return denom === 0 ? 0 : dot / denom;
|
|
2671
|
+
}
|
|
2672
|
+
async function openAIEmbed(text, apiKey) {
|
|
2673
|
+
const res = await fetch(OPENAI_EMBED_URL, {
|
|
2674
|
+
method: "POST",
|
|
2675
|
+
headers: {
|
|
2676
|
+
"Content-Type": "application/json",
|
|
2677
|
+
Authorization: `Bearer ${apiKey}`
|
|
2678
|
+
},
|
|
2679
|
+
body: JSON.stringify({
|
|
2680
|
+
model: EMBED_MODEL,
|
|
2681
|
+
input: text.slice(0, 8192)
|
|
2682
|
+
}),
|
|
2683
|
+
signal: AbortSignal.timeout(1e4)
|
|
2684
|
+
});
|
|
2685
|
+
if (!res.ok) {
|
|
2686
|
+
throw new Error(`OpenAI embedding API ${res.status}: ${await res.text()}`);
|
|
2687
|
+
}
|
|
2688
|
+
const data = await res.json();
|
|
2689
|
+
return data.data[0].embedding;
|
|
2690
|
+
}
|
|
2691
|
+
function tfidfVector(text) {
|
|
2692
|
+
const DIMS = 512;
|
|
2693
|
+
const vec = new Float32Array(DIMS);
|
|
2694
|
+
const tokens = text.toLowerCase().match(/\b\w+\b/g) ?? [];
|
|
2695
|
+
for (const token of tokens) {
|
|
2696
|
+
let hash = 2166136261;
|
|
2697
|
+
for (let i = 0;i < token.length; i++) {
|
|
2698
|
+
hash ^= token.charCodeAt(i);
|
|
2699
|
+
hash = hash * 16777619 >>> 0;
|
|
2700
|
+
}
|
|
2701
|
+
vec[hash % DIMS] += 1;
|
|
2702
|
+
}
|
|
2703
|
+
let norm = 0;
|
|
2704
|
+
for (let i = 0;i < DIMS; i++)
|
|
2705
|
+
norm += vec[i] * vec[i];
|
|
2706
|
+
norm = Math.sqrt(norm);
|
|
2707
|
+
if (norm > 0)
|
|
2708
|
+
for (let i = 0;i < DIMS; i++)
|
|
2709
|
+
vec[i] /= norm;
|
|
2710
|
+
return Array.from(vec);
|
|
2711
|
+
}
|
|
2712
|
+
async function generateEmbedding(text) {
|
|
2713
|
+
const apiKey = process.env["OPENAI_API_KEY"];
|
|
2714
|
+
if (apiKey) {
|
|
2715
|
+
try {
|
|
2716
|
+
const embedding2 = await openAIEmbed(text, apiKey);
|
|
2717
|
+
return { embedding: embedding2, model: EMBED_MODEL, dimensions: EMBED_DIMENSIONS };
|
|
2718
|
+
} catch {}
|
|
2719
|
+
}
|
|
2720
|
+
const embedding = tfidfVector(text);
|
|
2721
|
+
return { embedding, model: "tfidf-512", dimensions: 512 };
|
|
2722
|
+
}
|
|
2723
|
+
function serializeEmbedding(embedding) {
|
|
2724
|
+
return JSON.stringify(embedding);
|
|
2725
|
+
}
|
|
2726
|
+
function deserializeEmbedding(raw) {
|
|
2727
|
+
return JSON.parse(raw);
|
|
2728
|
+
}
|
|
2729
|
+
var OPENAI_EMBED_URL = "https://api.openai.com/v1/embeddings", EMBED_MODEL = "text-embedding-3-small", EMBED_DIMENSIONS = 1536;
|
|
2730
|
+
|
|
2636
2731
|
// src/lib/redact.ts
|
|
2637
2732
|
function redactSecrets(text) {
|
|
2638
2733
|
let result = text;
|
|
@@ -2809,8 +2904,10 @@ var exports_memories = {};
|
|
|
2809
2904
|
__export(exports_memories, {
|
|
2810
2905
|
updateMemory: () => updateMemory,
|
|
2811
2906
|
touchMemory: () => touchMemory,
|
|
2907
|
+
semanticSearch: () => semanticSearch,
|
|
2812
2908
|
parseMemoryRow: () => parseMemoryRow,
|
|
2813
2909
|
listMemories: () => listMemories,
|
|
2910
|
+
indexMemoryEmbedding: () => indexMemoryEmbedding,
|
|
2814
2911
|
incrementRecallCount: () => incrementRecallCount,
|
|
2815
2912
|
getMemoryVersions: () => getMemoryVersions,
|
|
2816
2913
|
getMemoryByKey: () => getMemoryByKey,
|
|
@@ -2866,7 +2963,16 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
2866
2963
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
2867
2964
|
const safeValue = redactSecrets(input.value);
|
|
2868
2965
|
const safeSummary = input.summary ? redactSecrets(input.summary) : null;
|
|
2869
|
-
|
|
2966
|
+
const effectiveMode = dedupeMode === "overwrite" ? "merge" : dedupeMode === "version-fork" ? "create" : dedupeMode;
|
|
2967
|
+
if (effectiveMode === "error") {
|
|
2968
|
+
const existing = d.query(`SELECT id, agent_id, updated_at FROM memories
|
|
2969
|
+
WHERE key = ? AND scope = ? AND COALESCE(project_id, '') = ? AND status = 'active'
|
|
2970
|
+
LIMIT 1`).get(input.key, input.scope || "private", input.project_id || "");
|
|
2971
|
+
if (existing) {
|
|
2972
|
+
throw new MemoryConflictError(input.key, existing);
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
if (effectiveMode === "merge") {
|
|
2870
2976
|
const existing = d.query(`SELECT id, version FROM memories
|
|
2871
2977
|
WHERE key = ? AND scope = ?
|
|
2872
2978
|
AND COALESCE(agent_id, '') = ?
|
|
@@ -3252,6 +3358,52 @@ function getMemoryVersions(memoryId, db) {
|
|
|
3252
3358
|
return [];
|
|
3253
3359
|
}
|
|
3254
3360
|
}
|
|
3361
|
+
async function indexMemoryEmbedding(memoryId, text, db) {
|
|
3362
|
+
try {
|
|
3363
|
+
const d = db || getDatabase();
|
|
3364
|
+
const { embedding, model, dimensions } = await generateEmbedding(text);
|
|
3365
|
+
const serialized = serializeEmbedding(embedding);
|
|
3366
|
+
d.run(`INSERT INTO memory_embeddings (memory_id, embedding, model, dimensions)
|
|
3367
|
+
VALUES (?, ?, ?, ?)
|
|
3368
|
+
ON CONFLICT(memory_id) DO UPDATE SET embedding=excluded.embedding, model=excluded.model, dimensions=excluded.dimensions, created_at=datetime('now')`, [memoryId, serialized, model, dimensions]);
|
|
3369
|
+
} catch {}
|
|
3370
|
+
}
|
|
3371
|
+
async function semanticSearch(queryText, options = {}, db) {
|
|
3372
|
+
const d = db || getDatabase();
|
|
3373
|
+
const { threshold = 0.5, limit = 10, scope, agent_id, project_id } = options;
|
|
3374
|
+
const { embedding: queryEmbedding } = await generateEmbedding(queryText);
|
|
3375
|
+
const conditions = ["m.status = 'active'", "e.embedding IS NOT NULL"];
|
|
3376
|
+
const params = [];
|
|
3377
|
+
if (scope) {
|
|
3378
|
+
conditions.push("m.scope = ?");
|
|
3379
|
+
params.push(scope);
|
|
3380
|
+
}
|
|
3381
|
+
if (agent_id) {
|
|
3382
|
+
conditions.push("m.agent_id = ?");
|
|
3383
|
+
params.push(agent_id);
|
|
3384
|
+
}
|
|
3385
|
+
if (project_id) {
|
|
3386
|
+
conditions.push("m.project_id = ?");
|
|
3387
|
+
params.push(project_id);
|
|
3388
|
+
}
|
|
3389
|
+
const where = conditions.join(" AND ");
|
|
3390
|
+
const rows = d.prepare(`SELECT m.*, e.embedding FROM memories m
|
|
3391
|
+
JOIN memory_embeddings e ON e.memory_id = m.id
|
|
3392
|
+
WHERE ${where}`).all(...params);
|
|
3393
|
+
const scored = [];
|
|
3394
|
+
for (const row of rows) {
|
|
3395
|
+
try {
|
|
3396
|
+
const docEmbedding = deserializeEmbedding(row.embedding);
|
|
3397
|
+
const score = cosineSimilarity(queryEmbedding, docEmbedding);
|
|
3398
|
+
if (score >= threshold) {
|
|
3399
|
+
const { embedding: _, ...memRow } = row;
|
|
3400
|
+
scored.push({ memory: parseMemoryRow(memRow), score: Math.round(score * 1000) / 1000 });
|
|
3401
|
+
}
|
|
3402
|
+
} catch {}
|
|
3403
|
+
}
|
|
3404
|
+
scored.sort((a, b) => b.score - a.score);
|
|
3405
|
+
return scored.slice(0, limit);
|
|
3406
|
+
}
|
|
3255
3407
|
var RECALL_PROMOTE_THRESHOLD = 3;
|
|
3256
3408
|
var init_memories = __esm(() => {
|
|
3257
3409
|
init_types();
|
|
@@ -5473,6 +5625,18 @@ var init_built_in_hooks = __esm(() => {
|
|
|
5473
5625
|
});
|
|
5474
5626
|
}
|
|
5475
5627
|
});
|
|
5628
|
+
hookRegistry.register({
|
|
5629
|
+
type: "PostMemorySave",
|
|
5630
|
+
blocking: false,
|
|
5631
|
+
builtin: true,
|
|
5632
|
+
priority: 300,
|
|
5633
|
+
description: "Generate and store vector embedding for semantic memory search",
|
|
5634
|
+
handler: async (ctx) => {
|
|
5635
|
+
const { indexMemoryEmbedding: indexMemoryEmbedding2 } = await Promise.resolve().then(() => (init_memories(), exports_memories));
|
|
5636
|
+
const text = [ctx.memory.value, ctx.memory.summary].filter(Boolean).join(" ");
|
|
5637
|
+
indexMemoryEmbedding2(ctx.memory.id, text);
|
|
5638
|
+
}
|
|
5639
|
+
});
|
|
5476
5640
|
hookRegistry.register({
|
|
5477
5641
|
type: "PostMemoryInject",
|
|
5478
5642
|
blocking: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmCtC,wBAAgB,SAAS,IAAI,MAAM,CAkBlC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmCtC,wBAAgB,SAAS,IAAI,MAAM,CAkBlC;AA0aD,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAerD;AA+BD,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAef"}
|
package/dist/db/memories.d.ts
CHANGED
|
@@ -17,4 +17,24 @@ export declare function touchMemory(id: string, db?: Database): void;
|
|
|
17
17
|
export declare function incrementRecallCount(id: string, db?: Database): void;
|
|
18
18
|
export declare function cleanExpiredMemories(db?: Database): number;
|
|
19
19
|
export declare function getMemoryVersions(memoryId: string, db?: Database): MemoryVersion[];
|
|
20
|
+
export interface SemanticSearchResult {
|
|
21
|
+
memory: Memory;
|
|
22
|
+
score: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Store or update the embedding for a memory. Called asynchronously after saves.
|
|
26
|
+
* Non-blocking: failures are silently ignored.
|
|
27
|
+
*/
|
|
28
|
+
export declare function indexMemoryEmbedding(memoryId: string, text: string, db?: Database): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Semantic search across memories using cosine similarity.
|
|
31
|
+
* Falls back gracefully if no embeddings exist yet.
|
|
32
|
+
*/
|
|
33
|
+
export declare function semanticSearch(queryText: string, options?: {
|
|
34
|
+
threshold?: number;
|
|
35
|
+
limit?: number;
|
|
36
|
+
scope?: string;
|
|
37
|
+
agent_id?: string;
|
|
38
|
+
project_id?: string;
|
|
39
|
+
}, db?: Database): Promise<SemanticSearchResult[]>;
|
|
20
40
|
//# sourceMappingURL=memories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../src/db/memories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAyB,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,YAAY,EACZ,aAAa,EACb,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../src/db/memories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAyB,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,YAAY,EACZ,aAAa,EACb,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AA+B3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAwBnE;AAMD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,iBAAiB,EACxB,UAAU,GAAE,UAAoB,EAChC,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,CAqKR;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAOlE;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,GAAG,IAAI,CA4Bf;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,EAAE,CAuBV;AAMD,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,EAAE,CA4G3E;AAMD,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,iBAAiB,EACxB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,CAiHR;AAMD,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAW/D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAmBvE;AAMD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAM3D;AAUD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAsBpE;AAMD,wBAAgB,oBAAoB,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAiB1D;AAMD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,aAAa,EAAE,CAwBlF;AAMD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,EACN,EAAE,CAAC,EAAE,QAAQ,GACZ,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAuCjC"}
|
package/dist/index.js
CHANGED
|
@@ -63,6 +63,19 @@ class VersionConflictError extends Error {
|
|
|
63
63
|
this.actual = actual;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
class MemoryConflictError extends Error {
|
|
68
|
+
existingId;
|
|
69
|
+
existingAgentId;
|
|
70
|
+
existingUpdatedAt;
|
|
71
|
+
constructor(key, existing) {
|
|
72
|
+
super(`Memory conflict: key "${key}" already exists (last written by ${existing.agent_id ?? "unknown"} at ${existing.updated_at}). Use conflict:"overwrite" to replace it.`);
|
|
73
|
+
this.name = "MemoryConflictError";
|
|
74
|
+
this.existingId = existing.id;
|
|
75
|
+
this.existingAgentId = existing.agent_id;
|
|
76
|
+
this.existingUpdatedAt = existing.updated_at;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
66
79
|
// src/db/database.ts
|
|
67
80
|
import { Database } from "bun:sqlite";
|
|
68
81
|
import { existsSync, mkdirSync } from "fs";
|
|
@@ -477,6 +490,17 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_resource_locks_exclusive
|
|
|
477
490
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_agent ON resource_locks(agent_id);
|
|
478
491
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_expires ON resource_locks(expires_at);
|
|
479
492
|
INSERT OR IGNORE INTO _migrations (id) VALUES (14);
|
|
493
|
+
`,
|
|
494
|
+
`
|
|
495
|
+
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
496
|
+
memory_id TEXT PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
497
|
+
embedding TEXT NOT NULL,
|
|
498
|
+
model TEXT NOT NULL DEFAULT 'tfidf-512',
|
|
499
|
+
dimensions INTEGER NOT NULL DEFAULT 512,
|
|
500
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
501
|
+
);
|
|
502
|
+
CREATE INDEX IF NOT EXISTS idx_memory_embeddings_model ON memory_embeddings(model);
|
|
503
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (15);
|
|
480
504
|
`
|
|
481
505
|
];
|
|
482
506
|
var _db = null;
|
|
@@ -783,7 +807,16 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
783
807
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
784
808
|
const safeValue = redactSecrets(input.value);
|
|
785
809
|
const safeSummary = input.summary ? redactSecrets(input.summary) : null;
|
|
786
|
-
|
|
810
|
+
const effectiveMode = dedupeMode === "overwrite" ? "merge" : dedupeMode === "version-fork" ? "create" : dedupeMode;
|
|
811
|
+
if (effectiveMode === "error") {
|
|
812
|
+
const existing = d.query(`SELECT id, agent_id, updated_at FROM memories
|
|
813
|
+
WHERE key = ? AND scope = ? AND COALESCE(project_id, '') = ? AND status = 'active'
|
|
814
|
+
LIMIT 1`).get(input.key, input.scope || "private", input.project_id || "");
|
|
815
|
+
if (existing) {
|
|
816
|
+
throw new MemoryConflictError(input.key, existing);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (effectiveMode === "merge") {
|
|
787
820
|
const existing = d.query(`SELECT id, version FROM memories
|
|
788
821
|
WHERE key = ? AND scope = ?
|
|
789
822
|
AND COALESCE(agent_id, '') = ?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"built-in-hooks.d.ts","sourceRoot":"","sources":["../../src/lib/built-in-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"built-in-hooks.d.ts","sourceRoot":"","sources":["../../src/lib/built-in-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAyIlD,wBAAgB,kBAAkB,IAAI,IAAI,CAyBzC;AAuBD,wBAAgB,cAAc,IAAI,IAAI,CAGrC;AAGD,YAAY,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding generation and cosine similarity for semantic memory search.
|
|
3
|
+
*
|
|
4
|
+
* Uses OpenAI text-embedding-3-small if OPENAI_API_KEY is set,
|
|
5
|
+
* falls back to a simple TF-IDF term frequency vector otherwise.
|
|
6
|
+
*/
|
|
7
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
8
|
+
export interface EmbeddingResult {
|
|
9
|
+
embedding: number[];
|
|
10
|
+
model: string;
|
|
11
|
+
dimensions: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate an embedding for a text string.
|
|
15
|
+
* Uses OpenAI if OPENAI_API_KEY is available, otherwise uses TF-IDF hash trick.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateEmbedding(text: string): Promise<EmbeddingResult>;
|
|
18
|
+
export declare function serializeEmbedding(embedding: number[]): string;
|
|
19
|
+
export declare function deserializeEmbedding(raw: string): number[];
|
|
20
|
+
//# sourceMappingURL=embeddings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../../src/lib/embeddings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAUjE;AAwDD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAY9E;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAE1D"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __export = (target, all) => {
|
|
|
17
17
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
18
|
|
|
19
19
|
// src/types/index.ts
|
|
20
|
-
var AgentConflictError, EntityNotFoundError, MemoryNotFoundError, DuplicateMemoryError, InvalidScopeError, VersionConflictError;
|
|
20
|
+
var AgentConflictError, EntityNotFoundError, MemoryNotFoundError, DuplicateMemoryError, InvalidScopeError, VersionConflictError, MemoryConflictError;
|
|
21
21
|
var init_types = __esm(() => {
|
|
22
22
|
AgentConflictError = class AgentConflictError extends Error {
|
|
23
23
|
conflict = true;
|
|
@@ -71,6 +71,18 @@ var init_types = __esm(() => {
|
|
|
71
71
|
this.actual = actual;
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
|
+
MemoryConflictError = class MemoryConflictError extends Error {
|
|
75
|
+
existingId;
|
|
76
|
+
existingAgentId;
|
|
77
|
+
existingUpdatedAt;
|
|
78
|
+
constructor(key, existing) {
|
|
79
|
+
super(`Memory conflict: key "${key}" already exists (last written by ${existing.agent_id ?? "unknown"} at ${existing.updated_at}). Use conflict:"overwrite" to replace it.`);
|
|
80
|
+
this.name = "MemoryConflictError";
|
|
81
|
+
this.existingId = existing.id;
|
|
82
|
+
this.existingAgentId = existing.agent_id;
|
|
83
|
+
this.existingUpdatedAt = existing.updated_at;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
74
86
|
});
|
|
75
87
|
|
|
76
88
|
// src/db/database.ts
|
|
@@ -538,10 +550,93 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_resource_locks_exclusive
|
|
|
538
550
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_agent ON resource_locks(agent_id);
|
|
539
551
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_expires ON resource_locks(expires_at);
|
|
540
552
|
INSERT OR IGNORE INTO _migrations (id) VALUES (14);
|
|
553
|
+
`,
|
|
554
|
+
`
|
|
555
|
+
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
556
|
+
memory_id TEXT PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
557
|
+
embedding TEXT NOT NULL,
|
|
558
|
+
model TEXT NOT NULL DEFAULT 'tfidf-512',
|
|
559
|
+
dimensions INTEGER NOT NULL DEFAULT 512,
|
|
560
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
561
|
+
);
|
|
562
|
+
CREATE INDEX IF NOT EXISTS idx_memory_embeddings_model ON memory_embeddings(model);
|
|
563
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (15);
|
|
541
564
|
`
|
|
542
565
|
];
|
|
543
566
|
});
|
|
544
567
|
|
|
568
|
+
// src/lib/embeddings.ts
|
|
569
|
+
function cosineSimilarity(a, b) {
|
|
570
|
+
if (a.length !== b.length || a.length === 0)
|
|
571
|
+
return 0;
|
|
572
|
+
let dot = 0, magA = 0, magB = 0;
|
|
573
|
+
for (let i = 0;i < a.length; i++) {
|
|
574
|
+
dot += a[i] * b[i];
|
|
575
|
+
magA += a[i] * a[i];
|
|
576
|
+
magB += b[i] * b[i];
|
|
577
|
+
}
|
|
578
|
+
const denom = Math.sqrt(magA) * Math.sqrt(magB);
|
|
579
|
+
return denom === 0 ? 0 : dot / denom;
|
|
580
|
+
}
|
|
581
|
+
async function openAIEmbed(text, apiKey) {
|
|
582
|
+
const res = await fetch(OPENAI_EMBED_URL, {
|
|
583
|
+
method: "POST",
|
|
584
|
+
headers: {
|
|
585
|
+
"Content-Type": "application/json",
|
|
586
|
+
Authorization: `Bearer ${apiKey}`
|
|
587
|
+
},
|
|
588
|
+
body: JSON.stringify({
|
|
589
|
+
model: EMBED_MODEL,
|
|
590
|
+
input: text.slice(0, 8192)
|
|
591
|
+
}),
|
|
592
|
+
signal: AbortSignal.timeout(1e4)
|
|
593
|
+
});
|
|
594
|
+
if (!res.ok) {
|
|
595
|
+
throw new Error(`OpenAI embedding API ${res.status}: ${await res.text()}`);
|
|
596
|
+
}
|
|
597
|
+
const data = await res.json();
|
|
598
|
+
return data.data[0].embedding;
|
|
599
|
+
}
|
|
600
|
+
function tfidfVector(text) {
|
|
601
|
+
const DIMS = 512;
|
|
602
|
+
const vec = new Float32Array(DIMS);
|
|
603
|
+
const tokens = text.toLowerCase().match(/\b\w+\b/g) ?? [];
|
|
604
|
+
for (const token of tokens) {
|
|
605
|
+
let hash = 2166136261;
|
|
606
|
+
for (let i = 0;i < token.length; i++) {
|
|
607
|
+
hash ^= token.charCodeAt(i);
|
|
608
|
+
hash = hash * 16777619 >>> 0;
|
|
609
|
+
}
|
|
610
|
+
vec[hash % DIMS] += 1;
|
|
611
|
+
}
|
|
612
|
+
let norm = 0;
|
|
613
|
+
for (let i = 0;i < DIMS; i++)
|
|
614
|
+
norm += vec[i] * vec[i];
|
|
615
|
+
norm = Math.sqrt(norm);
|
|
616
|
+
if (norm > 0)
|
|
617
|
+
for (let i = 0;i < DIMS; i++)
|
|
618
|
+
vec[i] /= norm;
|
|
619
|
+
return Array.from(vec);
|
|
620
|
+
}
|
|
621
|
+
async function generateEmbedding(text) {
|
|
622
|
+
const apiKey = process.env["OPENAI_API_KEY"];
|
|
623
|
+
if (apiKey) {
|
|
624
|
+
try {
|
|
625
|
+
const embedding2 = await openAIEmbed(text, apiKey);
|
|
626
|
+
return { embedding: embedding2, model: EMBED_MODEL, dimensions: EMBED_DIMENSIONS };
|
|
627
|
+
} catch {}
|
|
628
|
+
}
|
|
629
|
+
const embedding = tfidfVector(text);
|
|
630
|
+
return { embedding, model: "tfidf-512", dimensions: 512 };
|
|
631
|
+
}
|
|
632
|
+
function serializeEmbedding(embedding) {
|
|
633
|
+
return JSON.stringify(embedding);
|
|
634
|
+
}
|
|
635
|
+
function deserializeEmbedding(raw) {
|
|
636
|
+
return JSON.parse(raw);
|
|
637
|
+
}
|
|
638
|
+
var OPENAI_EMBED_URL = "https://api.openai.com/v1/embeddings", EMBED_MODEL = "text-embedding-3-small", EMBED_DIMENSIONS = 1536;
|
|
639
|
+
|
|
545
640
|
// src/lib/redact.ts
|
|
546
641
|
function redactSecrets(text) {
|
|
547
642
|
let result = text;
|
|
@@ -714,8 +809,10 @@ var exports_memories = {};
|
|
|
714
809
|
__export(exports_memories, {
|
|
715
810
|
updateMemory: () => updateMemory,
|
|
716
811
|
touchMemory: () => touchMemory,
|
|
812
|
+
semanticSearch: () => semanticSearch,
|
|
717
813
|
parseMemoryRow: () => parseMemoryRow,
|
|
718
814
|
listMemories: () => listMemories,
|
|
815
|
+
indexMemoryEmbedding: () => indexMemoryEmbedding,
|
|
719
816
|
incrementRecallCount: () => incrementRecallCount,
|
|
720
817
|
getMemoryVersions: () => getMemoryVersions,
|
|
721
818
|
getMemoryByKey: () => getMemoryByKey,
|
|
@@ -771,7 +868,16 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
771
868
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
772
869
|
const safeValue = redactSecrets(input.value);
|
|
773
870
|
const safeSummary = input.summary ? redactSecrets(input.summary) : null;
|
|
774
|
-
|
|
871
|
+
const effectiveMode = dedupeMode === "overwrite" ? "merge" : dedupeMode === "version-fork" ? "create" : dedupeMode;
|
|
872
|
+
if (effectiveMode === "error") {
|
|
873
|
+
const existing = d.query(`SELECT id, agent_id, updated_at FROM memories
|
|
874
|
+
WHERE key = ? AND scope = ? AND COALESCE(project_id, '') = ? AND status = 'active'
|
|
875
|
+
LIMIT 1`).get(input.key, input.scope || "private", input.project_id || "");
|
|
876
|
+
if (existing) {
|
|
877
|
+
throw new MemoryConflictError(input.key, existing);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
if (effectiveMode === "merge") {
|
|
775
881
|
const existing = d.query(`SELECT id, version FROM memories
|
|
776
882
|
WHERE key = ? AND scope = ?
|
|
777
883
|
AND COALESCE(agent_id, '') = ?
|
|
@@ -1157,6 +1263,52 @@ function getMemoryVersions(memoryId, db) {
|
|
|
1157
1263
|
return [];
|
|
1158
1264
|
}
|
|
1159
1265
|
}
|
|
1266
|
+
async function indexMemoryEmbedding(memoryId, text, db) {
|
|
1267
|
+
try {
|
|
1268
|
+
const d = db || getDatabase();
|
|
1269
|
+
const { embedding, model, dimensions } = await generateEmbedding(text);
|
|
1270
|
+
const serialized = serializeEmbedding(embedding);
|
|
1271
|
+
d.run(`INSERT INTO memory_embeddings (memory_id, embedding, model, dimensions)
|
|
1272
|
+
VALUES (?, ?, ?, ?)
|
|
1273
|
+
ON CONFLICT(memory_id) DO UPDATE SET embedding=excluded.embedding, model=excluded.model, dimensions=excluded.dimensions, created_at=datetime('now')`, [memoryId, serialized, model, dimensions]);
|
|
1274
|
+
} catch {}
|
|
1275
|
+
}
|
|
1276
|
+
async function semanticSearch(queryText, options = {}, db) {
|
|
1277
|
+
const d = db || getDatabase();
|
|
1278
|
+
const { threshold = 0.5, limit = 10, scope, agent_id, project_id } = options;
|
|
1279
|
+
const { embedding: queryEmbedding } = await generateEmbedding(queryText);
|
|
1280
|
+
const conditions = ["m.status = 'active'", "e.embedding IS NOT NULL"];
|
|
1281
|
+
const params = [];
|
|
1282
|
+
if (scope) {
|
|
1283
|
+
conditions.push("m.scope = ?");
|
|
1284
|
+
params.push(scope);
|
|
1285
|
+
}
|
|
1286
|
+
if (agent_id) {
|
|
1287
|
+
conditions.push("m.agent_id = ?");
|
|
1288
|
+
params.push(agent_id);
|
|
1289
|
+
}
|
|
1290
|
+
if (project_id) {
|
|
1291
|
+
conditions.push("m.project_id = ?");
|
|
1292
|
+
params.push(project_id);
|
|
1293
|
+
}
|
|
1294
|
+
const where = conditions.join(" AND ");
|
|
1295
|
+
const rows = d.prepare(`SELECT m.*, e.embedding FROM memories m
|
|
1296
|
+
JOIN memory_embeddings e ON e.memory_id = m.id
|
|
1297
|
+
WHERE ${where}`).all(...params);
|
|
1298
|
+
const scored = [];
|
|
1299
|
+
for (const row of rows) {
|
|
1300
|
+
try {
|
|
1301
|
+
const docEmbedding = deserializeEmbedding(row.embedding);
|
|
1302
|
+
const score = cosineSimilarity(queryEmbedding, docEmbedding);
|
|
1303
|
+
if (score >= threshold) {
|
|
1304
|
+
const { embedding: _, ...memRow } = row;
|
|
1305
|
+
scored.push({ memory: parseMemoryRow(memRow), score: Math.round(score * 1000) / 1000 });
|
|
1306
|
+
}
|
|
1307
|
+
} catch {}
|
|
1308
|
+
}
|
|
1309
|
+
scored.sort((a, b) => b.score - a.score);
|
|
1310
|
+
return scored.slice(0, limit);
|
|
1311
|
+
}
|
|
1160
1312
|
var RECALL_PROMOTE_THRESHOLD = 3;
|
|
1161
1313
|
var init_memories = __esm(() => {
|
|
1162
1314
|
init_types();
|
|
@@ -3244,6 +3396,18 @@ var init_built_in_hooks = __esm(() => {
|
|
|
3244
3396
|
});
|
|
3245
3397
|
}
|
|
3246
3398
|
});
|
|
3399
|
+
hookRegistry.register({
|
|
3400
|
+
type: "PostMemorySave",
|
|
3401
|
+
blocking: false,
|
|
3402
|
+
builtin: true,
|
|
3403
|
+
priority: 300,
|
|
3404
|
+
description: "Generate and store vector embedding for semantic memory search",
|
|
3405
|
+
handler: async (ctx) => {
|
|
3406
|
+
const { indexMemoryEmbedding: indexMemoryEmbedding2 } = await Promise.resolve().then(() => (init_memories(), exports_memories));
|
|
3407
|
+
const text = [ctx.memory.value, ctx.memory.summary].filter(Boolean).join(" ");
|
|
3408
|
+
indexMemoryEmbedding2(ctx.memory.id, text);
|
|
3409
|
+
}
|
|
3410
|
+
});
|
|
3247
3411
|
hookRegistry.register({
|
|
3248
3412
|
type: "PostMemoryInject",
|
|
3249
3413
|
blocking: false,
|
|
@@ -9179,7 +9343,7 @@ function formatMemory(m) {
|
|
|
9179
9343
|
return parts.join(`
|
|
9180
9344
|
`);
|
|
9181
9345
|
}
|
|
9182
|
-
server.tool("memory_save", "Save/upsert a memory. scope: global=all agents, shared=project, private=single agent.", {
|
|
9346
|
+
server.tool("memory_save", "Save/upsert a memory. scope: global=all agents, shared=project, private=single agent. conflict controls what happens when key already exists.", {
|
|
9183
9347
|
key: exports_external.string(),
|
|
9184
9348
|
value: exports_external.string(),
|
|
9185
9349
|
scope: exports_external.enum(["global", "shared", "private"]).optional(),
|
|
@@ -9192,20 +9356,23 @@ server.tool("memory_save", "Save/upsert a memory. scope: global=all agents, shar
|
|
|
9192
9356
|
session_id: exports_external.string().optional(),
|
|
9193
9357
|
ttl_ms: exports_external.union([exports_external.string(), exports_external.number()]).optional(),
|
|
9194
9358
|
source: exports_external.enum(["user", "agent", "system", "auto", "imported"]).optional(),
|
|
9195
|
-
metadata: exports_external.record(exports_external.unknown()).optional()
|
|
9359
|
+
metadata: exports_external.record(exports_external.unknown()).optional(),
|
|
9360
|
+
conflict: exports_external.enum(["merge", "overwrite", "error", "version-fork"]).optional().describe("Conflict strategy: merge=upsert(default), overwrite=same as merge, error=fail if key exists, version-fork=always create new")
|
|
9196
9361
|
}, async (args) => {
|
|
9197
9362
|
try {
|
|
9198
9363
|
ensureAutoProject();
|
|
9199
|
-
const
|
|
9200
|
-
|
|
9201
|
-
|
|
9364
|
+
const { conflict, ...restArgs } = args;
|
|
9365
|
+
const input = { ...restArgs };
|
|
9366
|
+
if (restArgs.ttl_ms !== undefined) {
|
|
9367
|
+
input.ttl_ms = parseDuration(restArgs.ttl_ms);
|
|
9202
9368
|
}
|
|
9203
9369
|
if (!input.project_id && input.agent_id) {
|
|
9204
9370
|
const focusedProject = resolveProjectId(input.agent_id, null);
|
|
9205
9371
|
if (focusedProject)
|
|
9206
9372
|
input.project_id = focusedProject;
|
|
9207
9373
|
}
|
|
9208
|
-
const
|
|
9374
|
+
const dedupeMode = conflict ?? "merge";
|
|
9375
|
+
const memory = createMemory(input, dedupeMode);
|
|
9209
9376
|
if (args.agent_id)
|
|
9210
9377
|
touchAgent(args.agent_id);
|
|
9211
9378
|
if (memory.scope === "shared" && memory.project_id && args.agent_id) {
|
|
@@ -9214,7 +9381,12 @@ server.tool("memory_save", "Save/upsert a memory. scope: global=all agents, shar
|
|
|
9214
9381
|
broadcastSharedMemory2(memory, args.agent_id).catch(() => {});
|
|
9215
9382
|
} catch {}
|
|
9216
9383
|
}
|
|
9217
|
-
return { content: [{ type: "text", text:
|
|
9384
|
+
return { content: [{ type: "text", text: JSON.stringify({
|
|
9385
|
+
saved: memory.key,
|
|
9386
|
+
id: memory.id.slice(0, 8),
|
|
9387
|
+
version: memory.version,
|
|
9388
|
+
conflict_mode: dedupeMode
|
|
9389
|
+
}) }] };
|
|
9218
9390
|
} catch (e) {
|
|
9219
9391
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9220
9392
|
}
|
|
@@ -9521,6 +9693,46 @@ ${lines.join(`
|
|
|
9521
9693
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9522
9694
|
}
|
|
9523
9695
|
});
|
|
9696
|
+
server.tool("memory_search_semantic", "Semantic (meaning-based) memory search using vector embeddings. Finds memories by conceptual similarity, not keyword match. Uses OpenAI embeddings if OPENAI_API_KEY is set, otherwise TF-IDF.", {
|
|
9697
|
+
query: exports_external.string().describe("Natural language query"),
|
|
9698
|
+
threshold: exports_external.coerce.number().min(0).max(1).optional().describe("Minimum cosine similarity score (default: 0.5)"),
|
|
9699
|
+
limit: exports_external.coerce.number().optional().describe("Max results (default: 10)"),
|
|
9700
|
+
scope: exports_external.enum(["global", "shared", "private"]).optional(),
|
|
9701
|
+
agent_id: exports_external.string().optional(),
|
|
9702
|
+
project_id: exports_external.string().optional(),
|
|
9703
|
+
index_missing: exports_external.coerce.boolean().optional().describe("If true, index any memories that lack embeddings before searching")
|
|
9704
|
+
}, async (args) => {
|
|
9705
|
+
try {
|
|
9706
|
+
ensureAutoProject();
|
|
9707
|
+
if (args.index_missing) {
|
|
9708
|
+
const db = getDatabase();
|
|
9709
|
+
const unindexed = db.prepare(`SELECT id, value, summary FROM memories
|
|
9710
|
+
WHERE status = 'active' AND id NOT IN (SELECT memory_id FROM memory_embeddings)
|
|
9711
|
+
LIMIT 100`).all();
|
|
9712
|
+
await Promise.all(unindexed.map((m) => indexMemoryEmbedding(m.id, [m.value, m.summary].filter(Boolean).join(" "))));
|
|
9713
|
+
}
|
|
9714
|
+
let effectiveProjectId = args.project_id;
|
|
9715
|
+
if (!args.project_id && args.agent_id) {
|
|
9716
|
+
effectiveProjectId = resolveProjectId(args.agent_id, null) ?? undefined;
|
|
9717
|
+
}
|
|
9718
|
+
const results = await semanticSearch(args.query, {
|
|
9719
|
+
threshold: args.threshold,
|
|
9720
|
+
limit: args.limit,
|
|
9721
|
+
scope: args.scope,
|
|
9722
|
+
agent_id: args.agent_id,
|
|
9723
|
+
project_id: effectiveProjectId
|
|
9724
|
+
});
|
|
9725
|
+
if (results.length === 0) {
|
|
9726
|
+
return { content: [{ type: "text", text: `No semantically similar memories found for: "${args.query}". Try a lower threshold or call with index_missing:true to generate embeddings first.` }] };
|
|
9727
|
+
}
|
|
9728
|
+
const lines = results.map((r, i) => `${i + 1}. [score:${r.score}] [${r.memory.scope}/${r.memory.category}] ${r.memory.key} = ${r.memory.value.slice(0, 120)}${r.memory.value.length > 120 ? "..." : ""}`);
|
|
9729
|
+
return { content: [{ type: "text", text: `${results.length} semantic result(s) for "${args.query}":
|
|
9730
|
+
${lines.join(`
|
|
9731
|
+
`)}` }] };
|
|
9732
|
+
} catch (e) {
|
|
9733
|
+
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9734
|
+
}
|
|
9735
|
+
});
|
|
9524
9736
|
server.tool("memory_stats", "Get aggregate statistics about stored memories", {}, async () => {
|
|
9525
9737
|
try {
|
|
9526
9738
|
const db = getDatabase();
|
package/dist/server/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
18
18
|
var __require = import.meta.require;
|
|
19
19
|
|
|
20
20
|
// src/types/index.ts
|
|
21
|
-
var AgentConflictError, EntityNotFoundError, MemoryNotFoundError, DuplicateMemoryError, VersionConflictError;
|
|
21
|
+
var AgentConflictError, EntityNotFoundError, MemoryNotFoundError, DuplicateMemoryError, VersionConflictError, MemoryConflictError;
|
|
22
22
|
var init_types = __esm(() => {
|
|
23
23
|
AgentConflictError = class AgentConflictError extends Error {
|
|
24
24
|
conflict = true;
|
|
@@ -66,6 +66,18 @@ var init_types = __esm(() => {
|
|
|
66
66
|
this.actual = actual;
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
|
+
MemoryConflictError = class MemoryConflictError extends Error {
|
|
70
|
+
existingId;
|
|
71
|
+
existingAgentId;
|
|
72
|
+
existingUpdatedAt;
|
|
73
|
+
constructor(key, existing) {
|
|
74
|
+
super(`Memory conflict: key "${key}" already exists (last written by ${existing.agent_id ?? "unknown"} at ${existing.updated_at}). Use conflict:"overwrite" to replace it.`);
|
|
75
|
+
this.name = "MemoryConflictError";
|
|
76
|
+
this.existingId = existing.id;
|
|
77
|
+
this.existingAgentId = existing.agent_id;
|
|
78
|
+
this.existingUpdatedAt = existing.updated_at;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
69
81
|
});
|
|
70
82
|
|
|
71
83
|
// src/db/database.ts
|
|
@@ -533,10 +545,93 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_resource_locks_exclusive
|
|
|
533
545
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_agent ON resource_locks(agent_id);
|
|
534
546
|
CREATE INDEX IF NOT EXISTS idx_resource_locks_expires ON resource_locks(expires_at);
|
|
535
547
|
INSERT OR IGNORE INTO _migrations (id) VALUES (14);
|
|
548
|
+
`,
|
|
549
|
+
`
|
|
550
|
+
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
551
|
+
memory_id TEXT PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
552
|
+
embedding TEXT NOT NULL,
|
|
553
|
+
model TEXT NOT NULL DEFAULT 'tfidf-512',
|
|
554
|
+
dimensions INTEGER NOT NULL DEFAULT 512,
|
|
555
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
556
|
+
);
|
|
557
|
+
CREATE INDEX IF NOT EXISTS idx_memory_embeddings_model ON memory_embeddings(model);
|
|
558
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (15);
|
|
536
559
|
`
|
|
537
560
|
];
|
|
538
561
|
});
|
|
539
562
|
|
|
563
|
+
// src/lib/embeddings.ts
|
|
564
|
+
function cosineSimilarity(a, b) {
|
|
565
|
+
if (a.length !== b.length || a.length === 0)
|
|
566
|
+
return 0;
|
|
567
|
+
let dot = 0, magA = 0, magB = 0;
|
|
568
|
+
for (let i = 0;i < a.length; i++) {
|
|
569
|
+
dot += a[i] * b[i];
|
|
570
|
+
magA += a[i] * a[i];
|
|
571
|
+
magB += b[i] * b[i];
|
|
572
|
+
}
|
|
573
|
+
const denom = Math.sqrt(magA) * Math.sqrt(magB);
|
|
574
|
+
return denom === 0 ? 0 : dot / denom;
|
|
575
|
+
}
|
|
576
|
+
async function openAIEmbed(text, apiKey) {
|
|
577
|
+
const res = await fetch(OPENAI_EMBED_URL, {
|
|
578
|
+
method: "POST",
|
|
579
|
+
headers: {
|
|
580
|
+
"Content-Type": "application/json",
|
|
581
|
+
Authorization: `Bearer ${apiKey}`
|
|
582
|
+
},
|
|
583
|
+
body: JSON.stringify({
|
|
584
|
+
model: EMBED_MODEL,
|
|
585
|
+
input: text.slice(0, 8192)
|
|
586
|
+
}),
|
|
587
|
+
signal: AbortSignal.timeout(1e4)
|
|
588
|
+
});
|
|
589
|
+
if (!res.ok) {
|
|
590
|
+
throw new Error(`OpenAI embedding API ${res.status}: ${await res.text()}`);
|
|
591
|
+
}
|
|
592
|
+
const data = await res.json();
|
|
593
|
+
return data.data[0].embedding;
|
|
594
|
+
}
|
|
595
|
+
function tfidfVector(text) {
|
|
596
|
+
const DIMS = 512;
|
|
597
|
+
const vec = new Float32Array(DIMS);
|
|
598
|
+
const tokens = text.toLowerCase().match(/\b\w+\b/g) ?? [];
|
|
599
|
+
for (const token of tokens) {
|
|
600
|
+
let hash = 2166136261;
|
|
601
|
+
for (let i = 0;i < token.length; i++) {
|
|
602
|
+
hash ^= token.charCodeAt(i);
|
|
603
|
+
hash = hash * 16777619 >>> 0;
|
|
604
|
+
}
|
|
605
|
+
vec[hash % DIMS] += 1;
|
|
606
|
+
}
|
|
607
|
+
let norm = 0;
|
|
608
|
+
for (let i = 0;i < DIMS; i++)
|
|
609
|
+
norm += vec[i] * vec[i];
|
|
610
|
+
norm = Math.sqrt(norm);
|
|
611
|
+
if (norm > 0)
|
|
612
|
+
for (let i = 0;i < DIMS; i++)
|
|
613
|
+
vec[i] /= norm;
|
|
614
|
+
return Array.from(vec);
|
|
615
|
+
}
|
|
616
|
+
async function generateEmbedding(text) {
|
|
617
|
+
const apiKey = process.env["OPENAI_API_KEY"];
|
|
618
|
+
if (apiKey) {
|
|
619
|
+
try {
|
|
620
|
+
const embedding2 = await openAIEmbed(text, apiKey);
|
|
621
|
+
return { embedding: embedding2, model: EMBED_MODEL, dimensions: EMBED_DIMENSIONS };
|
|
622
|
+
} catch {}
|
|
623
|
+
}
|
|
624
|
+
const embedding = tfidfVector(text);
|
|
625
|
+
return { embedding, model: "tfidf-512", dimensions: 512 };
|
|
626
|
+
}
|
|
627
|
+
function serializeEmbedding(embedding) {
|
|
628
|
+
return JSON.stringify(embedding);
|
|
629
|
+
}
|
|
630
|
+
function deserializeEmbedding(raw) {
|
|
631
|
+
return JSON.parse(raw);
|
|
632
|
+
}
|
|
633
|
+
var OPENAI_EMBED_URL = "https://api.openai.com/v1/embeddings", EMBED_MODEL = "text-embedding-3-small", EMBED_DIMENSIONS = 1536;
|
|
634
|
+
|
|
540
635
|
// src/lib/redact.ts
|
|
541
636
|
function redactSecrets(text) {
|
|
542
637
|
let result = text;
|
|
@@ -709,8 +804,10 @@ var exports_memories = {};
|
|
|
709
804
|
__export(exports_memories, {
|
|
710
805
|
updateMemory: () => updateMemory,
|
|
711
806
|
touchMemory: () => touchMemory,
|
|
807
|
+
semanticSearch: () => semanticSearch,
|
|
712
808
|
parseMemoryRow: () => parseMemoryRow,
|
|
713
809
|
listMemories: () => listMemories,
|
|
810
|
+
indexMemoryEmbedding: () => indexMemoryEmbedding,
|
|
714
811
|
incrementRecallCount: () => incrementRecallCount,
|
|
715
812
|
getMemoryVersions: () => getMemoryVersions,
|
|
716
813
|
getMemoryByKey: () => getMemoryByKey,
|
|
@@ -766,7 +863,16 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
766
863
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
767
864
|
const safeValue = redactSecrets(input.value);
|
|
768
865
|
const safeSummary = input.summary ? redactSecrets(input.summary) : null;
|
|
769
|
-
|
|
866
|
+
const effectiveMode = dedupeMode === "overwrite" ? "merge" : dedupeMode === "version-fork" ? "create" : dedupeMode;
|
|
867
|
+
if (effectiveMode === "error") {
|
|
868
|
+
const existing = d.query(`SELECT id, agent_id, updated_at FROM memories
|
|
869
|
+
WHERE key = ? AND scope = ? AND COALESCE(project_id, '') = ? AND status = 'active'
|
|
870
|
+
LIMIT 1`).get(input.key, input.scope || "private", input.project_id || "");
|
|
871
|
+
if (existing) {
|
|
872
|
+
throw new MemoryConflictError(input.key, existing);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
if (effectiveMode === "merge") {
|
|
770
876
|
const existing = d.query(`SELECT id, version FROM memories
|
|
771
877
|
WHERE key = ? AND scope = ?
|
|
772
878
|
AND COALESCE(agent_id, '') = ?
|
|
@@ -1152,6 +1258,52 @@ function getMemoryVersions(memoryId, db) {
|
|
|
1152
1258
|
return [];
|
|
1153
1259
|
}
|
|
1154
1260
|
}
|
|
1261
|
+
async function indexMemoryEmbedding(memoryId, text, db) {
|
|
1262
|
+
try {
|
|
1263
|
+
const d = db || getDatabase();
|
|
1264
|
+
const { embedding, model, dimensions } = await generateEmbedding(text);
|
|
1265
|
+
const serialized = serializeEmbedding(embedding);
|
|
1266
|
+
d.run(`INSERT INTO memory_embeddings (memory_id, embedding, model, dimensions)
|
|
1267
|
+
VALUES (?, ?, ?, ?)
|
|
1268
|
+
ON CONFLICT(memory_id) DO UPDATE SET embedding=excluded.embedding, model=excluded.model, dimensions=excluded.dimensions, created_at=datetime('now')`, [memoryId, serialized, model, dimensions]);
|
|
1269
|
+
} catch {}
|
|
1270
|
+
}
|
|
1271
|
+
async function semanticSearch(queryText, options = {}, db) {
|
|
1272
|
+
const d = db || getDatabase();
|
|
1273
|
+
const { threshold = 0.5, limit = 10, scope, agent_id, project_id } = options;
|
|
1274
|
+
const { embedding: queryEmbedding } = await generateEmbedding(queryText);
|
|
1275
|
+
const conditions = ["m.status = 'active'", "e.embedding IS NOT NULL"];
|
|
1276
|
+
const params = [];
|
|
1277
|
+
if (scope) {
|
|
1278
|
+
conditions.push("m.scope = ?");
|
|
1279
|
+
params.push(scope);
|
|
1280
|
+
}
|
|
1281
|
+
if (agent_id) {
|
|
1282
|
+
conditions.push("m.agent_id = ?");
|
|
1283
|
+
params.push(agent_id);
|
|
1284
|
+
}
|
|
1285
|
+
if (project_id) {
|
|
1286
|
+
conditions.push("m.project_id = ?");
|
|
1287
|
+
params.push(project_id);
|
|
1288
|
+
}
|
|
1289
|
+
const where = conditions.join(" AND ");
|
|
1290
|
+
const rows = d.prepare(`SELECT m.*, e.embedding FROM memories m
|
|
1291
|
+
JOIN memory_embeddings e ON e.memory_id = m.id
|
|
1292
|
+
WHERE ${where}`).all(...params);
|
|
1293
|
+
const scored = [];
|
|
1294
|
+
for (const row of rows) {
|
|
1295
|
+
try {
|
|
1296
|
+
const docEmbedding = deserializeEmbedding(row.embedding);
|
|
1297
|
+
const score = cosineSimilarity(queryEmbedding, docEmbedding);
|
|
1298
|
+
if (score >= threshold) {
|
|
1299
|
+
const { embedding: _, ...memRow } = row;
|
|
1300
|
+
scored.push({ memory: parseMemoryRow(memRow), score: Math.round(score * 1000) / 1000 });
|
|
1301
|
+
}
|
|
1302
|
+
} catch {}
|
|
1303
|
+
}
|
|
1304
|
+
scored.sort((a, b) => b.score - a.score);
|
|
1305
|
+
return scored.slice(0, limit);
|
|
1306
|
+
}
|
|
1155
1307
|
var RECALL_PROMOTE_THRESHOLD = 3;
|
|
1156
1308
|
var init_memories = __esm(() => {
|
|
1157
1309
|
init_types();
|
|
@@ -3599,6 +3751,18 @@ hookRegistry.register({
|
|
|
3599
3751
|
});
|
|
3600
3752
|
}
|
|
3601
3753
|
});
|
|
3754
|
+
hookRegistry.register({
|
|
3755
|
+
type: "PostMemorySave",
|
|
3756
|
+
blocking: false,
|
|
3757
|
+
builtin: true,
|
|
3758
|
+
priority: 300,
|
|
3759
|
+
description: "Generate and store vector embedding for semantic memory search",
|
|
3760
|
+
handler: async (ctx) => {
|
|
3761
|
+
const { indexMemoryEmbedding: indexMemoryEmbedding2 } = await Promise.resolve().then(() => (init_memories(), exports_memories));
|
|
3762
|
+
const text = [ctx.memory.value, ctx.memory.summary].filter(Boolean).join(" ");
|
|
3763
|
+
indexMemoryEmbedding2(ctx.memory.id, text);
|
|
3764
|
+
}
|
|
3765
|
+
});
|
|
3602
3766
|
hookRegistry.register({
|
|
3603
3767
|
type: "PostMemoryInject",
|
|
3604
3768
|
blocking: false,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -158,7 +158,7 @@ export interface MementosConfig {
|
|
|
158
158
|
stale_deprioritize_days: number;
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
|
-
export type DedupeMode = "merge" | "create";
|
|
161
|
+
export type DedupeMode = "merge" | "create" | "overwrite" | "error" | "version-fork";
|
|
162
162
|
export type SyncDirection = "push" | "pull" | "both";
|
|
163
163
|
export type ConflictResolution = "prefer-local" | "prefer-remote" | "prefer-newer";
|
|
164
164
|
export interface SyncOptions {
|
|
@@ -259,4 +259,14 @@ export declare class VersionConflictError extends Error {
|
|
|
259
259
|
actual: number;
|
|
260
260
|
constructor(id: string, expected: number, actual: number);
|
|
261
261
|
}
|
|
262
|
+
export declare class MemoryConflictError extends Error {
|
|
263
|
+
existingId: string;
|
|
264
|
+
existingAgentId: string | null;
|
|
265
|
+
existingUpdatedAt: string;
|
|
266
|
+
constructor(key: string, existing: {
|
|
267
|
+
id: string;
|
|
268
|
+
agent_id: string | null;
|
|
269
|
+
updated_at: string;
|
|
270
|
+
});
|
|
271
|
+
}
|
|
262
272
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAM1D,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAM7E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAM7E,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAM7D,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAMD,MAAM,WAAW,mBAAoB,SAAQ,MAAM;IACjD,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACzB;AAMD,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;IAC7C,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IACtC,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAgB,QAAQ,EAAG,IAAI,CAAU;IACzC,SAAgB,WAAW,EAAE,MAAM,CAAC;IACpC,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC,SAAgB,YAAY,EAAE,MAAM,CAAC;IACrC,SAAgB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,SAAgB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE/B,IAAI,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B;CAUF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,kBAAkB,CAE7E;AAMD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,WAAW,CAAC;IAC3B,gBAAgB,EAAE,cAAc,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACnD,SAAS,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,cAAc,EAAE,CAAC;QAC7B,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,uBAAuB,EAAE,MAAM,CAAC;KACjC,CAAC;CACH;AAMD,MAAM,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAM1D,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAM7E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAM7E,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAM7D,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAMD,MAAM,WAAW,mBAAoB,SAAQ,MAAM;IACjD,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACzB;AAMD,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;IAC7C,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IACtC,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAgB,QAAQ,EAAG,IAAI,CAAU;IACzC,SAAgB,WAAW,EAAE,MAAM,CAAC;IACpC,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC,SAAgB,YAAY,EAAE,MAAM,CAAC;IACrC,SAAgB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,SAAgB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE/B,IAAI,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B;CAUF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,kBAAkB,CAE7E;AAMD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,WAAW,CAAC;IAC3B,gBAAgB,EAAE,cAAc,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACnD,SAAS,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,cAAc,EAAE,CAAC;QAC7B,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,uBAAuB,EAAE,MAAM,CAAC;KACjC,CAAC;CACH;AAMD,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,QAAQ,GACR,WAAW,GACX,OAAO,GACP,cAAc,CAAC;AAMnB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG,eAAe,GAAG,cAAc,CAAC;AAEnF,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,aAAa,CAAC;IACzB,mBAAmB,CAAC,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAMD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,cAAc,CAAC;AACjH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;AACpI,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,YAAY,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,MAAM;IACjD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,YAAY,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,EAAE,EAAE,MAAM;CAIvB;AAUD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,EAAE,EAAE,MAAM;CAIvB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW;CAI5C;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,EAAE,EAAE,MAAM;CAIvB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;gBAEV,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAQzD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;gBAErB,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;CAS/F"}
|