neo4j-agent-memory 0.4.0 → 0.5.0
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/README.md +94 -2
- package/dist/cypher/auto_relate_memory_by_tags.cypher +9 -0
- package/dist/cypher/fallback_retrieve_memories.cypher +68 -0
- package/dist/cypher/feedback_batch.cypher +20 -26
- package/dist/cypher/get_memories_by_id.cypher +41 -0
- package/dist/cypher/get_memory_graph.cypher +108 -0
- package/dist/cypher/index.ts +4 -0
- package/dist/cypher/list_memory_edges.cypher +37 -0
- package/dist/index.cjs +189 -19
- package/dist/index.d.ts +96 -9
- package/dist/index.js +189 -19
- package/package.json +1 -1
- package/dist/index.d.cts +0 -246
package/dist/index.cjs
CHANGED
|
@@ -86,7 +86,11 @@ var cypher = {
|
|
|
86
86
|
feedbackCoUsed: loadCypher("feedback_co_used_with_batch.cypher"),
|
|
87
87
|
listMemories: loadCypher("list_memories.cypher"),
|
|
88
88
|
relateConcepts: loadCypher("relate_concepts.cypher"),
|
|
89
|
-
autoRelateByTags: loadCypher("auto_relate_memory_by_tags.cypher")
|
|
89
|
+
autoRelateByTags: loadCypher("auto_relate_memory_by_tags.cypher"),
|
|
90
|
+
getMemoriesById: loadCypher("get_memories_by_id.cypher"),
|
|
91
|
+
getMemoryGraph: loadCypher("get_memory_graph.cypher"),
|
|
92
|
+
fallbackRetrieveMemories: loadCypher("fallback_retrieve_memories.cypher"),
|
|
93
|
+
listMemoryEdges: loadCypher("list_memory_edges.cypher")
|
|
90
94
|
};
|
|
91
95
|
|
|
92
96
|
// src/neo4j/schema.ts
|
|
@@ -146,6 +150,20 @@ function envHash(env) {
|
|
|
146
150
|
function clamp01(x) {
|
|
147
151
|
return Math.max(0, Math.min(1, x));
|
|
148
152
|
}
|
|
153
|
+
function parseJsonField(value) {
|
|
154
|
+
if (value === null || value === void 0) return void 0;
|
|
155
|
+
if (typeof value !== "string") return value;
|
|
156
|
+
try {
|
|
157
|
+
return JSON.parse(value);
|
|
158
|
+
} catch {
|
|
159
|
+
return void 0;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function toDateString(value) {
|
|
163
|
+
if (value === null || value === void 0) return void 0;
|
|
164
|
+
if (typeof value?.toString === "function") return value.toString();
|
|
165
|
+
return String(value);
|
|
166
|
+
}
|
|
149
167
|
var DEFAULT_AUTO_RELATE = {
|
|
150
168
|
enabled: true,
|
|
151
169
|
minSharedTags: 2,
|
|
@@ -172,6 +190,23 @@ function toBetaEdge(raw) {
|
|
|
172
190
|
updatedAt: raw?.updatedAt ?? null
|
|
173
191
|
};
|
|
174
192
|
}
|
|
193
|
+
function toMemoryRecord(raw) {
|
|
194
|
+
return {
|
|
195
|
+
id: raw.id,
|
|
196
|
+
kind: raw.kind,
|
|
197
|
+
polarity: raw.polarity ?? "positive",
|
|
198
|
+
title: raw.title,
|
|
199
|
+
content: raw.content,
|
|
200
|
+
tags: raw.tags ?? [],
|
|
201
|
+
confidence: raw.confidence ?? 0.7,
|
|
202
|
+
utility: raw.utility ?? 0.2,
|
|
203
|
+
createdAt: toDateString(raw.createdAt),
|
|
204
|
+
updatedAt: toDateString(raw.updatedAt),
|
|
205
|
+
triage: parseJsonField(raw.triage),
|
|
206
|
+
antiPattern: parseJsonField(raw.antiPattern),
|
|
207
|
+
env: raw.env ?? void 0
|
|
208
|
+
};
|
|
209
|
+
}
|
|
175
210
|
function defaultPolicy(req) {
|
|
176
211
|
return {
|
|
177
212
|
minConfidence: req?.minConfidence ?? 0.65,
|
|
@@ -243,6 +278,10 @@ var MemoryService = class {
|
|
|
243
278
|
cyListMemories = cypher.listMemories;
|
|
244
279
|
cyRelateConcepts = cypher.relateConcepts;
|
|
245
280
|
cyAutoRelateByTags = cypher.autoRelateByTags;
|
|
281
|
+
cyGetMemoriesById = cypher.getMemoriesById;
|
|
282
|
+
cyGetMemoryGraph = cypher.getMemoryGraph;
|
|
283
|
+
cyFallbackRetrieve = cypher.fallbackRetrieveMemories;
|
|
284
|
+
cyListMemoryEdges = cypher.listMemoryEdges;
|
|
246
285
|
cyGetRecallEdges = `
|
|
247
286
|
UNWIND $ids AS id
|
|
248
287
|
MATCH (m:Memory {id:id})
|
|
@@ -330,7 +369,7 @@ var MemoryService = class {
|
|
|
330
369
|
contentHash,
|
|
331
370
|
tags,
|
|
332
371
|
confidence: clamp01(l.confidence),
|
|
333
|
-
utility: 0.2,
|
|
372
|
+
utility: typeof l.utility === "number" ? clamp01(l.utility) : 0.2,
|
|
334
373
|
// start modest; reinforce via feedback
|
|
335
374
|
triage: l.triage ? JSON.stringify(l.triage) : null,
|
|
336
375
|
antiPattern: l.antiPattern ? JSON.stringify(l.antiPattern) : null
|
|
@@ -407,6 +446,13 @@ var MemoryService = class {
|
|
|
407
446
|
await session.close();
|
|
408
447
|
}
|
|
409
448
|
}
|
|
449
|
+
/**
|
|
450
|
+
* Create a new Case with an auto-generated id if none is provided.
|
|
451
|
+
*/
|
|
452
|
+
async createCase(c) {
|
|
453
|
+
const id = c.id ?? newId("case");
|
|
454
|
+
return this.upsertCase({ ...c, id });
|
|
455
|
+
}
|
|
410
456
|
/**
|
|
411
457
|
* Retrieve a ContextBundle with separate Fix and Do-not-do sections, using case-based reasoning.
|
|
412
458
|
* The key idea: match cases by symptoms + env similarity, then pull linked memories.
|
|
@@ -432,28 +478,49 @@ var MemoryService = class {
|
|
|
432
478
|
halfLifeSeconds: this.halfLifeSeconds
|
|
433
479
|
});
|
|
434
480
|
const sections = r.records[0].get("sections");
|
|
435
|
-
const
|
|
436
|
-
id: m.id,
|
|
437
|
-
kind: m.kind,
|
|
438
|
-
polarity: m.polarity ?? "positive",
|
|
439
|
-
title: m.title,
|
|
440
|
-
content: m.content,
|
|
441
|
-
tags: m.tags ?? [],
|
|
442
|
-
confidence: m.confidence ?? 0.7,
|
|
443
|
-
utility: m.utility ?? 0.2,
|
|
444
|
-
updatedAt: m.updatedAt?.toString?.() ?? null
|
|
445
|
-
}));
|
|
446
|
-
const doNot = (sections.doNot ?? []).map((m) => ({
|
|
481
|
+
const mapSummary = (m, fallbackPolarity) => ({
|
|
447
482
|
id: m.id,
|
|
448
483
|
kind: m.kind,
|
|
449
|
-
polarity: m.polarity ??
|
|
484
|
+
polarity: m.polarity ?? fallbackPolarity,
|
|
450
485
|
title: m.title,
|
|
451
486
|
content: m.content,
|
|
452
487
|
tags: m.tags ?? [],
|
|
453
488
|
confidence: m.confidence ?? 0.7,
|
|
454
489
|
utility: m.utility ?? 0.2,
|
|
455
490
|
updatedAt: m.updatedAt?.toString?.() ?? null
|
|
456
|
-
})
|
|
491
|
+
});
|
|
492
|
+
let fixes = (sections.fixes ?? []).map((m) => mapSummary(m, "positive"));
|
|
493
|
+
let doNot = (sections.doNot ?? []).map((m) => mapSummary(m, "negative"));
|
|
494
|
+
const fallback = args.fallback ?? {};
|
|
495
|
+
const shouldFallback = fallback.enabled === true && fixes.length === 0 && doNot.length === 0;
|
|
496
|
+
if (shouldFallback) {
|
|
497
|
+
const fallbackFixLimit = fallback.limit ?? fixLimit;
|
|
498
|
+
const fallbackDontLimit = fallback.limit ?? dontLimit;
|
|
499
|
+
try {
|
|
500
|
+
const fallbackRes = await session.run(this.cyFallbackRetrieve, {
|
|
501
|
+
prompt: args.prompt ?? "",
|
|
502
|
+
tags: args.tags ?? [],
|
|
503
|
+
kinds: args.kinds ?? [],
|
|
504
|
+
fulltextIndex: this.fulltextIndex,
|
|
505
|
+
vectorIndex: this.vectorIndex,
|
|
506
|
+
embedding: fallback.embedding ?? null,
|
|
507
|
+
useFulltext: fallback.useFulltext ?? true,
|
|
508
|
+
useVector: fallback.useVector ?? false,
|
|
509
|
+
useTags: fallback.useTags ?? true,
|
|
510
|
+
fixLimit: fallbackFixLimit,
|
|
511
|
+
dontLimit: fallbackDontLimit
|
|
512
|
+
});
|
|
513
|
+
const fbSections = fallbackRes.records[0]?.get("sections");
|
|
514
|
+
fixes = (fbSections?.fixes ?? []).map((m) => mapSummary(m, "positive"));
|
|
515
|
+
doNot = (fbSections?.doNot ?? []).map((m) => mapSummary(m, "negative"));
|
|
516
|
+
} catch (err) {
|
|
517
|
+
this.emit({
|
|
518
|
+
type: "read",
|
|
519
|
+
action: "retrieveContextBundle.fallbackError",
|
|
520
|
+
meta: { message: err instanceof Error ? err.message : String(err) }
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
457
524
|
const allIds = [.../* @__PURE__ */ new Set([...fixes.map((x) => x.id), ...doNot.map((x) => x.id)])];
|
|
458
525
|
const edgeAfter = /* @__PURE__ */ new Map();
|
|
459
526
|
if (allIds.length > 0) {
|
|
@@ -528,6 +595,66 @@ ${m.content}`).join("");
|
|
|
528
595
|
await session.close();
|
|
529
596
|
}
|
|
530
597
|
}
|
|
598
|
+
async getMemoriesById(args) {
|
|
599
|
+
const ids = [...new Set((args.ids ?? []).filter(Boolean))];
|
|
600
|
+
if (ids.length === 0) return [];
|
|
601
|
+
const session = this.client.session("READ");
|
|
602
|
+
try {
|
|
603
|
+
const res = await session.run(this.cyGetMemoriesById, { ids });
|
|
604
|
+
const memories = res.records[0]?.get("memories") ?? [];
|
|
605
|
+
return memories.map(toMemoryRecord);
|
|
606
|
+
} finally {
|
|
607
|
+
await session.close();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
async getMemoryGraph(args) {
|
|
611
|
+
const ids = [...new Set((args.memoryIds ?? []).filter(Boolean))];
|
|
612
|
+
if (ids.length === 0) return { nodes: [], edges: [] };
|
|
613
|
+
const session = this.client.session("READ");
|
|
614
|
+
try {
|
|
615
|
+
const res = await session.run(this.cyGetMemoryGraph, {
|
|
616
|
+
agentId: args.agentId ?? null,
|
|
617
|
+
memoryIds: ids,
|
|
618
|
+
includeNodes: args.includeNodes ?? true,
|
|
619
|
+
includeRelatedTo: args.includeRelatedTo ?? false
|
|
620
|
+
});
|
|
621
|
+
const record = res.records[0];
|
|
622
|
+
const nodesRaw = record?.get("nodes") ?? [];
|
|
623
|
+
const edges = record?.get("edges") ?? [];
|
|
624
|
+
return {
|
|
625
|
+
nodes: nodesRaw.map(toMemoryRecord),
|
|
626
|
+
edges
|
|
627
|
+
};
|
|
628
|
+
} finally {
|
|
629
|
+
await session.close();
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
async listMemoryEdges(args = {}) {
|
|
633
|
+
const session = this.client.session("READ");
|
|
634
|
+
try {
|
|
635
|
+
const res = await session.run(this.cyListMemoryEdges, {
|
|
636
|
+
limit: args.limit ?? 200,
|
|
637
|
+
minStrength: args.minStrength ?? 0
|
|
638
|
+
});
|
|
639
|
+
return res.records[0]?.get("edges") ?? [];
|
|
640
|
+
} finally {
|
|
641
|
+
await session.close();
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
async retrieveContextBundleWithGraph(args) {
|
|
645
|
+
const bundle = await this.retrieveContextBundle(args);
|
|
646
|
+
const ids = [
|
|
647
|
+
...bundle.sections.fix.map((m) => m.id),
|
|
648
|
+
...bundle.sections.doNotDo.map((m) => m.id)
|
|
649
|
+
];
|
|
650
|
+
const graph = await this.getMemoryGraph({
|
|
651
|
+
agentId: args.agentId,
|
|
652
|
+
memoryIds: ids,
|
|
653
|
+
includeNodes: args.includeNodes ?? false,
|
|
654
|
+
includeRelatedTo: args.includeRelatedTo ?? false
|
|
655
|
+
});
|
|
656
|
+
return { bundle, graph };
|
|
657
|
+
}
|
|
531
658
|
async listEpisodes(args = {}) {
|
|
532
659
|
return this.listMemories({ ...args, kind: "episodic" });
|
|
533
660
|
}
|
|
@@ -558,6 +685,22 @@ ${m.content}`).join("");
|
|
|
558
685
|
this.emit({ type: "write", action: "captureEpisode", meta: { runId: args.runId, title } });
|
|
559
686
|
return result;
|
|
560
687
|
}
|
|
688
|
+
async captureUsefulLearning(args) {
|
|
689
|
+
if (args.useful === false) {
|
|
690
|
+
return { saved: [], rejected: [{ title: args.learning.title, reason: "not marked useful" }] };
|
|
691
|
+
}
|
|
692
|
+
const result = await this.saveLearnings({
|
|
693
|
+
agentId: args.agentId,
|
|
694
|
+
sessionId: args.sessionId,
|
|
695
|
+
learnings: [args.learning]
|
|
696
|
+
});
|
|
697
|
+
this.emit({
|
|
698
|
+
type: "write",
|
|
699
|
+
action: "captureUsefulLearning",
|
|
700
|
+
meta: { title: args.learning.title, savedCount: result.saved.length }
|
|
701
|
+
});
|
|
702
|
+
return result;
|
|
703
|
+
}
|
|
561
704
|
async captureStepEpisode(args) {
|
|
562
705
|
const title = `Episode ${args.workflowName} - ${args.stepName}`;
|
|
563
706
|
const base = {
|
|
@@ -587,29 +730,45 @@ ${m.content}`).join("");
|
|
|
587
730
|
const used = new Set(fb.usedIds ?? []);
|
|
588
731
|
const useful = new Set(fb.usefulIds ?? []);
|
|
589
732
|
const notUseful = new Set(fb.notUsefulIds ?? []);
|
|
733
|
+
const neutral = new Set(fb.neutralIds ?? []);
|
|
590
734
|
const prevented = new Set(fb.preventedErrorIds ?? []);
|
|
735
|
+
const updateUnratedUsed = fb.updateUnratedUsed ?? true;
|
|
591
736
|
for (const id of prevented) useful.add(id);
|
|
592
737
|
for (const id of useful) notUseful.delete(id);
|
|
738
|
+
for (const id of neutral) notUseful.delete(id);
|
|
593
739
|
for (const id of useful) used.add(id);
|
|
594
740
|
for (const id of notUseful) used.add(id);
|
|
741
|
+
for (const id of neutral) used.add(id);
|
|
595
742
|
const quality = clamp01(fb.metrics?.quality ?? 0.7);
|
|
596
743
|
const hallucRisk = clamp01(fb.metrics?.hallucinationRisk ?? 0.2);
|
|
597
744
|
const baseY = clamp01(quality - 0.7 * hallucRisk);
|
|
598
745
|
const w = 0.5 + 1.5 * quality;
|
|
599
746
|
const yById = /* @__PURE__ */ new Map();
|
|
600
747
|
for (const id of used) {
|
|
601
|
-
|
|
748
|
+
if (useful.has(id)) {
|
|
749
|
+
yById.set(id, baseY);
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
if (notUseful.has(id)) {
|
|
753
|
+
yById.set(id, 0);
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
if (neutral.has(id) || !updateUnratedUsed) {
|
|
757
|
+
yById.set(id, 0.5);
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
yById.set(id, 0);
|
|
602
761
|
}
|
|
603
762
|
const items = [...used].map((memoryId) => ({
|
|
604
763
|
memoryId,
|
|
605
764
|
y: yById.get(memoryId) ?? 0,
|
|
606
765
|
w
|
|
607
766
|
}));
|
|
608
|
-
if (items.length === 0) return;
|
|
767
|
+
if (items.length === 0) return { updated: [] };
|
|
609
768
|
const session = this.client.session("WRITE");
|
|
610
769
|
try {
|
|
611
770
|
await session.run("MERGE (a:Agent {id:$id}) RETURN a", { id: fb.agentId });
|
|
612
|
-
await session.run(this.cyFeedbackBatch, {
|
|
771
|
+
const feedbackRes = await session.run(this.cyFeedbackBatch, {
|
|
613
772
|
agentId: fb.agentId,
|
|
614
773
|
nowIso,
|
|
615
774
|
items,
|
|
@@ -617,6 +776,16 @@ ${m.content}`).join("");
|
|
|
617
776
|
aMin: 1e-3,
|
|
618
777
|
bMin: 1e-3
|
|
619
778
|
});
|
|
779
|
+
const updated = feedbackRes.records.map((rec) => {
|
|
780
|
+
const raw = {
|
|
781
|
+
a: rec.get("a"),
|
|
782
|
+
b: rec.get("b"),
|
|
783
|
+
strength: rec.get("strength"),
|
|
784
|
+
evidence: rec.get("evidence"),
|
|
785
|
+
updatedAt: rec.get("updatedAt")
|
|
786
|
+
};
|
|
787
|
+
return { id: rec.get("id"), edge: toBetaEdge(raw) };
|
|
788
|
+
});
|
|
620
789
|
const ids = [...used];
|
|
621
790
|
const pairs = [];
|
|
622
791
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -638,6 +807,7 @@ ${m.content}`).join("");
|
|
|
638
807
|
});
|
|
639
808
|
}
|
|
640
809
|
this.emit({ type: "write", action: "feedback", meta: { agentId: fb.agentId, usedCount: used.size } });
|
|
810
|
+
return { updated };
|
|
641
811
|
} finally {
|
|
642
812
|
await session.close();
|
|
643
813
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,13 @@ interface DistilledInvariant {
|
|
|
21
21
|
applicability?: string[];
|
|
22
22
|
risks?: string[];
|
|
23
23
|
}
|
|
24
|
+
interface MemoryTriage {
|
|
25
|
+
symptoms: string[];
|
|
26
|
+
likelyCauses: string[];
|
|
27
|
+
verificationSteps?: string[];
|
|
28
|
+
fixSteps?: string[];
|
|
29
|
+
gotchas?: string[];
|
|
30
|
+
}
|
|
24
31
|
interface MemoryRecord {
|
|
25
32
|
id: string;
|
|
26
33
|
kind: MemoryKind;
|
|
@@ -32,6 +39,7 @@ interface MemoryRecord {
|
|
|
32
39
|
utility: number;
|
|
33
40
|
createdAt?: string;
|
|
34
41
|
updatedAt?: string;
|
|
42
|
+
triage?: MemoryTriage;
|
|
35
43
|
signals?: {
|
|
36
44
|
symptoms?: string[];
|
|
37
45
|
environment?: string[];
|
|
@@ -60,6 +68,18 @@ interface MemorySummary {
|
|
|
60
68
|
createdAt?: string | null;
|
|
61
69
|
updatedAt?: string | null;
|
|
62
70
|
}
|
|
71
|
+
interface MemoryGraphEdge {
|
|
72
|
+
source: string;
|
|
73
|
+
target: string;
|
|
74
|
+
kind: "recalls" | "co_used_with" | "related_to";
|
|
75
|
+
strength: number;
|
|
76
|
+
evidence: number;
|
|
77
|
+
updatedAt?: string | null;
|
|
78
|
+
}
|
|
79
|
+
interface MemoryGraphResponse {
|
|
80
|
+
nodes: MemoryRecord[];
|
|
81
|
+
edges: MemoryGraphEdge[];
|
|
82
|
+
}
|
|
63
83
|
interface CaseRecord {
|
|
64
84
|
id: string;
|
|
65
85
|
title: string;
|
|
@@ -86,12 +106,29 @@ interface RetrieveContextArgs {
|
|
|
86
106
|
fixLimit?: number;
|
|
87
107
|
dontLimit?: number;
|
|
88
108
|
nowIso?: string;
|
|
109
|
+
fallback?: {
|
|
110
|
+
enabled?: boolean;
|
|
111
|
+
limit?: number;
|
|
112
|
+
useFulltext?: boolean;
|
|
113
|
+
useVector?: boolean;
|
|
114
|
+
useTags?: boolean;
|
|
115
|
+
embedding?: number[];
|
|
116
|
+
};
|
|
89
117
|
}
|
|
90
118
|
interface ListMemoriesArgs {
|
|
91
119
|
kind?: MemoryKind;
|
|
92
120
|
limit?: number;
|
|
93
121
|
agentId?: string;
|
|
94
122
|
}
|
|
123
|
+
interface GetMemoriesByIdArgs {
|
|
124
|
+
ids: string[];
|
|
125
|
+
}
|
|
126
|
+
interface GetMemoryGraphArgs {
|
|
127
|
+
agentId?: string;
|
|
128
|
+
memoryIds: string[];
|
|
129
|
+
includeNodes?: boolean;
|
|
130
|
+
includeRelatedTo?: boolean;
|
|
131
|
+
}
|
|
95
132
|
interface BetaEdge {
|
|
96
133
|
a: number;
|
|
97
134
|
b: number;
|
|
@@ -132,10 +169,46 @@ interface MemoryFeedback {
|
|
|
132
169
|
usedIds: string[];
|
|
133
170
|
usefulIds: string[];
|
|
134
171
|
notUsefulIds: string[];
|
|
172
|
+
neutralIds?: string[];
|
|
173
|
+
updateUnratedUsed?: boolean;
|
|
135
174
|
preventedErrorIds?: string[];
|
|
136
175
|
metrics?: FeedbackMetrics;
|
|
137
176
|
notes?: string;
|
|
138
177
|
}
|
|
178
|
+
interface MemoryFeedbackResult {
|
|
179
|
+
updated: Array<{
|
|
180
|
+
id: string;
|
|
181
|
+
edge: BetaEdge;
|
|
182
|
+
}>;
|
|
183
|
+
}
|
|
184
|
+
interface ListMemoryEdgesArgs {
|
|
185
|
+
limit?: number;
|
|
186
|
+
minStrength?: number;
|
|
187
|
+
}
|
|
188
|
+
interface MemoryEdgeExport {
|
|
189
|
+
source: string;
|
|
190
|
+
target: string;
|
|
191
|
+
kind: "co_used_with" | "related_to";
|
|
192
|
+
strength: number;
|
|
193
|
+
evidence: number;
|
|
194
|
+
updatedAt?: string | null;
|
|
195
|
+
}
|
|
196
|
+
interface RetrieveContextBundleWithGraphArgs extends RetrieveContextArgs {
|
|
197
|
+
includeNodes?: boolean;
|
|
198
|
+
includeRelatedTo?: boolean;
|
|
199
|
+
}
|
|
200
|
+
interface ContextBundleWithGraph {
|
|
201
|
+
bundle: ContextBundle;
|
|
202
|
+
graph: MemoryGraphResponse;
|
|
203
|
+
}
|
|
204
|
+
interface CaptureUsefulLearningArgs {
|
|
205
|
+
agentId: string;
|
|
206
|
+
sessionId?: string;
|
|
207
|
+
useful?: boolean;
|
|
208
|
+
learning: LearningCandidate & {
|
|
209
|
+
utility?: number;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
139
212
|
interface CaptureEpisodeArgs {
|
|
140
213
|
agentId: string;
|
|
141
214
|
runId: string;
|
|
@@ -161,15 +234,10 @@ interface LearningCandidate {
|
|
|
161
234
|
content: string;
|
|
162
235
|
tags: string[];
|
|
163
236
|
confidence: number;
|
|
237
|
+
utility?: number;
|
|
164
238
|
signals?: MemoryRecord["signals"];
|
|
165
239
|
env?: EnvironmentFingerprint;
|
|
166
|
-
triage?:
|
|
167
|
-
symptoms: string[];
|
|
168
|
-
likelyCauses: string[];
|
|
169
|
-
verificationSteps?: string[];
|
|
170
|
-
fixSteps?: string[];
|
|
171
|
-
gotchas?: string[];
|
|
172
|
-
};
|
|
240
|
+
triage?: MemoryTriage;
|
|
173
241
|
antiPattern?: MemoryRecord["antiPattern"];
|
|
174
242
|
}
|
|
175
243
|
interface SaveLearningRequest {
|
|
@@ -241,6 +309,10 @@ declare class MemoryService {
|
|
|
241
309
|
private cyListMemories;
|
|
242
310
|
private cyRelateConcepts;
|
|
243
311
|
private cyAutoRelateByTags;
|
|
312
|
+
private cyGetMemoriesById;
|
|
313
|
+
private cyGetMemoryGraph;
|
|
314
|
+
private cyFallbackRetrieve;
|
|
315
|
+
private cyListMemoryEdges;
|
|
244
316
|
private cyGetRecallEdges;
|
|
245
317
|
constructor(cfg: MemoryServiceConfig);
|
|
246
318
|
init(): Promise<void>;
|
|
@@ -261,12 +333,22 @@ declare class MemoryService {
|
|
|
261
333
|
* Upsert an episodic Case (case-based reasoning) that links symptoms + env + resolved_by + negative memories.
|
|
262
334
|
*/
|
|
263
335
|
upsertCase(c: CaseRecord): Promise<string>;
|
|
336
|
+
/**
|
|
337
|
+
* Create a new Case with an auto-generated id if none is provided.
|
|
338
|
+
*/
|
|
339
|
+
createCase(c: Omit<CaseRecord, "id"> & {
|
|
340
|
+
id?: string;
|
|
341
|
+
}): Promise<string>;
|
|
264
342
|
/**
|
|
265
343
|
* Retrieve a ContextBundle with separate Fix and Do-not-do sections, using case-based reasoning.
|
|
266
344
|
* The key idea: match cases by symptoms + env similarity, then pull linked memories.
|
|
267
345
|
*/
|
|
268
346
|
retrieveContextBundle(args: RetrieveContextArgs): Promise<ContextBundle>;
|
|
269
347
|
listMemories(args?: ListMemoriesArgs): Promise<MemorySummary[]>;
|
|
348
|
+
getMemoriesById(args: GetMemoriesByIdArgs): Promise<MemoryRecord[]>;
|
|
349
|
+
getMemoryGraph(args: GetMemoryGraphArgs): Promise<MemoryGraphResponse>;
|
|
350
|
+
listMemoryEdges(args?: ListMemoryEdgesArgs): Promise<MemoryEdgeExport[]>;
|
|
351
|
+
retrieveContextBundleWithGraph(args: RetrieveContextBundleWithGraphArgs): Promise<ContextBundleWithGraph>;
|
|
270
352
|
listEpisodes(args?: Omit<ListMemoriesArgs, "kind">): Promise<MemorySummary[]>;
|
|
271
353
|
listSkills(args?: Omit<ListMemoriesArgs, "kind">): Promise<MemorySummary[]>;
|
|
272
354
|
listConcepts(args?: Omit<ListMemoriesArgs, "kind">): Promise<MemorySummary[]>;
|
|
@@ -276,12 +358,13 @@ declare class MemoryService {
|
|
|
276
358
|
weight?: number;
|
|
277
359
|
}): Promise<void>;
|
|
278
360
|
captureEpisode(args: CaptureEpisodeArgs): Promise<SaveLearningResult>;
|
|
361
|
+
captureUsefulLearning(args: CaptureUsefulLearningArgs): Promise<SaveLearningResult>;
|
|
279
362
|
captureStepEpisode(args: CaptureStepEpisodeArgs): Promise<SaveLearningResult>;
|
|
280
363
|
/**
|
|
281
364
|
* Reinforce/degrade agent->memory association weights using a single batched Cypher query.
|
|
282
365
|
* This supports mid-run retrieval by making feedback cheap and frequent.
|
|
283
366
|
*/
|
|
284
|
-
feedback(fb: MemoryFeedback): Promise<
|
|
367
|
+
feedback(fb: MemoryFeedback): Promise<MemoryFeedbackResult>;
|
|
285
368
|
/**
|
|
286
369
|
* Save distilled learnings discovered during a task.
|
|
287
370
|
* Enforces quality gates and stores negative memories explicitly.
|
|
@@ -320,6 +403,10 @@ declare const cypher: {
|
|
|
320
403
|
listMemories: string;
|
|
321
404
|
relateConcepts: string;
|
|
322
405
|
autoRelateByTags: string;
|
|
406
|
+
getMemoriesById: string;
|
|
407
|
+
getMemoryGraph: string;
|
|
408
|
+
fallbackRetrieveMemories: string;
|
|
409
|
+
listMemoryEdges: string;
|
|
323
410
|
};
|
|
324
411
|
|
|
325
412
|
declare function createMemoryTools(service: MemoryService): MemoryToolSet;
|
|
@@ -330,4 +417,4 @@ declare function newId(prefix: string): string;
|
|
|
330
417
|
declare function normaliseSymptom(s: string): string;
|
|
331
418
|
declare function envHash(env: EnvironmentFingerprint): string;
|
|
332
419
|
|
|
333
|
-
export { type AutoRelateConfig, type BetaEdge, type CaptureEpisodeArgs, type CaptureStepEpisodeArgs, type CaseRecord, type ContextBundle, type ContextMemoryBase, type ContextMemorySummary, type DistilledInvariant, type EnvironmentFingerprint, type FeedbackMetrics, type LearningCandidate, type ListMemoriesArgs, type MemoryEvent, type MemoryFeedback, type MemoryKind, type MemoryPolarity, type MemoryRecord, MemoryService, type MemoryServiceConfig, type MemorySummary, type MemoryToolDefinition, type MemoryToolName, type MemoryToolSet, Neo4jClient, type Neo4jClientConfig, type RetrieveContextArgs, type SaveLearningRequest, type SaveLearningResult, canonicaliseForHash, createMemoryService, createMemoryTools, cypher, ensureSchema, envHash, loadCypher, migrate, newId, normaliseSymptom, schemaVersion, sha256Hex };
|
|
420
|
+
export { type AutoRelateConfig, type BetaEdge, type CaptureEpisodeArgs, type CaptureStepEpisodeArgs, type CaptureUsefulLearningArgs, type CaseRecord, type ContextBundle, type ContextBundleWithGraph, type ContextMemoryBase, type ContextMemorySummary, type DistilledInvariant, type EnvironmentFingerprint, type FeedbackMetrics, type GetMemoriesByIdArgs, type GetMemoryGraphArgs, type LearningCandidate, type ListMemoriesArgs, type ListMemoryEdgesArgs, type MemoryEdgeExport, type MemoryEvent, type MemoryFeedback, type MemoryFeedbackResult, type MemoryGraphEdge, type MemoryGraphResponse, type MemoryKind, type MemoryPolarity, type MemoryRecord, MemoryService, type MemoryServiceConfig, type MemorySummary, type MemoryToolDefinition, type MemoryToolName, type MemoryToolSet, type MemoryTriage, Neo4jClient, type Neo4jClientConfig, type RetrieveContextArgs, type RetrieveContextBundleWithGraphArgs, type SaveLearningRequest, type SaveLearningResult, canonicaliseForHash, createMemoryService, createMemoryTools, cypher, ensureSchema, envHash, loadCypher, migrate, newId, normaliseSymptom, schemaVersion, sha256Hex };
|