pi-automem-bridge 0.2.2 → 0.2.3
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 +3 -1
- package/package.json +1 -1
- package/src/tools/memory-tools.ts +24 -40
- package/src/tools/relationship-tools.ts +13 -23
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
pi install npm:pi-automem-bridge
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
[](https://www.npmjs.com/package/pi-automem-bridge)
|
|
14
14
|
[](https://www.npmjs.com/package/pi-automem-bridge)
|
|
15
15
|
|
|
16
16
|
[](https://ko-fi.com/L2J320X82M)
|
|
@@ -135,6 +135,8 @@ You don't type these — pi does, in plain conversation. Tell it *"remember that
|
|
|
135
135
|
| `automem_link_memories` | Create a typed relationship between two existing memories. |
|
|
136
136
|
| `automem_correct_memory` | Store a correction and link old → new with a provenance relationship (EVOLVED_INTO or CONTRADICTS). |
|
|
137
137
|
|
|
138
|
+
Policy blocks, missing approval in non-interactive contexts, and invalid update requests surface as pi tool errors. User-cancelled confirmations and duplicate detection are normal control-flow results, so the agent can stop or choose the next write path deliberately.
|
|
139
|
+
|
|
138
140
|
---
|
|
139
141
|
|
|
140
142
|
## Write policy
|
package/package.json
CHANGED
|
@@ -68,11 +68,10 @@ export function registerMemoryTools(pi: ExtensionAPI) {
|
|
|
68
68
|
config,
|
|
69
69
|
).catch(() => ({ text: "Similar recall failed.", matches: [] }));
|
|
70
70
|
|
|
71
|
-
return {
|
|
72
|
-
content: [{ type: "text" as const, text: formatProposal(decision.action, decision.reasons, decision.normalized, similarText, similarMatches) }],
|
|
73
|
-
details: { action: decision.action, reasons: decision.reasons, findings: decision.findings, candidate: decision.normalized, similarMatches },
|
|
74
|
-
|
|
75
|
-
};
|
|
71
|
+
return {
|
|
72
|
+
content: [{ type: "text" as const, text: formatProposal(decision.action, decision.reasons, decision.normalized, similarText, similarMatches) }],
|
|
73
|
+
details: { action: decision.action, reasons: decision.reasons, findings: decision.findings, candidate: decision.normalized, similarMatches },
|
|
74
|
+
};
|
|
76
75
|
},
|
|
77
76
|
});
|
|
78
77
|
|
|
@@ -87,15 +86,11 @@ export function registerMemoryTools(pi: ExtensionAPI) {
|
|
|
87
86
|
const config = loadConfig();
|
|
88
87
|
setAutoMemMcpServerName(config.mcpServerName);
|
|
89
88
|
const candidate = toCandidate(params);
|
|
90
|
-
const decision = evaluateWritePolicy(candidate, config);
|
|
91
|
-
|
|
92
|
-
if (decision.action === "block") {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
details: { action: decision.action, reasons: decision.reasons, findings: decision.findings },
|
|
96
|
-
isError: true,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
89
|
+
const decision = evaluateWritePolicy(candidate, config);
|
|
90
|
+
|
|
91
|
+
if (decision.action === "block") {
|
|
92
|
+
throw new Error("Blocked by AutoMem write policy.\n" + decision.reasons.map((r: string) => "- " + r).join("\n"));
|
|
93
|
+
}
|
|
99
94
|
|
|
100
95
|
const needsConfirmation = decision.action !== "auto";
|
|
101
96
|
if (needsConfirmation && !params.approvedByUser) {
|
|
@@ -104,14 +99,10 @@ export function registerMemoryTools(pi: ExtensionAPI) {
|
|
|
104
99
|
if (!ok) {
|
|
105
100
|
return { content: [{ type: "text" as const, text: "AutoMem memory write cancelled." }], details: { cancelled: true } };
|
|
106
101
|
}
|
|
107
|
-
} else {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
isError: true,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
}
|
|
102
|
+
} else {
|
|
103
|
+
throw new Error("Confirmation required before storing this memory. Re-run with approvedByUser=true only after explicit user approval.");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
115
106
|
|
|
116
107
|
// ── UPDATE path ──────────────────────────────────────────────────────
|
|
117
108
|
if (params.updateMemoryId) {
|
|
@@ -158,11 +149,10 @@ export function registerMemoryTools(pi: ExtensionAPI) {
|
|
|
158
149
|
" 2. Store anyway (new memory): call automem_commit_memory with dedupeQuery=\"\" to skip dedupe",
|
|
159
150
|
" 3. Cancel: do nothing if this is not worth storing separately",
|
|
160
151
|
].join("\n"),
|
|
161
|
-
}],
|
|
162
|
-
details: { duplicateDetected: true, existingMemoryId: top.id, existingContent: top.content, candidate: decision.normalized, allSimilar: similarMatches },
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
152
|
+
}],
|
|
153
|
+
details: { duplicateDetected: true, existingMemoryId: top.id, existingContent: top.content, candidate: decision.normalized, allSimilar: similarMatches },
|
|
154
|
+
};
|
|
155
|
+
}
|
|
166
156
|
|
|
167
157
|
// ── STORE path ───────────────────────────────────────────────────────
|
|
168
158
|
const result = await automemStore(
|
|
@@ -193,12 +183,9 @@ export function registerMemoryTools(pi: ExtensionAPI) {
|
|
|
193
183
|
promptSnippet: "Use after automem_commit_memory returns DUPLICATE_DETECTED, or when correcting a known memory. Requires the existing memory ID.",
|
|
194
184
|
parameters: UpdateParams,
|
|
195
185
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx: any) {
|
|
196
|
-
if (!params.memoryId) {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
isError: true,
|
|
200
|
-
};
|
|
201
|
-
}
|
|
186
|
+
if (!params.memoryId) {
|
|
187
|
+
throw new Error("memoryId is required for automem_update_memory.");
|
|
188
|
+
}
|
|
202
189
|
|
|
203
190
|
if (!params.approvedByUser) {
|
|
204
191
|
if (ctx && ctx.ui && typeof ctx.ui.confirm === "function") {
|
|
@@ -212,13 +199,10 @@ export function registerMemoryTools(pi: ExtensionAPI) {
|
|
|
212
199
|
if (!ok) {
|
|
213
200
|
return { content: [{ type: "text" as const, text: "AutoMem memory update cancelled." }], details: { cancelled: true } };
|
|
214
201
|
}
|
|
215
|
-
} else {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
}
|
|
202
|
+
} else {
|
|
203
|
+
throw new Error("Confirmation required before updating this memory. Re-run with approvedByUser=true only after explicit user approval.");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
222
206
|
|
|
223
207
|
const result = await automemUpdate(params.memoryId, {
|
|
224
208
|
content: params.content,
|
|
@@ -31,14 +31,11 @@ export function registerRelationshipTools(pi: ExtensionAPI) {
|
|
|
31
31
|
parameters: LinkParams,
|
|
32
32
|
async execute(_toolCallId: string, params: any) {
|
|
33
33
|
const config = loadConfig();
|
|
34
|
-
setAutoMemMcpServerName(config.mcpServerName);
|
|
35
|
-
|
|
36
|
-
if (!params.approvedByUser) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
isError: true,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
34
|
+
setAutoMemMcpServerName(config.mcpServerName);
|
|
35
|
+
|
|
36
|
+
if (!params.approvedByUser) {
|
|
37
|
+
throw new Error("Confirmation required before linking memories. Re-run with approvedByUser=true only after explicit user approval.\n\nWould link:\n " + params.memoryId1 + " -> " + params.relationship + " -> " + params.memoryId2);
|
|
38
|
+
}
|
|
42
39
|
|
|
43
40
|
const strength = typeof params.strength === "number" ? params.strength : 0.5;
|
|
44
41
|
const result = await automemAssociate(params.memoryId1, params.memoryId2, params.relationship, strength);
|
|
@@ -66,21 +63,14 @@ export function registerRelationshipTools(pi: ExtensionAPI) {
|
|
|
66
63
|
tags: Array.isArray(params.tags) ? params.tags : [],
|
|
67
64
|
importance: params.importance,
|
|
68
65
|
};
|
|
69
|
-
const decision = evaluateWritePolicy(candidate, config);
|
|
70
|
-
if (decision.action === "block") {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (!params.approvedByUser) {
|
|
79
|
-
return {
|
|
80
|
-
content: [{ type: "text" as const, text: "Confirmation required before correcting memory. Re-run with approvedByUser=true only after explicit user approval.\n\nWould correct memory " + params.memoryId + " with:\n " + params.correction }],
|
|
81
|
-
isError: true,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
66
|
+
const decision = evaluateWritePolicy(candidate, config);
|
|
67
|
+
if (decision.action === "block") {
|
|
68
|
+
throw new Error("Blocked by AutoMem write policy.\n" + decision.reasons.map((r: string) => "- " + r).join("\n"));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!params.approvedByUser) {
|
|
72
|
+
throw new Error("Confirmation required before correcting memory. Re-run with approvedByUser=true only after explicit user approval.\n\nWould correct memory " + params.memoryId + " with:\n " + params.correction);
|
|
73
|
+
}
|
|
84
74
|
|
|
85
75
|
const rel = params.relationship === "CONTRADICTS" ? "CONTRADICTS" : "EVOLVED_INTO";
|
|
86
76
|
// Store the normalized candidate so corrections get the same alwaysTag,
|