@gralkor/openclaw 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.env.example +32 -0
  2. package/README.md +77 -0
  3. package/config.yaml +16 -0
  4. package/dist/config.d.ts +33 -0
  5. package/dist/config.d.ts.map +1 -0
  6. package/dist/config.js +49 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/ctx-to-messages.d.ts +36 -0
  9. package/dist/ctx-to-messages.d.ts.map +1 -0
  10. package/dist/ctx-to-messages.js +120 -0
  11. package/dist/ctx-to-messages.js.map +1 -0
  12. package/dist/ctx-to-turn.d.ts +32 -0
  13. package/dist/ctx-to-turn.d.ts.map +1 -0
  14. package/dist/ctx-to-turn.js +55 -0
  15. package/dist/ctx-to-turn.js.map +1 -0
  16. package/dist/gralkor/client/http.d.ts +55 -0
  17. package/dist/gralkor/client/http.d.ts.map +1 -0
  18. package/dist/gralkor/client/http.js +150 -0
  19. package/dist/gralkor/client/http.js.map +1 -0
  20. package/dist/gralkor/client/in-memory.d.ts +38 -0
  21. package/dist/gralkor/client/in-memory.d.ts.map +1 -0
  22. package/dist/gralkor/client/in-memory.js +72 -0
  23. package/dist/gralkor/client/in-memory.js.map +1 -0
  24. package/dist/gralkor/client.d.ts +64 -0
  25. package/dist/gralkor/client.d.ts.map +1 -0
  26. package/dist/gralkor/client.js +32 -0
  27. package/dist/gralkor/client.js.map +1 -0
  28. package/dist/gralkor/config.d.ts +33 -0
  29. package/dist/gralkor/config.d.ts.map +1 -0
  30. package/dist/gralkor/config.js +58 -0
  31. package/dist/gralkor/config.js.map +1 -0
  32. package/dist/gralkor/connection.d.ts +20 -0
  33. package/dist/gralkor/connection.d.ts.map +1 -0
  34. package/dist/gralkor/connection.js +31 -0
  35. package/dist/gralkor/connection.js.map +1 -0
  36. package/dist/gralkor/index.d.ts +11 -0
  37. package/dist/gralkor/index.d.ts.map +1 -0
  38. package/dist/gralkor/index.js +6 -0
  39. package/dist/gralkor/index.js.map +1 -0
  40. package/dist/gralkor/server-env.d.ts +11 -0
  41. package/dist/gralkor/server-env.d.ts.map +1 -0
  42. package/dist/gralkor/server-env.js +26 -0
  43. package/dist/gralkor/server-env.js.map +1 -0
  44. package/dist/gralkor/server-manager.d.ts +58 -0
  45. package/dist/gralkor/server-manager.d.ts.map +1 -0
  46. package/dist/gralkor/server-manager.js +390 -0
  47. package/dist/gralkor/server-manager.js.map +1 -0
  48. package/dist/gralkor/testing.d.ts +10 -0
  49. package/dist/gralkor/testing.d.ts.map +1 -0
  50. package/dist/gralkor/testing.js +10 -0
  51. package/dist/gralkor/testing.js.map +1 -0
  52. package/dist/hooks/agent-end.d.ts +25 -0
  53. package/dist/hooks/agent-end.d.ts.map +1 -0
  54. package/dist/hooks/agent-end.js +51 -0
  55. package/dist/hooks/agent-end.js.map +1 -0
  56. package/dist/hooks/before-prompt-build.d.ts +12 -0
  57. package/dist/hooks/before-prompt-build.d.ts.map +1 -0
  58. package/dist/hooks/before-prompt-build.js +15 -0
  59. package/dist/hooks/before-prompt-build.js.map +1 -0
  60. package/dist/hooks/session-end.d.ts +18 -0
  61. package/dist/hooks/session-end.d.ts.map +1 -0
  62. package/dist/hooks/session-end.js +19 -0
  63. package/dist/hooks/session-end.js.map +1 -0
  64. package/dist/index.d.ts +130 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +133 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/native-indexer.d.ts +43 -0
  69. package/dist/native-indexer.d.ts.map +1 -0
  70. package/dist/native-indexer.js +107 -0
  71. package/dist/native-indexer.js.map +1 -0
  72. package/dist/register.d.ts +25 -0
  73. package/dist/register.d.ts.map +1 -0
  74. package/dist/register.js +184 -0
  75. package/dist/register.js.map +1 -0
  76. package/dist/session-map.d.ts +13 -0
  77. package/dist/session-map.d.ts.map +1 -0
  78. package/dist/session-map.js +32 -0
  79. package/dist/session-map.js.map +1 -0
  80. package/dist/tools/memory-add.d.ts +15 -0
  81. package/dist/tools/memory-add.d.ts.map +1 -0
  82. package/dist/tools/memory-add.js +15 -0
  83. package/dist/tools/memory-add.js.map +1 -0
  84. package/dist/tools/memory-build-communities.d.ts +19 -0
  85. package/dist/tools/memory-build-communities.d.ts.map +1 -0
  86. package/dist/tools/memory-build-communities.js +18 -0
  87. package/dist/tools/memory-build-communities.js.map +1 -0
  88. package/dist/tools/memory-build-indices.d.ts +12 -0
  89. package/dist/tools/memory-build-indices.d.ts.map +1 -0
  90. package/dist/tools/memory-build-indices.js +11 -0
  91. package/dist/tools/memory-build-indices.js.map +1 -0
  92. package/dist/tools/memory-search.d.ts +20 -0
  93. package/dist/tools/memory-search.d.ts.map +1 -0
  94. package/dist/tools/memory-search.js +18 -0
  95. package/dist/tools/memory-search.js.map +1 -0
  96. package/dist/types.d.ts +62 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +8 -0
  99. package/dist/types.js.map +1 -0
  100. package/openclaw.plugin.json +130 -0
  101. package/package.json +75 -0
  102. package/server/server/.python-version +1 -0
  103. package/server/server/main.py +902 -0
  104. package/server/server/pipelines/__init__.py +0 -0
  105. package/server/server/pipelines/capture_buffer.py +170 -0
  106. package/server/server/pipelines/distill.py +122 -0
  107. package/server/server/pipelines/formatting.py +48 -0
  108. package/server/server/pipelines/interpret.py +165 -0
  109. package/server/server/pipelines/messages.py +13 -0
  110. package/server/server/pyproject.toml +19 -0
  111. package/server/server/pytest.ini +4 -0
  112. package/server/server/requirements-dev.txt +3 -0
  113. package/server/server/requirements.txt +5 -0
  114. package/server/server/uv.lock +1162 -0
  115. package/server/wheels/falkordblite-0.9.0-py3-none-manylinux_2_36_aarch64.whl +0 -0
@@ -0,0 +1,184 @@
1
+ import { GralkorHttpClient, createServerManager, sanitizeGroupId, waitForHealth, GRALKOR_URL, } from "./gralkor/index.js";
2
+ import { buildSecretEnv } from "./config.js";
3
+ import { runMemorySearch } from "./tools/memory-search.js";
4
+ import { runMemoryAdd } from "./tools/memory-add.js";
5
+ import { runMemoryBuildIndices } from "./tools/memory-build-indices.js";
6
+ import { runMemoryBuildCommunities } from "./tools/memory-build-communities.js";
7
+ import { runBeforePromptBuild } from "./hooks/before-prompt-build.js";
8
+ import { runAgentEnd } from "./hooks/agent-end.js";
9
+ import { runSessionEnd } from "./hooks/session-end.js";
10
+ import { runNativeIndexer } from "./native-indexer.js";
11
+ import { requireSessionKey } from "./session-map.js";
12
+ export function registerTools(api, client, config) {
13
+ api.registerTool((ctx) => {
14
+ const rawSessionKey = ctx?.sessionKey;
15
+ return [
16
+ {
17
+ name: "memory_search",
18
+ description: "Search long-term memory for relevant context. Use specific, focused queries.",
19
+ parameters: {
20
+ type: "object",
21
+ properties: {
22
+ query: { type: "string", description: "The search query" },
23
+ },
24
+ required: ["query"],
25
+ },
26
+ execute: async (_toolCallId, args) => {
27
+ const r = await runMemorySearch(client, {
28
+ query: args.query,
29
+ sessionKey: requireSessionKey(rawSessionKey),
30
+ agentName: config.agentName,
31
+ maxResults: config.search.maxResults,
32
+ });
33
+ if ("error" in r)
34
+ throw new Error(JSON.stringify(r.error));
35
+ return r.ok;
36
+ },
37
+ },
38
+ {
39
+ name: "memory_add",
40
+ description: "Store a thought, insight, reflection, or decision in long-term memory.",
41
+ parameters: {
42
+ type: "object",
43
+ properties: {
44
+ content: { type: "string" },
45
+ source_description: { type: "string" },
46
+ },
47
+ required: ["content"],
48
+ },
49
+ execute: async (_toolCallId, args) => {
50
+ const r = await runMemoryAdd(client, {
51
+ sessionKey: requireSessionKey(rawSessionKey),
52
+ content: args.content,
53
+ sourceDescription: args.source_description,
54
+ });
55
+ if ("error" in r)
56
+ throw new Error(JSON.stringify(r.error));
57
+ return "Queued for storage.";
58
+ },
59
+ },
60
+ {
61
+ name: "memory_build_indices",
62
+ description: "ADMIN — DO NOT CALL unless the user has explicitly asked you to rebuild Gralkor's graph search indices. This is an operator-maintenance action; calling it unprompted wastes time without improving anything the user will notice. Idempotent rebuild of the graph search indices.",
63
+ parameters: { type: "object", properties: {} },
64
+ execute: async () => {
65
+ const r = await runMemoryBuildIndices(client);
66
+ if ("error" in r)
67
+ throw new Error(JSON.stringify(r.error));
68
+ return `Indices rebuilt (${r.ok.status}).`;
69
+ },
70
+ },
71
+ {
72
+ name: "memory_build_communities",
73
+ description: "ADMIN — DO NOT CALL unless the user has explicitly asked you to build Gralkor communities. This is an expensive operator-maintenance action; calling it unprompted wastes time. Runs Graphiti community detection over this agent's memory partition.",
74
+ parameters: { type: "object", properties: {} },
75
+ execute: async () => {
76
+ const r = await runMemoryBuildCommunities(client, {
77
+ sessionKey: requireSessionKey(rawSessionKey),
78
+ });
79
+ if ("error" in r)
80
+ throw new Error(JSON.stringify(r.error));
81
+ return `Built ${r.ok.communities} communities across ${r.ok.edges} edges.`;
82
+ },
83
+ },
84
+ ];
85
+ });
86
+ }
87
+ export function registerHooks(api, client, config) {
88
+ api.on("before_prompt_build", async (event, ctx) => {
89
+ const sessionKey = requireSessionKey(ctx.sessionKey);
90
+ const agentId = ctx.agentId ?? sessionKey;
91
+ const workspaceDir = ctx.workspaceDir ?? config.workspaceDir;
92
+ if (workspaceDir) {
93
+ void runNativeIndexer(client, workspaceDir, sanitizeGroupId(agentId)).catch((err) => {
94
+ console.error("[gralkor] native-index error:", err);
95
+ });
96
+ }
97
+ const result = await runBeforePromptBuild(client, {
98
+ sessionKey,
99
+ agentId,
100
+ agentName: config.agentName,
101
+ prompt: event.prompt ?? "",
102
+ });
103
+ if ("error" in result)
104
+ throw new Error(JSON.stringify(result.error));
105
+ return result.ok;
106
+ });
107
+ api.on("agent_end", async (event, ctx) => {
108
+ const sessionKey = requireSessionKey(ctx.sessionKey);
109
+ const result = await runAgentEnd(client, {
110
+ sessionKey,
111
+ agentName: config.agentName,
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ messages: (event.messages ?? []),
114
+ });
115
+ if ("error" in result)
116
+ throw new Error(JSON.stringify(result.error));
117
+ });
118
+ api.on("session_end", async (_event, ctx) => {
119
+ const sessionKey = requireSessionKey(ctx.sessionKey);
120
+ const result = await runSessionEnd(client, { sessionKey });
121
+ if ("error" in result)
122
+ throw new Error(JSON.stringify(result.error));
123
+ });
124
+ }
125
+ let cachedManager = null;
126
+ export function resetServerManagerForTests() {
127
+ cachedManager = null;
128
+ }
129
+ const MEMORY_TOOL_PROMPT_LINES = [
130
+ "Memory is stored in a Graphiti knowledge graph backed by FalkorDB.",
131
+ "Use `memory_search` to recall prior facts before answering questions about past decisions, dates, people, preferences, or todos.",
132
+ "Use `memory_add` to store new insights, reflections, or durable decisions you want available in future sessions.",
133
+ ];
134
+ /**
135
+ * Declares this plugin as the active memory capability for OpenClaw 2026.5.x+.
136
+ * Once registered, `openclaw plugins info` reports `Shape: memory capability`
137
+ * and OpenClaw routes the `plugins.slots.memory` slot through this plugin.
138
+ *
139
+ * The capability is intentionally minimal — capture/recall is hook+tool-driven
140
+ * (see registerHooks / registerTools). The promptBuilder only contributes the
141
+ * static usage hints that the agent reads alongside the tool definitions, and
142
+ * flushPlanResolver opts out of OpenClaw's compaction-flush turn (we capture
143
+ * per agent_end, so a follow-up flush turn would duplicate the work).
144
+ */
145
+ export function registerMemoryCapability(api) {
146
+ if (typeof api.registerMemoryCapability !== "function")
147
+ return;
148
+ api.registerMemoryCapability({
149
+ promptBuilder: () => MEMORY_TOOL_PROMPT_LINES,
150
+ flushPlanResolver: () => null,
151
+ });
152
+ }
153
+ export function registerServerService(api, config, version, wheelRepo) {
154
+ if (!config.dataDir) {
155
+ throw new Error("[gralkor] dataDir is required — set plugins.entries.openclaw-gralkor.config.dataDir");
156
+ }
157
+ // OpenClaw 2026.5.x hot-reloads the plugin module on every agent run; the
158
+ // hook/tool/service bindings must happen on each load (the new registry is
159
+ // empty), but the underlying Python uvicorn process must be a singleton
160
+ // for the process lifetime. Module-level slot achieves that — the slot
161
+ // clears when the module is re-imported in a new process, never within one.
162
+ const manager = (cachedManager ??= createServerManager({
163
+ dataDir: config.dataDir,
164
+ port: 4000,
165
+ version,
166
+ wheelRepo,
167
+ secretEnv: buildSecretEnv(config),
168
+ llmConfig: config.llm,
169
+ embedderConfig: config.embedder,
170
+ ontologyConfig: config.ontology,
171
+ test: config.test,
172
+ }));
173
+ api.registerService({
174
+ id: "gralkor-server",
175
+ start: async () => {
176
+ await manager.start();
177
+ const client = new GralkorHttpClient({ baseUrl: GRALKOR_URL });
178
+ await waitForHealth(client, { timeoutMs: 120_000, backoffMs: 500 });
179
+ },
180
+ stop: () => manager.stop(),
181
+ });
182
+ return manager;
183
+ }
184
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare function setSessionGroup(sessionKey: string, agentId: string): void;
2
+ export declare function getSessionGroup(sessionKey: string): string | null;
3
+ /**
4
+ * Gralkor requires a non-blank session_id at every boundary. Call this
5
+ * at the top of each hook and inside each tool's execute — there is no
6
+ * "default" bucket and no silent fallback. If OpenClaw dispatches an
7
+ * event without a sessionKey, that's a bug in the caller's lifecycle,
8
+ * not something this plugin masks.
9
+ */
10
+ export declare function requireSessionKey(sessionKey: string | undefined | null): string;
11
+ /** Reset module-level state. Test-only. */
12
+ export declare function resetSessionMap(): void;
13
+ //# sourceMappingURL=session-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-map.d.ts","sourceRoot":"","sources":["../src/session-map.ts"],"names":[],"mappings":"AAUA,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAO/E;AAED,2CAA2C;AAC3C,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,32 @@
1
+ import { sanitizeGroupId } from "./gralkor/index.js";
2
+ /**
3
+ * Module-level session → group map. Shared across all plugin instances
4
+ * in the process — OpenClaw reloads plugins multiple times per event,
5
+ * and a per-instance map would lose state on each reload. Module scope
6
+ * survives reloads within the same Node process.
7
+ */
8
+ const sessionGroups = new Map();
9
+ export function setSessionGroup(sessionKey, agentId) {
10
+ sessionGroups.set(sessionKey, sanitizeGroupId(agentId));
11
+ }
12
+ export function getSessionGroup(sessionKey) {
13
+ return sessionGroups.get(sessionKey) ?? null;
14
+ }
15
+ /**
16
+ * Gralkor requires a non-blank session_id at every boundary. Call this
17
+ * at the top of each hook and inside each tool's execute — there is no
18
+ * "default" bucket and no silent fallback. If OpenClaw dispatches an
19
+ * event without a sessionKey, that's a bug in the caller's lifecycle,
20
+ * not something this plugin masks.
21
+ */
22
+ export function requireSessionKey(sessionKey) {
23
+ if (typeof sessionKey !== "string" || sessionKey.length === 0) {
24
+ throw new Error("Gralkor requires a non-blank session_id; OpenClaw did not provide a sessionKey");
25
+ }
26
+ return sessionKey;
27
+ }
28
+ /** Reset module-level state. Test-only. */
29
+ export function resetSessionMap() {
30
+ sessionGroups.clear();
31
+ }
32
+ //# sourceMappingURL=session-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-map.js","sourceRoot":"","sources":["../src/session-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEhD,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,OAAe;IACjE,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,OAAO,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAqC;IACrE,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,eAAe;IAC7B,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { GralkorClient, Result } from "../gralkor/index.js";
2
+ export interface MemoryAddArgs {
3
+ sessionKey: string;
4
+ content: string;
5
+ sourceDescription?: string;
6
+ }
7
+ /**
8
+ * The `memory_add` ReAct tool. Thin wrapper around
9
+ * `GralkorClient.memoryAdd`. The server queues the add for async ingest
10
+ * (Graphiti entity/edge extraction is slow) so the client side returns
11
+ * as soon as the HTTP 2xx comes back; that's what `{ ok: true }` means
12
+ * here.
13
+ */
14
+ export declare function runMemoryAdd(client: GralkorClient, args: MemoryAddArgs): Promise<Result<true>>;
15
+ //# sourceMappingURL=memory-add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-add.d.ts","sourceRoot":"","sources":["../../src/tools/memory-add.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGjE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAKvB"}
@@ -0,0 +1,15 @@
1
+ import { getSessionGroup } from "../session-map.js";
2
+ /**
3
+ * The `memory_add` ReAct tool. Thin wrapper around
4
+ * `GralkorClient.memoryAdd`. The server queues the add for async ingest
5
+ * (Graphiti entity/edge extraction is slow) so the client side returns
6
+ * as soon as the HTTP 2xx comes back; that's what `{ ok: true }` means
7
+ * here.
8
+ */
9
+ export async function runMemoryAdd(client, args) {
10
+ const groupId = getSessionGroup(args.sessionKey);
11
+ if (groupId === null)
12
+ return { error: "session_not_registered" };
13
+ return client.memoryAdd(groupId, args.content, args.sourceDescription ?? null);
14
+ }
15
+ //# sourceMappingURL=memory-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-add.js","sourceRoot":"","sources":["../../src/tools/memory-add.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQpD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAqB,EACrB,IAAmB;IAEnB,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAEjE,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,CAAC;AACjF,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { GralkorClient, Result } from "../gralkor/index.js";
2
+ export interface MemoryBuildCommunitiesArgs {
3
+ sessionKey: string;
4
+ }
5
+ /**
6
+ * The `memory_build_communities` admin tool. Thin wrapper around
7
+ * `GralkorClient.buildCommunities`. Runs Graphiti's community detection
8
+ * over the session's group partition — expensive-ish but improves search
9
+ * quality by clustering related entities.
10
+ *
11
+ * Per-group rather than whole-graph, so the session must be registered
12
+ * (via `before_prompt_build`) before this can fire. Returns
13
+ * `session_not_registered` rather than silently routing to `"default"`.
14
+ */
15
+ export declare function runMemoryBuildCommunities(client: GralkorClient, args: MemoryBuildCommunitiesArgs): Promise<Result<{
16
+ communities: number;
17
+ edges: number;
18
+ }>>;
19
+ //# sourceMappingURL=memory-build-communities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-build-communities.d.ts","sourceRoot":"","sources":["../../src/tools/memory-build-communities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGjE,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,MAAM,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAKzD"}
@@ -0,0 +1,18 @@
1
+ import { getSessionGroup } from "../session-map.js";
2
+ /**
3
+ * The `memory_build_communities` admin tool. Thin wrapper around
4
+ * `GralkorClient.buildCommunities`. Runs Graphiti's community detection
5
+ * over the session's group partition — expensive-ish but improves search
6
+ * quality by clustering related entities.
7
+ *
8
+ * Per-group rather than whole-graph, so the session must be registered
9
+ * (via `before_prompt_build`) before this can fire. Returns
10
+ * `session_not_registered` rather than silently routing to `"default"`.
11
+ */
12
+ export async function runMemoryBuildCommunities(client, args) {
13
+ const groupId = getSessionGroup(args.sessionKey);
14
+ if (groupId === null)
15
+ return { error: "session_not_registered" };
16
+ return client.buildCommunities(groupId);
17
+ }
18
+ //# sourceMappingURL=memory-build-communities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-build-communities.js","sourceRoot":"","sources":["../../src/tools/memory-build-communities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMpD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,MAAqB,EACrB,IAAgC;IAEhC,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAEjE,OAAO,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { GralkorClient, Result } from "../gralkor/index.js";
2
+ /**
3
+ * The `memory_build_indices` admin tool. Thin wrapper around
4
+ * `GralkorClient.buildIndices`. Rebuilds the Graphiti search indices —
5
+ * idempotent, safe to run any time, but only useful after schema changes
6
+ * or when search behaviour looks stale. Operates across the whole graph
7
+ * (not per-group).
8
+ */
9
+ export declare function runMemoryBuildIndices(client: GralkorClient): Promise<Result<{
10
+ status: string;
11
+ }>>;
12
+ //# sourceMappingURL=memory-build-indices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-build-indices.d.ts","sourceRoot":"","sources":["../../src/tools/memory-build-indices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAErC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The `memory_build_indices` admin tool. Thin wrapper around
3
+ * `GralkorClient.buildIndices`. Rebuilds the Graphiti search indices —
4
+ * idempotent, safe to run any time, but only useful after schema changes
5
+ * or when search behaviour looks stale. Operates across the whole graph
6
+ * (not per-group).
7
+ */
8
+ export async function runMemoryBuildIndices(client) {
9
+ return client.buildIndices();
10
+ }
11
+ //# sourceMappingURL=memory-build-indices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-build-indices.js","sourceRoot":"","sources":["../../src/tools/memory-build-indices.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAqB;IAErB,OAAO,MAAM,CAAC,YAAY,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { GralkorClient, Result } from "../gralkor/index.js";
2
+ export interface MemorySearchArgs {
3
+ query: string;
4
+ sessionKey: string;
5
+ agentName: string;
6
+ /** Max facts to interpret. Forwarded as max_results. Omit to use the server default. */
7
+ maxResults?: number;
8
+ }
9
+ /**
10
+ * The `memory_search` ReAct tool. Calls `GralkorClient.recall` — the
11
+ * same path the `before_prompt_build` hook uses for auto-recall. There
12
+ * is no separate manual-search endpoint.
13
+ *
14
+ * Returns the recalled memory block (the server always wraps a block;
15
+ * "no facts" and "no relevant facts" both collapse to a
16
+ * `"No relevant memories found."` body inside the same envelope), and
17
+ * surfaces session-map / client errors otherwise.
18
+ */
19
+ export declare function runMemorySearch(client: GralkorClient, args: MemorySearchArgs): Promise<Result<string>>;
20
+ //# sourceMappingURL=memory-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-search.d.ts","sourceRoot":"","sources":["../../src/tools/memory-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGjE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAWzB"}
@@ -0,0 +1,18 @@
1
+ import { getSessionGroup } from "../session-map.js";
2
+ /**
3
+ * The `memory_search` ReAct tool. Calls `GralkorClient.recall` — the
4
+ * same path the `before_prompt_build` hook uses for auto-recall. There
5
+ * is no separate manual-search endpoint.
6
+ *
7
+ * Returns the recalled memory block (the server always wraps a block;
8
+ * "no facts" and "no relevant facts" both collapse to a
9
+ * `"No relevant memories found."` body inside the same envelope), and
10
+ * surfaces session-map / client errors otherwise.
11
+ */
12
+ export async function runMemorySearch(client, args) {
13
+ const groupId = getSessionGroup(args.sessionKey);
14
+ if (groupId === null)
15
+ return { error: "session_not_registered" };
16
+ return client.recall(groupId, args.sessionKey, args.query, args.agentName, args.maxResults);
17
+ }
18
+ //# sourceMappingURL=memory-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-search.js","sourceRoot":"","sources":["../../src/tools/memory-search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAUpD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAqB,EACrB,IAAsB;IAEtB,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAEjE,OAAO,MAAM,CAAC,MAAM,CAClB,OAAO,EACP,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,UAAU,CAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * OpenClaw plugin API surface used by this plugin.
3
+ *
4
+ * OpenClaw doesn't export types, so we define the subset we use here.
5
+ * Keep in sync with the OpenClaw plugin contract.
6
+ */
7
+ type AnyFn = (...args: any[]) => any;
8
+ export type RegistrationMode = "full" | "setup-only" | "setup-runtime" | "cli-metadata";
9
+ export interface MemoryPluginApi {
10
+ pluginConfig?: Record<string, unknown>;
11
+ registrationMode?: RegistrationMode;
12
+ on(event: string, handler: AnyFn): void;
13
+ registerService(service: {
14
+ id: string;
15
+ start: () => void | Promise<void>;
16
+ stop: () => void | Promise<void>;
17
+ }): void;
18
+ registerCli(registrar: (ctx: {
19
+ program: any;
20
+ config: any;
21
+ workspaceDir?: string;
22
+ logger: any;
23
+ }) => void | Promise<void>, opts?: {
24
+ commands?: string[];
25
+ }): void;
26
+ registerTool(tool: {
27
+ name: string;
28
+ description: string;
29
+ parameters: unknown;
30
+ execute: AnyFn;
31
+ }, opts?: {
32
+ optional?: boolean;
33
+ }): void;
34
+ registerTool(factory: (ctx: any) => any | any[] | null, opts?: {
35
+ names?: string[];
36
+ }): void;
37
+ /**
38
+ * Declare this plugin as the active memory capability. OpenClaw 2026.5.x
39
+ * routes the `plugins.slots.memory` slot owner through this surface — once
40
+ * called, `openclaw plugins info` reports `Shape: memory capability`. All
41
+ * fields are optional; an empty object is enough for slot ownership.
42
+ *
43
+ * `promptBuilder` is invoked synchronously during system-prompt assembly
44
+ * with `{ availableTools, citationsMode }` and returns static lines (no
45
+ * session/query context — recall is agent-driven via `memory_search`).
46
+ * `flushPlanResolver` is invoked synchronously at compaction time; return
47
+ * `null` to opt out of OpenClaw's compaction-flush turn (we capture per
48
+ * agent_end hook, so the flush turn would be redundant).
49
+ */
50
+ registerMemoryCapability?(capability: {
51
+ promptBuilder?: (params: {
52
+ availableTools?: readonly string[];
53
+ citationsMode?: string;
54
+ }) => readonly string[];
55
+ flushPlanResolver?: (params: {
56
+ cfg?: unknown;
57
+ nowMs?: number;
58
+ }) => Record<string, unknown> | null;
59
+ }): void;
60
+ }
61
+ export {};
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,KAAK,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AAErC,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,YAAY,GAAG,eAAe,GAAG,cAAc,CAAC;AAExF,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC;IACxC,eAAe,CAAC,OAAO,EAAE;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAClC,GAAG,IAAI,CAAC;IACT,WAAW,CACT,SAAS,EAAE,CAAC,GAAG,EAAE;QAEf,OAAO,EAAE,GAAG,CAAC;QAEb,MAAM,EAAE,GAAG,CAAC;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;QAEtB,MAAM,EAAE,GAAG,CAAC;KACb,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC1B,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC7B,IAAI,CAAC;IACR,YAAY,CACV,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,KAAK,CAAA;KAAE,EAChF,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAC5B,IAAI,CAAC;IACR,YAAY,CAEV,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,EACzC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC1B,IAAI,CAAC;IACR;;;;;;;;;;;;OAYG;IACH,wBAAwB,CAAC,CAAC,UAAU,EAAE;QACpC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;YACvB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YACnC,aAAa,CAAC,EAAE,MAAM,CAAC;SACxB,KAAK,SAAS,MAAM,EAAE,CAAC;QACxB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE;YAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;YACd,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;KACtC,GAAG,IAAI,CAAC;CACV"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * OpenClaw plugin API surface used by this plugin.
3
+ *
4
+ * OpenClaw doesn't export types, so we define the subset we use here.
5
+ * Keep in sync with the OpenClaw plugin contract.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,130 @@
1
+ {
2
+ "id": "@gralkor/openclaw",
3
+ "kind": "memory",
4
+ "name": "Gralkor Memory (OpenClaw)",
5
+ "description": "Persistent, temporally-aware memory via Graphiti knowledge graphs and FalkorDB",
6
+ "configSchema": {
7
+ "type": "object",
8
+ "required": [
9
+ "agentName"
10
+ ],
11
+ "properties": {
12
+ "agentName": {
13
+ "type": "string",
14
+ "minLength": 1,
15
+ "description": "Display name for this agent. Used to label its turns in stored and recalled memory."
16
+ },
17
+ "search": {
18
+ "type": "object",
19
+ "properties": {
20
+ "maxResults": {
21
+ "type": "number",
22
+ "default": 20,
23
+ "description": "Maximum number of facts returned by the memory_search tool"
24
+ }
25
+ }
26
+ },
27
+ "llm": {
28
+ "type": "object",
29
+ "properties": {
30
+ "provider": {
31
+ "type": "string",
32
+ "description": "LLM provider for knowledge extraction (openai, anthropic, gemini, groq)"
33
+ },
34
+ "model": {
35
+ "type": "string",
36
+ "description": "LLM model name (e.g. gpt-4.1-mini, gemini-2.0-flash)"
37
+ }
38
+ }
39
+ },
40
+ "embedder": {
41
+ "type": "object",
42
+ "properties": {
43
+ "provider": {
44
+ "type": "string",
45
+ "description": "Embedding provider (openai, gemini)"
46
+ },
47
+ "model": {
48
+ "type": "string",
49
+ "description": "Embedding model name (e.g. text-embedding-3-small)"
50
+ }
51
+ }
52
+ },
53
+ "test": {
54
+ "type": "boolean",
55
+ "default": false,
56
+ "description": "Enable test mode — logs full episode bodies and search results for debugging"
57
+ },
58
+ "googleApiKey": {
59
+ "type": [
60
+ "string",
61
+ "object",
62
+ "null"
63
+ ],
64
+ "description": "Google API key for Gemini LLM and embeddings"
65
+ },
66
+ "openaiApiKey": {
67
+ "type": [
68
+ "string",
69
+ "object",
70
+ "null"
71
+ ],
72
+ "description": "OpenAI API key; also needed for embeddings with Anthropic/Groq providers"
73
+ },
74
+ "anthropicApiKey": {
75
+ "type": [
76
+ "string",
77
+ "object",
78
+ "null"
79
+ ],
80
+ "description": "Anthropic API key for Claude-based LLM extraction"
81
+ },
82
+ "groqApiKey": {
83
+ "type": [
84
+ "string",
85
+ "object",
86
+ "null"
87
+ ],
88
+ "description": "Groq API key for Groq-hosted LLM extraction"
89
+ }
90
+ }
91
+ },
92
+ "contracts": {
93
+ "tools": [
94
+ "memory_search",
95
+ "memory_add",
96
+ "memory_build_indices",
97
+ "memory_build_communities"
98
+ ]
99
+ },
100
+ "uiHints": {
101
+ "llm.provider": {
102
+ "label": "LLM provider"
103
+ },
104
+ "llm.model": {
105
+ "label": "LLM model"
106
+ },
107
+ "embedder.provider": {
108
+ "label": "Embedding provider"
109
+ },
110
+ "embedder.model": {
111
+ "label": "Embedding model"
112
+ },
113
+ "test": {
114
+ "label": "Test mode (verbose logging)"
115
+ },
116
+ "googleApiKey": {
117
+ "label": "Google API key"
118
+ },
119
+ "openaiApiKey": {
120
+ "label": "OpenAI API key"
121
+ },
122
+ "anthropicApiKey": {
123
+ "label": "Anthropic API key"
124
+ },
125
+ "groqApiKey": {
126
+ "label": "Groq API key"
127
+ }
128
+ },
129
+ "version": "4.0.0"
130
+ }