opencode-graphiti 0.1.7 → 0.1.8
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/README.md +14 -10
- package/esm/src/handlers/chat.d.ts.map +1 -1
- package/esm/src/handlers/chat.js +24 -1
- package/esm/src/handlers/event.d.ts.map +1 -1
- package/esm/src/handlers/event.js +3 -0
- package/esm/src/handlers/messages.d.ts +11 -0
- package/esm/src/handlers/messages.d.ts.map +1 -0
- package/esm/src/handlers/messages.js +75 -0
- package/esm/src/index.js +2 -2
- package/esm/src/services/context.d.ts +4 -0
- package/esm/src/services/context.d.ts.map +1 -1
- package/esm/src/services/context.js +15 -0
- package/esm/src/session.d.ts +5 -1
- package/esm/src/session.d.ts.map +1 -1
- package/esm/src/session.js +2 -0
- package/package.json +3 -2
- package/script/src/handlers/chat.d.ts.map +1 -1
- package/script/src/handlers/chat.js +24 -1
- package/script/src/handlers/event.d.ts.map +1 -1
- package/script/src/handlers/event.js +3 -0
- package/script/src/handlers/messages.d.ts +11 -0
- package/script/src/handlers/messages.d.ts.map +1 -0
- package/script/src/handlers/messages.js +78 -0
- package/script/src/index.js +2 -2
- package/script/src/services/context.d.ts +4 -0
- package/script/src/services/context.d.ts.map +1 -1
- package/script/src/services/context.js +16 -0
- package/script/src/session.d.ts +5 -1
- package/script/src/session.d.ts.map +1 -1
- package/script/src/session.js +2 -0
- package/esm/src/handlers/system.d.ts +0 -11
- package/esm/src/handlers/system.d.ts.map +0 -1
- package/esm/src/handlers/system.js +0 -18
- package/script/src/handlers/system.d.ts +0 -11
- package/script/src/handlers/system.d.ts.map +0 -1
- package/script/src/handlers/system.js +0 -21
package/README.md
CHANGED
|
@@ -23,8 +23,9 @@ reminded of recent project context — regardless of what survived the summary.
|
|
|
23
23
|
This plugin connects to a Graphiti MCP server and:
|
|
24
24
|
|
|
25
25
|
- Searches Graphiti for relevant facts and entities on each user message
|
|
26
|
-
- Injects memories into the
|
|
27
|
-
`experimental.chat.
|
|
26
|
+
- Injects memories into the last user message as a `<memory>` block via
|
|
27
|
+
`experimental.chat.messages.transform`, keeping the system prompt static for
|
|
28
|
+
prefix caching
|
|
28
29
|
- Detects context drift using Jaccard similarity and re-injects when the
|
|
29
30
|
conversation topic shifts
|
|
30
31
|
- Buffers user and assistant messages, flushing them to Graphiti on idle or
|
|
@@ -128,8 +129,8 @@ On each user message the plugin searches Graphiti for facts and entities
|
|
|
128
129
|
relevant to the message content. Results are split into project and user scopes
|
|
129
130
|
(70% / 30% budget), deduplicated, filtered for validity, annotated with
|
|
130
131
|
staleness if older than `factStaleDays`, and formatted as Markdown. The
|
|
131
|
-
formatted context is cached on the session state for the
|
|
132
|
-
pick up.
|
|
132
|
+
formatted context is cached on the session state for the messages transform hook
|
|
133
|
+
to pick up.
|
|
133
134
|
|
|
134
135
|
On the very first message of a session, the plugin also loads the most recent
|
|
135
136
|
session snapshot episode to prime the conversation with prior context.
|
|
@@ -137,13 +138,16 @@ session snapshot episode to prime the conversation with prior context.
|
|
|
137
138
|
The injection budget is calculated dynamically: 5% of the model's context limit
|
|
138
139
|
(resolved from the provider list) multiplied by 4 characters per token.
|
|
139
140
|
|
|
140
|
-
###
|
|
141
|
+
### User Message Injection (`experimental.chat.messages.transform`)
|
|
141
142
|
|
|
142
|
-
A separate hook reads the cached memory context and
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
A separate hook reads the cached memory context and prepends it to the last user
|
|
144
|
+
message as a `<memory data-uuids="...">` block. The `data-uuids` attribute lists
|
|
145
|
+
the fact UUIDs included in the injection, which are tracked in
|
|
146
|
+
`visibleFactUuids` so subsequent searches can filter out already-visible facts.
|
|
147
|
+
This approach keeps the system prompt static, enabling provider-side prefix
|
|
148
|
+
caching, and avoids influencing session titles. The cache is cleared after
|
|
149
|
+
injection so stale context is not re-injected on subsequent LLM calls within the
|
|
150
|
+
same turn.
|
|
147
151
|
|
|
148
152
|
### Drift-Based Re-injection (`chat.message`)
|
|
149
153
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAkLvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBA6EzE"}
|
package/esm/src/handlers/chat.js
CHANGED
|
@@ -46,6 +46,28 @@ export function createChatHandler(deps) {
|
|
|
46
46
|
facts: userFacts,
|
|
47
47
|
nodes: userNodes,
|
|
48
48
|
});
|
|
49
|
+
const visibleSet = new Set(state.visibleFactUuids ?? []);
|
|
50
|
+
const beforeProjectFacts = projectContext.facts.length;
|
|
51
|
+
const beforeUserFacts = userContext.facts.length;
|
|
52
|
+
projectContext.facts = projectContext.facts.filter((fact) => !visibleSet.has(fact.uuid));
|
|
53
|
+
userContext.facts = userContext.facts.filter((fact) => !visibleSet.has(fact.uuid));
|
|
54
|
+
logger.debug("Filtered visible facts from injection", {
|
|
55
|
+
visibleCount: visibleSet.size,
|
|
56
|
+
filteredProjectFacts: beforeProjectFacts - projectContext.facts.length,
|
|
57
|
+
filteredUserFacts: beforeUserFacts - userContext.facts.length,
|
|
58
|
+
remainingProjectFacts: projectContext.facts.length,
|
|
59
|
+
remainingUserFacts: userContext.facts.length,
|
|
60
|
+
});
|
|
61
|
+
if (projectContext.facts.length === 0 &&
|
|
62
|
+
userContext.facts.length === 0 &&
|
|
63
|
+
projectContext.nodes.length === 0 &&
|
|
64
|
+
userContext.nodes.length === 0) {
|
|
65
|
+
logger.debug("All facts filtered; skipping context cache", {
|
|
66
|
+
groupId: state.groupId,
|
|
67
|
+
userGroupId: state.userGroupId,
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
49
71
|
const projectContextString = formatMemoryContext(projectContext.facts, projectContext.nodes, { factStaleDays });
|
|
50
72
|
const userContextString = formatMemoryContext(userContext.facts, userContext.nodes, { factStaleDays });
|
|
51
73
|
if (!projectContextString && !userContextString)
|
|
@@ -102,7 +124,8 @@ export function createChatHandler(deps) {
|
|
|
102
124
|
];
|
|
103
125
|
const factUuids = seedFactUuids ?? Array.from(new Set(allFactUuids));
|
|
104
126
|
state.cachedMemoryContext = memoryContext;
|
|
105
|
-
|
|
127
|
+
state.cachedFactUuids = factUuids;
|
|
128
|
+
logger.info(`Cached ${projectFacts.length + userFacts.length} facts and ${projectNodes.length + userNodes.length} nodes for user message injection`);
|
|
106
129
|
state.lastInjectionFactUuids = factUuids;
|
|
107
130
|
};
|
|
108
131
|
const computeJaccardSimilarity = (left, right) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAkDzC,WAAW,UAAU,
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAkDzC,WAAW,UAAU,mBAqLpC"}
|
|
@@ -60,6 +60,9 @@ export function createEventHandler(deps) {
|
|
|
60
60
|
userGroupId: defaultUserGroupId,
|
|
61
61
|
injectedMemories: false,
|
|
62
62
|
lastInjectionFactUuids: [],
|
|
63
|
+
cachedMemoryContext: undefined,
|
|
64
|
+
cachedFactUuids: undefined,
|
|
65
|
+
visibleFactUuids: [],
|
|
63
66
|
messageCount: 0,
|
|
64
67
|
pendingMessages: [],
|
|
65
68
|
contextLimit: 200_000,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
|
+
import type { SessionManager } from "../session.js";
|
|
3
|
+
type MessagesTransformHook = NonNullable<Hooks["experimental.chat.messages.transform"]>;
|
|
4
|
+
type MessagesTransformInput = Parameters<MessagesTransformHook>[0];
|
|
5
|
+
type MessagesTransformOutput = Parameters<MessagesTransformHook>[1];
|
|
6
|
+
export interface MessagesHandlerDeps {
|
|
7
|
+
sessionManager: SessionManager;
|
|
8
|
+
}
|
|
9
|
+
export declare function createMessagesHandler(deps: MessagesHandlerDeps): (_input: MessagesTransformInput, output: MessagesTransformOutput) => Promise<void>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +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;AAGjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,qBAAqB,GAAG,WAAW,CACtC,KAAK,CAAC,sCAAsC,CAAC,CAC9C,CAAC;AACF,KAAK,sBAAsB,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,KAAK,uBAAuB,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,IAK3D,QAAQ,sBAAsB,EAC9B,QAAQ,uBAAuB,mBAkFlC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { extractVisibleUuids } from "../services/context.js";
|
|
2
|
+
import { logger } from "../services/logger.js";
|
|
3
|
+
export function createMessagesHandler(deps) {
|
|
4
|
+
const { sessionManager } = deps;
|
|
5
|
+
// deno-lint-ignore require-await
|
|
6
|
+
return async (_input, output) => {
|
|
7
|
+
const lastUserEntry = [...output.messages]
|
|
8
|
+
.reverse()
|
|
9
|
+
.find((message) => message.info.role === "user");
|
|
10
|
+
if (!lastUserEntry)
|
|
11
|
+
return;
|
|
12
|
+
const sessionID = lastUserEntry.info.sessionID;
|
|
13
|
+
const state = sessionManager.getState(sessionID);
|
|
14
|
+
if (!state?.isMain) {
|
|
15
|
+
logger.debug("Skipping memory injection; not main session", {
|
|
16
|
+
sessionID,
|
|
17
|
+
});
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const allVisibleUuids = [];
|
|
21
|
+
for (const entry of output.messages) {
|
|
22
|
+
for (const part of entry.parts) {
|
|
23
|
+
if (part.type === "text" && "text" in part) {
|
|
24
|
+
const uuids = extractVisibleUuids(part.text);
|
|
25
|
+
if (uuids.length > 0) {
|
|
26
|
+
logger.debug("Found <memory> block UUIDs", {
|
|
27
|
+
sessionID,
|
|
28
|
+
uuids,
|
|
29
|
+
messageID: entry.info.id,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
allVisibleUuids.push(...uuids);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
state.visibleFactUuids = [...new Set(allVisibleUuids)];
|
|
37
|
+
logger.debug("Updated visibleFactUuids from message scan", {
|
|
38
|
+
sessionID,
|
|
39
|
+
visibleCount: state.visibleFactUuids.length,
|
|
40
|
+
});
|
|
41
|
+
if (!state.cachedMemoryContext) {
|
|
42
|
+
logger.debug("Skipping memory injection; no cached context", {
|
|
43
|
+
sessionID,
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const textPart = lastUserEntry.parts.find((part) => part.type === "text" && "text" in part);
|
|
48
|
+
if (!textPart) {
|
|
49
|
+
logger.debug("Skipping memory injection; no text part", {
|
|
50
|
+
sessionID,
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (textPart.text.includes("<memory")) {
|
|
55
|
+
logger.debug("Skipping memory injection; already injected", {
|
|
56
|
+
sessionID,
|
|
57
|
+
});
|
|
58
|
+
state.cachedMemoryContext = undefined;
|
|
59
|
+
state.cachedFactUuids = undefined;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const uuids = state.cachedFactUuids ?? [];
|
|
63
|
+
const uuidAttr = uuids.length > 0 ? ` data-uuids="${uuids.join(",")}"` : "";
|
|
64
|
+
const memoryBlock = `<memory${uuidAttr}>\n${state.cachedMemoryContext}\n</memory>`;
|
|
65
|
+
textPart.text = `${memoryBlock}\n\n${textPart.text}`;
|
|
66
|
+
logger.info("Injected memory context into last user message", {
|
|
67
|
+
sessionID,
|
|
68
|
+
factCount: uuids.length,
|
|
69
|
+
blockLength: memoryBlock.length,
|
|
70
|
+
preview: state.cachedMemoryContext.slice(0, 100),
|
|
71
|
+
});
|
|
72
|
+
state.cachedMemoryContext = undefined;
|
|
73
|
+
state.cachedFactUuids = undefined;
|
|
74
|
+
};
|
|
75
|
+
}
|
package/esm/src/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { loadConfig } from "./config.js";
|
|
|
2
2
|
import { createChatHandler } from "./handlers/chat.js";
|
|
3
3
|
import { createCompactingHandler } from "./handlers/compacting.js";
|
|
4
4
|
import { createEventHandler } from "./handlers/event.js";
|
|
5
|
-
import {
|
|
5
|
+
import { createMessagesHandler } from "./handlers/messages.js";
|
|
6
6
|
import { GraphitiClient } from "./services/client.js";
|
|
7
7
|
import { logger } from "./services/logger.js";
|
|
8
8
|
import { SessionManager } from "./session.js";
|
|
@@ -44,7 +44,7 @@ export const graphiti = async (input) => {
|
|
|
44
44
|
defaultGroupId,
|
|
45
45
|
factStaleDays: config.factStaleDays,
|
|
46
46
|
}),
|
|
47
|
-
"experimental.chat.
|
|
47
|
+
"experimental.chat.messages.transform": createMessagesHandler({
|
|
48
48
|
sessionManager,
|
|
49
49
|
}),
|
|
50
50
|
};
|
|
@@ -30,4 +30,8 @@ export declare function formatMemoryContext(facts: GraphitiFact[], nodes: Graphi
|
|
|
30
30
|
factStaleDays?: number;
|
|
31
31
|
now?: Date;
|
|
32
32
|
}): string;
|
|
33
|
+
/**
|
|
34
|
+
* Extract fact UUIDs from all <memory data-uuids="..."> blocks in a text string.
|
|
35
|
+
*/
|
|
36
|
+
export declare function extractVisibleUuids(text: string): string[];
|
|
33
37
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,KAAG,IAAI,GAAG,IAKjD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,YAAY,EAAE,KAAK,IAAI,KAAG,OAQ7D,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,YAAY,EAClB,KAAK,IAAI,EACT,eAAe,MAAM,KACpB,YAUF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,YAAY,EAAE,KAAG,YAAY,EAWtE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,YAAY,EAMd,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,YAAY,KAAG,MAMnD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,MAAM,EAGR,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,OAAO,YAAY,EAAE,EACrB,OAAO,YAAY,EAAE,KACpB,YAAY,EAOd,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ;IACzC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,KAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAQjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GACA,MAAM,CA6BR"}
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,KAAG,IAAI,GAAG,IAKjD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,YAAY,EAAE,KAAK,IAAI,KAAG,OAQ7D,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,YAAY,EAClB,KAAK,IAAI,EACT,eAAe,MAAM,KACpB,YAUF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,YAAY,EAAE,KAAG,YAAY,EAWtE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,YAAY,EAMd,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,YAAY,KAAG,MAMnD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,MAAM,EAGR,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,OAAO,YAAY,EAAE,EACrB,OAAO,YAAY,EAAE,KACpB,YAAY,EAOd,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ;IACzC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,KAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAQjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GACA,MAAM,CA6BR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAW1D"}
|
|
@@ -129,3 +129,18 @@ export function formatMemoryContext(facts, nodes, options) {
|
|
|
129
129
|
}
|
|
130
130
|
return sections.join("\n");
|
|
131
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Extract fact UUIDs from all <memory data-uuids="..."> blocks in a text string.
|
|
134
|
+
*/
|
|
135
|
+
export function extractVisibleUuids(text) {
|
|
136
|
+
const uuids = [];
|
|
137
|
+
const regex = /<memory[^>]*\bdata-uuids="([^"]*)"[^>]*>/g;
|
|
138
|
+
let match;
|
|
139
|
+
while ((match = regex.exec(text)) !== null) {
|
|
140
|
+
const raw = match[1];
|
|
141
|
+
if (raw) {
|
|
142
|
+
uuids.push(...raw.split(",").filter(Boolean));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return uuids;
|
|
146
|
+
}
|
package/esm/src/session.d.ts
CHANGED
|
@@ -12,8 +12,12 @@ export type SessionState = {
|
|
|
12
12
|
injectedMemories: boolean;
|
|
13
13
|
/** Fact UUIDs included in the last memory injection. */
|
|
14
14
|
lastInjectionFactUuids: string[];
|
|
15
|
-
/** Cached formatted memory context for
|
|
15
|
+
/** Cached formatted memory context for user message injection. */
|
|
16
16
|
cachedMemoryContext?: string;
|
|
17
|
+
/** Fact UUIDs from cached context, for embedding in <memory> tag. */
|
|
18
|
+
cachedFactUuids?: string[];
|
|
19
|
+
/** Fact UUIDs currently visible in <memory> blocks across all messages. */
|
|
20
|
+
visibleFactUuids: string[];
|
|
17
21
|
/** Count of messages observed in this session. */
|
|
18
22
|
messageCount: number;
|
|
19
23
|
/** Buffered message strings awaiting flush. */
|
package/esm/src/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/src/session.ts"],"names":[],"mappings":"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"}
|
package/esm/src/session.js
CHANGED
|
@@ -108,6 +108,8 @@ export class SessionManager {
|
|
|
108
108
|
injectedMemories: false,
|
|
109
109
|
lastInjectionFactUuids: [],
|
|
110
110
|
cachedMemoryContext: undefined,
|
|
111
|
+
cachedFactUuids: undefined,
|
|
112
|
+
visibleFactUuids: [],
|
|
111
113
|
messageCount: 0,
|
|
112
114
|
pendingMessages: [],
|
|
113
115
|
contextLimit: 200_000,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-graphiti",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "OpenCode plugin for persistent memory via Graphiti knowledge graph",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opencode",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"hooks": [
|
|
41
41
|
"chat.message",
|
|
42
42
|
"event",
|
|
43
|
-
"experimental.session.compacting"
|
|
43
|
+
"experimental.session.compacting",
|
|
44
|
+
"experimental.chat.messages.transform"
|
|
44
45
|
]
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAkLvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBA6EzE"}
|
|
@@ -49,6 +49,28 @@ function createChatHandler(deps) {
|
|
|
49
49
|
facts: userFacts,
|
|
50
50
|
nodes: userNodes,
|
|
51
51
|
});
|
|
52
|
+
const visibleSet = new Set(state.visibleFactUuids ?? []);
|
|
53
|
+
const beforeProjectFacts = projectContext.facts.length;
|
|
54
|
+
const beforeUserFacts = userContext.facts.length;
|
|
55
|
+
projectContext.facts = projectContext.facts.filter((fact) => !visibleSet.has(fact.uuid));
|
|
56
|
+
userContext.facts = userContext.facts.filter((fact) => !visibleSet.has(fact.uuid));
|
|
57
|
+
logger_js_1.logger.debug("Filtered visible facts from injection", {
|
|
58
|
+
visibleCount: visibleSet.size,
|
|
59
|
+
filteredProjectFacts: beforeProjectFacts - projectContext.facts.length,
|
|
60
|
+
filteredUserFacts: beforeUserFacts - userContext.facts.length,
|
|
61
|
+
remainingProjectFacts: projectContext.facts.length,
|
|
62
|
+
remainingUserFacts: userContext.facts.length,
|
|
63
|
+
});
|
|
64
|
+
if (projectContext.facts.length === 0 &&
|
|
65
|
+
userContext.facts.length === 0 &&
|
|
66
|
+
projectContext.nodes.length === 0 &&
|
|
67
|
+
userContext.nodes.length === 0) {
|
|
68
|
+
logger_js_1.logger.debug("All facts filtered; skipping context cache", {
|
|
69
|
+
groupId: state.groupId,
|
|
70
|
+
userGroupId: state.userGroupId,
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
52
74
|
const projectContextString = (0, context_js_1.formatMemoryContext)(projectContext.facts, projectContext.nodes, { factStaleDays });
|
|
53
75
|
const userContextString = (0, context_js_1.formatMemoryContext)(userContext.facts, userContext.nodes, { factStaleDays });
|
|
54
76
|
if (!projectContextString && !userContextString)
|
|
@@ -105,7 +127,8 @@ function createChatHandler(deps) {
|
|
|
105
127
|
];
|
|
106
128
|
const factUuids = seedFactUuids ?? Array.from(new Set(allFactUuids));
|
|
107
129
|
state.cachedMemoryContext = memoryContext;
|
|
108
|
-
|
|
130
|
+
state.cachedFactUuids = factUuids;
|
|
131
|
+
logger_js_1.logger.info(`Cached ${projectFacts.length + userFacts.length} facts and ${projectNodes.length + userNodes.length} nodes for user message injection`);
|
|
109
132
|
state.lastInjectionFactUuids = factUuids;
|
|
110
133
|
};
|
|
111
134
|
const computeJaccardSimilarity = (left, right) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAkDzC,WAAW,UAAU,
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAkDzC,WAAW,UAAU,mBAqLpC"}
|
|
@@ -63,6 +63,9 @@ function createEventHandler(deps) {
|
|
|
63
63
|
userGroupId: defaultUserGroupId,
|
|
64
64
|
injectedMemories: false,
|
|
65
65
|
lastInjectionFactUuids: [],
|
|
66
|
+
cachedMemoryContext: undefined,
|
|
67
|
+
cachedFactUuids: undefined,
|
|
68
|
+
visibleFactUuids: [],
|
|
66
69
|
messageCount: 0,
|
|
67
70
|
pendingMessages: [],
|
|
68
71
|
contextLimit: 200_000,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
|
+
import type { SessionManager } from "../session.js";
|
|
3
|
+
type MessagesTransformHook = NonNullable<Hooks["experimental.chat.messages.transform"]>;
|
|
4
|
+
type MessagesTransformInput = Parameters<MessagesTransformHook>[0];
|
|
5
|
+
type MessagesTransformOutput = Parameters<MessagesTransformHook>[1];
|
|
6
|
+
export interface MessagesHandlerDeps {
|
|
7
|
+
sessionManager: SessionManager;
|
|
8
|
+
}
|
|
9
|
+
export declare function createMessagesHandler(deps: MessagesHandlerDeps): (_input: MessagesTransformInput, output: MessagesTransformOutput) => Promise<void>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +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;AAGjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,qBAAqB,GAAG,WAAW,CACtC,KAAK,CAAC,sCAAsC,CAAC,CAC9C,CAAC;AACF,KAAK,sBAAsB,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,KAAK,uBAAuB,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,IAK3D,QAAQ,sBAAsB,EAC9B,QAAQ,uBAAuB,mBAkFlC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMessagesHandler = createMessagesHandler;
|
|
4
|
+
const context_js_1 = require("../services/context.js");
|
|
5
|
+
const logger_js_1 = require("../services/logger.js");
|
|
6
|
+
function createMessagesHandler(deps) {
|
|
7
|
+
const { sessionManager } = deps;
|
|
8
|
+
// deno-lint-ignore require-await
|
|
9
|
+
return async (_input, output) => {
|
|
10
|
+
const lastUserEntry = [...output.messages]
|
|
11
|
+
.reverse()
|
|
12
|
+
.find((message) => message.info.role === "user");
|
|
13
|
+
if (!lastUserEntry)
|
|
14
|
+
return;
|
|
15
|
+
const sessionID = lastUserEntry.info.sessionID;
|
|
16
|
+
const state = sessionManager.getState(sessionID);
|
|
17
|
+
if (!state?.isMain) {
|
|
18
|
+
logger_js_1.logger.debug("Skipping memory injection; not main session", {
|
|
19
|
+
sessionID,
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const allVisibleUuids = [];
|
|
24
|
+
for (const entry of output.messages) {
|
|
25
|
+
for (const part of entry.parts) {
|
|
26
|
+
if (part.type === "text" && "text" in part) {
|
|
27
|
+
const uuids = (0, context_js_1.extractVisibleUuids)(part.text);
|
|
28
|
+
if (uuids.length > 0) {
|
|
29
|
+
logger_js_1.logger.debug("Found <memory> block UUIDs", {
|
|
30
|
+
sessionID,
|
|
31
|
+
uuids,
|
|
32
|
+
messageID: entry.info.id,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
allVisibleUuids.push(...uuids);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
state.visibleFactUuids = [...new Set(allVisibleUuids)];
|
|
40
|
+
logger_js_1.logger.debug("Updated visibleFactUuids from message scan", {
|
|
41
|
+
sessionID,
|
|
42
|
+
visibleCount: state.visibleFactUuids.length,
|
|
43
|
+
});
|
|
44
|
+
if (!state.cachedMemoryContext) {
|
|
45
|
+
logger_js_1.logger.debug("Skipping memory injection; no cached context", {
|
|
46
|
+
sessionID,
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const textPart = lastUserEntry.parts.find((part) => part.type === "text" && "text" in part);
|
|
51
|
+
if (!textPart) {
|
|
52
|
+
logger_js_1.logger.debug("Skipping memory injection; no text part", {
|
|
53
|
+
sessionID,
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (textPart.text.includes("<memory")) {
|
|
58
|
+
logger_js_1.logger.debug("Skipping memory injection; already injected", {
|
|
59
|
+
sessionID,
|
|
60
|
+
});
|
|
61
|
+
state.cachedMemoryContext = undefined;
|
|
62
|
+
state.cachedFactUuids = undefined;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const uuids = state.cachedFactUuids ?? [];
|
|
66
|
+
const uuidAttr = uuids.length > 0 ? ` data-uuids="${uuids.join(",")}"` : "";
|
|
67
|
+
const memoryBlock = `<memory${uuidAttr}>\n${state.cachedMemoryContext}\n</memory>`;
|
|
68
|
+
textPart.text = `${memoryBlock}\n\n${textPart.text}`;
|
|
69
|
+
logger_js_1.logger.info("Injected memory context into last user message", {
|
|
70
|
+
sessionID,
|
|
71
|
+
factCount: uuids.length,
|
|
72
|
+
blockLength: memoryBlock.length,
|
|
73
|
+
preview: state.cachedMemoryContext.slice(0, 100),
|
|
74
|
+
});
|
|
75
|
+
state.cachedMemoryContext = undefined;
|
|
76
|
+
state.cachedFactUuids = undefined;
|
|
77
|
+
};
|
|
78
|
+
}
|
package/script/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const config_js_1 = require("./config.js");
|
|
|
5
5
|
const chat_js_1 = require("./handlers/chat.js");
|
|
6
6
|
const compacting_js_1 = require("./handlers/compacting.js");
|
|
7
7
|
const event_js_1 = require("./handlers/event.js");
|
|
8
|
-
const
|
|
8
|
+
const messages_js_1 = require("./handlers/messages.js");
|
|
9
9
|
const client_js_1 = require("./services/client.js");
|
|
10
10
|
const logger_js_1 = require("./services/logger.js");
|
|
11
11
|
const session_js_1 = require("./session.js");
|
|
@@ -47,7 +47,7 @@ const graphiti = async (input) => {
|
|
|
47
47
|
defaultGroupId,
|
|
48
48
|
factStaleDays: config.factStaleDays,
|
|
49
49
|
}),
|
|
50
|
-
"experimental.chat.
|
|
50
|
+
"experimental.chat.messages.transform": (0, messages_js_1.createMessagesHandler)({
|
|
51
51
|
sessionManager,
|
|
52
52
|
}),
|
|
53
53
|
};
|
|
@@ -30,4 +30,8 @@ export declare function formatMemoryContext(facts: GraphitiFact[], nodes: Graphi
|
|
|
30
30
|
factStaleDays?: number;
|
|
31
31
|
now?: Date;
|
|
32
32
|
}): string;
|
|
33
|
+
/**
|
|
34
|
+
* Extract fact UUIDs from all <memory data-uuids="..."> blocks in a text string.
|
|
35
|
+
*/
|
|
36
|
+
export declare function extractVisibleUuids(text: string): string[];
|
|
33
37
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,KAAG,IAAI,GAAG,IAKjD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,YAAY,EAAE,KAAK,IAAI,KAAG,OAQ7D,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,YAAY,EAClB,KAAK,IAAI,EACT,eAAe,MAAM,KACpB,YAUF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,YAAY,EAAE,KAAG,YAAY,EAWtE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,YAAY,EAMd,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,YAAY,KAAG,MAMnD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,MAAM,EAGR,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,OAAO,YAAY,EAAE,EACrB,OAAO,YAAY,EAAE,KACpB,YAAY,EAOd,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ;IACzC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,KAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAQjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GACA,MAAM,CA6BR"}
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,KAAG,IAAI,GAAG,IAKjD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,YAAY,EAAE,KAAK,IAAI,KAAG,OAQ7D,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,YAAY,EAClB,KAAK,IAAI,EACT,eAAe,MAAM,KACpB,YAUF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,YAAY,EAAE,KAAG,YAAY,EAWtE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,YAAY,EAMd,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,YAAY,KAAG,MAMnD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,YAAY,EAAE,EACrB,UAAU;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,KACA,MAAM,EAGR,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,YAAY,EAAE,KACpB,YAAY,EASd,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,OAAO,YAAY,EAAE,EACrB,OAAO,YAAY,EAAE,KACpB,YAAY,EAOd,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ;IACzC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,KAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAQjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GACA,MAAM,CA6BR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAW1D"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deduplicateContext = exports.removeNodesReferencedByFacts = exports.deduplicateNodesByUuid = exports.deduplicateFactsByUuid = exports.formatNodeLines = exports.formatFactLines = exports.formatFactLine = exports.filterAndAnnotateFacts = exports.sortFactsByRecency = exports.annotateStaleFact = exports.isFactInvalid = exports.parseDate = void 0;
|
|
4
4
|
exports.formatMemoryContext = formatMemoryContext;
|
|
5
|
+
exports.extractVisibleUuids = extractVisibleUuids;
|
|
5
6
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
6
7
|
const parseDate = (value) => {
|
|
7
8
|
if (!value)
|
|
@@ -145,3 +146,18 @@ function formatMemoryContext(facts, nodes, options) {
|
|
|
145
146
|
}
|
|
146
147
|
return sections.join("\n");
|
|
147
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Extract fact UUIDs from all <memory data-uuids="..."> blocks in a text string.
|
|
151
|
+
*/
|
|
152
|
+
function extractVisibleUuids(text) {
|
|
153
|
+
const uuids = [];
|
|
154
|
+
const regex = /<memory[^>]*\bdata-uuids="([^"]*)"[^>]*>/g;
|
|
155
|
+
let match;
|
|
156
|
+
while ((match = regex.exec(text)) !== null) {
|
|
157
|
+
const raw = match[1];
|
|
158
|
+
if (raw) {
|
|
159
|
+
uuids.push(...raw.split(",").filter(Boolean));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return uuids;
|
|
163
|
+
}
|
package/script/src/session.d.ts
CHANGED
|
@@ -12,8 +12,12 @@ export type SessionState = {
|
|
|
12
12
|
injectedMemories: boolean;
|
|
13
13
|
/** Fact UUIDs included in the last memory injection. */
|
|
14
14
|
lastInjectionFactUuids: string[];
|
|
15
|
-
/** Cached formatted memory context for
|
|
15
|
+
/** Cached formatted memory context for user message injection. */
|
|
16
16
|
cachedMemoryContext?: string;
|
|
17
|
+
/** Fact UUIDs from cached context, for embedding in <memory> tag. */
|
|
18
|
+
cachedFactUuids?: string[];
|
|
19
|
+
/** Fact UUIDs currently visible in <memory> blocks across all messages. */
|
|
20
|
+
visibleFactUuids: string[];
|
|
17
21
|
/** Count of messages observed in this session. */
|
|
18
22
|
messageCount: number;
|
|
19
23
|
/** Buffered message strings awaiting flush. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/src/session.ts"],"names":[],"mappings":"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"}
|
package/script/src/session.js
CHANGED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
|
-
import type { SessionManager } from "../session.js";
|
|
3
|
-
type SystemTransformHook = NonNullable<Hooks["experimental.chat.system.transform"]>;
|
|
4
|
-
type SystemTransformInput = Parameters<SystemTransformHook>[0];
|
|
5
|
-
type SystemTransformOutput = Parameters<SystemTransformHook>[1];
|
|
6
|
-
export interface SystemHandlerDeps {
|
|
7
|
-
sessionManager: SessionManager;
|
|
8
|
-
}
|
|
9
|
-
export declare function createSystemHandler(deps: SystemHandlerDeps): ({ sessionID }: SystemTransformInput, output: SystemTransformOutput) => Promise<void>;
|
|
10
|
-
export {};
|
|
11
|
-
//# sourceMappingURL=system.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/system.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,mBAAmB,GAAG,WAAW,CACpC,KAAK,CAAC,oCAAoC,CAAC,CAC5C,CAAC;AACF,KAAK,oBAAoB,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,KAAK,qBAAqB,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,IAMvD,eAAe,oBAAoB,EACnC,QAAQ,qBAAqB,mBAYhC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { logger } from "../services/logger.js";
|
|
2
|
-
export function createSystemHandler(deps) {
|
|
3
|
-
const { sessionManager } = deps;
|
|
4
|
-
// Assumes chat.message hook completes before system.transform fires for the same turn.
|
|
5
|
-
// deno-lint-ignore require-await
|
|
6
|
-
return async ({ sessionID }, output) => {
|
|
7
|
-
if (!sessionID)
|
|
8
|
-
return;
|
|
9
|
-
const state = sessionManager.getState(sessionID);
|
|
10
|
-
if (!state?.isMain)
|
|
11
|
-
return;
|
|
12
|
-
if (!state.cachedMemoryContext)
|
|
13
|
-
return;
|
|
14
|
-
output.system.push(state.cachedMemoryContext);
|
|
15
|
-
state.cachedMemoryContext = undefined;
|
|
16
|
-
logger.info("Injected memory context into system prompt");
|
|
17
|
-
};
|
|
18
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
|
-
import type { SessionManager } from "../session.js";
|
|
3
|
-
type SystemTransformHook = NonNullable<Hooks["experimental.chat.system.transform"]>;
|
|
4
|
-
type SystemTransformInput = Parameters<SystemTransformHook>[0];
|
|
5
|
-
type SystemTransformOutput = Parameters<SystemTransformHook>[1];
|
|
6
|
-
export interface SystemHandlerDeps {
|
|
7
|
-
sessionManager: SessionManager;
|
|
8
|
-
}
|
|
9
|
-
export declare function createSystemHandler(deps: SystemHandlerDeps): ({ sessionID }: SystemTransformInput, output: SystemTransformOutput) => Promise<void>;
|
|
10
|
-
export {};
|
|
11
|
-
//# sourceMappingURL=system.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/system.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,mBAAmB,GAAG,WAAW,CACpC,KAAK,CAAC,oCAAoC,CAAC,CAC5C,CAAC;AACF,KAAK,oBAAoB,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,KAAK,qBAAqB,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,IAMvD,eAAe,oBAAoB,EACnC,QAAQ,qBAAqB,mBAYhC"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createSystemHandler = createSystemHandler;
|
|
4
|
-
const logger_js_1 = require("../services/logger.js");
|
|
5
|
-
function createSystemHandler(deps) {
|
|
6
|
-
const { sessionManager } = deps;
|
|
7
|
-
// Assumes chat.message hook completes before system.transform fires for the same turn.
|
|
8
|
-
// deno-lint-ignore require-await
|
|
9
|
-
return async ({ sessionID }, output) => {
|
|
10
|
-
if (!sessionID)
|
|
11
|
-
return;
|
|
12
|
-
const state = sessionManager.getState(sessionID);
|
|
13
|
-
if (!state?.isMain)
|
|
14
|
-
return;
|
|
15
|
-
if (!state.cachedMemoryContext)
|
|
16
|
-
return;
|
|
17
|
-
output.system.push(state.cachedMemoryContext);
|
|
18
|
-
state.cachedMemoryContext = undefined;
|
|
19
|
-
logger_js_1.logger.info("Injected memory context into system prompt");
|
|
20
|
-
};
|
|
21
|
-
}
|