@mojoaar/opencode-mimir 0.29.0 → 0.29.2
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/dist/index.js +5 -1
- package/dist/tools.js +15 -15
- package/package.json +1 -1
- package/src/index.ts +8 -1
- package/src/tools.ts +15 -15
package/dist/index.js
CHANGED
|
@@ -62,8 +62,12 @@ export default Plugin.define({
|
|
|
62
62
|
id: 'mimir',
|
|
63
63
|
async setup(ctx) {
|
|
64
64
|
const config = resolveConfig(ctx.options);
|
|
65
|
-
if (!config)
|
|
65
|
+
if (!config) {
|
|
66
|
+
// This API has no logger, and an inert plugin is otherwise invisible:
|
|
67
|
+
// the digest, the tools and /mimir-learn simply never appear.
|
|
68
|
+
console.warn('mimir: no url, so no digest, tools or /mimir-learn. Set MIMIR_URL and MIMIR_TOKEN, or add options.url and options.tokenFile to the plugin entry.');
|
|
66
69
|
return;
|
|
70
|
+
}
|
|
67
71
|
// A folder without a git remote still needs a stable key, or every write
|
|
68
72
|
// lands in a fresh project. The server maps absolute paths to `local:<hash>`.
|
|
69
73
|
const repo = detectRepo(ctx.location.directory) ?? ctx.location.directory;
|
package/dist/tools.js
CHANGED
|
@@ -10,11 +10,11 @@ export async function registerTools(ctx, config, repo) {
|
|
|
10
10
|
if (config.tools === 'auto' && (await servedByMcp(ctx, config.url)))
|
|
11
11
|
return IDLE;
|
|
12
12
|
return ctx.tool.transform((editor) => {
|
|
13
|
-
editor.add(digestTool(repo));
|
|
14
|
-
editor.add(rememberTool(repo));
|
|
15
|
-
editor.add(searchTool(repo));
|
|
16
|
-
editor.add(readTool(repo));
|
|
17
|
-
editor.add(learnTool(repo));
|
|
13
|
+
editor.add(digestTool(repo, config));
|
|
14
|
+
editor.add(rememberTool(repo, config));
|
|
15
|
+
editor.add(searchTool(repo, config));
|
|
16
|
+
editor.add(readTool(repo, config));
|
|
17
|
+
editor.add(learnTool(repo, config));
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
const IDLE = { dispose: async () => { } };
|
|
@@ -40,7 +40,7 @@ function sameEndpoint(actual, expected) {
|
|
|
40
40
|
function strip(value) {
|
|
41
41
|
return (value ?? '').replace(/\/+$/, '');
|
|
42
42
|
}
|
|
43
|
-
function digestTool(repo) {
|
|
43
|
+
function digestTool(repo, config) {
|
|
44
44
|
return {
|
|
45
45
|
name: 'mimir_digest',
|
|
46
46
|
description: 'Load what this project already knows from Mimir. Call once at the start of a session, before searching for anything.',
|
|
@@ -57,7 +57,7 @@ function digestTool(repo) {
|
|
|
57
57
|
},
|
|
58
58
|
async execute(input) {
|
|
59
59
|
const args = input;
|
|
60
|
-
const result = await callTool('memory_digest', { budget_tokens: Number(args.budget_tokens ?? 800), repo: repo ?? undefined }, { timeoutMs: 5000 });
|
|
60
|
+
const result = await callTool('memory_digest', { budget_tokens: Number(args.budget_tokens ?? 800), repo: repo ?? undefined }, { url: config.url, token: config.token, timeoutMs: 5000 });
|
|
61
61
|
if (!result.ok)
|
|
62
62
|
return { content: `Mimir is unavailable (${result.error}). Carry on without it.` };
|
|
63
63
|
const digest = result.result;
|
|
@@ -68,7 +68,7 @@ function digestTool(repo) {
|
|
|
68
68
|
// A project created from a repo a teammate already knows about splits the
|
|
69
69
|
// knowledge in two until someone asks the owner for a grant.
|
|
70
70
|
const NEW_PROJECT = ' Started a new project. If a teammate already uses this repository, request access at /app/requests on your Mimir install.';
|
|
71
|
-
function rememberTool(repo) {
|
|
71
|
+
function rememberTool(repo, config) {
|
|
72
72
|
return {
|
|
73
73
|
name: 'mimir_remember',
|
|
74
74
|
description: 'Store one durable fact in Mimir. Use a path like "deploy/rollback" or "auth/token-rotation"; rewriting the same path replaces what was there.',
|
|
@@ -97,7 +97,7 @@ function rememberTool(repo) {
|
|
|
97
97
|
repo: repo ?? undefined,
|
|
98
98
|
client: 'opencode',
|
|
99
99
|
session: context?.sessionID,
|
|
100
|
-
}, { timeoutMs: 8000 });
|
|
100
|
+
}, { url: config.url, token: config.token, timeoutMs: 8000 });
|
|
101
101
|
if (!result.ok)
|
|
102
102
|
return { content: `Could not store that (${result.error}).` };
|
|
103
103
|
const written = result.result;
|
|
@@ -108,7 +108,7 @@ function rememberTool(repo) {
|
|
|
108
108
|
},
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
-
function searchTool(repo) {
|
|
111
|
+
function searchTool(repo, config) {
|
|
112
112
|
return {
|
|
113
113
|
name: 'mimir_search',
|
|
114
114
|
description: 'Search what this project has already settled in Mimir. Returns paths, titles and summaries; read a path with the MCP server if you need the body.',
|
|
@@ -123,7 +123,7 @@ function searchTool(repo) {
|
|
|
123
123
|
},
|
|
124
124
|
async execute(input) {
|
|
125
125
|
const args = input;
|
|
126
|
-
const result = await callTool('memory_search', { query: typeof args.query === 'string' ? args.query : '', path_prefix: typeof args.path_prefix === 'string' ? args.path_prefix : undefined, repo: repo ?? undefined }, { timeoutMs: 8000 });
|
|
126
|
+
const result = await callTool('memory_search', { query: typeof args.query === 'string' ? args.query : '', path_prefix: typeof args.path_prefix === 'string' ? args.path_prefix : undefined, repo: repo ?? undefined }, { url: config.url, token: config.token, timeoutMs: 8000 });
|
|
127
127
|
if (!result.ok)
|
|
128
128
|
return { content: `Mimir is unavailable (${result.error}). Carry on without it.` };
|
|
129
129
|
const hits = result.result;
|
|
@@ -143,7 +143,7 @@ function renderMemory(memory) {
|
|
|
143
143
|
const head = day ? `${memory.path ?? ''} · updated ${day}` : (memory.path ?? '');
|
|
144
144
|
return `${head}\n# ${memory.title ?? ''}\n\n${memory.body ?? ''}`;
|
|
145
145
|
}
|
|
146
|
-
function readTool(repo) {
|
|
146
|
+
function readTool(repo, config) {
|
|
147
147
|
return {
|
|
148
148
|
name: 'mimir_read',
|
|
149
149
|
description: 'Read one memory in full by its path. Search returns paths and summaries; this is the body behind one.',
|
|
@@ -155,14 +155,14 @@ function readTool(repo) {
|
|
|
155
155
|
},
|
|
156
156
|
async execute(input) {
|
|
157
157
|
const args = input;
|
|
158
|
-
const result = await callTool('memory_read', { path: String(args.path ?? ''), repo: repo ?? undefined }, { timeoutMs: 8000 });
|
|
158
|
+
const result = await callTool('memory_read', { path: String(args.path ?? ''), repo: repo ?? undefined }, { url: config.url, token: config.token, timeoutMs: 8000 });
|
|
159
159
|
if (!result.ok)
|
|
160
160
|
return { content: 'Nothing is stored at that path.' };
|
|
161
161
|
return { content: renderMemory(result.result) };
|
|
162
162
|
},
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
|
-
function learnTool(repo) {
|
|
165
|
+
function learnTool(repo, config) {
|
|
166
166
|
return {
|
|
167
167
|
name: 'mimir_learn',
|
|
168
168
|
description: 'Hand the part of this conversation worth keeping to Mimir. The project model writes at most three memories, in the background, so this answers at once.',
|
|
@@ -183,7 +183,7 @@ function learnTool(repo) {
|
|
|
183
183
|
repo: repo ?? undefined,
|
|
184
184
|
client: 'opencode',
|
|
185
185
|
session: context?.sessionID,
|
|
186
|
-
}, { timeoutMs: 8000 });
|
|
186
|
+
}, { url: config.url, token: config.token, timeoutMs: 8000 });
|
|
187
187
|
if (!result.ok)
|
|
188
188
|
return { content: `Could not hand that over (${result.error}).` };
|
|
189
189
|
const queued = result.result;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -66,7 +66,14 @@ export default Plugin.define({
|
|
|
66
66
|
id: 'mimir',
|
|
67
67
|
async setup(ctx) {
|
|
68
68
|
const config = resolveConfig(ctx.options)
|
|
69
|
-
if (!config)
|
|
69
|
+
if (!config) {
|
|
70
|
+
// This API has no logger, and an inert plugin is otherwise invisible:
|
|
71
|
+
// the digest, the tools and /mimir-learn simply never appear.
|
|
72
|
+
console.warn(
|
|
73
|
+
'mimir: no url, so no digest, tools or /mimir-learn. Set MIMIR_URL and MIMIR_TOKEN, or add options.url and options.tokenFile to the plugin entry.',
|
|
74
|
+
)
|
|
75
|
+
return
|
|
76
|
+
}
|
|
70
77
|
|
|
71
78
|
// A folder without a git remote still needs a stable key, or every write
|
|
72
79
|
// lands in a fresh project. The server maps absolute paths to `local:<hash>`.
|
package/src/tools.ts
CHANGED
|
@@ -36,11 +36,11 @@ export async function registerTools(
|
|
|
36
36
|
if (config.tools === 'auto' && (await servedByMcp(ctx, config.url))) return IDLE
|
|
37
37
|
|
|
38
38
|
return ctx.tool.transform((editor) => {
|
|
39
|
-
editor.add(digestTool(repo))
|
|
40
|
-
editor.add(rememberTool(repo))
|
|
41
|
-
editor.add(searchTool(repo))
|
|
42
|
-
editor.add(readTool(repo))
|
|
43
|
-
editor.add(learnTool(repo))
|
|
39
|
+
editor.add(digestTool(repo, config))
|
|
40
|
+
editor.add(rememberTool(repo, config))
|
|
41
|
+
editor.add(searchTool(repo, config))
|
|
42
|
+
editor.add(readTool(repo, config))
|
|
43
|
+
editor.add(learnTool(repo, config))
|
|
44
44
|
})
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -70,7 +70,7 @@ function strip(value: string | undefined): string {
|
|
|
70
70
|
return (value ?? '').replace(/\/+$/, '')
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
function digestTool(repo: string | null): ToolDefinition {
|
|
73
|
+
function digestTool(repo: string | null, config: MimirConfig): ToolDefinition {
|
|
74
74
|
return {
|
|
75
75
|
name: 'mimir_digest',
|
|
76
76
|
description:
|
|
@@ -91,7 +91,7 @@ function digestTool(repo: string | null): ToolDefinition {
|
|
|
91
91
|
const result = await callTool(
|
|
92
92
|
'memory_digest',
|
|
93
93
|
{ budget_tokens: Number(args.budget_tokens ?? 800), repo: repo ?? undefined },
|
|
94
|
-
{ timeoutMs: 5000 },
|
|
94
|
+
{ url: config.url, token: config.token, timeoutMs: 5000 },
|
|
95
95
|
)
|
|
96
96
|
if (!result.ok) return { content: `Mimir is unavailable (${result.error}). Carry on without it.` }
|
|
97
97
|
const digest = result.result as { text?: string }
|
|
@@ -104,7 +104,7 @@ function digestTool(repo: string | null): ToolDefinition {
|
|
|
104
104
|
// knowledge in two until someone asks the owner for a grant.
|
|
105
105
|
const NEW_PROJECT = ' Started a new project. If a teammate already uses this repository, request access at /app/requests on your Mimir install.'
|
|
106
106
|
|
|
107
|
-
function rememberTool(repo: string | null): ToolDefinition {
|
|
107
|
+
function rememberTool(repo: string | null, config: MimirConfig): ToolDefinition {
|
|
108
108
|
return {
|
|
109
109
|
name: 'mimir_remember',
|
|
110
110
|
description:
|
|
@@ -137,7 +137,7 @@ function rememberTool(repo: string | null): ToolDefinition {
|
|
|
137
137
|
client: 'opencode',
|
|
138
138
|
session: context?.sessionID,
|
|
139
139
|
},
|
|
140
|
-
{ timeoutMs: 8000 },
|
|
140
|
+
{ url: config.url, token: config.token, timeoutMs: 8000 },
|
|
141
141
|
)
|
|
142
142
|
if (!result.ok) return { content: `Could not store that (${result.error}).` }
|
|
143
143
|
const written = result.result as { path?: string; created?: boolean; projectCreated?: boolean }
|
|
@@ -149,7 +149,7 @@ function rememberTool(repo: string | null): ToolDefinition {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
function searchTool(repo: string | null): ToolDefinition {
|
|
152
|
+
function searchTool(repo: string | null, config: MimirConfig): ToolDefinition {
|
|
153
153
|
return {
|
|
154
154
|
name: 'mimir_search',
|
|
155
155
|
description:
|
|
@@ -168,7 +168,7 @@ function searchTool(repo: string | null): ToolDefinition {
|
|
|
168
168
|
const result = await callTool(
|
|
169
169
|
'memory_search',
|
|
170
170
|
{ query: typeof args.query === 'string' ? args.query : '', path_prefix: typeof args.path_prefix === 'string' ? args.path_prefix : undefined, repo: repo ?? undefined },
|
|
171
|
-
{ timeoutMs: 8000 },
|
|
171
|
+
{ url: config.url, token: config.token, timeoutMs: 8000 },
|
|
172
172
|
)
|
|
173
173
|
if (!result.ok) return { content: `Mimir is unavailable (${result.error}). Carry on without it.` }
|
|
174
174
|
const hits = result.result as { path: string; title: string; summary: string | null }[]
|
|
@@ -189,7 +189,7 @@ function renderMemory(memory: { path?: string; title?: string; body?: string; up
|
|
|
189
189
|
return `${head}\n# ${memory.title ?? ''}\n\n${memory.body ?? ''}`
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
function readTool(repo: string | null): ToolDefinition {
|
|
192
|
+
function readTool(repo: string | null, config: MimirConfig): ToolDefinition {
|
|
193
193
|
return {
|
|
194
194
|
name: 'mimir_read',
|
|
195
195
|
description:
|
|
@@ -205,7 +205,7 @@ function readTool(repo: string | null): ToolDefinition {
|
|
|
205
205
|
const result = await callTool(
|
|
206
206
|
'memory_read',
|
|
207
207
|
{ path: String(args.path ?? ''), repo: repo ?? undefined },
|
|
208
|
-
{ timeoutMs: 8000 },
|
|
208
|
+
{ url: config.url, token: config.token, timeoutMs: 8000 },
|
|
209
209
|
)
|
|
210
210
|
if (!result.ok) return { content: 'Nothing is stored at that path.' }
|
|
211
211
|
return { content: renderMemory(result.result as { path?: string; title?: string; body?: string; updatedAt?: string }) }
|
|
@@ -213,7 +213,7 @@ function readTool(repo: string | null): ToolDefinition {
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
function learnTool(repo: string | null): ToolDefinition {
|
|
216
|
+
function learnTool(repo: string | null, config: MimirConfig): ToolDefinition {
|
|
217
217
|
return {
|
|
218
218
|
name: 'mimir_learn',
|
|
219
219
|
description:
|
|
@@ -238,7 +238,7 @@ function learnTool(repo: string | null): ToolDefinition {
|
|
|
238
238
|
client: 'opencode',
|
|
239
239
|
session: context?.sessionID,
|
|
240
240
|
},
|
|
241
|
-
{ timeoutMs: 8000 },
|
|
241
|
+
{ url: config.url, token: config.token, timeoutMs: 8000 },
|
|
242
242
|
)
|
|
243
243
|
if (!result.ok) return { content: `Could not hand that over (${result.error}).` }
|
|
244
244
|
const queued = result.result as { queued?: boolean; reason?: string; projectCreated?: boolean }
|