@kalera/munin-openclaw 1.2.0 → 1.2.7
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/.turbo/turbo-build.log +1 -1
- package/SKILL.md +51 -39
- package/dist/index.d.ts +13 -2
- package/dist/index.js +57 -34
- package/package.json +3 -3
- package/src/index.ts +77 -47
package/.turbo/turbo-build.log
CHANGED
package/SKILL.md
CHANGED
|
@@ -1,71 +1,83 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "@kalera/munin-openclaw"
|
|
3
3
|
description: "Munin - The Free (or $1.6/mo) Persistent Memory for OpenClaw. Stop your agent from having Alzheimer's."
|
|
4
|
-
version: "1.0.
|
|
4
|
+
version: "1.0.2"
|
|
5
5
|
metadata:
|
|
6
6
|
clawdbot:
|
|
7
7
|
type: "plugin"
|
|
8
8
|
permissions:
|
|
9
|
-
env: ["MUNIN_BASE_URL", "MUNIN_API_KEY"]
|
|
9
|
+
env: ["MUNIN_BASE_URL", "MUNIN_API_KEY", "MUNIN_PROJECT", "MUNIN_ENCRYPTION_KEY"]
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# Munin: Reliable Memory for Your OpenClaw Agent
|
|
13
13
|
|
|
14
14
|
<CRITICAL-INSTRUCTION>
|
|
15
15
|
**HOW TO USE THIS SKILL**:
|
|
16
|
-
|
|
17
|
-
You MUST call them using your standard tool-calling interface (e.g. `callTool("munin_search_memories", {...})`).
|
|
16
|
+
All `munin_*` actions are registered as native tools (MCP).
|
|
17
|
+
You MUST call them using your standard tool-calling interface (e.g. `callTool("munin_search_memories", {...})`).
|
|
18
18
|
**DO NOT under any circumstances try to run them as shell commands or bash scripts.**
|
|
19
19
|
</CRITICAL-INSTRUCTION>
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
## Available Tools
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
| Tool | Purpose |
|
|
24
|
+
|------|---------|
|
|
25
|
+
| `munin_store_memory` | Store or update a memory |
|
|
26
|
+
| `munin_retrieve_memory` | Get memory by exact key |
|
|
27
|
+
| `munin_search_memories` | Semantic search |
|
|
28
|
+
| `munin_list_memories` | Paginated list of all memories |
|
|
29
|
+
| `munin_recent_memories` | Most recently updated memories |
|
|
30
|
+
| `munin_share_memory` | Share memories to other projects (Pro/Elite only) |
|
|
24
31
|
|
|
25
|
-
|
|
32
|
+
## Before Any Task
|
|
33
|
+
1. Call `munin_search_memories` with keywords relevant to the current task
|
|
34
|
+
2. Call `munin_retrieve_memory` for detailed context on promising matches
|
|
35
|
+
3. Present findings — DO NOT guess, verify from memory first
|
|
26
36
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
| **MCP Support** | Mixed | **Native / First-class** |
|
|
33
|
-
| **Zero-Knowledge E2EE** | Optional / Complex | **Built-in (Client-side)** |
|
|
34
|
-
| **Bullshit Factor** | High (Enterprise-synergy) | **Zero (Developer-first)** |
|
|
35
|
-
|
|
36
|
-
**That’s a 10x - 150x price gap.** We aren't building "Enterprise Synergy Platforms". We're building a notebook for your AI.
|
|
37
|
+
## After Completing a Task
|
|
38
|
+
Call `munin_store_memory` with:
|
|
39
|
+
- **title**: Concise summary (max 80 chars)
|
|
40
|
+
- **content**: Detailed description including file paths, line numbers, decisions
|
|
41
|
+
- **tags**: Relevant tags (e.g., `task`, `architecture`, `bug-fix`, `setup`, `decision`)
|
|
37
42
|
|
|
38
43
|
---
|
|
39
44
|
|
|
40
|
-
##
|
|
45
|
+
## E2EE & Hash Key
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
Data stays where you tell it to stay. All data is encrypted locally (if E2EE is enabled) and isolated by your Context Core. We are completely blind to your plaintext.
|
|
47
|
+
Every E2EE project uses a Hash Key — the password the user set in the WebUI.
|
|
44
48
|
|
|
45
|
-
**
|
|
46
|
-
Data is sent ONLY to your `MUNIN_BASE_URL`. We don't phone home. We don't sell your "memories" to train models.
|
|
49
|
+
**Setup:** Set `MUNIN_ENCRYPTION_KEY=<hash-key>` in your environment. The adapter automatically passes this key to all tool calls.
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
**Critical:**
|
|
52
|
+
- Wrong Hash Key → all reads/writes fail. Re-confirm with the user.
|
|
53
|
+
- NEVER log or share the Hash Key in plain text.
|
|
54
|
+
- NEVER hardcode the Hash Key in scripts.
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- You **MUST** include the embedding array in the `store` payload: `{ "content": "encrypted...", "embedding": [0.1, -0.02, ...], "encryptionMeta": {...} }`.
|
|
53
|
-
- Munin will use this vector for zero-knowledge semantic search. It will reject the request if the embedding is missing.
|
|
56
|
+
### E2EE + GraphRAG (Elite Tier)
|
|
57
|
+
`munin_store_memory` payload MUST include an `embedding` field (encrypted vector generated client-side). Server returns HTTP 400 if missing.
|
|
54
58
|
|
|
55
|
-
|
|
59
|
+
### Sharing Across Projects
|
|
60
|
+
Use `munin_share_memory({ memoryIds: [...], targetProjectIds: [...] })` (Pro/Elite only).
|
|
61
|
+
- Target project must share the same Hash Key to read encrypted content.
|
|
62
|
+
- If target has E2EE ON and key differs → shared memory is unreadable until the target's Hash Key is updated.
|
|
56
63
|
|
|
57
|
-
|
|
64
|
+
---
|
|
58
65
|
|
|
59
|
-
|
|
60
|
-
2. **Configure OpenClaw:** Once installed via `openclaw plugins install @kalera/munin-openclaw`, you can set your API key and Context Core ID directly via the OpenClaw CLI without manually editing any config files:
|
|
66
|
+
## Setup
|
|
61
67
|
|
|
68
|
+
1. **Install the plugin:**
|
|
62
69
|
```bash
|
|
63
|
-
openclaw
|
|
64
|
-
openclaw config set plugins.entries.munin-openclaw.config.projectId "your-context-core-id"
|
|
70
|
+
openclaw plugins install @kalera/munin-openclaw
|
|
65
71
|
```
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
2. **Get your key:** [munin.kalera.dev](https://munin.kalera.dev)
|
|
73
|
+
3. **Configure:**
|
|
74
|
+
```bash
|
|
75
|
+
openclaw config set plugins.entries.munin-openclaw.config.apiKey "your-api-key"
|
|
76
|
+
openclaw config set plugins.entries.munin-openclaw.config.projectId "your-project-id"
|
|
77
|
+
```
|
|
78
|
+
Or via env vars: `MUNIN_BASE_URL`, `MUNIN_API_KEY`, `MUNIN_PROJECT`
|
|
79
|
+
4. **E2EE:** Add `MUNIN_ENCRYPTION_KEY=<hash-key>` if the project has E2EE enabled.
|
|
80
|
+
5. **Restart OpenClaw** — the agent will now have access to all `munin_*` tools.
|
|
81
|
+
6. **Profit.**
|
|
69
82
|
|
|
70
|
-
|
|
71
|
-
*Built with ❤️ by Kalera for the OpenClaw Ecosystem.*
|
|
83
|
+
*Built with ❤️ by Kalera for the OpenClaw Ecosystem.*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
declare const _default: {
|
|
2
3
|
id: string;
|
|
3
4
|
name: string;
|
|
4
5
|
description: string;
|
|
5
6
|
kind: string;
|
|
6
|
-
configSchema:
|
|
7
|
-
|
|
7
|
+
configSchema: z.ZodObject<{
|
|
8
|
+
baseUrl: z.ZodDefault<z.ZodString>;
|
|
9
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
10
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
register(api: {
|
|
13
|
+
logger: {
|
|
14
|
+
warn: (msg: string) => void;
|
|
15
|
+
};
|
|
16
|
+
registerTool: (tool: Record<string, unknown>) => void;
|
|
17
|
+
pluginConfig?: Record<string, unknown>;
|
|
18
|
+
}): void;
|
|
8
19
|
};
|
|
9
20
|
export default _default;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MuninClient } from "@kalera/munin-sdk";
|
|
2
|
+
import { resolveProjectId } from "@kalera/munin-runtime";
|
|
2
3
|
import { Type } from "@sinclair/typebox";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
export default {
|
|
@@ -19,12 +20,21 @@ export default {
|
|
|
19
20
|
process.env.MUNIN_BASE_URL ||
|
|
20
21
|
"https://munin.kalera.dev";
|
|
21
22
|
const apiKey = api.pluginConfig?.apiKey || process.env.MUNIN_API_KEY;
|
|
22
|
-
const projectId = api.pluginConfig?.projectId ||
|
|
23
|
+
const projectId = api.pluginConfig?.projectId ||
|
|
24
|
+
process.env.MUNIN_PROJECT ||
|
|
25
|
+
resolveProjectId(); // walk-up fallback for .env files
|
|
26
|
+
const encryptionKey = process.env.MUNIN_ENCRYPTION_KEY;
|
|
23
27
|
if (!apiKey || !projectId) {
|
|
24
28
|
api.logger.warn("Munin apiKey or projectId is missing. Munin tools will not be registered.");
|
|
25
29
|
return;
|
|
26
30
|
}
|
|
27
31
|
const client = new MuninClient({ baseUrl, apiKey });
|
|
32
|
+
// Helper: inject encryptionKey if set (only for E2EE-compatible tools)
|
|
33
|
+
const enrichPayload = (payload) => encryptionKey ? { ...payload, encryptionKey } : payload;
|
|
34
|
+
const handleResult = (res) => ({
|
|
35
|
+
content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }],
|
|
36
|
+
details: res.data,
|
|
37
|
+
});
|
|
28
38
|
api.registerTool({
|
|
29
39
|
name: "munin_store_memory",
|
|
30
40
|
label: "Store Munin Memory",
|
|
@@ -36,16 +46,8 @@ export default {
|
|
|
36
46
|
title: Type.Optional(Type.String({ description: "Human-readable title." })),
|
|
37
47
|
}),
|
|
38
48
|
async execute(_toolCallId, payload) {
|
|
39
|
-
const res = await client.invoke(projectId, "store", payload);
|
|
40
|
-
return
|
|
41
|
-
content: [
|
|
42
|
-
{
|
|
43
|
-
type: "text",
|
|
44
|
-
text: JSON.stringify(res.data, null, 2),
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
details: res.data,
|
|
48
|
-
};
|
|
49
|
+
const res = await client.invoke(projectId, "store", enrichPayload(payload));
|
|
50
|
+
return handleResult(res);
|
|
49
51
|
},
|
|
50
52
|
});
|
|
51
53
|
api.registerTool({
|
|
@@ -53,22 +55,12 @@ export default {
|
|
|
53
55
|
label: "Retrieve Munin Memory",
|
|
54
56
|
description: "Retrieve a memory by its key from Munin.",
|
|
55
57
|
parameters: Type.Object({
|
|
56
|
-
key: Type.String({
|
|
57
|
-
description: "The unique identifier of the memory.",
|
|
58
|
-
}),
|
|
58
|
+
key: Type.String({ description: "The unique identifier of the memory." }),
|
|
59
59
|
}),
|
|
60
60
|
async execute(_toolCallId, params) {
|
|
61
61
|
const { key } = params;
|
|
62
|
-
const res = await client.invoke(projectId, "retrieve", { key });
|
|
63
|
-
return
|
|
64
|
-
content: [
|
|
65
|
-
{
|
|
66
|
-
type: "text",
|
|
67
|
-
text: JSON.stringify(res.data, null, 2),
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
details: res.data,
|
|
71
|
-
};
|
|
62
|
+
const res = await client.invoke(projectId, "retrieve", enrichPayload({ key }));
|
|
63
|
+
return handleResult(res);
|
|
72
64
|
},
|
|
73
65
|
});
|
|
74
66
|
api.registerTool({
|
|
@@ -80,16 +72,47 @@ export default {
|
|
|
80
72
|
}),
|
|
81
73
|
async execute(_toolCallId, params) {
|
|
82
74
|
const { query } = params;
|
|
83
|
-
const res = await client.invoke(projectId, "search", { query });
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
75
|
+
const res = await client.invoke(projectId, "search", enrichPayload({ query }));
|
|
76
|
+
return handleResult(res);
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
api.registerTool({
|
|
80
|
+
name: "munin_list_memories",
|
|
81
|
+
label: "List Munin Memories",
|
|
82
|
+
description: "List all memories with pagination support.",
|
|
83
|
+
parameters: Type.Object({
|
|
84
|
+
limit: Type.Optional(Type.Number({ description: "Max results (default: 10)." })),
|
|
85
|
+
offset: Type.Optional(Type.Number({ description: "Pagination offset (default: 0)." })),
|
|
86
|
+
}),
|
|
87
|
+
async execute(_toolCallId, params) {
|
|
88
|
+
const res = await client.invoke(projectId, "list", enrichPayload(params));
|
|
89
|
+
return handleResult(res);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
api.registerTool({
|
|
93
|
+
name: "munin_recent_memories",
|
|
94
|
+
label: "Recent Munin Memories",
|
|
95
|
+
description: "Get the most recently updated memories.",
|
|
96
|
+
parameters: Type.Object({
|
|
97
|
+
limit: Type.Optional(Type.Number({ description: "Max results (default: 10)." })),
|
|
98
|
+
}),
|
|
99
|
+
async execute(_toolCallId, params) {
|
|
100
|
+
const res = await client.invoke(projectId, "recent", enrichPayload(params));
|
|
101
|
+
return handleResult(res);
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
api.registerTool({
|
|
105
|
+
name: "munin_share_memory",
|
|
106
|
+
label: "Share Munin Memories",
|
|
107
|
+
description: "Share one or more memories to other projects. Requires Pro/Elite tier. Target project must share the same Hash Key for encrypted content.",
|
|
108
|
+
parameters: Type.Object({
|
|
109
|
+
memoryIds: Type.Array(Type.String(), { description: "Array of memory IDs to share." }),
|
|
110
|
+
targetProjectIds: Type.Array(Type.String(), { description: "Array of target project IDs." }),
|
|
111
|
+
}),
|
|
112
|
+
async execute(_toolCallId, params) {
|
|
113
|
+
const { memoryIds, targetProjectIds } = params;
|
|
114
|
+
const res = await client.invoke(projectId, "share", enrichPayload({ memoryIds, targetProjectIds }));
|
|
115
|
+
return handleResult(res);
|
|
93
116
|
},
|
|
94
117
|
});
|
|
95
118
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kalera/munin-openclaw",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"openclaw": {
|
|
6
6
|
"extensions": [
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@sinclair/typebox": "^0.34.49",
|
|
18
18
|
"zod": "^4.3.6",
|
|
19
|
-
"@kalera/munin-sdk": "1.2.
|
|
20
|
-
"@kalera/munin-runtime": "1.2.
|
|
19
|
+
"@kalera/munin-sdk": "1.2.6",
|
|
20
|
+
"@kalera/munin-runtime": "1.2.6"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"openclaw": "^2026.3.28",
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { MuninClient } from "@kalera/munin-sdk";
|
|
2
|
+
import { resolveProjectId } from "@kalera/munin-runtime";
|
|
3
|
+
import type { MuninAction } from "@kalera/munin-sdk";
|
|
2
4
|
import { Type } from "@sinclair/typebox";
|
|
3
5
|
import { z } from "zod";
|
|
4
6
|
|
|
@@ -14,16 +16,23 @@ export default {
|
|
|
14
16
|
.describe("The base URL for your Munin server."),
|
|
15
17
|
apiKey: z.string().optional().describe("Your API key for Munin."),
|
|
16
18
|
projectId: z.string().optional().describe("Your Context Core ID (e.g. proj_xxx)."),
|
|
17
|
-
})
|
|
18
|
-
register(api:
|
|
19
|
+
}),
|
|
20
|
+
register(api: {
|
|
21
|
+
logger: { warn: (msg: string) => void };
|
|
22
|
+
registerTool: (tool: Record<string, unknown>) => void;
|
|
23
|
+
pluginConfig?: Record<string, unknown>;
|
|
24
|
+
}) {
|
|
19
25
|
const baseUrl =
|
|
20
|
-
(api.pluginConfig?.baseUrl as string) ||
|
|
26
|
+
(api.pluginConfig?.baseUrl as string | undefined) ||
|
|
21
27
|
process.env.MUNIN_BASE_URL ||
|
|
22
28
|
"https://munin.kalera.dev";
|
|
23
29
|
const apiKey =
|
|
24
|
-
(api.pluginConfig?.apiKey as string) || process.env.MUNIN_API_KEY;
|
|
30
|
+
(api.pluginConfig?.apiKey as string | undefined) || process.env.MUNIN_API_KEY;
|
|
25
31
|
const projectId =
|
|
26
|
-
(api.pluginConfig?.projectId as string) ||
|
|
32
|
+
(api.pluginConfig?.projectId as string | undefined) ||
|
|
33
|
+
process.env.MUNIN_PROJECT ||
|
|
34
|
+
resolveProjectId(); // walk-up fallback for .env files
|
|
35
|
+
const encryptionKey = process.env.MUNIN_ENCRYPTION_KEY;
|
|
27
36
|
|
|
28
37
|
if (!apiKey || !projectId) {
|
|
29
38
|
api.logger.warn(
|
|
@@ -34,6 +43,15 @@ export default {
|
|
|
34
43
|
|
|
35
44
|
const client = new MuninClient({ baseUrl, apiKey });
|
|
36
45
|
|
|
46
|
+
// Helper: inject encryptionKey if set (only for E2EE-compatible tools)
|
|
47
|
+
const enrichPayload = (payload: Record<string, unknown>): Record<string, unknown> =>
|
|
48
|
+
encryptionKey ? { ...payload, encryptionKey } : payload;
|
|
49
|
+
|
|
50
|
+
const handleResult = (res: { data?: unknown }) => ({
|
|
51
|
+
content: [{ type: "text" as const, text: JSON.stringify(res.data, null, 2) }],
|
|
52
|
+
details: res.data,
|
|
53
|
+
});
|
|
54
|
+
|
|
37
55
|
api.registerTool({
|
|
38
56
|
name: "munin_store_memory",
|
|
39
57
|
label: "Store Munin Memory",
|
|
@@ -41,24 +59,12 @@ export default {
|
|
|
41
59
|
parameters: Type.Object({
|
|
42
60
|
key: Type.String({ description: "Unique identifier for the memory." }),
|
|
43
61
|
content: Type.String({ description: "The content of the memory." }),
|
|
44
|
-
tags: Type.Optional(
|
|
45
|
-
|
|
46
|
-
),
|
|
47
|
-
title: Type.Optional(
|
|
48
|
-
Type.String({ description: "Human-readable title." }),
|
|
49
|
-
),
|
|
62
|
+
tags: Type.Optional(Type.String({ description: "Comma-separated list of tags." })),
|
|
63
|
+
title: Type.Optional(Type.String({ description: "Human-readable title." })),
|
|
50
64
|
}),
|
|
51
|
-
async execute(_toolCallId: string, payload:
|
|
52
|
-
const res = await client.invoke(projectId, "store", payload);
|
|
53
|
-
return
|
|
54
|
-
content: [
|
|
55
|
-
{
|
|
56
|
-
type: "text",
|
|
57
|
-
text: JSON.stringify(res.data, null, 2),
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
details: res.data,
|
|
61
|
-
};
|
|
65
|
+
async execute(_toolCallId: string, payload: Record<string, unknown>) {
|
|
66
|
+
const res = await client.invoke(projectId, "store" as MuninAction, enrichPayload(payload));
|
|
67
|
+
return handleResult(res);
|
|
62
68
|
},
|
|
63
69
|
});
|
|
64
70
|
|
|
@@ -67,22 +73,12 @@ export default {
|
|
|
67
73
|
label: "Retrieve Munin Memory",
|
|
68
74
|
description: "Retrieve a memory by its key from Munin.",
|
|
69
75
|
parameters: Type.Object({
|
|
70
|
-
key: Type.String({
|
|
71
|
-
description: "The unique identifier of the memory.",
|
|
72
|
-
}),
|
|
76
|
+
key: Type.String({ description: "The unique identifier of the memory." }),
|
|
73
77
|
}),
|
|
74
|
-
async execute(_toolCallId: string, params:
|
|
78
|
+
async execute(_toolCallId: string, params: Record<string, unknown>) {
|
|
75
79
|
const { key } = params;
|
|
76
|
-
const res = await client.invoke(projectId, "retrieve", { key });
|
|
77
|
-
return
|
|
78
|
-
content: [
|
|
79
|
-
{
|
|
80
|
-
type: "text",
|
|
81
|
-
text: JSON.stringify(res.data, null, 2),
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
details: res.data,
|
|
85
|
-
};
|
|
80
|
+
const res = await client.invoke(projectId, "retrieve" as MuninAction, enrichPayload({ key }));
|
|
81
|
+
return handleResult(res);
|
|
86
82
|
},
|
|
87
83
|
});
|
|
88
84
|
|
|
@@ -93,18 +89,52 @@ export default {
|
|
|
93
89
|
parameters: Type.Object({
|
|
94
90
|
query: Type.String({ description: "The search term." }),
|
|
95
91
|
}),
|
|
96
|
-
async execute(_toolCallId: string, params:
|
|
92
|
+
async execute(_toolCallId: string, params: Record<string, unknown>) {
|
|
97
93
|
const { query } = params;
|
|
98
|
-
const res = await client.invoke(projectId, "search", { query });
|
|
99
|
-
return
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
94
|
+
const res = await client.invoke(projectId, "search" as MuninAction, enrichPayload({ query }));
|
|
95
|
+
return handleResult(res);
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
api.registerTool({
|
|
100
|
+
name: "munin_list_memories",
|
|
101
|
+
label: "List Munin Memories",
|
|
102
|
+
description: "List all memories with pagination support.",
|
|
103
|
+
parameters: Type.Object({
|
|
104
|
+
limit: Type.Optional(Type.Number({ description: "Max results (default: 10)." })),
|
|
105
|
+
offset: Type.Optional(Type.Number({ description: "Pagination offset (default: 0)." })),
|
|
106
|
+
}),
|
|
107
|
+
async execute(_toolCallId: string, params: Record<string, unknown>) {
|
|
108
|
+
const res = await client.invoke(projectId, "list" as MuninAction, enrichPayload(params));
|
|
109
|
+
return handleResult(res);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
api.registerTool({
|
|
114
|
+
name: "munin_recent_memories",
|
|
115
|
+
label: "Recent Munin Memories",
|
|
116
|
+
description: "Get the most recently updated memories.",
|
|
117
|
+
parameters: Type.Object({
|
|
118
|
+
limit: Type.Optional(Type.Number({ description: "Max results (default: 10)." })),
|
|
119
|
+
}),
|
|
120
|
+
async execute(_toolCallId: string, params: Record<string, unknown>) {
|
|
121
|
+
const res = await client.invoke(projectId, "recent" as MuninAction, enrichPayload(params));
|
|
122
|
+
return handleResult(res);
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
api.registerTool({
|
|
127
|
+
name: "munin_share_memory",
|
|
128
|
+
label: "Share Munin Memories",
|
|
129
|
+
description: "Share one or more memories to other projects. Requires Pro/Elite tier. Target project must share the same Hash Key for encrypted content.",
|
|
130
|
+
parameters: Type.Object({
|
|
131
|
+
memoryIds: Type.Array(Type.String(), { description: "Array of memory IDs to share." }),
|
|
132
|
+
targetProjectIds: Type.Array(Type.String(), { description: "Array of target project IDs." }),
|
|
133
|
+
}),
|
|
134
|
+
async execute(_toolCallId: string, params: Record<string, unknown>) {
|
|
135
|
+
const { memoryIds, targetProjectIds } = params;
|
|
136
|
+
const res = await client.invoke(projectId, "share" as MuninAction, enrichPayload({ memoryIds, targetProjectIds }));
|
|
137
|
+
return handleResult(res);
|
|
108
138
|
},
|
|
109
139
|
});
|
|
110
140
|
},
|