@eleboucher/pi-memini 0.6.9 → 0.6.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.
Files changed (2) hide show
  1. package/dist/index.js +45 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -905,10 +905,28 @@ function meminiExtension(pi) {
905
905
  } catch (error) {
906
906
  warn(`command registration skipped: ${String(error)}`);
907
907
  }
908
+ const MAX_TRACKED_SESSIONS = 200;
908
909
  const pendingUser = /* @__PURE__ */ new Map();
910
+ const rememberPendingUser = (session, prompt) => {
911
+ pendingUser.set(session, prompt);
912
+ while (pendingUser.size > MAX_TRACKED_SESSIONS) {
913
+ const oldest = pendingUser.keys().next().value;
914
+ if (oldest === void 0) break;
915
+ pendingUser.delete(oldest);
916
+ }
917
+ };
909
918
  const captured = /* @__PURE__ */ new Set();
919
+ const MAX_CAPTURED = 200;
920
+ const rememberCaptured = (id) => {
921
+ captured.add(id);
922
+ while (captured.size > MAX_CAPTURED) {
923
+ const oldest = captured.values().next().value;
924
+ if (oldest === void 0) break;
925
+ captured.delete(oldest);
926
+ }
927
+ };
910
928
  const injectedBySession = /* @__PURE__ */ new Map();
911
- const MAX_TRACKED_SESSIONS = 200;
929
+ const MAX_INJECTED_PER_SESSION = 200;
912
930
  const rememberInjected = (session, ids) => {
913
931
  let seen = injectedBySession.get(session);
914
932
  if (!seen) {
@@ -921,16 +939,39 @@ function meminiExtension(pi) {
921
939
  }
922
940
  }
923
941
  for (const id of ids) if (id) seen.add(id);
942
+ while (seen.size > MAX_INJECTED_PER_SESSION) {
943
+ const oldest = seen.values().next().value;
944
+ if (oldest === void 0) break;
945
+ seen.delete(oldest);
946
+ }
947
+ };
948
+ let serverExcludeIds = true;
949
+ const searchExcluding = async (body, excludeIds) => {
950
+ if (!serverExcludeIds || excludeIds.length === 0) {
951
+ return client.postJson("/v1/search", body);
952
+ }
953
+ try {
954
+ const result = await client.postJson("/v1/search", { ...body, exclude_ids: excludeIds });
955
+ if (result !== null) return result;
956
+ } catch {
957
+ }
958
+ const retry = await client.postJson("/v1/search", body);
959
+ if (retry !== null) {
960
+ serverExcludeIds = false;
961
+ warn("memini: server does not accept exclude_ids; using client-side dedupe only");
962
+ }
963
+ return retry;
924
964
  };
925
965
  pi.on("before_agent_start", async (event, ctx) => {
926
966
  const sid = sessionIdOf(ctx);
927
967
  const query = String(event?.prompt || "").trim();
928
- if (query && sid) pendingUser.set(sid, query);
968
+ if (query && sid) rememberPendingUser(sid, query);
929
969
  if (!cfg.recall || !query) return;
930
970
  const body = { query, limit: cfg.recall_limit };
931
971
  if (sid) body.exclude_metadata = { session_id: sid };
932
972
  if (cfg.recall_min_score > 0) body.min_score = cfg.recall_min_score;
933
- const result = await client.postJson("/v1/search", body);
973
+ const excludeIds = sid ? [...injectedBySession.get(sid) ?? []] : [];
974
+ const result = await searchExcluding(body, excludeIds);
934
975
  const floor = cfg.recall_min_score > 0 ? cfg.recall_min_score : 0;
935
976
  let rawHits = Array.isArray(result?.results) ? result.results : [];
936
977
  if (sid) {
@@ -979,7 +1020,7 @@ function meminiExtension(pi) {
979
1020
  metadata
980
1021
  });
981
1022
  if (stored !== null) {
982
- if (dedupKey) captured.add(dedupKey);
1023
+ if (dedupKey) rememberCaptured(dedupKey);
983
1024
  if (sid) pendingUser.delete(sid);
984
1025
  }
985
1026
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eleboucher/pi-memini",
3
- "version": "0.6.9",
3
+ "version": "0.6.11",
4
4
  "description": "Shared cross-session memory for the Pi coding agent, backed by a memini service.",
5
5
  "files": [
6
6
  "dist"