dominds 1.27.2 → 1.27.3
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/apps/runtime.js +3 -1
- package/dist/dialog-global-registry.d.ts +11 -1
- package/dist/dialog-global-registry.js +45 -0
- package/dist/dialog.d.ts +11 -2
- package/dist/dialog.js +107 -17
- package/dist/docs/daemon-cmd-runner.md +5 -0
- package/dist/docs/daemon-cmd-runner.zh.md +5 -0
- package/dist/llm/kernel-driver/drive.js +163 -11
- package/dist/llm/kernel-driver/fbr.d.ts +9 -0
- package/dist/llm/kernel-driver/fbr.js +186 -59
- package/dist/minds/load.js +1 -0
- package/dist/persistence.js +18 -1
- package/dist/runtime/driver-messages.d.ts +9 -0
- package/dist/runtime/driver-messages.js +61 -5
- package/dist/runtime/shared-reminder-update-impact.d.ts +20 -0
- package/dist/runtime/shared-reminder-update-impact.js +110 -0
- package/dist/tool-availability.js +1 -0
- package/dist/tools/builtins.js +2 -0
- package/dist/tools/cmd-runner-protocol.d.ts +6 -0
- package/dist/tools/cmd-runner-protocol.js +57 -2
- package/dist/tools/cmd-runner.js +83 -2
- package/dist/tools/ctrl.d.ts +2 -0
- package/dist/tools/ctrl.js +179 -5
- package/dist/tools/os.js +115 -14
- package/dist/tools/process-kill.js +49 -0
- package/dist/tools/prompts/control/en/errors.md +1 -1
- package/dist/tools/prompts/control/en/index.md +1 -1
- package/dist/tools/prompts/control/en/principles.md +18 -17
- package/dist/tools/prompts/control/en/tools.md +24 -1
- package/dist/tools/prompts/control/zh/errors.md +1 -1
- package/dist/tools/prompts/control/zh/index.md +1 -1
- package/dist/tools/prompts/control/zh/principles.md +17 -16
- package/dist/tools/prompts/control/zh/tools.md +24 -1
- package/dist/tools/prompts/os/en/tools.md +2 -0
- package/dist/tools/prompts/os/zh/tools.md +2 -0
- package/package.json +4 -4
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MAX_CMD_RUNNER_OUTPUT_WAIT_TIMEOUT_MS = void 0;
|
|
6
7
|
exports.parseCmdRunnerInitMessage = parseCmdRunnerInitMessage;
|
|
7
8
|
exports.parseCmdRunnerInitialIpcMessage = parseCmdRunnerInitialIpcMessage;
|
|
8
9
|
exports.parseCmdRunnerRequestLine = parseCmdRunnerRequestLine;
|
|
@@ -10,6 +11,7 @@ exports.parseCmdRunnerResponseLine = parseCmdRunnerResponseLine;
|
|
|
10
11
|
exports.getCmdRunnerEndpointForDaemonPid = getCmdRunnerEndpointForDaemonPid;
|
|
11
12
|
const node_os_1 = __importDefault(require("node:os"));
|
|
12
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
14
|
+
exports.MAX_CMD_RUNNER_OUTPUT_WAIT_TIMEOUT_MS = 24 * 60 * 60 * 1_000;
|
|
13
15
|
function isRecord(value) {
|
|
14
16
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
15
17
|
}
|
|
@@ -33,13 +35,39 @@ function parseStreamSnapshot(raw, label) {
|
|
|
33
35
|
}
|
|
34
36
|
const content = asString(raw['content']);
|
|
35
37
|
const linesScrolledOut = asNumber(raw['linesScrolledOut']);
|
|
38
|
+
const version = asNumber(raw['version']);
|
|
36
39
|
if (content === null) {
|
|
37
40
|
throw new Error(`Invalid cmd_runner ${label}.content: expected string`);
|
|
38
41
|
}
|
|
39
42
|
if (linesScrolledOut === null) {
|
|
40
43
|
throw new Error(`Invalid cmd_runner ${label}.linesScrolledOut: expected number`);
|
|
41
44
|
}
|
|
42
|
-
|
|
45
|
+
if (version === null) {
|
|
46
|
+
throw new Error(`Invalid cmd_runner ${label}.version: expected number`);
|
|
47
|
+
}
|
|
48
|
+
return { content, linesScrolledOut, version };
|
|
49
|
+
}
|
|
50
|
+
function parseOptionalTimeoutMs(raw, label) {
|
|
51
|
+
if (raw === undefined) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const value = asNumber(raw);
|
|
55
|
+
if (value === null ||
|
|
56
|
+
!Number.isInteger(value) ||
|
|
57
|
+
value < 0 ||
|
|
58
|
+
value > exports.MAX_CMD_RUNNER_OUTPUT_WAIT_TIMEOUT_MS) {
|
|
59
|
+
throw new Error(`Invalid cmd_runner ${label}: expected non-negative integer <= ${String(exports.MAX_CMD_RUNNER_OUTPUT_WAIT_TIMEOUT_MS)}`);
|
|
60
|
+
}
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
function parseOutputWaitStatus(raw) {
|
|
64
|
+
if (raw === undefined) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
if (raw === 'output' || raw === 'timeout' || raw === 'exited') {
|
|
68
|
+
return raw;
|
|
69
|
+
}
|
|
70
|
+
throw new Error(`Invalid cmd_runner output waitStatus: ${String(raw)}`);
|
|
43
71
|
}
|
|
44
72
|
function parseStatusPayload(raw) {
|
|
45
73
|
const daemonPid = asNumber(raw['daemonPid']);
|
|
@@ -239,10 +267,28 @@ function parseCmdRunnerRequestLine(line) {
|
|
|
239
267
|
if (type === 'get_output') {
|
|
240
268
|
const stdout = asBoolean(raw['stdout']);
|
|
241
269
|
const stderr = asBoolean(raw['stderr']);
|
|
270
|
+
const waitForNewOutputRaw = raw['waitForNewOutput'];
|
|
271
|
+
const waitForNewOutput = waitForNewOutputRaw === undefined ? false : asBoolean(waitForNewOutputRaw);
|
|
272
|
+
const timeoutMs = parseOptionalTimeoutMs(raw['timeoutMs'], 'get_output.timeoutMs');
|
|
242
273
|
if (stdout === null || stderr === null) {
|
|
243
274
|
throw new Error('Invalid cmd_runner get_output request: stdout/stderr must be boolean');
|
|
244
275
|
}
|
|
245
|
-
|
|
276
|
+
if (waitForNewOutput === null) {
|
|
277
|
+
throw new Error('Invalid cmd_runner get_output request: waitForNewOutput must be boolean');
|
|
278
|
+
}
|
|
279
|
+
if (!stdout && !stderr) {
|
|
280
|
+
throw new Error('Invalid cmd_runner get_output request: at least one stream is required');
|
|
281
|
+
}
|
|
282
|
+
if (!waitForNewOutput && timeoutMs !== undefined) {
|
|
283
|
+
throw new Error('Invalid cmd_runner get_output request: timeoutMs requires waitForNewOutput=true');
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
type,
|
|
287
|
+
stdout,
|
|
288
|
+
stderr,
|
|
289
|
+
waitForNewOutput,
|
|
290
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
291
|
+
};
|
|
246
292
|
}
|
|
247
293
|
throw new Error(`Invalid cmd_runner request type: ${String(type)}`);
|
|
248
294
|
}
|
|
@@ -269,6 +315,15 @@ function parseCmdRunnerResponseLine(line) {
|
|
|
269
315
|
if (type !== 'pong' && type !== 'status' && type !== 'output' && type !== 'stop_result') {
|
|
270
316
|
throw new Error(`Invalid cmd_runner response type: ${String(type)}`);
|
|
271
317
|
}
|
|
318
|
+
if (type === 'output') {
|
|
319
|
+
const waitStatus = parseOutputWaitStatus(raw['waitStatus']);
|
|
320
|
+
return {
|
|
321
|
+
type,
|
|
322
|
+
ok: true,
|
|
323
|
+
...(waitStatus === undefined ? {} : { waitStatus }),
|
|
324
|
+
...parseStatusPayload(raw),
|
|
325
|
+
};
|
|
326
|
+
}
|
|
272
327
|
return {
|
|
273
328
|
type,
|
|
274
329
|
ok: true,
|
package/dist/tools/cmd-runner.js
CHANGED
|
@@ -17,10 +17,15 @@ class ScrollingBuffer {
|
|
|
17
17
|
maxLines;
|
|
18
18
|
lines = [];
|
|
19
19
|
linesScrolledOut = 0;
|
|
20
|
+
version = 0;
|
|
20
21
|
constructor(maxLines) {
|
|
21
22
|
this.maxLines = maxLines;
|
|
22
23
|
}
|
|
23
24
|
addText(text) {
|
|
25
|
+
if (text.length === 0) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
this.version += 1;
|
|
24
29
|
const newLines = text.split('\n');
|
|
25
30
|
if (newLines[newLines.length - 1] === '') {
|
|
26
31
|
newLines.pop();
|
|
@@ -37,8 +42,12 @@ class ScrollingBuffer {
|
|
|
37
42
|
return {
|
|
38
43
|
content: this.lines.join('\n'),
|
|
39
44
|
linesScrolledOut: this.linesScrolledOut,
|
|
45
|
+
version: this.version,
|
|
40
46
|
};
|
|
41
47
|
}
|
|
48
|
+
getVersion() {
|
|
49
|
+
return this.version;
|
|
50
|
+
}
|
|
42
51
|
}
|
|
43
52
|
async function flushIpc(msg) {
|
|
44
53
|
const send = process.send;
|
|
@@ -177,6 +186,64 @@ async function main() {
|
|
|
177
186
|
let closeRequested = false;
|
|
178
187
|
let timeoutHandle;
|
|
179
188
|
let initialResultSent = false;
|
|
189
|
+
const outputWaiters = [];
|
|
190
|
+
const requestedOutputChanged = (waiter) => (waiter.stdout && state.stdout.getVersion() !== waiter.initialStdoutVersion) ||
|
|
191
|
+
(waiter.stderr && state.stderr.getVersion() !== waiter.initialStderrVersion);
|
|
192
|
+
const removeOutputWaiter = (waiter) => {
|
|
193
|
+
const index = outputWaiters.indexOf(waiter);
|
|
194
|
+
if (index !== -1) {
|
|
195
|
+
outputWaiters.splice(index, 1);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
const settleOutputWaiter = (waiter, status) => {
|
|
199
|
+
removeOutputWaiter(waiter);
|
|
200
|
+
if (waiter.timeoutHandle !== undefined) {
|
|
201
|
+
clearTimeout(waiter.timeoutHandle);
|
|
202
|
+
}
|
|
203
|
+
waiter.resolve(status);
|
|
204
|
+
};
|
|
205
|
+
const notifyOutputWaiters = () => {
|
|
206
|
+
for (const waiter of [...outputWaiters]) {
|
|
207
|
+
if (requestedOutputChanged(waiter)) {
|
|
208
|
+
settleOutputWaiter(waiter, 'output');
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (!state.isRunning) {
|
|
212
|
+
settleOutputWaiter(waiter, 'exited');
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const waitForRequestedNewOutput = async (request, socket) => {
|
|
217
|
+
if (!state.isRunning) {
|
|
218
|
+
return 'exited';
|
|
219
|
+
}
|
|
220
|
+
return await new Promise((resolve) => {
|
|
221
|
+
let waiter;
|
|
222
|
+
const onSocketClosed = () => {
|
|
223
|
+
if (waiter !== undefined) {
|
|
224
|
+
settleOutputWaiter(waiter, 'client_closed');
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
waiter = {
|
|
228
|
+
stdout: request.stdout,
|
|
229
|
+
stderr: request.stderr,
|
|
230
|
+
initialStdoutVersion: state.stdout.getVersion(),
|
|
231
|
+
initialStderrVersion: state.stderr.getVersion(),
|
|
232
|
+
resolve: (status) => {
|
|
233
|
+
socket.off('close', onSocketClosed);
|
|
234
|
+
resolve(status);
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
if (request.timeoutMs !== undefined) {
|
|
238
|
+
waiter.timeoutHandle = setTimeout(() => {
|
|
239
|
+
settleOutputWaiter(waiter, 'timeout');
|
|
240
|
+
}, request.timeoutMs);
|
|
241
|
+
}
|
|
242
|
+
socket.once('close', onSocketClosed);
|
|
243
|
+
outputWaiters.push(waiter);
|
|
244
|
+
notifyOutputWaiters();
|
|
245
|
+
});
|
|
246
|
+
};
|
|
180
247
|
const tryFlushInitialResult = async (msg) => {
|
|
181
248
|
if (initialResultSent) {
|
|
182
249
|
return false;
|
|
@@ -262,6 +329,7 @@ async function main() {
|
|
|
262
329
|
state.isRunning = false;
|
|
263
330
|
state.exitCode = code;
|
|
264
331
|
state.exitSignal = signal;
|
|
332
|
+
notifyOutputWaiters();
|
|
265
333
|
void (async () => {
|
|
266
334
|
if (state.daemonCommandLine === null && !initialResultSent) {
|
|
267
335
|
await tryFlushInitialResult({
|
|
@@ -292,9 +360,11 @@ async function main() {
|
|
|
292
360
|
});
|
|
293
361
|
stdout.on('data', (data) => {
|
|
294
362
|
state.stdout.addText(data.toString());
|
|
363
|
+
notifyOutputWaiters();
|
|
295
364
|
});
|
|
296
365
|
stderr.on('data', (data) => {
|
|
297
366
|
state.stderr.addText(data.toString());
|
|
367
|
+
notifyOutputWaiters();
|
|
298
368
|
});
|
|
299
369
|
await ensureSocketParentDir(endpoint);
|
|
300
370
|
if (closeRequested) {
|
|
@@ -331,13 +401,24 @@ async function main() {
|
|
|
331
401
|
return;
|
|
332
402
|
}
|
|
333
403
|
if (request.type === 'get_output') {
|
|
404
|
+
const waitStatus = request.waitForNewOutput
|
|
405
|
+
? await waitForRequestedNewOutput(request, socket)
|
|
406
|
+
: undefined;
|
|
407
|
+
if (waitStatus === 'client_closed') {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
334
410
|
const payload = buildStatusPayload(state);
|
|
335
411
|
writeSocketResponse(socket, {
|
|
336
412
|
type: 'output',
|
|
337
413
|
ok: true,
|
|
414
|
+
...(waitStatus === undefined ? {} : { waitStatus }),
|
|
338
415
|
...payload,
|
|
339
|
-
stdout: request.stdout
|
|
340
|
-
|
|
416
|
+
stdout: request.stdout
|
|
417
|
+
? payload.stdout
|
|
418
|
+
: { content: '', linesScrolledOut: 0, version: 0 },
|
|
419
|
+
stderr: request.stderr
|
|
420
|
+
? payload.stderr
|
|
421
|
+
: { content: '', linesScrolledOut: 0, version: 0 },
|
|
341
422
|
});
|
|
342
423
|
return;
|
|
343
424
|
}
|
package/dist/tools/ctrl.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* - add_reminder: Add a reminder
|
|
13
13
|
* - delete_reminder: Delete a reminder by id
|
|
14
14
|
* - update_reminder: Update reminder content
|
|
15
|
+
* - migrate_reminder: Move a visible shared reminder back into the current dialog
|
|
15
16
|
* - clear_mind: Start a new course, optionally add a reminder
|
|
16
17
|
* - do_mind: Main Dialog only; create a new `.tsk/` Taskdoc section without starting a new course
|
|
17
18
|
* - change_mind: Main Dialog only; update a `.tsk/` Taskdoc section without starting a new course
|
|
@@ -32,6 +33,7 @@ import { type FuncTool } from '../tool';
|
|
|
32
33
|
export declare const deleteReminderTool: FuncTool;
|
|
33
34
|
export declare const addReminderTool: FuncTool;
|
|
34
35
|
export declare const updateReminderTool: FuncTool;
|
|
36
|
+
export declare const migrateReminderTool: FuncTool;
|
|
35
37
|
export declare const clearMindTool: FuncTool;
|
|
36
38
|
export declare const changeMindTool: FuncTool;
|
|
37
39
|
export declare const doMindTool: FuncTool;
|
package/dist/tools/ctrl.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* - add_reminder: Add a reminder
|
|
14
14
|
* - delete_reminder: Delete a reminder by id
|
|
15
15
|
* - update_reminder: Update reminder content
|
|
16
|
+
* - migrate_reminder: Move a visible shared reminder back into the current dialog
|
|
16
17
|
* - clear_mind: Start a new course, optionally add a reminder
|
|
17
18
|
* - do_mind: Main Dialog only; create a new `.tsk/` Taskdoc section without starting a new course
|
|
18
19
|
* - change_mind: Main Dialog only; update a `.tsk/` Taskdoc section without starting a new course
|
|
@@ -63,12 +64,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
63
64
|
};
|
|
64
65
|
})();
|
|
65
66
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
66
|
-
exports.recallTaskdocTool = exports.mindMoreTool = exports.neverMindTool = exports.doMindTool = exports.changeMindTool = exports.clearMindTool = exports.updateReminderTool = exports.addReminderTool = exports.deleteReminderTool = void 0;
|
|
67
|
+
exports.recallTaskdocTool = exports.mindMoreTool = exports.neverMindTool = exports.doMindTool = exports.changeMindTool = exports.clearMindTool = exports.migrateReminderTool = exports.updateReminderTool = exports.addReminderTool = exports.deleteReminderTool = void 0;
|
|
67
68
|
const fs = __importStar(require("fs"));
|
|
68
69
|
const path = __importStar(require("path"));
|
|
69
70
|
const dialog_1 = require("../dialog");
|
|
70
71
|
const rtws_1 = require("../rtws");
|
|
71
72
|
const driver_messages_1 = require("../runtime/driver-messages");
|
|
73
|
+
const shared_reminder_update_impact_1 = require("../runtime/shared-reminder-update-impact");
|
|
72
74
|
const tool_result_messages_1 = require("../runtime/tool-result-messages");
|
|
73
75
|
const work_language_1 = require("../runtime/work-language");
|
|
74
76
|
const shared_reminders_1 = require("../shared-reminders");
|
|
@@ -276,6 +278,87 @@ function replaceReminderContent(reminder, content, meta, renderMode) {
|
|
|
276
278
|
renderMode: renderMode ?? reminder.renderMode,
|
|
277
279
|
});
|
|
278
280
|
}
|
|
281
|
+
function resolveSharedReminderUpdateImpactScope(target) {
|
|
282
|
+
if (target.source !== 'runtime') {
|
|
283
|
+
return undefined;
|
|
284
|
+
}
|
|
285
|
+
if (target.target.kind === 'task') {
|
|
286
|
+
return 'task';
|
|
287
|
+
}
|
|
288
|
+
return target.reminder.scope === 'runtime' ? 'runtime' : 'agent';
|
|
289
|
+
}
|
|
290
|
+
function appendSharedReminderUpdateImpactToToolResult(output, language, reminderId, dispatch) {
|
|
291
|
+
if (dispatch === undefined) {
|
|
292
|
+
return output;
|
|
293
|
+
}
|
|
294
|
+
const notice = (0, driver_messages_1.formatSharedReminderUpdateImpactNotice)(language, {
|
|
295
|
+
reminderId,
|
|
296
|
+
scope: dispatch.scope,
|
|
297
|
+
audience: 'updater',
|
|
298
|
+
});
|
|
299
|
+
const dispatchLine = language === 'zh'
|
|
300
|
+
? `已向 ${dispatch.dispatchedDialogCount}/${dispatch.peerDialogCount} 个受影响的并行对话派发提醒。`
|
|
301
|
+
: `Dispatched notices to ${dispatch.dispatchedDialogCount}/${dispatch.peerDialogCount} affected parallel dialog(s).`;
|
|
302
|
+
return {
|
|
303
|
+
...output,
|
|
304
|
+
content: `${output.content}\n\n${notice}\n${dispatchLine}`,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function appendSharedReminderMigrationImpactToToolResult(output, language, dispatch) {
|
|
308
|
+
if (dispatch === undefined) {
|
|
309
|
+
return output;
|
|
310
|
+
}
|
|
311
|
+
const dispatchLine = language === 'zh'
|
|
312
|
+
? `已向 ${dispatch.dispatchedDialogCount}/${dispatch.peerDialogCount} 个受影响的并行对话派发撤下提醒。`
|
|
313
|
+
: `Dispatched withdrawal notices to ${dispatch.dispatchedDialogCount}/${dispatch.peerDialogCount} affected parallel dialog(s).`;
|
|
314
|
+
return {
|
|
315
|
+
...output,
|
|
316
|
+
content: `${output.content}\n${dispatchLine}`,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
async function formatUpdateReminderSuccessResult(args) {
|
|
320
|
+
const scope = resolveSharedReminderUpdateImpactScope(args.target);
|
|
321
|
+
const dispatch = scope === undefined
|
|
322
|
+
? undefined
|
|
323
|
+
: await (0, shared_reminder_update_impact_1.dispatchSharedReminderUpdateImpact)({
|
|
324
|
+
updater: args.dlg,
|
|
325
|
+
reminderId: args.target.reminder.id,
|
|
326
|
+
scope,
|
|
327
|
+
language: args.language,
|
|
328
|
+
});
|
|
329
|
+
return appendSharedReminderUpdateImpactToToolResult((0, tool_result_messages_1.formatToolActionResult)(args.language, 'updated'), args.language, args.target.reminder.id, dispatch);
|
|
330
|
+
}
|
|
331
|
+
async function migrateSharedReminderTargetToDialog(args) {
|
|
332
|
+
const reminderId = args.target.reminder.id;
|
|
333
|
+
const existingDialogIndex = findReminderIndexById('dialog', args.dlg.reminders, reminderId);
|
|
334
|
+
if (existingDialogIndex !== null) {
|
|
335
|
+
throw new Error(`Duplicate visible reminder_id before migration: ${reminderId}`);
|
|
336
|
+
}
|
|
337
|
+
let migratedReminder;
|
|
338
|
+
await (0, shared_reminders_1.mutateSharedReminders)(args.target.target, (sharedReminders) => {
|
|
339
|
+
const index = findReminderIndexById('shared', sharedReminders, reminderId);
|
|
340
|
+
if (index === null)
|
|
341
|
+
return;
|
|
342
|
+
migratedReminder = sharedReminders[index];
|
|
343
|
+
sharedReminders.splice(index, 1);
|
|
344
|
+
});
|
|
345
|
+
if (migratedReminder === undefined) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
args.dlg.reminders.push((0, tool_1.materializeReminder)({
|
|
349
|
+
id: migratedReminder.id,
|
|
350
|
+
content: migratedReminder.content,
|
|
351
|
+
owner: migratedReminder.owner,
|
|
352
|
+
meta: migratedReminder.meta,
|
|
353
|
+
echoback: migratedReminder.echoback,
|
|
354
|
+
scope: 'dialog',
|
|
355
|
+
createdAt: migratedReminder.createdAt,
|
|
356
|
+
priority: migratedReminder.priority,
|
|
357
|
+
renderMode: migratedReminder.renderMode,
|
|
358
|
+
}));
|
|
359
|
+
args.dlg.touchReminders();
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
279
362
|
async function deleteResolvedReminderTarget(dlg, target) {
|
|
280
363
|
switch (target.source) {
|
|
281
364
|
case 'dialog': {
|
|
@@ -325,6 +408,9 @@ function getCtrlMessages(language) {
|
|
|
325
408
|
invalidFormatAdd: '参数格式不对。用法:add_reminder({ content: string, scope?: "dialog" | "task" | "agent" })(省略 scope 表示 task)',
|
|
326
409
|
reminderContentEmpty: '提醒内容不能为空',
|
|
327
410
|
invalidFormatUpdate: '参数格式不对。用法:update_reminder({ reminder_id: string, content: string })',
|
|
411
|
+
invalidFormatMigrate: '参数格式不对。用法:migrate_reminder({ reminder_id: string, scope: "dialog" })',
|
|
412
|
+
reminderAlreadyDialogScope: (reminderId) => `reminder_id=${reminderId} 已经是当前对话范围提醒项,不需要迁移。`,
|
|
413
|
+
reminderMigrateManagedBlocked: (managerTool) => `错误:该提醒项由工具 ${managerTool} 管理,不能用 migrate_reminder 迁移;请使用 ${managerTool} 更新。`,
|
|
328
414
|
invalidFormatDoMind: '参数格式不对。用法:do_mind({ selector: string, category?: string, content: string })',
|
|
329
415
|
invalidFormatChangeMind: '参数格式不对。用法:change_mind({ selector: string, category?: string, content: string, previous_content_hash: string })',
|
|
330
416
|
tooManyArgsChangeMind: '参数格式不对。用法:change_mind({ selector: string, category?: string, content: string, previous_content_hash: string })',
|
|
@@ -372,6 +458,9 @@ function getCtrlMessages(language) {
|
|
|
372
458
|
invalidFormatAdd: 'Error: Invalid args. Use: add_reminder({ content: string, scope?: "dialog" | "task" | "agent" }) (omitting scope means task).',
|
|
373
459
|
reminderContentEmpty: 'Error: Reminder content cannot be empty',
|
|
374
460
|
invalidFormatUpdate: 'Error: Invalid args. Use: update_reminder({ reminder_id: string, content: string })',
|
|
461
|
+
invalidFormatMigrate: 'Error: Invalid args. Use: migrate_reminder({ reminder_id: string, scope: "dialog" })',
|
|
462
|
+
reminderAlreadyDialogScope: (reminderId) => `reminder_id=${reminderId} is already dialog-scope in the current dialog; no migration is needed.`,
|
|
463
|
+
reminderMigrateManagedBlocked: (managerTool) => `Error: This reminder is managed by tool ${managerTool}. Do not migrate it via migrate_reminder; use ${managerTool} instead.`,
|
|
375
464
|
invalidFormatDoMind: 'Error: Invalid args. Use: do_mind({ selector: string, category?: string, content: string })',
|
|
376
465
|
invalidFormatChangeMind: 'Error: Invalid args. Use: change_mind({ selector: string, category?: string, content: string, previous_content_hash: string })',
|
|
377
466
|
tooManyArgsChangeMind: 'Error: Invalid args. Use: change_mind({ selector: string, category?: string, content: string, previous_content_hash: string })',
|
|
@@ -456,7 +545,7 @@ exports.addReminderTool = {
|
|
|
456
545
|
description: 'Add a manually maintained reminder for current work. Scope defaults to task so the reminder survives continuing the same Taskdoc in another dialog; dialog is only for truly dialog-local notes; agent is visible to this agent across dialogs and should be reserved for urgent short-lived global cues. Do not manually record runtime-maintained environment state such as background process status or in-flight background asks.',
|
|
457
546
|
descriptionI18n: {
|
|
458
547
|
en: 'Add a manually maintained reminder for current work. Scope defaults to task so the reminder survives continuing the same Taskdoc in another dialog; dialog is only for truly dialog-local notes; agent is visible to this agent across dialogs and should be reserved for urgent short-lived global cues. Do not manually record runtime-maintained environment state such as background process status or in-flight background asks.',
|
|
459
|
-
zh: '添加手工维护的手头工作提醒。scope 默认 task,以便同一差遣牒任务换新对话继续时仍可见;dialog 只用于真正对话局部的事项;agent
|
|
548
|
+
zh: '添加手工维护的手头工作提醒。scope 默认 task,以便同一差遣牒任务换新对话继续时仍可见;dialog 只用于真正对话局部的事项;agent 会在本智能体后续对话中继续可见,仅用于紧急、短期、全局刺眼提醒。不要手工记录后台进程状态、后台进行中诉请等 runtime 会自动维护的环境状态。',
|
|
460
549
|
},
|
|
461
550
|
parameters: {
|
|
462
551
|
type: 'object',
|
|
@@ -592,12 +681,20 @@ exports.updateReminderTool = {
|
|
|
592
681
|
const updated = await updateResolvedReminderTarget(dlg, resolved.target, reminderContent, stripResult.nextMeta, reminderRenderMode);
|
|
593
682
|
if (!updated)
|
|
594
683
|
return (0, tool_1.toolFailure)(t.reminderTargetChanged);
|
|
595
|
-
return
|
|
684
|
+
return await formatUpdateReminderSuccessResult({
|
|
685
|
+
dlg,
|
|
686
|
+
target: resolved.target,
|
|
687
|
+
language,
|
|
688
|
+
});
|
|
596
689
|
}
|
|
597
690
|
const updated = await updateResolvedReminderTarget(dlg, resolved.target, reminderContent, undefined, reminderRenderMode);
|
|
598
691
|
if (!updated)
|
|
599
692
|
return (0, tool_1.toolFailure)(t.reminderTargetChanged);
|
|
600
|
-
return
|
|
693
|
+
return await formatUpdateReminderSuccessResult({
|
|
694
|
+
dlg,
|
|
695
|
+
target: resolved.target,
|
|
696
|
+
language,
|
|
697
|
+
});
|
|
601
698
|
}
|
|
602
699
|
const reminderMeta = buildContinuationPackageReminderMeta({
|
|
603
700
|
existingMeta: reminder?.meta,
|
|
@@ -607,7 +704,84 @@ exports.updateReminderTool = {
|
|
|
607
704
|
const updated = await updateResolvedReminderTarget(dlg, resolved.target, reminderContent, reminderMeta, reminderRenderMode);
|
|
608
705
|
if (!updated)
|
|
609
706
|
return (0, tool_1.toolFailure)(t.reminderTargetChanged);
|
|
610
|
-
return
|
|
707
|
+
return await formatUpdateReminderSuccessResult({
|
|
708
|
+
dlg,
|
|
709
|
+
target: resolved.target,
|
|
710
|
+
language,
|
|
711
|
+
});
|
|
712
|
+
},
|
|
713
|
+
};
|
|
714
|
+
exports.migrateReminderTool = {
|
|
715
|
+
type: 'func',
|
|
716
|
+
name: 'migrate_reminder',
|
|
717
|
+
description: 'Move a visible shared reminder back into the current dialog scope. Use this after a task/agent shared reminder update turns out to belong only to the updater dialog, so Dominds withdraws it from affected parallel dialogs.',
|
|
718
|
+
descriptionI18n: {
|
|
719
|
+
en: 'Move a visible shared reminder back into the current dialog scope. Use this after a task/agent shared reminder update turns out to belong only to the updater dialog, so Dominds withdraws it from affected parallel dialogs.',
|
|
720
|
+
zh: '把当前可见的共享提醒项迁回当前对话范围。用于 task/agent 共享提醒更新后发现内容只属于更新者对话时,将它从受影响并行对话中撤下。',
|
|
721
|
+
},
|
|
722
|
+
parameters: {
|
|
723
|
+
type: 'object',
|
|
724
|
+
additionalProperties: false,
|
|
725
|
+
required: ['reminder_id', 'scope'],
|
|
726
|
+
properties: {
|
|
727
|
+
reminder_id: { type: 'string', description: 'Stable reminder id.' },
|
|
728
|
+
scope: {
|
|
729
|
+
type: 'string',
|
|
730
|
+
enum: ['dialog'],
|
|
731
|
+
description: 'Target scope. Currently only dialog is supported.',
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
argsValidation: 'dominds',
|
|
736
|
+
async call(dlg, _caller, args) {
|
|
737
|
+
const language = (0, work_language_1.getWorkLanguage)();
|
|
738
|
+
const t = getCtrlMessages(language);
|
|
739
|
+
if (args['scope'] !== 'dialog') {
|
|
740
|
+
return (0, tool_1.toolFailure)(t.invalidFormatMigrate);
|
|
741
|
+
}
|
|
742
|
+
const resolved = await resolveReminderTarget(dlg, args['reminder_id']);
|
|
743
|
+
if (!resolved.ok) {
|
|
744
|
+
const reminderId = resolved.reminderId.trim();
|
|
745
|
+
if (reminderId === '')
|
|
746
|
+
return (0, tool_1.toolFailure)(t.invalidFormatMigrate);
|
|
747
|
+
return (0, tool_1.toolFailure)(t.reminderDoesNotExist(reminderId));
|
|
748
|
+
}
|
|
749
|
+
const targetReminder = resolved.target.reminder;
|
|
750
|
+
if (resolved.target.source === 'dialog') {
|
|
751
|
+
return (0, tool_1.toolSuccess)(t.reminderAlreadyDialogScope(targetReminder.id));
|
|
752
|
+
}
|
|
753
|
+
const deleteAltInstruction = getDeleteAltInstruction(targetReminder.meta);
|
|
754
|
+
if (deleteAltInstruction !== undefined) {
|
|
755
|
+
return (0, tool_1.toolFailure)(formatManualDeleteBlockedError(language, deleteAltInstruction));
|
|
756
|
+
}
|
|
757
|
+
const managerTool = getManagerTool(targetReminder.meta);
|
|
758
|
+
if (managerTool !== undefined) {
|
|
759
|
+
return (0, tool_1.toolFailure)(t.reminderMigrateManagedBlocked(managerTool));
|
|
760
|
+
}
|
|
761
|
+
if (targetReminder.owner?.updateReminder !== undefined) {
|
|
762
|
+
return (0, tool_1.toolFailure)(language === 'zh'
|
|
763
|
+
? '错误:该提醒项由 reminder owner 自动维护,不能用 migrate_reminder 迁移。'
|
|
764
|
+
: 'Error: This reminder is automatically maintained by a reminder owner and cannot be migrated via migrate_reminder.');
|
|
765
|
+
}
|
|
766
|
+
const scope = resolveSharedReminderUpdateImpactScope(resolved.target);
|
|
767
|
+
const migrated = await migrateSharedReminderTargetToDialog({
|
|
768
|
+
dlg,
|
|
769
|
+
target: resolved.target,
|
|
770
|
+
});
|
|
771
|
+
if (!migrated)
|
|
772
|
+
return (0, tool_1.toolFailure)(t.reminderTargetChanged);
|
|
773
|
+
const baseOutput = (0, tool_1.toolSuccess)(language === 'zh'
|
|
774
|
+
? `已迁移:reminder_id=${targetReminder.id} 已从共享范围撤下,并保留为当前对话范围提醒项。`
|
|
775
|
+
: `Migrated: reminder_id=${targetReminder.id} has been withdrawn from shared scope and kept as a current-dialog reminder.`);
|
|
776
|
+
const dispatch = scope === undefined
|
|
777
|
+
? undefined
|
|
778
|
+
: await (0, shared_reminder_update_impact_1.dispatchSharedReminderMigrationImpact)({
|
|
779
|
+
updater: dlg,
|
|
780
|
+
reminderId: targetReminder.id,
|
|
781
|
+
scope,
|
|
782
|
+
language,
|
|
783
|
+
});
|
|
784
|
+
return appendSharedReminderMigrationImpactToToolResult(baseOutput, language, dispatch);
|
|
611
785
|
},
|
|
612
786
|
};
|
|
613
787
|
exports.clearMindTool = {
|