mcp-agents-memory 0.9.27 → 0.9.29

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/build/index.js +77 -32
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -32741,7 +32741,10 @@ var require_dist2 = __commonJS({
32741
32741
 
32742
32742
  // src/auto_save/buzz_envelope.ts
32743
32743
  function isNostrMetaLine(line) {
32744
- return /^Tags: \[\[".*\]\]\s*$/.test(line) && /[0-9a-f]{64}/.test(line) || /^Parsed: (?:root=[0-9a-f]{64}|mentions=\[.*\([0-9a-f]{64}\))/.test(line);
32744
+ return /^Tags: \[\[".*\]\]\s*$/.test(line) && /[0-9a-f]{64}/.test(line) || // `Parsed:` 꼬리표의 키는 순서·종류가 섞인다 — 관측: `root=`, `mentions=[이름 (hex)]`,
32745
+ // `mentions=[hex]`(이름 없는 구버전), `parent=…, root=…`(스레드 답글, 관측 4건 / 3행).
32746
+ // 그래서 특정 키로 앵커하지 말고 **첫 키가 hex 값을 갖는 꼬리표**인지로 본다.
32747
+ /^Parsed: (?:[a-z_]+=(?:\[(?:.*\()?)?[0-9a-f]{64})/.test(line);
32745
32748
  }
32746
32749
  function skipWhitespace(s, i) {
32747
32750
  while (i < s.length && /\s/.test(s[i])) i++;
@@ -32782,9 +32785,10 @@ function cleanBuzzEnvelope(message, opts = {}) {
32782
32785
  const closeTag = `</${history[1]}>`;
32783
32786
  const close = tail.indexOf(closeTag, history[0].length);
32784
32787
  if (close < 0) return null;
32788
+ if (historyHidesTurn(tail.slice(0, close), tail.slice(history[0].length, close))) return null;
32785
32789
  turnStart = close + closeTag.length;
32786
32790
  }
32787
- if (TURN_IN_DROPPED.test(rest.slice(0, pos)) || TURN_IN_DROPPED.test(tail.slice(0, turnStart))) return null;
32791
+ if (TURN_IN_DROPPED.test(rest.slice(0, pos))) return null;
32788
32792
  const turn = tail.slice(turnStart);
32789
32793
  if (!TURN_OPEN.test(turn)) return null;
32790
32794
  const turnText = turn.split("\n").filter((line) => !isNostrMetaLine(line)).join("\n").trim();
@@ -32813,42 +32817,81 @@ function buzzQuotedMessages(message) {
32813
32817
  const closeTag = `</${history[1]}>`;
32814
32818
  const close = tail.indexOf(closeTag, history[0].length);
32815
32819
  if (close < 0) return null;
32816
- const body = tail.slice(history[0].length, close).replace(/^\r?\n/, "").replace(/\r?\n$/, "");
32817
- if (!body.trim()) return [];
32818
- const out = [];
32819
- for (const line of body.split(/\r?\n/)) {
32820
- const e = QUOTE_ENTRY.exec(line);
32821
- if (e && Number(e[1]) === out.length + 1) {
32822
- out.push({ pubkey: e[2] ?? e[3], time: e[4], content: line.slice(e[0].length) });
32823
- } else if (out.length > 0) {
32824
- out[out.length - 1].content += "\n" + line;
32825
- } else {
32826
- return null;
32827
- }
32828
- }
32829
- return out;
32820
+ return parseQuoteBody(tail.slice(history[0].length, close));
32830
32821
  } catch {
32831
32822
  return null;
32832
32823
  }
32833
32824
  }
32825
+ function parseQuoteBody(raw) {
32826
+ const body = raw.replace(/^\r?\n/, "").replace(/\r?\n$/, "");
32827
+ if (!body.trim()) return [];
32828
+ const out = [];
32829
+ for (const line of body.split(/\r?\n/)) {
32830
+ const e = QUOTE_ENTRY.exec(line);
32831
+ if (e && Number(e[1]) === out.length + 1) {
32832
+ out.push({ pubkey: e[2] ?? e[3], time: e[4], content: line.slice(e[0].length) });
32833
+ } else if (out.length > 0) {
32834
+ out[out.length - 1].content += "\n" + line;
32835
+ } else {
32836
+ return null;
32837
+ }
32838
+ }
32839
+ return out;
32840
+ }
32841
+ function historyHidesTurn(dropped, body) {
32842
+ if (!TURN_IN_DROPPED.test(dropped)) return false;
32843
+ return TURN_LINE.test(dropped) || parseQuoteBody(body) === null;
32844
+ }
32845
+ function turnAfterContext(tail) {
32846
+ if (TURN_OPEN.test(tail)) return tail;
32847
+ const history = HISTORY_OPEN.exec(tail);
32848
+ if (!history) return null;
32849
+ const closeTag = `</${history[1]}>`;
32850
+ const close = tail.indexOf(closeTag, history[0].length);
32851
+ if (close < 0) return null;
32852
+ const rest = tail.slice(close + closeTag.length);
32853
+ return TURN_OPEN.test(rest) ? rest : null;
32854
+ }
32855
+ function envelopeTail(message) {
32856
+ const loc = message.startsWith("<base>") ? locateBuzzContext(message) : null;
32857
+ const text = loc ? loc.rest.slice(loc.pos) : message;
32858
+ if (text.startsWith("<context>\n")) {
32859
+ const close = text.indexOf(CONTEXT_CLOSE);
32860
+ return close < 0 ? null : text.slice(close + CONTEXT_CLOSE.length);
32861
+ }
32862
+ return TURN_OPEN.test(text) ? text : null;
32863
+ }
32834
32864
  function buzzEmbeddingText(message) {
32835
32865
  try {
32836
- if (!message.startsWith("<context>\n")) return message;
32837
- const close = message.indexOf(CONTEXT_CLOSE);
32838
- if (close < 0) return message;
32839
- const turn = message.slice(close + CONTEXT_CLOSE.length);
32840
- if (!TURN_OPEN.test(turn)) return message;
32841
- const text = turn.split("\n").filter((line) => !EVENT_HEADER.test(line) && !isNostrMetaLine(line)).map(
32866
+ const tail = envelopeTail(message);
32867
+ if (tail === null) return message;
32868
+ const turn = turnAfterContext(tail);
32869
+ if (turn === null) return message;
32870
+ const text = turn.split("\n").filter(
32871
+ (line) => !EVENT_HEADER.test(line) && !isNostrMetaLine(line) && !WRAPPER_LINE.test(line.trim())
32872
+ ).map(
32842
32873
  (line) => (
32843
32874
  // `$` 없이: 끝까지 되짚는 역추적을 막는다 (긴 줄에서 제곱 시간)
32844
- line.replace(/^From: (.*?) \(npub:.*/, "From: $1").replace(/^Channel: (\S+) \(#[0-9a-f-]+\)/, "Channel: $1")
32875
+ line.replace(/^From: (.*?) \(npub:.*/, "From: $1").replace(/^Channel: (\S+) \(#[0-9a-f-]+\)/, "Channel: $1").replace(EVENT_LABEL, "")
32845
32876
  )
32846
- ).join("\n").trim();
32877
+ ).filter((line) => !IDENTIFIER_ONLY.test(line.trim())).join("\n").trim();
32847
32878
  return text || message;
32848
32879
  } catch {
32849
32880
  return message;
32850
32881
  }
32851
32882
  }
32883
+ function buzzDisplayText(message) {
32884
+ try {
32885
+ if (!message.startsWith("<context>\n")) return message;
32886
+ const close = message.indexOf(CONTEXT_CLOSE);
32887
+ if (close < 0) return message;
32888
+ const tail = message.slice(close + CONTEXT_CLOSE.length).replace(/^\r?\n+/, "");
32889
+ if (turnAfterContext(tail) === null) return message;
32890
+ return tail || message;
32891
+ } catch {
32892
+ return message;
32893
+ }
32894
+ }
32852
32895
  function venueFromBuzzContext(message) {
32853
32896
  if (!CONTEXT_OPEN.test(message.slice(0, 12))) return null;
32854
32897
  const end = message.indexOf(CONTEXT_CLOSE);
@@ -32876,7 +32919,7 @@ function venueFromBuzzMessage(message) {
32876
32919
  return null;
32877
32920
  }
32878
32921
  }
32879
- var PREAMBLE_BLOCKS, HISTORY_OPEN, TURN_OPEN, TURN_IN_DROPPED, CONTEXT_OPEN, BUZZ_SCOPE, BUZZ_CHANNEL, CONTEXT_CLOSE, QUOTE_ENTRY, EVENT_HEADER;
32922
+ var PREAMBLE_BLOCKS, HISTORY_OPEN, TURN_OPEN, TURN_IN_DROPPED, TURN_LINE, CONTEXT_OPEN, BUZZ_SCOPE, BUZZ_CHANNEL, CONTEXT_CLOSE, QUOTE_ENTRY, EVENT_HEADER, WRAPPER_LINE, EVENT_LABEL, IDENTIFIER_ONLY;
32880
32923
  var init_buzz_envelope = __esm({
32881
32924
  "src/auto_save/buzz_envelope.ts"() {
32882
32925
  "use strict";
@@ -32884,12 +32927,16 @@ var init_buzz_envelope = __esm({
32884
32927
  HISTORY_OPEN = /^\s*<((?:thread|conversation)-context)(?:\s[^>]*)?>/;
32885
32928
  TURN_OPEN = /^\s*<(?:what-you-were-working-on|buzz-events?|new-message-arrived-while-you-were-working)[\s>]/;
32886
32929
  TURN_IN_DROPPED = /(?:^|>)[ \t]*<(?:what-you-were-working-on|buzz-events?|new-message-arrived-while-you-were-working)[\s>]/m;
32930
+ TURN_LINE = /(?:^|>[ \t]*)<(?:what-you-were-working-on|buzz-events?|new-message-arrived-while-you-were-working)(?:\s[^>\n]*)?>[ \t]*\r?$/m;
32887
32931
  CONTEXT_OPEN = /^<context>\r?\n/;
32888
32932
  BUZZ_SCOPE = /^Scope: (?:thread|channel|dm)\r?\n/;
32889
32933
  BUZZ_CHANNEL = /(?:^|\n)Channel: .+ \(#[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\)\r?(?=\n|$)/;
32890
32934
  CONTEXT_CLOSE = "\n</context>";
32891
32935
  QUOTE_ENTRY = /^\[(\d+)\] (?:([0-9a-f]{64})|.*? \(([0-9a-f]{64})\)) \((\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?(?:Z|[+-]\d\d:\d\d))\): ?/;
32892
32936
  EVENT_HEADER = /^(?:Event ID: [0-9a-f]{64}|Kind: \d+|Time: \d{4}-\d{2}-\d{2}T\S+|--- Event \d+ \(.*\) ---|Note: A new message arrived while you were working\..*)\s*$/;
32937
+ WRAPPER_LINE = /^<\/?[a-z-]+(\s[^>]*)?>\s*$/;
32938
+ EVENT_LABEL = /^(?:Channel|From|Content): /;
32939
+ IDENTIFIER_ONLY = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|npub1[0-9a-z]{20,}(?:\s*\(hex:\s*[0-9a-f]{64}\))?|[0-9a-f]{64})$/;
32893
32940
  }
32894
32941
  });
32895
32942
 
@@ -56479,10 +56526,7 @@ async function isRegistryMode() {
56479
56526
  }
56480
56527
  async function retrotagRegistry(userId, dryRun) {
56481
56528
  const names = await db.query(
56482
- `SELECT pt.id, pt.name
56483
- FROM project_tags pt
56484
- JOIN project_tags c ON c.id = canonical_project_tag_id(pt.id)
56485
- WHERE c.kind IS NOT NULL AND c.alias_of IS NULL`
56529
+ `SELECT id, name FROM project_tags WHERE ${REGISTRY_MEMBER_SQL}`
56486
56530
  );
56487
56531
  if (dryRun) return 0;
56488
56532
  let total = 0;
@@ -57657,6 +57701,7 @@ async function hasMemoryColumn(column) {
57657
57701
  }
57658
57702
 
57659
57703
  // src/tools/search_memory.ts
57704
+ init_buzz_envelope();
57660
57705
  var DEFAULT_LIMIT = 10;
57661
57706
  var DEFAULT_FALLBACK_THRESHOLD = 0.3;
57662
57707
  function parseDateRange(s) {
@@ -57821,7 +57866,7 @@ date_range \uC778\uC2DD \uD615\uC2DD:
57821
57866
  rows = r.rows.map((row) => ({
57822
57867
  id: Number(row.id),
57823
57868
  role: row.role,
57824
- message: row.message,
57869
+ message: buzzDisplayText(row.message),
57825
57870
  agent_platform: row.agent_platform,
57826
57871
  agent_model: row.agent_model,
57827
57872
  device_name: row.device_name ?? null,
@@ -57886,7 +57931,7 @@ date_range \uC778\uC2DD \uD615\uC2DD:
57886
57931
  rows = r.rows.map((row) => ({
57887
57932
  id: Number(row.id),
57888
57933
  role: row.role,
57889
- message: row.message,
57934
+ message: buzzDisplayText(row.message),
57890
57935
  agent_platform: row.agent_platform,
57891
57936
  agent_model: row.agent_model,
57892
57937
  device_name: row.device_name ?? null,
@@ -57915,7 +57960,7 @@ date_range \uC778\uC2DD \uD615\uC2DD:
57915
57960
  rows = r.rows.map((row) => ({
57916
57961
  id: Number(row.id),
57917
57962
  role: row.role,
57918
- message: row.message,
57963
+ message: buzzDisplayText(row.message),
57919
57964
  agent_platform: row.agent_platform,
57920
57965
  agent_model: row.agent_model,
57921
57966
  device_name: row.device_name ?? null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-agents-memory",
3
- "version": "0.9.27",
3
+ "version": "0.9.29",
4
4
  "description": "Long-term memory for AI agents with provenance tracking",
5
5
  "main": "build/index.js",
6
6
  "type": "module",