opencode-graphiti 0.2.4 → 0.2.5-canary.2b67949.20260521183008
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/index.d.ts.map +1 -1
- package/esm/src/index.js +86 -14
- 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/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-mcp-runtime.d.ts +11 -1
- package/esm/src/services/session-mcp-runtime.d.ts.map +1 -1
- package/esm/src/services/session-mcp-runtime.js +241 -31
- package/esm/src/services/session-mcp-types.d.ts +171 -21
- package/esm/src/services/session-mcp-types.d.ts.map +1 -1
- package/esm/src/services/session-mcp-types.js +47 -5
- 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/session.d.ts +7 -1
- 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/index.d.ts.map +1 -1
- package/script/src/index.js +84 -12
- 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/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-mcp-runtime.d.ts +11 -1
- package/script/src/services/session-mcp-runtime.d.ts.map +1 -1
- package/script/src/services/session-mcp-runtime.js +242 -32
- package/script/src/services/session-mcp-types.d.ts +171 -21
- package/script/src/services/session-mcp-types.d.ts.map +1 -1
- package/script/src/services/session-mcp-types.js +47 -5
- 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/session.d.ts +7 -1
- 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,
|
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,
|
|
@@ -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,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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { orderMemoryResults } from "./memory-results.js";
|
|
2
|
+
export const createSummarySearchAdapter = () => ({
|
|
3
|
+
search: () => Promise.resolve([]),
|
|
4
|
+
});
|
|
5
|
+
const uniqueRefs = (results) => [
|
|
6
|
+
...new Set(results.map((result) => result.ref)),
|
|
7
|
+
];
|
|
8
|
+
export const createMemorySearchService = (options) => {
|
|
9
|
+
const resultLimit = options.resultLimit ?? Number.POSITIVE_INFINITY;
|
|
10
|
+
return {
|
|
11
|
+
async search(input) {
|
|
12
|
+
const summaries = await options.summarySearchAdapter.search(input);
|
|
13
|
+
if (input.query === "") {
|
|
14
|
+
const ordered = orderMemoryResults(summaries, { mode: "reflection" });
|
|
15
|
+
const results = ordered.slice(0, resultLimit);
|
|
16
|
+
return {
|
|
17
|
+
status: "ok",
|
|
18
|
+
results,
|
|
19
|
+
refs: uniqueRefs(results),
|
|
20
|
+
truncated: ordered.length > results.length,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const [entries, notes] = await Promise.all([
|
|
24
|
+
options.exactHistoryAdapter.search(input),
|
|
25
|
+
options.notesService.searchNotes(input.rootSessionId, input.query),
|
|
26
|
+
]);
|
|
27
|
+
const normalizedNotes = notes.map((note) => ({
|
|
28
|
+
type: "note",
|
|
29
|
+
ref: `session:${options.groupId}:${note.root_session_id}:note:${note.id}`,
|
|
30
|
+
snippet: note.snippet,
|
|
31
|
+
score: note.score,
|
|
32
|
+
id: note.id,
|
|
33
|
+
root_session_id: note.root_session_id,
|
|
34
|
+
scope: note.scope,
|
|
35
|
+
created_at: note.created_at,
|
|
36
|
+
updated_at: note.updated_at,
|
|
37
|
+
source: "session-notes",
|
|
38
|
+
}));
|
|
39
|
+
const ordered = orderMemoryResults([
|
|
40
|
+
...entries,
|
|
41
|
+
...normalizedNotes,
|
|
42
|
+
...summaries,
|
|
43
|
+
], { mode: "query" });
|
|
44
|
+
const results = ordered.slice(0, resultLimit);
|
|
45
|
+
return {
|
|
46
|
+
status: "ok",
|
|
47
|
+
results,
|
|
48
|
+
refs: uniqueRefs(results),
|
|
49
|
+
truncated: ordered.length > results.length,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -6,4 +6,5 @@ export declare const logStructuredWarning: (message: string, extra?: unknown) =>
|
|
|
6
6
|
export declare const showWarningToast: (message: string, extra?: unknown) => boolean;
|
|
7
7
|
export declare const notifyPluginWarning: (message: string, extra?: unknown) => void;
|
|
8
8
|
export declare const notifyGraphitiAvailabilityIssue: (message: string, extra?: unknown) => void;
|
|
9
|
+
export declare const notifyDreamShutdownDelay: () => void;
|
|
9
10
|
//# sourceMappingURL=opencode-warning.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-warning.d.ts","sourceRoot":"","sources":["../../../src/src/services/opencode-warning.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,wCAAwC,QAAO,OAM3D,CAAC;AA6FF,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,OAAO,KACd,IAEF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,WAAW,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,KACtD,IAIF,CAAC;AAEF,eAAO,MAAM,6CAA6C,GACxD,OAAO,OAAO,GAAG,SAAS,KACzB,IAEF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,MAAM,EACf,QAAQ,OAAO,KACd,OAEF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,EAAE,QAAQ,OAAO,KAAG,OAEnE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,MAAM,EACf,QAAQ,OAAO,KACd,IAMF,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,SAAS,MAAM,EACf,QAAQ,OAAO,KACd,IAEF,CAAC"}
|
|
1
|
+
{"version":3,"file":"opencode-warning.d.ts","sourceRoot":"","sources":["../../../src/src/services/opencode-warning.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,wCAAwC,QAAO,OAM3D,CAAC;AA6FF,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,OAAO,KACd,IAEF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,WAAW,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,KACtD,IAIF,CAAC;AAEF,eAAO,MAAM,6CAA6C,GACxD,OAAO,OAAO,GAAG,SAAS,KACzB,IAEF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,MAAM,EACf,QAAQ,OAAO,KACd,OAEF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,EAAE,QAAQ,OAAO,KAAG,OAEnE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,MAAM,EACf,QAAQ,OAAO,KACd,IAMF,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,SAAS,MAAM,EACf,QAAQ,OAAO,KACd,IAEF,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAO,IAI3C,CAAC"}
|
|
@@ -105,3 +105,6 @@ export const notifyPluginWarning = (message, extra) => {
|
|
|
105
105
|
export const notifyGraphitiAvailabilityIssue = (message, extra) => {
|
|
106
106
|
notifyPluginWarning(message, extra);
|
|
107
107
|
};
|
|
108
|
+
export const notifyDreamShutdownDelay = () => {
|
|
109
|
+
notifyPluginWarning("Dreaming is still in progress; keep OpenCode open and wait for dreaming to complete before exiting.");
|
|
110
|
+
};
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { type SessionEvent } from "../types/index.js";
|
|
2
2
|
import type { RedisClient } from "./redis-client.js";
|
|
3
|
+
import type { NormalizedMemoryResult } from "../types/index.js";
|
|
4
|
+
export declare const createSnapshotSummaryResult: (input: {
|
|
5
|
+
rootSessionId: string;
|
|
6
|
+
created_at: string;
|
|
7
|
+
snippet: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
granularity?: string;
|
|
10
|
+
}) => NormalizedMemoryResult;
|
|
3
11
|
export declare const buildSessionSnapshotXml: (sessionId: string, events: SessionEvent[]) => string;
|
|
4
12
|
export interface RedisSnapshotServiceOptions {
|
|
5
13
|
ttlSeconds: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-snapshot.d.ts","sourceRoot":"","sources":["../../../src/src/services/redis-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"redis-snapshot.d.ts","sourceRoot":"","sources":["../../../src/src/services/redis-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAUrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAKhE,eAAO,MAAM,2BAA2B,GAAI,OAAO;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,KAAG,sBAaF,CAAC;AAoBH,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,EACjB,QAAQ,YAAY,EAAE,KACrB,MAiOF,CAAC;AAEF,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,2BAA2B;IAGjD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAItD,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EAAE,GACrB,OAAO,CAAC,MAAM,CAAC;CAKnB"}
|
|
@@ -3,6 +3,18 @@ import { sessionSnapshotKey } from "./redis-events.js";
|
|
|
3
3
|
import { escapeXml, normalizeMemoryText, renderXmlListSection, renderXmlSingleSection, sanitizeMemoryInput, uniqueNormalizedValues, } from "./render-utils.js";
|
|
4
4
|
const SNAPSHOT_BUDGET = 3_000;
|
|
5
5
|
const BLOCKER_PATTERN = /\b(blocker|blocked|blocking)\b/i;
|
|
6
|
+
export const createSnapshotSummaryResult = (input) => ({
|
|
7
|
+
type: "summary",
|
|
8
|
+
ref: `session:${input.rootSessionId}:summary:snapshot:${input.id ?? input.created_at}`,
|
|
9
|
+
snippet: input.snippet,
|
|
10
|
+
score: 1,
|
|
11
|
+
created_at: input.created_at,
|
|
12
|
+
id: input.id ?? input.created_at,
|
|
13
|
+
root_session_id: input.rootSessionId,
|
|
14
|
+
scope: "session",
|
|
15
|
+
granularity: input.granularity ?? "session",
|
|
16
|
+
source: "snapshot",
|
|
17
|
+
});
|
|
6
18
|
const selectRecent = (events, predicate, map, limit, excludedNormalized = new Set()) => uniqueNormalizedValues(events.flatMap((event) => {
|
|
7
19
|
if (!predicate(event))
|
|
8
20
|
return [];
|
|
@@ -2,6 +2,7 @@ export type RuntimeTeardownTask = {
|
|
|
2
2
|
name: string;
|
|
3
3
|
run: () => void | Promise<void>;
|
|
4
4
|
};
|
|
5
|
+
export declare const createRuntimeTeardownTask: (name: string, run: () => void | Promise<void>) => RuntimeTeardownTask;
|
|
5
6
|
export interface RuntimeTeardownRegistration {
|
|
6
7
|
run(): Promise<void>;
|
|
7
8
|
dispose(): void;
|