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.
- package/esm/src/handlers/chat.js +2 -2
- package/esm/src/handlers/compacting.d.ts.map +1 -1
- package/esm/src/handlers/compacting.js +3 -3
- package/esm/src/handlers/messages.d.ts.map +1 -1
- package/esm/src/handlers/messages.js +15 -8
- package/esm/src/handlers/tool-before.d.ts.map +1 -1
- package/esm/src/handlers/tool-before.js +8 -8
- package/esm/src/index.d.ts.map +1 -1
- package/esm/src/index.js +86 -14
- package/esm/src/services/connection-manager.d.ts +2 -2
- package/esm/src/services/connection-manager.d.ts.map +1 -1
- package/esm/src/services/dream-store.d.ts +21 -0
- package/esm/src/services/dream-store.d.ts.map +1 -0
- package/esm/src/services/dream-store.js +96 -0
- package/esm/src/services/exact-history.d.ts +10 -0
- package/esm/src/services/exact-history.d.ts.map +1 -0
- package/esm/src/services/exact-history.js +3 -0
- package/esm/src/services/graphiti-async.d.ts +2 -2
- package/esm/src/services/graphiti-async.d.ts.map +1 -1
- package/esm/src/services/memory-results.d.ts +6 -0
- package/esm/src/services/memory-results.d.ts.map +1 -0
- package/esm/src/services/memory-results.js +23 -0
- package/esm/src/services/memory-search.d.ts +29 -0
- package/esm/src/services/memory-search.d.ts.map +1 -0
- package/esm/src/services/memory-search.js +53 -0
- package/esm/src/services/opencode-warning.d.ts +1 -0
- package/esm/src/services/opencode-warning.d.ts.map +1 -1
- package/esm/src/services/opencode-warning.js +3 -0
- package/esm/src/services/redis-snapshot.d.ts +8 -0
- package/esm/src/services/redis-snapshot.d.ts.map +1 -1
- package/esm/src/services/redis-snapshot.js +12 -0
- package/esm/src/services/runtime-teardown.d.ts +1 -0
- package/esm/src/services/runtime-teardown.d.ts.map +1 -1
- package/esm/src/services/runtime-teardown.js +13 -4
- package/esm/src/services/session-executor.d.ts +9 -3
- package/esm/src/services/session-executor.d.ts.map +1 -1
- package/esm/src/services/session-mcp-runtime.d.ts +14 -2
- package/esm/src/services/session-mcp-runtime.d.ts.map +1 -1
- package/esm/src/services/session-mcp-runtime.js +269 -70
- package/esm/src/services/session-mcp-types.d.ts +177 -41
- package/esm/src/services/session-mcp-types.d.ts.map +1 -1
- package/esm/src/services/session-mcp-types.js +46 -23
- package/esm/src/services/session-notes.d.ts +70 -0
- package/esm/src/services/session-notes.d.ts.map +1 -0
- package/esm/src/services/session-notes.js +438 -0
- package/esm/src/services/tool-routing.js +1 -1
- package/esm/src/session.d.ts +9 -3
- package/esm/src/session.d.ts.map +1 -1
- package/esm/src/session.js +36 -13
- package/esm/src/types/index.d.ts +14 -0
- package/esm/src/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/script/src/handlers/chat.js +2 -2
- package/script/src/handlers/compacting.d.ts.map +1 -1
- package/script/src/handlers/compacting.js +3 -3
- package/script/src/handlers/messages.d.ts.map +1 -1
- package/script/src/handlers/messages.js +15 -8
- package/script/src/handlers/tool-before.d.ts.map +1 -1
- package/script/src/handlers/tool-before.js +8 -8
- package/script/src/index.d.ts.map +1 -1
- package/script/src/index.js +84 -12
- package/script/src/services/connection-manager.d.ts +2 -2
- package/script/src/services/connection-manager.d.ts.map +1 -1
- package/script/src/services/dream-store.d.ts +21 -0
- package/script/src/services/dream-store.d.ts.map +1 -0
- package/script/src/services/dream-store.js +100 -0
- package/script/src/services/exact-history.d.ts +10 -0
- package/script/src/services/exact-history.d.ts.map +1 -0
- package/script/src/services/exact-history.js +7 -0
- package/script/src/services/graphiti-async.d.ts +2 -2
- package/script/src/services/graphiti-async.d.ts.map +1 -1
- package/script/src/services/memory-results.d.ts +6 -0
- package/script/src/services/memory-results.d.ts.map +1 -0
- package/script/src/services/memory-results.js +28 -0
- package/script/src/services/memory-search.d.ts +29 -0
- package/script/src/services/memory-search.d.ts.map +1 -0
- package/script/src/services/memory-search.js +58 -0
- package/script/src/services/opencode-warning.d.ts +1 -0
- package/script/src/services/opencode-warning.d.ts.map +1 -1
- package/script/src/services/opencode-warning.js +5 -1
- package/script/src/services/redis-snapshot.d.ts +8 -0
- package/script/src/services/redis-snapshot.d.ts.map +1 -1
- package/script/src/services/redis-snapshot.js +14 -1
- package/script/src/services/runtime-teardown.d.ts +1 -0
- package/script/src/services/runtime-teardown.d.ts.map +1 -1
- package/script/src/services/runtime-teardown.js +15 -4
- package/script/src/services/session-executor.d.ts +9 -3
- package/script/src/services/session-executor.d.ts.map +1 -1
- package/script/src/services/session-mcp-runtime.d.ts +14 -2
- package/script/src/services/session-mcp-runtime.d.ts.map +1 -1
- package/script/src/services/session-mcp-runtime.js +270 -71
- package/script/src/services/session-mcp-types.d.ts +177 -41
- package/script/src/services/session-mcp-types.d.ts.map +1 -1
- package/script/src/services/session-mcp-types.js +46 -23
- package/script/src/services/session-notes.d.ts +70 -0
- package/script/src/services/session-notes.d.ts.map +1 -0
- package/script/src/services/session-notes.js +443 -0
- package/script/src/services/tool-routing.js +1 -1
- package/script/src/session.d.ts +9 -3
- package/script/src/session.d.ts.map +1 -1
- package/script/src/session.js +36 -13
- package/script/src/types/index.d.ts +14 -0
- package/script/src/types/index.d.ts.map +1 -1
package/esm/src/handlers/chat.js
CHANGED
|
@@ -34,7 +34,7 @@ export function createChatHandler(deps) {
|
|
|
34
34
|
if (prepared) {
|
|
35
35
|
state.injectedMemories = true;
|
|
36
36
|
}
|
|
37
|
-
logger.info("Prepared local
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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;
|
|
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
|
|
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
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
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;
|
|
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
|
|
9
|
-
...args
|
|
10
|
-
|
|
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
|
-
?
|
|
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
|
-
?
|
|
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
|
}
|
package/esm/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
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":
|
|
208
|
-
sessionManager
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
|
58
|
-
clearTimer
|
|
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":"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,
|
|
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"}
|
|
@@ -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
|
|
7
|
-
clearTimer
|
|
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,
|
|
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"}
|