@eleboucher/opencode-memini 0.3.6 → 0.3.7

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.
Files changed (3) hide show
  1. package/README.md +5 -3
  2. package/memini.js +8 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -11,10 +11,12 @@ required from the model.
11
11
  What it wires (two hooks):
12
12
 
13
13
  - **`chat.message`** — searches memini for the incoming user message and
14
- prepends the matches as a synthetic context part before the turn runs.
14
+ prepends the matches as a synthetic context part before the turn runs. It
15
+ excludes this session's own captured turns (already in the live context), so
16
+ they aren't echoed back as memory a turn behind; past sessions still recall.
15
17
  - **`event` (`session.idle`)** — once the session goes idle, stores the
16
- completed user/assistant turn back into memini (episodic) so it can be
17
- recalled later.
18
+ completed user/assistant turn back into memini (episodic, tagged with the
19
+ session id) so it can be recalled later.
18
20
 
19
21
  ### Install
20
22
 
package/memini.js CHANGED
@@ -206,15 +206,20 @@ export const MeminiPlugin = async ({ client, worktree, directory }, options) =>
206
206
  if (!cfg.recall) return;
207
207
  const query = extractPartsText(output && output.parts);
208
208
  if (!query) return;
209
- const result = await rest.postJson("/v1/search", { query, limit: cfg.recall_limit });
210
- const block = formatResults(result && result.results, cfg.recall_limit);
211
- if (!block) return;
212
209
  // Borrow sessionID/messageID from the real parts when the hook input
213
210
  // omits them (messageID is optional in the contract), so the injected
214
211
  // part is attributed to the same message.
215
212
  const sibling = output.parts.find((p) => p && p.type === "text") || {};
216
213
  const sessionID = input.sessionID || sibling.sessionID;
217
214
  const messageID = input.messageID || sibling.messageID;
215
+ const body = { query, limit: cfg.recall_limit };
216
+ // Exclude this session's own captured turns: they're still in the live
217
+ // context, so recalling them just echoes the conversation back a turn
218
+ // behind. Captures from other (past) sessions are still recalled.
219
+ if (sessionID) body.exclude_metadata = { session_id: sessionID };
220
+ const result = await rest.postJson("/v1/search", body);
221
+ const block = formatResults(result && result.results, cfg.recall_limit);
222
+ if (!block) return;
218
223
  // opencode's part schema requires ids to start with `prt`.
219
224
  output.parts.unshift({
220
225
  id: `prt_${crypto.randomUUID()}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eleboucher/opencode-memini",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Automatic cross-session memory for opencode via memini — recall before each turn, capture after.",
5
5
  "keywords": [
6
6
  "memini",