opencode-graphiti 0.2.4 → 0.2.5-canary.274f482.20260604214739

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 (103) hide show
  1. package/esm/src/handlers/chat.js +2 -2
  2. package/esm/src/handlers/compacting.d.ts.map +1 -1
  3. package/esm/src/handlers/compacting.js +3 -3
  4. package/esm/src/handlers/messages.d.ts.map +1 -1
  5. package/esm/src/handlers/messages.js +15 -8
  6. package/esm/src/handlers/tool-before.d.ts.map +1 -1
  7. package/esm/src/handlers/tool-before.js +8 -8
  8. package/esm/src/index.d.ts.map +1 -1
  9. package/esm/src/index.js +86 -14
  10. package/esm/src/services/connection-manager.d.ts +2 -2
  11. package/esm/src/services/connection-manager.d.ts.map +1 -1
  12. package/esm/src/services/dream-store.d.ts +21 -0
  13. package/esm/src/services/dream-store.d.ts.map +1 -0
  14. package/esm/src/services/dream-store.js +96 -0
  15. package/esm/src/services/exact-history.d.ts +10 -0
  16. package/esm/src/services/exact-history.d.ts.map +1 -0
  17. package/esm/src/services/exact-history.js +3 -0
  18. package/esm/src/services/graphiti-async.d.ts +2 -2
  19. package/esm/src/services/graphiti-async.d.ts.map +1 -1
  20. package/esm/src/services/memory-results.d.ts +6 -0
  21. package/esm/src/services/memory-results.d.ts.map +1 -0
  22. package/esm/src/services/memory-results.js +23 -0
  23. package/esm/src/services/memory-search.d.ts +29 -0
  24. package/esm/src/services/memory-search.d.ts.map +1 -0
  25. package/esm/src/services/memory-search.js +53 -0
  26. package/esm/src/services/opencode-warning.d.ts +1 -0
  27. package/esm/src/services/opencode-warning.d.ts.map +1 -1
  28. package/esm/src/services/opencode-warning.js +3 -0
  29. package/esm/src/services/redis-snapshot.d.ts +8 -0
  30. package/esm/src/services/redis-snapshot.d.ts.map +1 -1
  31. package/esm/src/services/redis-snapshot.js +12 -0
  32. package/esm/src/services/runtime-teardown.d.ts +1 -0
  33. package/esm/src/services/runtime-teardown.d.ts.map +1 -1
  34. package/esm/src/services/runtime-teardown.js +13 -4
  35. package/esm/src/services/session-executor.d.ts +9 -3
  36. package/esm/src/services/session-executor.d.ts.map +1 -1
  37. package/esm/src/services/session-mcp-runtime.d.ts +14 -2
  38. package/esm/src/services/session-mcp-runtime.d.ts.map +1 -1
  39. package/esm/src/services/session-mcp-runtime.js +269 -70
  40. package/esm/src/services/session-mcp-types.d.ts +177 -41
  41. package/esm/src/services/session-mcp-types.d.ts.map +1 -1
  42. package/esm/src/services/session-mcp-types.js +46 -23
  43. package/esm/src/services/session-notes.d.ts +70 -0
  44. package/esm/src/services/session-notes.d.ts.map +1 -0
  45. package/esm/src/services/session-notes.js +438 -0
  46. package/esm/src/services/tool-routing.js +1 -1
  47. package/esm/src/session.d.ts +9 -3
  48. package/esm/src/session.d.ts.map +1 -1
  49. package/esm/src/session.js +36 -13
  50. package/esm/src/types/index.d.ts +14 -0
  51. package/esm/src/types/index.d.ts.map +1 -1
  52. package/package.json +1 -1
  53. package/script/src/handlers/chat.js +2 -2
  54. package/script/src/handlers/compacting.d.ts.map +1 -1
  55. package/script/src/handlers/compacting.js +3 -3
  56. package/script/src/handlers/messages.d.ts.map +1 -1
  57. package/script/src/handlers/messages.js +15 -8
  58. package/script/src/handlers/tool-before.d.ts.map +1 -1
  59. package/script/src/handlers/tool-before.js +8 -8
  60. package/script/src/index.d.ts.map +1 -1
  61. package/script/src/index.js +84 -12
  62. package/script/src/services/connection-manager.d.ts +2 -2
  63. package/script/src/services/connection-manager.d.ts.map +1 -1
  64. package/script/src/services/dream-store.d.ts +21 -0
  65. package/script/src/services/dream-store.d.ts.map +1 -0
  66. package/script/src/services/dream-store.js +100 -0
  67. package/script/src/services/exact-history.d.ts +10 -0
  68. package/script/src/services/exact-history.d.ts.map +1 -0
  69. package/script/src/services/exact-history.js +7 -0
  70. package/script/src/services/graphiti-async.d.ts +2 -2
  71. package/script/src/services/graphiti-async.d.ts.map +1 -1
  72. package/script/src/services/memory-results.d.ts +6 -0
  73. package/script/src/services/memory-results.d.ts.map +1 -0
  74. package/script/src/services/memory-results.js +28 -0
  75. package/script/src/services/memory-search.d.ts +29 -0
  76. package/script/src/services/memory-search.d.ts.map +1 -0
  77. package/script/src/services/memory-search.js +58 -0
  78. package/script/src/services/opencode-warning.d.ts +1 -0
  79. package/script/src/services/opencode-warning.d.ts.map +1 -1
  80. package/script/src/services/opencode-warning.js +5 -1
  81. package/script/src/services/redis-snapshot.d.ts +8 -0
  82. package/script/src/services/redis-snapshot.d.ts.map +1 -1
  83. package/script/src/services/redis-snapshot.js +14 -1
  84. package/script/src/services/runtime-teardown.d.ts +1 -0
  85. package/script/src/services/runtime-teardown.d.ts.map +1 -1
  86. package/script/src/services/runtime-teardown.js +15 -4
  87. package/script/src/services/session-executor.d.ts +9 -3
  88. package/script/src/services/session-executor.d.ts.map +1 -1
  89. package/script/src/services/session-mcp-runtime.d.ts +14 -2
  90. package/script/src/services/session-mcp-runtime.d.ts.map +1 -1
  91. package/script/src/services/session-mcp-runtime.js +270 -71
  92. package/script/src/services/session-mcp-types.d.ts +177 -41
  93. package/script/src/services/session-mcp-types.d.ts.map +1 -1
  94. package/script/src/services/session-mcp-types.js +46 -23
  95. package/script/src/services/session-notes.d.ts +70 -0
  96. package/script/src/services/session-notes.d.ts.map +1 -0
  97. package/script/src/services/session-notes.js +443 -0
  98. package/script/src/services/tool-routing.js +1 -1
  99. package/script/src/session.d.ts +9 -3
  100. package/script/src/session.d.ts.map +1 -1
  101. package/script/src/session.js +36 -13
  102. package/script/src/types/index.d.ts +14 -0
  103. package/script/src/types/index.d.ts.map +1 -1
@@ -34,7 +34,7 @@ export function createChatHandler(deps) {
34
34
  if (prepared) {
35
35
  state.injectedMemories = true;
36
36
  }
37
- logger.info("Prepared local session memory for chat transform", {
37
+ logger.info("Prepared local memory for chat transform", {
38
38
  sessionID: canonicalSessionId,
39
39
  sourceSessionID: sessionID,
40
40
  hotTierReady: state.hotTierReady,
@@ -48,7 +48,7 @@ export function createChatHandler(deps) {
48
48
  }
49
49
  }
50
50
  catch (error) {
51
- logger.warn("Unable to prepare local session memory for chat transform", {
51
+ logger.warn("Unable to prepare local memory for chat transform", {
52
52
  sessionID,
53
53
  error,
54
54
  });
@@ -1 +1 @@
1
- {"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;AAI5E,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,qBAAqB,GAC1B,cAAc,CAmChB"}
1
+ {"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;AAI5E,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,qBAAqB,GAC1B,cAAc,CAqChB"}
@@ -9,19 +9,19 @@ export function createCompactingHandler(deps) {
9
9
  if (!state?.isMain)
10
10
  return;
11
11
  sessionManager.markResolvedSessionActive(sessionID, canonicalSessionId);
12
- const prepared = await sessionManager.prepareInjection(canonicalSessionId);
12
+ const prepared = await sessionManager.prepareInjection(canonicalSessionId, undefined, { forCompaction: true });
13
13
  if (!prepared?.envelope)
14
14
  return;
15
15
  output.context.push(prepared.envelope);
16
16
  sessionManager.clearPendingInjection(state, prepared);
17
- logger.info("Injected local session_memory into compaction context", {
17
+ logger.info("Injected local memory into compaction context", {
18
18
  sessionID: canonicalSessionId,
19
19
  sourceSessionID: sessionID,
20
20
  hotTierReady: state.hotTierReady,
21
21
  });
22
22
  }
23
23
  catch (error) {
24
- logger.warn("Unable to prepare local session memory for compaction", {
24
+ logger.warn("Unable to prepare local memory for compaction", {
25
25
  sessionID,
26
26
  error,
27
27
  });
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAQjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,qBAAqB,GAAG,WAAW,CACtC,KAAK,CAAC,sCAAsC,CAAC,CAC9C,CAAC;AAIF,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,cAAc,CAAC;CAChC;AAyFD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,mBAAmB,GACxB,qBAAqB,CAmEvB"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAQjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,qBAAqB,GAAG,WAAW,CACtC,KAAK,CAAC,sCAAsC,CAAC,CAC9C,CAAC;AAIF,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,cAAc,CAAC;CAChC;AAuGD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,mBAAmB,GACxB,qBAAqB,CAmEvB"}
@@ -9,16 +9,24 @@ const getTransformMessage = (input) => {
9
9
  return typeof message === "string" ? message : undefined;
10
10
  };
11
11
  const LEADING_SESSION_MEMORY_BLOCK = /^<session_memory\b[^>]*>[\s\S]*?<\/session_memory>(?:\r?\n){0,2}/;
12
- const LEADING_INJECTED_LEGACY_MEMORY_BLOCK_WITH_UUIDS = /^<memory\b(?=[^>]*\bdata-uuids=(["'])(?:[^"']*)\1)[^>]*>[\s\S]*?<\/memory>(?:\r?\n){0,2}/;
13
- const LEADING_INJECTED_EMPTY_LEGACY_MEMORY_BLOCK = /^<memory\b(?![^>]*\bdata-uuids=)[^>]*>\s*<\/memory>(?:\r?\n){0,2}/;
12
+ const LEADING_MEMORY_BLOCK = /^<memory\b[^>]*>[\s\S]*?<\/memory>(?:\r?\n){0,2}/;
14
13
  const LEADING_PERSISTENT_MEMORY_BLOCK = /^<persistent_memory\b[^>]*>[\s\S]*?<\/persistent_memory>(?:\r?\n){0,2}/;
15
14
  const SESSION_MEMORY_SOURCE_ATTR_PATTERN = /<session_memory\b[^>]*\bsource=(['"])[^'"]+\1/i;
16
15
  const SESSION_MEMORY_GENERATED_SECTION_PATTERN = /<(?:session_snapshot|persistent_memory)\b/i;
16
+ const MEMORY_VERSION_ATTR_PATTERN = /<memory\b[^>]*\bversion=(['"])2\1/i;
17
+ const LEGACY_MEMORY_UUID_ATTR_PATTERN = /<memory\b[^>]*\bdata-uuids=(['"])(?:[^'"]*)\1/i;
18
+ const EMPTY_MEMORY_BLOCK_PATTERN = /^<memory\b[^>]*>\s*<\/memory>$/i;
19
+ const MEMORY_GENERATED_SECTION_PATTERN = /<(?:session_snapshot|persistent_memory)\b/i;
17
20
  const PERSISTENT_MEMORY_GENERATED_CONTENT_PATTERN = /<(?:node|fact|episode)\b/i;
18
21
  const USER_MEMORY_ENVELOPE_TAG_PATTERN = /<\/?(?:session_memory|memory|persistent_memory)\b[^>]*>/gi;
19
22
  const looksLikeInjectedSessionMemoryBlock = (block, allowAttrlessFollowup) => SESSION_MEMORY_SOURCE_ATTR_PATTERN.test(block) ||
20
23
  SESSION_MEMORY_GENERATED_SECTION_PATTERN.test(block) ||
21
24
  allowAttrlessFollowup;
25
+ const looksLikeInjectedMemoryBlock = (block, allowAttrlessFollowup) => MEMORY_VERSION_ATTR_PATTERN.test(block) ||
26
+ LEGACY_MEMORY_UUID_ATTR_PATTERN.test(block) ||
27
+ EMPTY_MEMORY_BLOCK_PATTERN.test(block) ||
28
+ MEMORY_GENERATED_SECTION_PATTERN.test(block) ||
29
+ allowAttrlessFollowup;
22
30
  const looksLikeInjectedPersistentMemoryBlock = (block) => PERSISTENT_MEMORY_GENERATED_CONTENT_PATTERN.test(block);
23
31
  const scrubPromptMemoryText = (text) => {
24
32
  let scrubbed = text;
@@ -33,11 +41,10 @@ const scrubPromptMemoryText = (text) => {
33
41
  scrubbedInjectedPrefix = true;
34
42
  continue;
35
43
  }
36
- const next = scrubbed
37
- .replace(LEADING_INJECTED_LEGACY_MEMORY_BLOCK_WITH_UUIDS, "")
38
- .replace(LEADING_INJECTED_EMPTY_LEGACY_MEMORY_BLOCK, "");
39
- if (next !== scrubbed) {
40
- scrubbed = next;
44
+ const leadingMemory = scrubbed.match(LEADING_MEMORY_BLOCK)?.[0];
45
+ if (leadingMemory &&
46
+ looksLikeInjectedMemoryBlock(leadingMemory, scrubbedInjectedPrefix)) {
47
+ scrubbed = scrubbed.slice(leadingMemory.length);
41
48
  scrubbedInjectedPrefix = true;
42
49
  continue;
43
50
  }
@@ -83,7 +90,7 @@ export function createMessagesHandler(deps) {
83
90
  return;
84
91
  }
85
92
  textPart.text = `${prepared.envelope}\n\n${effectiveUserText}`;
86
- logger.info("Injected canonical session_memory block", {
93
+ logger.info("Injected canonical memory block", {
87
94
  sessionID: canonicalSessionId,
88
95
  sourceSessionID,
89
96
  rewroteExistingMemory: scrubbedUserText !== latestUserText,
@@ -1 +1 @@
1
- {"version":3,"file":"tool-before.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/tool-before.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAErE,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAIhE,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,+BAA+B,CAAC;IACtD,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,eAAe,CAAC;CAChE;AAqCD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,qBAAqB,GAC1B,cAAc,CAuDhB"}
1
+ {"version":3,"file":"tool-before.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/tool-before.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAErE,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAIhE,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,+BAA+B,CAAC;IACtD,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,eAAe,CAAC;CAChE;AAoCD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,qBAAqB,GAC1B,cAAc,CAuDhB"}
@@ -5,10 +5,10 @@ const toRecord = (value) => value && typeof value === "object" && !Array.isArray
5
5
  : {};
6
6
  const SESSION_MCP_TOOL_NAME_SET = new Set(SESSION_MCP_TOOL_NAMES);
7
7
  const isSessionMcpTool = (toolName) => SESSION_MCP_TOOL_NAME_SET.has(toolName);
8
- const injectRootSessionId = (args, canonicalSessionId) => ({
9
- ...args,
10
- root_session_id: canonicalSessionId,
11
- });
8
+ const stripRootSessionId = (args) => {
9
+ const { root_session_id: _ignored, ...rest } = args;
10
+ return rest;
11
+ };
12
12
  const resolveCanonicalSessionId = async (sessionCanonicalizer, sessionId) => {
13
13
  const cached = sessionCanonicalizer.getCachedCanonicalSessionId(sessionId);
14
14
  if (cached)
@@ -23,10 +23,10 @@ const resolveCanonicalSessionId = async (sessionCanonicalizer, sessionId) => {
23
23
  export function createToolBeforeHandler(deps) {
24
24
  const route = deps.routeToolCall ?? defaultRouteToolCall;
25
25
  return async ({ tool, sessionID, callID }, output) => {
26
- const canonicalSessionId = await resolveCanonicalSessionId(deps.sessionCanonicalizer, sessionID);
27
26
  const sessionTool = isSessionMcpTool(tool);
27
+ const canonicalSessionId = await resolveCanonicalSessionId(deps.sessionCanonicalizer, sessionID);
28
28
  const args = sessionTool
29
- ? injectRootSessionId(toRecord(output.args), canonicalSessionId)
29
+ ? stripRootSessionId(toRecord(output.args))
30
30
  : toRecord(output.args);
31
31
  if (sessionTool) {
32
32
  output.args = args;
@@ -42,7 +42,7 @@ export function createToolBeforeHandler(deps) {
42
42
  return;
43
43
  case "modify":
44
44
  output.args = sessionTool
45
- ? injectRootSessionId(toRecord(decision.args), canonicalSessionId)
45
+ ? stripRootSessionId(toRecord(decision.args))
46
46
  : decision.args;
47
47
  deps.routingOutcomes.set(callID, {
48
48
  source: "tool-routing",
@@ -64,7 +64,7 @@ export function createToolBeforeHandler(deps) {
64
64
  action: "deny",
65
65
  reason: decision.reason,
66
66
  });
67
- throw new Error(`Tool denied (${tool})`);
67
+ throw new Error(decision.guidance || `Tool denied (${tool})`);
68
68
  }
69
69
  };
70
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAsE/D,eAAO,MAAM,gCAAgC,GAC3C,WAAW,OAAO,EAClB,UAAU,MAAM,KACf,IAOF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,WAAW,OAAO,EAClB,UAAU,MAAM,KACf,IAOF,CAAC;AA+BF,eAAO,MAAM,QAAQ,EAAE,MA0OtB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,MAAM,EAAe,MAAM,qBAAqB,CAAC;AA6GtE,eAAO,MAAM,gCAAgC,GAC3C,WAAW,OAAO,EAClB,UAAU,MAAM,KACf,IAOF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,WAAW,OAAO,EAClB,UAAU,MAAM,KACf,IAOF,CAAC;AAmCF,eAAO,MAAM,QAAQ,EAAE,MAkTtB,CAAC"}
package/esm/src/index.js CHANGED
@@ -11,18 +11,32 @@ import { GraphitiConnectionManager } from "./services/connection-manager.js";
11
11
  import { GraphitiAsyncService } from "./services/graphiti-async.js";
12
12
  import { GraphitiMcpClient } from "./services/graphiti-mcp.js";
13
13
  import { redactEndpointUserInfo } from "./services/endpoint-redaction.js";
14
- import { notifyGraphitiAvailabilityIssue, setOpenCodeClient, } from "./services/opencode-warning.js";
14
+ import { notifyDreamShutdownDelay, notifyGraphitiAvailabilityIssue, setOpenCodeClient, } from "./services/opencode-warning.js";
15
15
  import { RedisCacheService } from "./services/redis-cache.js";
16
16
  import { RedisClient } from "./services/redis-client.js";
17
17
  import { RedisEventsService } from "./services/redis-events.js";
18
+ import { DreamStore } from "./services/dream-store.js";
18
19
  import { logger } from "./services/logger.js";
20
+ import { SessionNotesService } from "./services/session-notes.js";
19
21
  import { RedisSnapshotService } from "./services/redis-snapshot.js";
20
22
  import { registerRuntimeTeardown } from "./services/runtime-teardown.js";
21
23
  import { createSessionExecutor } from "./services/session-executor.js";
22
- import { createSessionMcpRuntime } from "./services/session-mcp-runtime.js";
24
+ import { createSessionMcpRuntime, SESSION_SEARCH_STRENGTHENED_DESCRIPTION, } from "./services/session-mcp-runtime.js";
23
25
  import { ToolGuidanceCache } from "./services/tool-guidance-cache.js";
24
26
  import { ToolRoutingOutcomeCache } from "./services/tool-routing-outcome-cache.js";
25
27
  import { makeGroupId, makeUserGroupId } from "./utils.js";
28
+ const getTrackedRootSessionIds = (sessionManager) => {
29
+ const manager = sessionManager;
30
+ const tracked = manager.getTrackedRootSessionIds;
31
+ if (typeof tracked === "function") {
32
+ return tracked.call(sessionManager);
33
+ }
34
+ if (!(manager.sessions instanceof Map))
35
+ return [];
36
+ return [...manager.sessions.entries()]
37
+ .filter(([, state]) => state?.isMain)
38
+ .map(([sessionId]) => sessionId);
39
+ };
26
40
  let activeRuntimeTeardown = null;
27
41
  let runtimeInitialization = Promise.resolve();
28
42
  export const warnOnGraphitiStartupUnavailable = (connected, endpoint) => {
@@ -40,6 +54,7 @@ export const warnOnRedisStartupUnavailable = (connected, endpoint) => {
40
54
  const defaultGraphitiDependencies = {
41
55
  loadConfig,
42
56
  setOpenCodeClient,
57
+ notifyDreamShutdownDelay,
43
58
  warnOnGraphitiStartupUnavailable,
44
59
  warnOnRedisStartupUnavailable,
45
60
  GraphitiConnectionManager,
@@ -49,6 +64,8 @@ const defaultGraphitiDependencies = {
49
64
  RedisEventsService,
50
65
  RedisSnapshotService,
51
66
  RedisCacheService,
67
+ DreamStore,
68
+ SessionNotesService,
52
69
  BatchDrainService,
53
70
  GraphitiAsyncService,
54
71
  createSessionExecutor,
@@ -64,6 +81,7 @@ const defaultGraphitiDependencies = {
64
81
  ToolRoutingOutcomeCache,
65
82
  makeGroupId,
66
83
  makeUserGroupId,
84
+ now: () => new Date().toISOString(),
67
85
  };
68
86
  export const graphiti = (input, dependencies = defaultGraphitiDependencies) => {
69
87
  const setup = runtimeInitialization.then(async () => {
@@ -137,13 +155,17 @@ export const graphiti = (input, dependencies = defaultGraphitiDependencies) => {
137
155
  ttlSeconds: config.redis.cacheTtlSeconds,
138
156
  driftThreshold: config.graphiti.driftThreshold,
139
157
  });
158
+ const dreamStore = new dependencies.DreamStore(redisClient);
159
+ const defaultGroupId = dependencies.makeGroupId(config.graphiti.groupIdPrefix, input.directory);
160
+ const defaultUserGroupId = dependencies.makeUserGroupId(config.graphiti.groupIdPrefix, input.directory);
161
+ const notesService = new dependencies.SessionNotesService(redisClient, {
162
+ groupId: defaultGroupId,
163
+ });
140
164
  const batchDrain = new dependencies.BatchDrainService(redisClient, redisEvents, {
141
165
  batchSize: config.redis.batchSize,
142
166
  batchMaxBytes: config.redis.batchMaxBytes,
143
167
  drainRetryMax: config.redis.drainRetryMax,
144
168
  });
145
- const defaultGroupId = dependencies.makeGroupId(config.graphiti.groupIdPrefix, input.directory);
146
- const defaultUserGroupId = dependencies.makeUserGroupId(config.graphiti.groupIdPrefix, input.directory);
147
169
  const graphitiAsync = new dependencies.GraphitiAsyncService(graphitiClient, redisCache, batchDrain);
148
170
  startupCleanupTasks.unshift({
149
171
  name: "graphiti-async",
@@ -153,6 +175,7 @@ export const graphiti = (input, dependencies = defaultGraphitiDependencies) => {
153
175
  const sessionMcpRuntime = dependencies.createSessionMcpRuntime({
154
176
  redisClient,
155
177
  graphitiCache: redisCache,
178
+ notesService,
156
179
  sessionTtlSeconds: config.redis.sessionTtlSeconds,
157
180
  groupId: defaultGroupId,
158
181
  sessionExecutor,
@@ -164,12 +187,37 @@ export const graphiti = (input, dependencies = defaultGraphitiDependencies) => {
164
187
  });
165
188
  const sessionManager = new dependencies.SessionManager(defaultGroupId, defaultUserGroupId, input.client, redisEvents, redisSnapshot, redisCache, {
166
189
  idleRetentionMs: config.redis.sessionTtlSeconds * 1000,
190
+ notesService,
167
191
  runtimeStateMigrator: sessionMcpRuntime,
168
192
  });
169
193
  sessionMcpRuntime.setSessionCanonicalizer(sessionManager);
170
194
  const toolGuidanceCache = new dependencies.ToolGuidanceCache();
171
195
  const toolRoutingOutcomes = new dependencies.ToolRoutingOutcomeCache();
196
+ const sessionBiasState = new Map();
197
+ const chatHandler = dependencies.createChatHandler({
198
+ sessionManager,
199
+ redisEvents,
200
+ graphitiAsync,
201
+ drainTriggerSize: config.redis.batchSize,
202
+ });
203
+ const compactingHandler = dependencies
204
+ .createCompactingHandler({
205
+ sessionManager,
206
+ });
172
207
  startupTeardown = dependencies.registerRuntimeTeardown([
208
+ {
209
+ name: "dream-shutdown-warning",
210
+ run: async () => {
211
+ const targetWatermark = dependencies.now();
212
+ for (const rootSessionId of getTrackedRootSessionIds(sessionManager)) {
213
+ const watermark = await dreamStore.getWatermark(rootSessionId);
214
+ if (watermark === null || watermark < targetWatermark) {
215
+ dependencies.notifyDreamShutdownDelay();
216
+ return;
217
+ }
218
+ }
219
+ },
220
+ },
173
221
  {
174
222
  name: "graphiti-drain-flush",
175
223
  run: () => graphitiAsync.flushPendingGroups(sessionManager.getTrackedGroupIds()),
@@ -204,21 +252,45 @@ export const graphiti = (input, dependencies = defaultGraphitiDependencies) => {
204
252
  sdkClient: input.client,
205
253
  directory: input.directory,
206
254
  }),
207
- "chat.message": dependencies.createChatHandler({
208
- sessionManager,
209
- redisEvents,
210
- graphitiAsync,
211
- drainTriggerSize: config.redis.batchSize,
212
- }),
213
- "experimental.session.compacting": dependencies
214
- .createCompactingHandler({
215
- sessionManager,
216
- }),
255
+ "chat.message": async (hookInput, output) => {
256
+ const canonicalSessionId = sessionManager.getCachedCanonicalSessionId(hookInput.sessionID) ??
257
+ await sessionManager.resolveCanonicalSessionId(hookInput.sessionID);
258
+ if (canonicalSessionId && !sessionBiasState.has(canonicalSessionId)) {
259
+ const priorEvents = await redisEvents.getRecentSessionEvents(canonicalSessionId, 1, false);
260
+ if (priorEvents.length === 0) {
261
+ sessionBiasState.set(canonicalSessionId, "new-session");
262
+ }
263
+ }
264
+ await chatHandler(hookInput, output);
265
+ },
266
+ "experimental.session.compacting": async (hookInput, output) => {
267
+ const canonicalSessionId = sessionManager.getCachedCanonicalSessionId(hookInput.sessionID) ??
268
+ await sessionManager.resolveCanonicalSessionId(hookInput.sessionID);
269
+ if (canonicalSessionId) {
270
+ sessionBiasState.set(canonicalSessionId, "post-compaction");
271
+ }
272
+ await compactingHandler(hookInput, output);
273
+ },
217
274
  "experimental.chat.messages.transform": dependencies
218
275
  .createMessagesHandler({
219
276
  sessionManager,
220
277
  }),
221
278
  tool: sessionMcpRuntime.tools,
279
+ "tool.definition": (hookInput, output) => {
280
+ if (hookInput.toolID !== "session_search")
281
+ return Promise.resolve();
282
+ let anyBiased = false;
283
+ for (const [sessionId, state] of sessionBiasState) {
284
+ if (state === "normal")
285
+ continue;
286
+ anyBiased = true;
287
+ sessionBiasState.delete(sessionId);
288
+ }
289
+ if (anyBiased) {
290
+ output.description = SESSION_SEARCH_STRENGTHENED_DESCRIPTION;
291
+ }
292
+ return Promise.resolve();
293
+ },
222
294
  "tool.execute.before": dependencies.createToolBeforeHandler({
223
295
  sessionCanonicalizer: sessionManager,
224
296
  guidanceThrottle: toolGuidanceCache,
@@ -54,8 +54,8 @@ type GraphitiConnectionManagerOptions = {
54
54
  connectionFactory?: ConnectionFactory;
55
55
  random?: () => number;
56
56
  now?: () => number;
57
- setTimer?: (callback: () => void, delayMs: number) => TimerHandle;
58
- clearTimer?: (timer: TimerHandle) => void;
57
+ setTimer?(callback: () => void, delayMs: number): TimerHandle;
58
+ clearTimer?(timer: TimerHandle): void;
59
59
  };
60
60
  export declare class GraphitiConnectionManager implements GraphitiToolCaller {
61
61
  private readonly endpoint;
@@ -1 +1 @@
1
- {"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../../src/src/services/connection-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../../src/src/services/connection-manager.ts"],"names":[],"mappings":"AAyDA,MAAM,MAAM,uBAAuB,GAC/B,YAAY,GACZ,WAAW,GACX,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEd,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,MAAM,CAAC;AAE1D,qBAAa,oBAAqB,SAAQ,KAAK;IAI3C,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS;IAHnD,QAAQ,CAAC,IAAI,aAAa;gBAGf,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,EACjD,OAAO,CAAC,EAAE,MAAM;CAYnB;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,IAAI,mBAAmB;gBAG9B,OAAO,SAA4D;CAKtE;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,IAAI,qBAAqB;gBAEtB,OAAO,SAA+B;CAInD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,uBAAuB;gBAExB,OAAO,SAA+B;CAInD;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,IAAI,qBAAqB;gBAEtB,OAAO,SAA6B;CAIjD;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,GACX,GAAG,IAAI,oBAAoB,CAE7B;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,GACX,GAAG,IAAI,yBAAyB,GAAG,2BAA2B,CAGhE;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,QAAQ,CACN,OAAO,EAAE,mBAAmB,EAC5B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAWD,KAAK,iBAAiB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,kBAAkB,CAAC;AA4BlE,KAAK,gCAAgC,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9D,UAAU,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACvC,CAAC;AAkGF,qBAAa,yBAA0B,YAAW,kBAAkB;IAClE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAGZ;IACjB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+B;IAE9D,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,wBAAwB,CAA8B;gBAElD,OAAO,EAAE,gCAAgC;IAoBrD,QAAQ,IAAI,uBAAuB;IAInC,KAAK,IAAI,IAAI;IAcP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDrB,KAAK,CAAC,SAAS,SAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IAwB1D,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,SAAyB,GAClC,OAAO,CAAC,OAAO,CAAC;IA0Bb,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;YAerB,gBAAgB;YAoDhB,kCAAkC;YA0ElC,uCAAuC;IAyBrD,OAAO,CAAC,sBAAsB;YAIhB,uBAAuB;IASrC,OAAO,CAAC,sBAAsB;IAwC9B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,cAAc;YAyCR,iBAAiB;IAgC/B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,mBAAmB;CAO5B"}
@@ -0,0 +1,21 @@
1
+ import type { NormalizedMemoryResult } from "../types/index.js";
2
+ import type { RedisClient } from "./redis-client.js";
3
+ export type DreamSummaryRecord = {
4
+ rootSessionId: string;
5
+ granularity: string;
6
+ created_at: string;
7
+ body: string;
8
+ };
9
+ export declare class DreamStore {
10
+ private readonly redis;
11
+ constructor(redis: RedisClient);
12
+ putSummary(record: DreamSummaryRecord): Promise<void>;
13
+ getSummariesAround(input: {
14
+ rootSessionId: string;
15
+ when: string;
16
+ query?: string;
17
+ }): Promise<NormalizedMemoryResult[]>;
18
+ getWatermark(rootSessionId: string): Promise<string | null>;
19
+ setWatermark(rootSessionId: string, value: string): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=dream-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dream-store.d.ts","sourceRoot":"","sources":["../../../src/src/services/dream-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAgEF,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,WAAW;IAEzC,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYrD,kBAAkB,CAAC,KAAK,EAAE;QAC9B,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;IA8C/B,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI3D,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGxE"}
@@ -0,0 +1,96 @@
1
+ const dreamSummariesKey = (rootSessionId) => `session:${rootSessionId}:dream:summaries`;
2
+ const dreamSummaryField = (record) => `${record.granularity}:${record.created_at}`;
3
+ const dreamWatermarkKey = (rootSessionId) => `session:${rootSessionId}:dream:watermark`;
4
+ const normalizeText = (value) => value.trim().replace(/\s+/g, " ");
5
+ const tokenize = (value) => normalizeText(value).toLowerCase().match(/[a-z0-9]{2,}/g) ?? [];
6
+ const parseStoredRecord = (value) => {
7
+ try {
8
+ const parsed = JSON.parse(value);
9
+ if (typeof parsed.granularity !== "string" ||
10
+ typeof parsed.created_at !== "string" ||
11
+ typeof parsed.body !== "string") {
12
+ return null;
13
+ }
14
+ return {
15
+ granularity: parsed.granularity,
16
+ created_at: parsed.created_at,
17
+ body: parsed.body,
18
+ };
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ };
24
+ const scoreSummary = (record, query) => {
25
+ const normalizedQuery = normalizeText(query ?? "").toLowerCase();
26
+ if (!normalizedQuery)
27
+ return 1;
28
+ const body = normalizeText(record.body).toLowerCase();
29
+ if (body === normalizedQuery)
30
+ return 1;
31
+ if (body.includes(normalizedQuery))
32
+ return 0.95;
33
+ const queryTokens = [...new Set(tokenize(normalizedQuery))];
34
+ if (queryTokens.length === 0)
35
+ return 0;
36
+ const matched = queryTokens.filter((token) => body.includes(token));
37
+ if (matched.length === 0)
38
+ return 0;
39
+ return Number((matched.length / queryTokens.length).toFixed(6));
40
+ };
41
+ export class DreamStore {
42
+ constructor(redis) {
43
+ Object.defineProperty(this, "redis", {
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true,
47
+ value: redis
48
+ });
49
+ }
50
+ async putSummary(record) {
51
+ await this.redis.setHashFields(dreamSummariesKey(record.rootSessionId), {
52
+ [dreamSummaryField(record)]: JSON.stringify({
53
+ granularity: record.granularity,
54
+ created_at: record.created_at,
55
+ body: record.body,
56
+ }),
57
+ });
58
+ }
59
+ async getSummariesAround(input) {
60
+ const summaries = Object.values(await this.redis.getHashAll(dreamSummariesKey(input.rootSessionId)))
61
+ .map(parseStoredRecord)
62
+ .filter((record) => record !== null)
63
+ .map((record) => ({
64
+ record,
65
+ score: scoreSummary(record, input.query),
66
+ }))
67
+ .filter(({ score }) => score > 0)
68
+ .sort((left, right) => left.record.created_at.localeCompare(right.record.created_at));
69
+ const before = summaries.filter(({ record }) => record.created_at < input.when);
70
+ const exact = summaries.filter(({ record }) => record.created_at === input.when);
71
+ const after = summaries.filter(({ record }) => record.created_at > input.when);
72
+ const selected = [
73
+ ...before.slice(-1),
74
+ ...exact,
75
+ ...after.slice(0, 1),
76
+ ];
77
+ return selected.map(({ record, score }) => ({
78
+ type: "summary",
79
+ ref: `session:${input.rootSessionId}:summary:dream:${record.granularity}:${record.created_at}`,
80
+ snippet: record.body,
81
+ score,
82
+ id: `${record.granularity}:${record.created_at}`,
83
+ root_session_id: input.rootSessionId,
84
+ scope: "session",
85
+ granularity: record.granularity,
86
+ created_at: record.created_at,
87
+ source: "dream",
88
+ }));
89
+ }
90
+ async getWatermark(rootSessionId) {
91
+ return await this.redis.getString(dreamWatermarkKey(rootSessionId));
92
+ }
93
+ async setWatermark(rootSessionId, value) {
94
+ await this.redis.setString(dreamWatermarkKey(rootSessionId), value);
95
+ }
96
+ }
@@ -0,0 +1,10 @@
1
+ import type { NormalizedMemoryResult } from "../types/index.js";
2
+ export type ExactHistoryAdapter = {
3
+ search(input: {
4
+ rootSessionId: string;
5
+ query: string;
6
+ when: string;
7
+ }): Promise<NormalizedMemoryResult[]>;
8
+ };
9
+ export declare const createExactHistoryAdapter: () => ExactHistoryAdapter;
10
+ //# sourceMappingURL=exact-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exact-history.d.ts","sourceRoot":"","sources":["../../../src/src/services/exact-history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,CAAC,KAAK,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAO,mBAE3C,CAAC"}
@@ -0,0 +1,3 @@
1
+ export const createExactHistoryAdapter = () => ({
2
+ search: () => Promise.resolve([]),
3
+ });
@@ -3,8 +3,8 @@ import type { GraphitiMcpClient } from "./graphiti-mcp.js";
3
3
  import type { RedisCacheService } from "./redis-cache.js";
4
4
  type TimerHandle = ReturnType<typeof setTimeout> | number;
5
5
  type GraphitiAsyncServiceOptions = {
6
- setTimer?: (callback: () => void, delayMs: number) => TimerHandle;
7
- clearTimer?: (timer: TimerHandle) => void;
6
+ setTimer?(callback: () => void, delayMs: number): TimerHandle;
7
+ clearTimer?(timer: TimerHandle): void;
8
8
  };
9
9
  export declare class GraphitiAsyncService {
10
10
  private readonly graphiti;
@@ -1 +1 @@
1
- {"version":3,"file":"graphiti-async.d.ts","sourceRoot":"","sources":["../../../src/src/services/graphiti-async.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,MAAM,CAAC;AAE1D,KAAK,2BAA2B,GAAG;IACjC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,WAAW,CAAC;IAClE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF,qBAAa,oBAAoB;IAqB7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAxBvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,+BAA+B,CAAU;IACjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;IAClE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAGZ;IACjB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+B;IAC9D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAMhC;IACJ,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IACpE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoC;IACnE,OAAO,CAAC,OAAO,CAAS;gBAGL,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,iBAAiB,EACxB,iBAAiB,SAAQ,EACzB,oBAAoB,SACiB,EACtD,OAAO,GAAE,2BAAgC;IAQrC,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,kBAAkB;IAO1B,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAyBrC,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA2E1D,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAsDrC"}
1
+ {"version":3,"file":"graphiti-async.d.ts","sourceRoot":"","sources":["../../../src/src/services/graphiti-async.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,MAAM,CAAC;AAE1D,KAAK,2BAA2B,GAAG;IACjC,QAAQ,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9D,UAAU,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACvC,CAAC;AAEF,qBAAa,oBAAoB;IAqB7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAxBvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,+BAA+B,CAAU;IACjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;IAClE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAGZ;IACjB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+B;IAC9D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAMhC;IACJ,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IACpE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoC;IACnE,OAAO,CAAC,OAAO,CAAS;gBAGL,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,iBAAiB,EACxB,iBAAiB,SAAQ,EACzB,oBAAoB,SACiB,EACtD,OAAO,GAAE,2BAAgC;IAQrC,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,kBAAkB;IAO1B,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAyBrC,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA2E1D,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAsDrC"}
@@ -0,0 +1,6 @@
1
+ import type { NormalizedMemoryResult } from "../types/index.js";
2
+ export declare const compareWeightedResults: (left: NormalizedMemoryResult, right: NormalizedMemoryResult) => number;
3
+ export declare const orderMemoryResults: (results: NormalizedMemoryResult[], options: {
4
+ mode: "query" | "reflection";
5
+ }) => NormalizedMemoryResult[];
6
+ //# sourceMappingURL=memory-results.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-results.d.ts","sourceRoot":"","sources":["../../../src/src/services/memory-results.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,eAAO,MAAM,sBAAsB,GACjC,MAAM,sBAAsB,EAC5B,OAAO,sBAAsB,KAC5B,MAQF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,sBAAsB,EAAE,EACjC,SAAS;IAAE,IAAI,EAAE,OAAO,GAAG,YAAY,CAAA;CAAE,KACxC,sBAAsB,EAexB,CAAC"}
@@ -0,0 +1,23 @@
1
+ export const compareWeightedResults = (left, right) => {
2
+ if (right.score !== left.score) {
3
+ return right.score - left.score;
4
+ }
5
+ if (right.created_at !== left.created_at) {
6
+ return right.created_at.localeCompare(left.created_at);
7
+ }
8
+ return left.ref.localeCompare(right.ref);
9
+ };
10
+ export const orderMemoryResults = (results, options) => {
11
+ if (options.mode === "reflection") {
12
+ return results
13
+ .filter((result) => result.type === "summary")
14
+ .sort((left, right) => left.created_at.localeCompare(right.created_at));
15
+ }
16
+ const primary = results
17
+ .filter((result) => result.type === "entry" || result.type === "note")
18
+ .sort(compareWeightedResults);
19
+ const summaries = results
20
+ .filter((result) => result.type === "summary")
21
+ .sort(compareWeightedResults);
22
+ return [...primary, ...summaries];
23
+ };
@@ -0,0 +1,29 @@
1
+ import type { NormalizedMemoryResult } from "../types/index.js";
2
+ import type { ExactHistoryAdapter } from "./exact-history.js";
3
+ import type { SessionMcpResponseMap } from "./session-mcp-types.js";
4
+ import type { SessionNotesService } from "./session-notes.js";
5
+ export type SummarySearchAdapter = {
6
+ search(input: {
7
+ rootSessionId: string;
8
+ query: string;
9
+ when: string;
10
+ }): Promise<NormalizedMemoryResult[]>;
11
+ };
12
+ export type MemorySearchService = {
13
+ search(input: {
14
+ rootSessionId: string;
15
+ query: string;
16
+ when: string;
17
+ }): Promise<SessionMcpResponseMap["session_search"]>;
18
+ };
19
+ type MemorySearchServiceOptions = {
20
+ exactHistoryAdapter: ExactHistoryAdapter;
21
+ notesService: Pick<SessionNotesService, "searchNotes">;
22
+ summarySearchAdapter: SummarySearchAdapter;
23
+ groupId: string;
24
+ resultLimit?: number;
25
+ };
26
+ export declare const createSummarySearchAdapter: () => SummarySearchAdapter;
27
+ export declare const createMemorySearchService: (options: MemorySearchServiceOptions) => MemorySearchService;
28
+ export {};
29
+ //# sourceMappingURL=memory-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-search.d.ts","sourceRoot":"","sources":["../../../src/src/services/memory-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,KAAK,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,CAAC,KAAK,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CACtD,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,YAAY,EAAE,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;IACvD,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,0BAA0B,QAAO,oBAE5C,CAAC;AAMH,eAAO,MAAM,yBAAyB,GACpC,SAAS,0BAA0B,KAClC,mBAqDF,CAAC"}