opencode-graphiti 0.1.3 → 0.1.5
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 +10 -17
- package/esm/deno.d.ts +47 -0
- package/esm/deno.d.ts.map +1 -0
- package/esm/deno.js +41 -0
- package/esm/src/handlers/chat.d.ts +6 -11
- package/esm/src/handlers/chat.d.ts.map +1 -1
- package/esm/src/handlers/chat.js +28 -22
- package/esm/src/handlers/compacting.d.ts +6 -5
- package/esm/src/handlers/compacting.d.ts.map +1 -1
- package/esm/src/handlers/event.d.ts +5 -4
- package/esm/src/handlers/event.d.ts.map +1 -1
- package/esm/src/services/client.d.ts.map +1 -1
- package/esm/src/services/client.js +9 -2
- package/esm/src/services/compaction.d.ts.map +1 -1
- package/esm/src/services/compaction.js +25 -11
- package/esm/src/services/context.d.ts.map +1 -1
- package/esm/src/services/context.js +12 -14
- package/package.json +24 -1
- package/script/deno.d.ts +47 -0
- package/script/deno.d.ts.map +1 -0
- package/script/deno.js +43 -0
- package/script/src/handlers/chat.d.ts +6 -11
- package/script/src/handlers/chat.d.ts.map +1 -1
- package/script/src/handlers/chat.js +28 -22
- package/script/src/handlers/compacting.d.ts +6 -5
- package/script/src/handlers/compacting.d.ts.map +1 -1
- package/script/src/handlers/event.d.ts +5 -4
- package/script/src/handlers/event.d.ts.map +1 -1
- package/script/src/services/client.d.ts.map +1 -1
- package/script/src/services/client.js +12 -2
- package/script/src/services/compaction.d.ts.map +1 -1
- package/script/src/services/compaction.js +25 -11
- package/script/src/services/context.d.ts.map +1 -1
- package/script/src/services/context.js +12 -14
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ Create a config file at `~/.config/opencode/graphiti.jsonc`:
|
|
|
101
101
|
// Graphiti MCP server endpoint
|
|
102
102
|
"endpoint": "http://localhost:8000/mcp",
|
|
103
103
|
|
|
104
|
-
// Prefix for project group IDs (e.g. "
|
|
104
|
+
// Prefix for project group IDs (e.g. "opencode-my-project")
|
|
105
105
|
"groupIdPrefix": "opencode",
|
|
106
106
|
|
|
107
107
|
// Number of user messages between memory re-injections (0 = disabled)
|
|
@@ -118,8 +118,12 @@ values.
|
|
|
118
118
|
|
|
119
119
|
On the first user message in a session, the plugin searches Graphiti for facts
|
|
120
120
|
and entities relevant to the message content. Results are split into project and
|
|
121
|
-
user scopes (70% / 30% budget split), formatted
|
|
122
|
-
|
|
121
|
+
user scopes (70% / 30% budget split), formatted in XML-style `<memory>` blocks
|
|
122
|
+
with explicit de-emphasis instructions, and injected into the conversation.
|
|
123
|
+
|
|
124
|
+
Memory is injected via `output.message.system` (system-level instruction) when
|
|
125
|
+
available, which prevents memory from influencing session titles. If the system
|
|
126
|
+
field is unavailable, the plugin falls back to prepending synthetic parts.
|
|
123
127
|
|
|
124
128
|
The injection budget is calculated dynamically: 5% of the model's context limit
|
|
125
129
|
(resolved from the provider list) multiplied by 4 characters per token.
|
|
@@ -167,21 +171,10 @@ Each project gets a unique `group_id` derived from its directory name (e.g.
|
|
|
167
171
|
underscores (colons are not allowed). This ensures memories from different
|
|
168
172
|
projects stay isolated.
|
|
169
173
|
|
|
170
|
-
##
|
|
171
|
-
|
|
172
|
-
```bash
|
|
173
|
-
# Format
|
|
174
|
-
deno fmt
|
|
175
|
-
|
|
176
|
-
# Lint
|
|
177
|
-
deno lint
|
|
174
|
+
## Contributing
|
|
178
175
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
# Build
|
|
183
|
-
deno task build
|
|
184
|
-
```
|
|
176
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and release
|
|
177
|
+
process.
|
|
185
178
|
|
|
186
179
|
## License
|
|
187
180
|
|
package/esm/deno.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
declare namespace _default {
|
|
2
|
+
export let name: string;
|
|
3
|
+
export let description: string;
|
|
4
|
+
export let version: string;
|
|
5
|
+
export let license: string;
|
|
6
|
+
export namespace tasks {
|
|
7
|
+
let build: string;
|
|
8
|
+
namespace deploy {
|
|
9
|
+
let command: string;
|
|
10
|
+
let dependencies: string[];
|
|
11
|
+
}
|
|
12
|
+
let dev: string;
|
|
13
|
+
let check: string;
|
|
14
|
+
let lint: string;
|
|
15
|
+
let fmt: string;
|
|
16
|
+
}
|
|
17
|
+
export namespace lint_1 {
|
|
18
|
+
let exclude: string[];
|
|
19
|
+
namespace rules {
|
|
20
|
+
let exclude_1: string[];
|
|
21
|
+
export { exclude_1 as exclude };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export { lint_1 as lint };
|
|
25
|
+
export namespace fmt_1 {
|
|
26
|
+
let exclude_2: string[];
|
|
27
|
+
export { exclude_2 as exclude };
|
|
28
|
+
}
|
|
29
|
+
export { fmt_1 as fmt };
|
|
30
|
+
export namespace compilerOptions {
|
|
31
|
+
let strict: boolean;
|
|
32
|
+
let lib: string[];
|
|
33
|
+
}
|
|
34
|
+
export let nodeModulesDir: string;
|
|
35
|
+
export let imports: {
|
|
36
|
+
"@modelcontextprotocol/sdk": string;
|
|
37
|
+
"@opencode-ai/plugin": string;
|
|
38
|
+
"@opencode-ai/sdk": string;
|
|
39
|
+
cosmiconfig: string;
|
|
40
|
+
zod: string;
|
|
41
|
+
};
|
|
42
|
+
export let exports: {
|
|
43
|
+
".": string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export default _default;
|
|
47
|
+
//# sourceMappingURL=deno.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deno.d.ts","sourceRoot":"","sources":["../src/deno.js"],"names":[],"mappings":""}
|
package/esm/deno.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
"name": "opencode-graphiti",
|
|
3
|
+
"description": "OpenCode plugin for persistent memory via Graphiti knowledge graph",
|
|
4
|
+
"version": "0.0.0-development",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"tasks": {
|
|
7
|
+
"build": "deno run -A dnt.ts",
|
|
8
|
+
"deploy": {
|
|
9
|
+
"command": "cd dist/ && npm publish",
|
|
10
|
+
"dependencies": ["build"]
|
|
11
|
+
},
|
|
12
|
+
"dev": "deno run --allow-all src/index.ts",
|
|
13
|
+
"check": "deno check src/index.ts",
|
|
14
|
+
"lint": "deno lint",
|
|
15
|
+
"fmt": "deno fmt"
|
|
16
|
+
},
|
|
17
|
+
"lint": {
|
|
18
|
+
"exclude": ["dist/"],
|
|
19
|
+
"rules": {
|
|
20
|
+
"exclude": ["no-import-prefix"]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"fmt": {
|
|
24
|
+
"exclude": ["dist/"]
|
|
25
|
+
},
|
|
26
|
+
"compilerOptions": {
|
|
27
|
+
"strict": true,
|
|
28
|
+
"lib": ["deno.ns", "dom", "esnext"]
|
|
29
|
+
},
|
|
30
|
+
"nodeModulesDir": "auto",
|
|
31
|
+
"imports": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "npm:@modelcontextprotocol/sdk@^1.25.2",
|
|
33
|
+
"@opencode-ai/plugin": "npm:@opencode-ai/plugin@^1.1.53",
|
|
34
|
+
"@opencode-ai/sdk": "npm:@opencode-ai/sdk@^1.1.53",
|
|
35
|
+
"cosmiconfig": "npm:cosmiconfig@9.0.0",
|
|
36
|
+
"zod": "npm:zod@4.3.6"
|
|
37
|
+
},
|
|
38
|
+
"exports": {
|
|
39
|
+
".": "./mod.ts"
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type ChatMessageHook = NonNullable<Hooks["chat.message"]>;
|
|
5
|
+
type ChatMessageInput = Parameters<ChatMessageHook>[0];
|
|
6
|
+
type ChatMessageOutput = Parameters<ChatMessageHook>[1];
|
|
4
7
|
/** Dependencies for the chat message handler. */
|
|
5
8
|
export interface ChatHandlerDeps {
|
|
6
9
|
sessionManager: SessionManager;
|
|
@@ -8,14 +11,6 @@ export interface ChatHandlerDeps {
|
|
|
8
11
|
client: GraphitiClient;
|
|
9
12
|
}
|
|
10
13
|
/** Creates the `chat.message` hook handler. */
|
|
11
|
-
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }:
|
|
12
|
-
|
|
13
|
-
}, output: {
|
|
14
|
-
allow_buffering?: boolean;
|
|
15
|
-
parts: Part[];
|
|
16
|
-
message: {
|
|
17
|
-
sessionID: string;
|
|
18
|
-
id: string;
|
|
19
|
-
};
|
|
20
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }: ChatMessageInput, output: ChatMessageOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
21
16
|
//# sourceMappingURL=chat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,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;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,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,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAyGvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBAuDzE"}
|
package/esm/src/handlers/chat.js
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import { formatMemoryContext } from "../services/context.js";
|
|
2
1
|
import { calculateInjectionBudget } from "../services/context-limit.js";
|
|
2
|
+
import { formatMemoryContext } from "../services/context.js";
|
|
3
3
|
import { logger } from "../services/logger.js";
|
|
4
4
|
import { extractTextFromParts } from "../utils.js";
|
|
5
5
|
/** Creates the `chat.message` hook handler. */
|
|
6
6
|
export function createChatHandler(deps) {
|
|
7
7
|
const { sessionManager, injectionInterval, client } = deps;
|
|
8
8
|
const removeSyntheticMemoryParts = (parts) => parts.filter((part) => {
|
|
9
|
-
|
|
10
|
-
const id = typeof part.id === "string"
|
|
11
|
-
? String(part.id)
|
|
12
|
-
: "";
|
|
13
|
-
if (!synthetic)
|
|
9
|
+
if (part.type !== "text")
|
|
14
10
|
return true;
|
|
15
|
-
if (id
|
|
11
|
+
if (part.id?.startsWith("graphiti-memory-"))
|
|
16
12
|
return false;
|
|
17
|
-
if (id
|
|
13
|
+
if (part.id?.startsWith("graphiti-refresh-"))
|
|
18
14
|
return false;
|
|
19
15
|
return true;
|
|
20
16
|
});
|
|
21
|
-
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget) => {
|
|
17
|
+
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject) => {
|
|
22
18
|
const userGroupId = state.userGroupId;
|
|
23
19
|
const projectFactsPromise = client.searchFacts({
|
|
24
20
|
query: messageText,
|
|
@@ -67,14 +63,28 @@ export function createChatHandler(deps) {
|
|
|
67
63
|
.slice(0, characterBudget);
|
|
68
64
|
if (!memoryContext)
|
|
69
65
|
return;
|
|
70
|
-
output.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
if ("system" in output.message) {
|
|
67
|
+
try {
|
|
68
|
+
output.message.system = memoryContext;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
catch (_err) {
|
|
72
|
+
// Fall through to synthetic injection.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (shouldReinject) {
|
|
76
|
+
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
77
|
+
}
|
|
78
|
+
{
|
|
79
|
+
output.parts.unshift({
|
|
80
|
+
type: "text",
|
|
81
|
+
text: memoryContext,
|
|
82
|
+
id: `${prefix}${Date.now()}`,
|
|
83
|
+
sessionID: output.message.sessionID,
|
|
84
|
+
messageID: output.message.id,
|
|
85
|
+
synthetic: true,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
78
88
|
logger.info(`Injected ${projectFacts.length + userFacts.length} facts and ${projectNodes.length + userNodes.length} nodes`);
|
|
79
89
|
};
|
|
80
90
|
return async ({ sessionID }, output) => {
|
|
@@ -84,7 +94,6 @@ export function createChatHandler(deps) {
|
|
|
84
94
|
}
|
|
85
95
|
const { state, resolved } = await sessionManager.resolveSessionState(sessionID);
|
|
86
96
|
if (!resolved) {
|
|
87
|
-
output.allow_buffering = true;
|
|
88
97
|
logger.debug("Unable to resolve session for message:", { sessionID });
|
|
89
98
|
return;
|
|
90
99
|
}
|
|
@@ -109,14 +118,11 @@ export function createChatHandler(deps) {
|
|
|
109
118
|
injectionInterval;
|
|
110
119
|
if (!shouldInjectOnFirst && !shouldReinject)
|
|
111
120
|
return;
|
|
112
|
-
if (shouldReinject) {
|
|
113
|
-
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
114
|
-
}
|
|
115
121
|
try {
|
|
116
122
|
const prefix = shouldReinject ? "graphiti-refresh-" : "graphiti-memory-";
|
|
117
123
|
const useUserScope = shouldInjectOnFirst;
|
|
118
124
|
const characterBudget = calculateInjectionBudget(state.contextLimit);
|
|
119
|
-
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget);
|
|
125
|
+
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject);
|
|
120
126
|
state.injectedMemories = true;
|
|
121
127
|
state.lastInjectionMessageCount = state.messageCount;
|
|
122
128
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
1
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
2
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type CompactingHook = NonNullable<Hooks["experimental.session.compacting"]>;
|
|
5
|
+
type CompactingInput = Parameters<CompactingHook>[0];
|
|
6
|
+
type CompactingOutput = Parameters<CompactingHook>[1];
|
|
3
7
|
/** Dependencies for the compacting handler. */
|
|
4
8
|
export interface CompactingHandlerDeps {
|
|
5
9
|
sessionManager: SessionManager;
|
|
@@ -7,9 +11,6 @@ export interface CompactingHandlerDeps {
|
|
|
7
11
|
defaultGroupId: string;
|
|
8
12
|
}
|
|
9
13
|
/** Creates the `experimental.session.compacting` hook handler. */
|
|
10
|
-
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }:
|
|
11
|
-
|
|
12
|
-
}, output: {
|
|
13
|
-
context: string[];
|
|
14
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }: CompactingInput, output: CompactingOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
15
16
|
//# sourceMappingURL=compacting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe
|
|
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;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;AAC5E,KAAK,eAAe,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,KAAK,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe,eAAe,EAC9B,QAAQ,gBAAgB,mBAyB3B"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { ProviderListClient } from "../services/context-limit.js";
|
|
4
4
|
import type { SessionManager } from "../session.js";
|
|
5
|
+
type EventHook = NonNullable<Hooks["event"]>;
|
|
6
|
+
type EventInput = Parameters<EventHook>[0];
|
|
5
7
|
/** Dependencies for the event handler. */
|
|
6
8
|
export interface EventHandlerDeps {
|
|
7
9
|
sessionManager: SessionManager;
|
|
@@ -12,7 +14,6 @@ export interface EventHandlerDeps {
|
|
|
12
14
|
groupIdPrefix: string;
|
|
13
15
|
}
|
|
14
16
|
/** Creates the `event` hook handler. */
|
|
15
|
-
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }:
|
|
16
|
-
|
|
17
|
-
}) => Promise<void>;
|
|
17
|
+
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }: EventInput) => Promise<void>;
|
|
18
|
+
export {};
|
|
18
19
|
//# sourceMappingURL=event.d.ts.map
|
|
@@ -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,
|
|
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,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,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,kBAAkB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAWzC,WAAW,UAAU,mBA+JpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/src/services/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/src/services/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,YAAY,EAEb,MAAM,mBAAmB,CAAC;AAG3B;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IAEzB;;OAEG;gBACS,QAAQ,EAAE,MAAM;IAS5B,oDAAoD;IACpD,OAAO,CAAC,wBAAwB;IAUhC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBjC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAOnB,QAAQ;IAkCtB,OAAO,CAAC,gBAAgB;YASV,SAAS;IAavB;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;IAyBzC;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjB;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAsB3B;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAsB3B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
2
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
import manifest from "../../deno.js";
|
|
3
4
|
import { logger } from "./logger.js";
|
|
4
5
|
/**
|
|
5
6
|
* Graphiti MCP client wrapper for connecting, querying,
|
|
@@ -35,12 +36,18 @@ export class GraphitiClient {
|
|
|
35
36
|
value: void 0
|
|
36
37
|
});
|
|
37
38
|
this.endpoint = endpoint;
|
|
38
|
-
this.client = new Client({
|
|
39
|
+
this.client = new Client({
|
|
40
|
+
name: manifest.name,
|
|
41
|
+
version: manifest.version,
|
|
42
|
+
});
|
|
39
43
|
this.transport = new StreamableHTTPClientTransport(new URL(endpoint));
|
|
40
44
|
}
|
|
41
45
|
/** Create a fresh MCP Client and Transport pair. */
|
|
42
46
|
createClientAndTransport() {
|
|
43
|
-
this.client = new Client({
|
|
47
|
+
this.client = new Client({
|
|
48
|
+
name: manifest.name,
|
|
49
|
+
version: manifest.version,
|
|
50
|
+
});
|
|
44
51
|
this.transport = new StreamableHTTPClientTransport(new URL(this.endpoint));
|
|
45
52
|
}
|
|
46
53
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgIpB"}
|
|
@@ -69,32 +69,40 @@ export async function getCompactionContext(params) {
|
|
|
69
69
|
const buildSection = (header, facts, nodes) => {
|
|
70
70
|
const lines = [];
|
|
71
71
|
lines.push(header);
|
|
72
|
+
lines.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
72
73
|
if (facts.length > 0) {
|
|
73
|
-
lines.push("
|
|
74
|
+
lines.push("<facts>");
|
|
74
75
|
lines.push(...formatFactLines(facts));
|
|
76
|
+
lines.push("</facts>");
|
|
75
77
|
}
|
|
76
78
|
if (nodes.length > 0) {
|
|
77
|
-
lines.push("
|
|
79
|
+
lines.push("<nodes>");
|
|
78
80
|
lines.push(...formatNodeLines(nodes));
|
|
81
|
+
lines.push("</nodes>");
|
|
79
82
|
}
|
|
80
83
|
return lines.join("\n");
|
|
81
84
|
};
|
|
82
|
-
const projectSection = buildSection(
|
|
83
|
-
const userSection = buildSection(
|
|
85
|
+
const projectSection = buildSection('<memory source="project">', projectFacts, projectNodes);
|
|
86
|
+
const userSection = buildSection('<memory source="user">', userFacts, userNodes);
|
|
84
87
|
const headerLines = [
|
|
85
|
-
"
|
|
88
|
+
"<summary>",
|
|
89
|
+
"<current_goal>",
|
|
86
90
|
"- ",
|
|
91
|
+
"</current_goal>",
|
|
87
92
|
"",
|
|
88
|
-
"
|
|
93
|
+
"<work_completed>",
|
|
89
94
|
"- ",
|
|
95
|
+
"</work_completed>",
|
|
90
96
|
"",
|
|
91
|
-
"
|
|
97
|
+
"<remaining_tasks>",
|
|
92
98
|
"- ",
|
|
99
|
+
"</remaining_tasks>",
|
|
93
100
|
"",
|
|
94
|
-
"
|
|
101
|
+
"<constraints_decisions>",
|
|
95
102
|
"- ",
|
|
103
|
+
"</constraints_decisions>",
|
|
96
104
|
"",
|
|
97
|
-
"
|
|
105
|
+
"<persistent_memory>",
|
|
98
106
|
];
|
|
99
107
|
const header = headerLines.join("\n");
|
|
100
108
|
const base = `${header}\n`;
|
|
@@ -104,10 +112,16 @@ export async function getCompactionContext(params) {
|
|
|
104
112
|
const truncatedProject = projectSection.slice(0, projectBudget);
|
|
105
113
|
const truncatedUser = userSection.slice(0, userBudget);
|
|
106
114
|
const sections = [header];
|
|
107
|
-
if (truncatedProject.trim())
|
|
115
|
+
if (truncatedProject.trim()) {
|
|
108
116
|
sections.push(truncatedProject);
|
|
109
|
-
|
|
117
|
+
sections.push("</memory>");
|
|
118
|
+
}
|
|
119
|
+
if (truncatedUser.trim()) {
|
|
110
120
|
sections.push(truncatedUser);
|
|
121
|
+
sections.push("</memory>");
|
|
122
|
+
}
|
|
123
|
+
sections.push("</persistent_memory>");
|
|
124
|
+
sections.push("</summary>");
|
|
111
125
|
const content = sections.join("\n").slice(0, characterBudget);
|
|
112
126
|
return [content];
|
|
113
127
|
}
|
|
@@ -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;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,
|
|
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;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,CA0BR"}
|
|
@@ -5,35 +5,33 @@ export const formatFactLines = (facts) => facts.map((fact) => {
|
|
|
5
5
|
if (fact.target_node?.name)
|
|
6
6
|
entities.push(fact.target_node.name);
|
|
7
7
|
const entityStr = entities.length > 0 ? ` [${entities.join(" -> ")}]` : "";
|
|
8
|
-
return
|
|
8
|
+
return `<fact>${fact.fact}${entityStr}</fact>`;
|
|
9
9
|
});
|
|
10
10
|
export const formatNodeLines = (nodes) => nodes.map((node) => {
|
|
11
11
|
const labels = node.labels?.length ? ` (${node.labels.join(", ")})` : "";
|
|
12
12
|
const summary = node.summary ? `: ${node.summary}` : "";
|
|
13
|
-
return
|
|
13
|
+
return `<node>${node.name}${labels}${summary}</node>`;
|
|
14
14
|
});
|
|
15
15
|
/**
|
|
16
16
|
* Format Graphiti facts and nodes into a user-facing context block.
|
|
17
17
|
*/
|
|
18
18
|
export function formatMemoryContext(facts, nodes) {
|
|
19
|
+
if (facts.length === 0 && nodes.length === 0) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
19
22
|
const sections = [];
|
|
20
|
-
sections.push("
|
|
21
|
-
sections.push("");
|
|
22
|
-
sections.push("The following information was retrieved from your persistent memory.");
|
|
23
|
-
sections.push("Use this context to inform your responses, but do not mention it unless asked.");
|
|
24
|
-
sections.push("");
|
|
23
|
+
sections.push("<memory>");
|
|
24
|
+
sections.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
25
25
|
if (facts.length > 0) {
|
|
26
|
-
sections.push("
|
|
26
|
+
sections.push("<facts>");
|
|
27
27
|
sections.push(...formatFactLines(facts));
|
|
28
|
-
sections.push("");
|
|
28
|
+
sections.push("</facts>");
|
|
29
29
|
}
|
|
30
30
|
if (nodes.length > 0) {
|
|
31
|
-
sections.push("
|
|
31
|
+
sections.push("<nodes>");
|
|
32
32
|
sections.push(...formatNodeLines(nodes));
|
|
33
|
-
sections.push("");
|
|
34
|
-
}
|
|
35
|
-
if (facts.length === 0 && nodes.length === 0) {
|
|
36
|
-
return "";
|
|
33
|
+
sections.push("</nodes>");
|
|
37
34
|
}
|
|
35
|
+
sections.push("</memory>");
|
|
38
36
|
return sections.join("\n");
|
|
39
37
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-graphiti",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "OpenCode plugin for persistent memory via Graphiti knowledge graph",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"opencode",
|
|
7
|
+
"graphiti",
|
|
8
|
+
"knowledge-graph",
|
|
9
|
+
"persistent-memory",
|
|
10
|
+
"plugin",
|
|
11
|
+
"mcp",
|
|
12
|
+
"ai",
|
|
13
|
+
"context"
|
|
14
|
+
],
|
|
15
|
+
"author": "Vicary A. <vicary.archangel@member.mensa.org>",
|
|
16
|
+
"homepage": "https://github.com/vicary/opencode-graphiti#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/vicary/opencode-graphiti.git"
|
|
20
|
+
},
|
|
5
21
|
"license": "MIT",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/vicary/opencode-graphiti/issues"
|
|
24
|
+
},
|
|
6
25
|
"main": "./esm/mod.js",
|
|
7
26
|
"module": "./esm/mod.js",
|
|
27
|
+
"types": "./esm/mod.d.ts",
|
|
8
28
|
"exports": {
|
|
9
29
|
".": {
|
|
10
30
|
"import": "./esm/mod.js",
|
|
@@ -12,6 +32,9 @@
|
|
|
12
32
|
}
|
|
13
33
|
},
|
|
14
34
|
"scripts": {},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20"
|
|
37
|
+
},
|
|
15
38
|
"opencode": {
|
|
16
39
|
"type": "plugin",
|
|
17
40
|
"hooks": [
|
package/script/deno.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
declare namespace _default {
|
|
2
|
+
export let name: string;
|
|
3
|
+
export let description: string;
|
|
4
|
+
export let version: string;
|
|
5
|
+
export let license: string;
|
|
6
|
+
export namespace tasks {
|
|
7
|
+
let build: string;
|
|
8
|
+
namespace deploy {
|
|
9
|
+
let command: string;
|
|
10
|
+
let dependencies: string[];
|
|
11
|
+
}
|
|
12
|
+
let dev: string;
|
|
13
|
+
let check: string;
|
|
14
|
+
let lint: string;
|
|
15
|
+
let fmt: string;
|
|
16
|
+
}
|
|
17
|
+
export namespace lint_1 {
|
|
18
|
+
let exclude: string[];
|
|
19
|
+
namespace rules {
|
|
20
|
+
let exclude_1: string[];
|
|
21
|
+
export { exclude_1 as exclude };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export { lint_1 as lint };
|
|
25
|
+
export namespace fmt_1 {
|
|
26
|
+
let exclude_2: string[];
|
|
27
|
+
export { exclude_2 as exclude };
|
|
28
|
+
}
|
|
29
|
+
export { fmt_1 as fmt };
|
|
30
|
+
export namespace compilerOptions {
|
|
31
|
+
let strict: boolean;
|
|
32
|
+
let lib: string[];
|
|
33
|
+
}
|
|
34
|
+
export let nodeModulesDir: string;
|
|
35
|
+
export let imports: {
|
|
36
|
+
"@modelcontextprotocol/sdk": string;
|
|
37
|
+
"@opencode-ai/plugin": string;
|
|
38
|
+
"@opencode-ai/sdk": string;
|
|
39
|
+
cosmiconfig: string;
|
|
40
|
+
zod: string;
|
|
41
|
+
};
|
|
42
|
+
export let exports: {
|
|
43
|
+
".": string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export default _default;
|
|
47
|
+
//# sourceMappingURL=deno.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deno.d.ts","sourceRoot":"","sources":["../src/deno.js"],"names":[],"mappings":""}
|
package/script/deno.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = {
|
|
4
|
+
"name": "opencode-graphiti",
|
|
5
|
+
"description": "OpenCode plugin for persistent memory via Graphiti knowledge graph",
|
|
6
|
+
"version": "0.0.0-development",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"tasks": {
|
|
9
|
+
"build": "deno run -A dnt.ts",
|
|
10
|
+
"deploy": {
|
|
11
|
+
"command": "cd dist/ && npm publish",
|
|
12
|
+
"dependencies": ["build"]
|
|
13
|
+
},
|
|
14
|
+
"dev": "deno run --allow-all src/index.ts",
|
|
15
|
+
"check": "deno check src/index.ts",
|
|
16
|
+
"lint": "deno lint",
|
|
17
|
+
"fmt": "deno fmt"
|
|
18
|
+
},
|
|
19
|
+
"lint": {
|
|
20
|
+
"exclude": ["dist/"],
|
|
21
|
+
"rules": {
|
|
22
|
+
"exclude": ["no-import-prefix"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"fmt": {
|
|
26
|
+
"exclude": ["dist/"]
|
|
27
|
+
},
|
|
28
|
+
"compilerOptions": {
|
|
29
|
+
"strict": true,
|
|
30
|
+
"lib": ["deno.ns", "dom", "esnext"]
|
|
31
|
+
},
|
|
32
|
+
"nodeModulesDir": "auto",
|
|
33
|
+
"imports": {
|
|
34
|
+
"@modelcontextprotocol/sdk": "npm:@modelcontextprotocol/sdk@^1.25.2",
|
|
35
|
+
"@opencode-ai/plugin": "npm:@opencode-ai/plugin@^1.1.53",
|
|
36
|
+
"@opencode-ai/sdk": "npm:@opencode-ai/sdk@^1.1.53",
|
|
37
|
+
"cosmiconfig": "npm:cosmiconfig@9.0.0",
|
|
38
|
+
"zod": "npm:zod@4.3.6"
|
|
39
|
+
},
|
|
40
|
+
"exports": {
|
|
41
|
+
".": "./mod.ts"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type ChatMessageHook = NonNullable<Hooks["chat.message"]>;
|
|
5
|
+
type ChatMessageInput = Parameters<ChatMessageHook>[0];
|
|
6
|
+
type ChatMessageOutput = Parameters<ChatMessageHook>[1];
|
|
4
7
|
/** Dependencies for the chat message handler. */
|
|
5
8
|
export interface ChatHandlerDeps {
|
|
6
9
|
sessionManager: SessionManager;
|
|
@@ -8,14 +11,6 @@ export interface ChatHandlerDeps {
|
|
|
8
11
|
client: GraphitiClient;
|
|
9
12
|
}
|
|
10
13
|
/** Creates the `chat.message` hook handler. */
|
|
11
|
-
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }:
|
|
12
|
-
|
|
13
|
-
}, output: {
|
|
14
|
-
allow_buffering?: boolean;
|
|
15
|
-
parts: Part[];
|
|
16
|
-
message: {
|
|
17
|
-
sessionID: string;
|
|
18
|
-
id: string;
|
|
19
|
-
};
|
|
20
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }: ChatMessageInput, output: ChatMessageOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
21
16
|
//# sourceMappingURL=chat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,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;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,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,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAyGvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBAuDzE"}
|
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createChatHandler = createChatHandler;
|
|
4
|
-
const context_js_1 = require("../services/context.js");
|
|
5
4
|
const context_limit_js_1 = require("../services/context-limit.js");
|
|
5
|
+
const context_js_1 = require("../services/context.js");
|
|
6
6
|
const logger_js_1 = require("../services/logger.js");
|
|
7
7
|
const utils_js_1 = require("../utils.js");
|
|
8
8
|
/** Creates the `chat.message` hook handler. */
|
|
9
9
|
function createChatHandler(deps) {
|
|
10
10
|
const { sessionManager, injectionInterval, client } = deps;
|
|
11
11
|
const removeSyntheticMemoryParts = (parts) => parts.filter((part) => {
|
|
12
|
-
|
|
13
|
-
const id = typeof part.id === "string"
|
|
14
|
-
? String(part.id)
|
|
15
|
-
: "";
|
|
16
|
-
if (!synthetic)
|
|
12
|
+
if (part.type !== "text")
|
|
17
13
|
return true;
|
|
18
|
-
if (id
|
|
14
|
+
if (part.id?.startsWith("graphiti-memory-"))
|
|
19
15
|
return false;
|
|
20
|
-
if (id
|
|
16
|
+
if (part.id?.startsWith("graphiti-refresh-"))
|
|
21
17
|
return false;
|
|
22
18
|
return true;
|
|
23
19
|
});
|
|
24
|
-
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget) => {
|
|
20
|
+
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject) => {
|
|
25
21
|
const userGroupId = state.userGroupId;
|
|
26
22
|
const projectFactsPromise = client.searchFacts({
|
|
27
23
|
query: messageText,
|
|
@@ -70,14 +66,28 @@ function createChatHandler(deps) {
|
|
|
70
66
|
.slice(0, characterBudget);
|
|
71
67
|
if (!memoryContext)
|
|
72
68
|
return;
|
|
73
|
-
output.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
if ("system" in output.message) {
|
|
70
|
+
try {
|
|
71
|
+
output.message.system = memoryContext;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
catch (_err) {
|
|
75
|
+
// Fall through to synthetic injection.
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (shouldReinject) {
|
|
79
|
+
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
80
|
+
}
|
|
81
|
+
{
|
|
82
|
+
output.parts.unshift({
|
|
83
|
+
type: "text",
|
|
84
|
+
text: memoryContext,
|
|
85
|
+
id: `${prefix}${Date.now()}`,
|
|
86
|
+
sessionID: output.message.sessionID,
|
|
87
|
+
messageID: output.message.id,
|
|
88
|
+
synthetic: true,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
81
91
|
logger_js_1.logger.info(`Injected ${projectFacts.length + userFacts.length} facts and ${projectNodes.length + userNodes.length} nodes`);
|
|
82
92
|
};
|
|
83
93
|
return async ({ sessionID }, output) => {
|
|
@@ -87,7 +97,6 @@ function createChatHandler(deps) {
|
|
|
87
97
|
}
|
|
88
98
|
const { state, resolved } = await sessionManager.resolveSessionState(sessionID);
|
|
89
99
|
if (!resolved) {
|
|
90
|
-
output.allow_buffering = true;
|
|
91
100
|
logger_js_1.logger.debug("Unable to resolve session for message:", { sessionID });
|
|
92
101
|
return;
|
|
93
102
|
}
|
|
@@ -112,14 +121,11 @@ function createChatHandler(deps) {
|
|
|
112
121
|
injectionInterval;
|
|
113
122
|
if (!shouldInjectOnFirst && !shouldReinject)
|
|
114
123
|
return;
|
|
115
|
-
if (shouldReinject) {
|
|
116
|
-
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
117
|
-
}
|
|
118
124
|
try {
|
|
119
125
|
const prefix = shouldReinject ? "graphiti-refresh-" : "graphiti-memory-";
|
|
120
126
|
const useUserScope = shouldInjectOnFirst;
|
|
121
127
|
const characterBudget = (0, context_limit_js_1.calculateInjectionBudget)(state.contextLimit);
|
|
122
|
-
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget);
|
|
128
|
+
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject);
|
|
123
129
|
state.injectedMemories = true;
|
|
124
130
|
state.lastInjectionMessageCount = state.messageCount;
|
|
125
131
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
1
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
2
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type CompactingHook = NonNullable<Hooks["experimental.session.compacting"]>;
|
|
5
|
+
type CompactingInput = Parameters<CompactingHook>[0];
|
|
6
|
+
type CompactingOutput = Parameters<CompactingHook>[1];
|
|
3
7
|
/** Dependencies for the compacting handler. */
|
|
4
8
|
export interface CompactingHandlerDeps {
|
|
5
9
|
sessionManager: SessionManager;
|
|
@@ -7,9 +11,6 @@ export interface CompactingHandlerDeps {
|
|
|
7
11
|
defaultGroupId: string;
|
|
8
12
|
}
|
|
9
13
|
/** Creates the `experimental.session.compacting` hook handler. */
|
|
10
|
-
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }:
|
|
11
|
-
|
|
12
|
-
}, output: {
|
|
13
|
-
context: string[];
|
|
14
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }: CompactingInput, output: CompactingOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
15
16
|
//# sourceMappingURL=compacting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe
|
|
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;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;AAC5E,KAAK,eAAe,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,KAAK,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe,eAAe,EAC9B,QAAQ,gBAAgB,mBAyB3B"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { ProviderListClient } from "../services/context-limit.js";
|
|
4
4
|
import type { SessionManager } from "../session.js";
|
|
5
|
+
type EventHook = NonNullable<Hooks["event"]>;
|
|
6
|
+
type EventInput = Parameters<EventHook>[0];
|
|
5
7
|
/** Dependencies for the event handler. */
|
|
6
8
|
export interface EventHandlerDeps {
|
|
7
9
|
sessionManager: SessionManager;
|
|
@@ -12,7 +14,6 @@ export interface EventHandlerDeps {
|
|
|
12
14
|
groupIdPrefix: string;
|
|
13
15
|
}
|
|
14
16
|
/** Creates the `event` hook handler. */
|
|
15
|
-
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }:
|
|
16
|
-
|
|
17
|
-
}) => Promise<void>;
|
|
17
|
+
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }: EventInput) => Promise<void>;
|
|
18
|
+
export {};
|
|
18
19
|
//# sourceMappingURL=event.d.ts.map
|
|
@@ -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,
|
|
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,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,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,kBAAkB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAWzC,WAAW,UAAU,mBA+JpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/src/services/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/src/services/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,YAAY,EAEb,MAAM,mBAAmB,CAAC;AAG3B;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IAEzB;;OAEG;gBACS,QAAQ,EAAE,MAAM;IAS5B,oDAAoD;IACpD,OAAO,CAAC,wBAAwB;IAUhC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBjC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAOnB,QAAQ;IAkCtB,OAAO,CAAC,gBAAgB;YASV,SAAS;IAavB;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;IAyBzC;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjB;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAsB3B;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAsB3B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.GraphitiClient = void 0;
|
|
4
7
|
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
5
8
|
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
9
|
+
const deno_js_1 = __importDefault(require("../../deno.js"));
|
|
6
10
|
const logger_js_1 = require("./logger.js");
|
|
7
11
|
/**
|
|
8
12
|
* Graphiti MCP client wrapper for connecting, querying,
|
|
@@ -38,12 +42,18 @@ class GraphitiClient {
|
|
|
38
42
|
value: void 0
|
|
39
43
|
});
|
|
40
44
|
this.endpoint = endpoint;
|
|
41
|
-
this.client = new index_js_1.Client({
|
|
45
|
+
this.client = new index_js_1.Client({
|
|
46
|
+
name: deno_js_1.default.name,
|
|
47
|
+
version: deno_js_1.default.version,
|
|
48
|
+
});
|
|
42
49
|
this.transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(endpoint));
|
|
43
50
|
}
|
|
44
51
|
/** Create a fresh MCP Client and Transport pair. */
|
|
45
52
|
createClientAndTransport() {
|
|
46
|
-
this.client = new index_js_1.Client({
|
|
53
|
+
this.client = new index_js_1.Client({
|
|
54
|
+
name: deno_js_1.default.name,
|
|
55
|
+
version: deno_js_1.default.version,
|
|
56
|
+
});
|
|
47
57
|
this.transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(this.endpoint));
|
|
48
58
|
}
|
|
49
59
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgIpB"}
|
|
@@ -73,32 +73,40 @@ async function getCompactionContext(params) {
|
|
|
73
73
|
const buildSection = (header, facts, nodes) => {
|
|
74
74
|
const lines = [];
|
|
75
75
|
lines.push(header);
|
|
76
|
+
lines.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
76
77
|
if (facts.length > 0) {
|
|
77
|
-
lines.push("
|
|
78
|
+
lines.push("<facts>");
|
|
78
79
|
lines.push(...(0, context_js_1.formatFactLines)(facts));
|
|
80
|
+
lines.push("</facts>");
|
|
79
81
|
}
|
|
80
82
|
if (nodes.length > 0) {
|
|
81
|
-
lines.push("
|
|
83
|
+
lines.push("<nodes>");
|
|
82
84
|
lines.push(...(0, context_js_1.formatNodeLines)(nodes));
|
|
85
|
+
lines.push("</nodes>");
|
|
83
86
|
}
|
|
84
87
|
return lines.join("\n");
|
|
85
88
|
};
|
|
86
|
-
const projectSection = buildSection(
|
|
87
|
-
const userSection = buildSection(
|
|
89
|
+
const projectSection = buildSection('<memory source="project">', projectFacts, projectNodes);
|
|
90
|
+
const userSection = buildSection('<memory source="user">', userFacts, userNodes);
|
|
88
91
|
const headerLines = [
|
|
89
|
-
"
|
|
92
|
+
"<summary>",
|
|
93
|
+
"<current_goal>",
|
|
90
94
|
"- ",
|
|
95
|
+
"</current_goal>",
|
|
91
96
|
"",
|
|
92
|
-
"
|
|
97
|
+
"<work_completed>",
|
|
93
98
|
"- ",
|
|
99
|
+
"</work_completed>",
|
|
94
100
|
"",
|
|
95
|
-
"
|
|
101
|
+
"<remaining_tasks>",
|
|
96
102
|
"- ",
|
|
103
|
+
"</remaining_tasks>",
|
|
97
104
|
"",
|
|
98
|
-
"
|
|
105
|
+
"<constraints_decisions>",
|
|
99
106
|
"- ",
|
|
107
|
+
"</constraints_decisions>",
|
|
100
108
|
"",
|
|
101
|
-
"
|
|
109
|
+
"<persistent_memory>",
|
|
102
110
|
];
|
|
103
111
|
const header = headerLines.join("\n");
|
|
104
112
|
const base = `${header}\n`;
|
|
@@ -108,10 +116,16 @@ async function getCompactionContext(params) {
|
|
|
108
116
|
const truncatedProject = projectSection.slice(0, projectBudget);
|
|
109
117
|
const truncatedUser = userSection.slice(0, userBudget);
|
|
110
118
|
const sections = [header];
|
|
111
|
-
if (truncatedProject.trim())
|
|
119
|
+
if (truncatedProject.trim()) {
|
|
112
120
|
sections.push(truncatedProject);
|
|
113
|
-
|
|
121
|
+
sections.push("</memory>");
|
|
122
|
+
}
|
|
123
|
+
if (truncatedUser.trim()) {
|
|
114
124
|
sections.push(truncatedUser);
|
|
125
|
+
sections.push("</memory>");
|
|
126
|
+
}
|
|
127
|
+
sections.push("</persistent_memory>");
|
|
128
|
+
sections.push("</summary>");
|
|
115
129
|
const content = sections.join("\n").slice(0, characterBudget);
|
|
116
130
|
return [content];
|
|
117
131
|
}
|
|
@@ -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;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,
|
|
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;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,CA0BR"}
|
|
@@ -9,37 +9,35 @@ const formatFactLines = (facts) => facts.map((fact) => {
|
|
|
9
9
|
if (fact.target_node?.name)
|
|
10
10
|
entities.push(fact.target_node.name);
|
|
11
11
|
const entityStr = entities.length > 0 ? ` [${entities.join(" -> ")}]` : "";
|
|
12
|
-
return
|
|
12
|
+
return `<fact>${fact.fact}${entityStr}</fact>`;
|
|
13
13
|
});
|
|
14
14
|
exports.formatFactLines = formatFactLines;
|
|
15
15
|
const formatNodeLines = (nodes) => nodes.map((node) => {
|
|
16
16
|
const labels = node.labels?.length ? ` (${node.labels.join(", ")})` : "";
|
|
17
17
|
const summary = node.summary ? `: ${node.summary}` : "";
|
|
18
|
-
return
|
|
18
|
+
return `<node>${node.name}${labels}${summary}</node>`;
|
|
19
19
|
});
|
|
20
20
|
exports.formatNodeLines = formatNodeLines;
|
|
21
21
|
/**
|
|
22
22
|
* Format Graphiti facts and nodes into a user-facing context block.
|
|
23
23
|
*/
|
|
24
24
|
function formatMemoryContext(facts, nodes) {
|
|
25
|
+
if (facts.length === 0 && nodes.length === 0) {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
25
28
|
const sections = [];
|
|
26
|
-
sections.push("
|
|
27
|
-
sections.push("");
|
|
28
|
-
sections.push("The following information was retrieved from your persistent memory.");
|
|
29
|
-
sections.push("Use this context to inform your responses, but do not mention it unless asked.");
|
|
30
|
-
sections.push("");
|
|
29
|
+
sections.push("<memory>");
|
|
30
|
+
sections.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
31
31
|
if (facts.length > 0) {
|
|
32
|
-
sections.push("
|
|
32
|
+
sections.push("<facts>");
|
|
33
33
|
sections.push(...(0, exports.formatFactLines)(facts));
|
|
34
|
-
sections.push("");
|
|
34
|
+
sections.push("</facts>");
|
|
35
35
|
}
|
|
36
36
|
if (nodes.length > 0) {
|
|
37
|
-
sections.push("
|
|
37
|
+
sections.push("<nodes>");
|
|
38
38
|
sections.push(...(0, exports.formatNodeLines)(nodes));
|
|
39
|
-
sections.push("");
|
|
40
|
-
}
|
|
41
|
-
if (facts.length === 0 && nodes.length === 0) {
|
|
42
|
-
return "";
|
|
39
|
+
sections.push("</nodes>");
|
|
43
40
|
}
|
|
41
|
+
sections.push("</memory>");
|
|
44
42
|
return sections.join("\n");
|
|
45
43
|
}
|