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.
Files changed (36) hide show
  1. package/dist/apps/runtime.js +3 -1
  2. package/dist/dialog-global-registry.d.ts +11 -1
  3. package/dist/dialog-global-registry.js +45 -0
  4. package/dist/dialog.d.ts +11 -2
  5. package/dist/dialog.js +107 -17
  6. package/dist/docs/daemon-cmd-runner.md +5 -0
  7. package/dist/docs/daemon-cmd-runner.zh.md +5 -0
  8. package/dist/llm/kernel-driver/drive.js +163 -11
  9. package/dist/llm/kernel-driver/fbr.d.ts +9 -0
  10. package/dist/llm/kernel-driver/fbr.js +186 -59
  11. package/dist/minds/load.js +1 -0
  12. package/dist/persistence.js +18 -1
  13. package/dist/runtime/driver-messages.d.ts +9 -0
  14. package/dist/runtime/driver-messages.js +61 -5
  15. package/dist/runtime/shared-reminder-update-impact.d.ts +20 -0
  16. package/dist/runtime/shared-reminder-update-impact.js +110 -0
  17. package/dist/tool-availability.js +1 -0
  18. package/dist/tools/builtins.js +2 -0
  19. package/dist/tools/cmd-runner-protocol.d.ts +6 -0
  20. package/dist/tools/cmd-runner-protocol.js +57 -2
  21. package/dist/tools/cmd-runner.js +83 -2
  22. package/dist/tools/ctrl.d.ts +2 -0
  23. package/dist/tools/ctrl.js +179 -5
  24. package/dist/tools/os.js +115 -14
  25. package/dist/tools/process-kill.js +49 -0
  26. package/dist/tools/prompts/control/en/errors.md +1 -1
  27. package/dist/tools/prompts/control/en/index.md +1 -1
  28. package/dist/tools/prompts/control/en/principles.md +18 -17
  29. package/dist/tools/prompts/control/en/tools.md +24 -1
  30. package/dist/tools/prompts/control/zh/errors.md +1 -1
  31. package/dist/tools/prompts/control/zh/index.md +1 -1
  32. package/dist/tools/prompts/control/zh/principles.md +17 -16
  33. package/dist/tools/prompts/control/zh/tools.md +24 -1
  34. package/dist/tools/prompts/os/en/tools.md +2 -0
  35. package/dist/tools/prompts/os/zh/tools.md +2 -0
  36. package/package.json +4 -4
@@ -7,11 +7,15 @@ exports.buildFbrToolAvailabilityNotice = buildFbrToolAvailabilityNotice;
7
7
  exports.buildFbrSystemPrompt = buildFbrSystemPrompt;
8
8
  exports.buildFbrConvergencePrompt = buildFbrConvergencePrompt;
9
9
  exports.buildFbrFinalizationPrompt = buildFbrFinalizationPrompt;
10
+ exports.buildFbrContextCautionFinalizationPrompt = buildFbrContextCautionFinalizationPrompt;
11
+ exports.buildProgrammaticFbrContextCriticalContent = buildProgrammaticFbrContextCriticalContent;
10
12
  exports.buildProgrammaticFbrUnreasonableSituationContent = buildProgrammaticFbrUnreasonableSituationContent;
11
13
  exports.inspectFbrConclusionAttempt = inspectFbrConclusionAttempt;
12
14
  exports.createInitialFbrState = createInitialFbrState;
13
15
  exports.markFbrPromptDelivered = markFbrPromptDelivered;
14
16
  exports.isFbrFinalizationState = isFbrFinalizationState;
17
+ exports.isFbrContextCautionFinalizationState = isFbrContextCautionFinalizationState;
18
+ exports.forceFbrContextCautionFinalizationState = forceFbrContextCautionFinalizationState;
15
19
  exports.advanceFbrState = advanceFbrState;
16
20
  exports.buildFbrPromptForState = buildFbrPromptForState;
17
21
  const fbr_body_1 = require("../../runtime/fbr-body");
@@ -196,6 +200,78 @@ function buildFbrFinalizationPrompt(args) {
196
200
  '- Earlier wild ideas that never gained independent support must be discarded as noise and must not appear in the final content.',
197
201
  ].join('\n');
198
202
  }
203
+ function buildFbrContextCautionFinalizationPrompt(args) {
204
+ if (args.language === 'zh') {
205
+ const retryLine = args.attempt <= 1
206
+ ? 'FBR 上下文状态:🟡 吃紧'
207
+ : `FBR 上下文仍然吃紧;这是第 ${args.attempt} 次要求你用结论函数收口。`;
208
+ return [
209
+ retryLine,
210
+ '',
211
+ '当前 FBR 已经因为上下文压力提前进入最终收口。把这视为问题复杂度、推理成本或噪音累积已经不适合继续发散/收敛的信号。',
212
+ '',
213
+ `现在必须且只能调用以下两个函数之一结束本次 FBR:`,
214
+ `- \`${exports.FBR_LOW_NOISE_CONCLUSION_TOOL_NAME}({ content })\``,
215
+ `- \`${exports.FBR_UNREASONABLE_SITUATION_TOOL_NAME}({ content })\``,
216
+ '',
217
+ '选择规则:',
218
+ '- 如果基于已经完成的发散、收敛推演,仍能形成稳定共识:调用低噪高信息结论函数。',
219
+ '- 如果已有推演仍相互矛盾、证据不足、关键上下文缺失,或上下文吃紧本身说明问题过于复杂:调用“不合理现状”函数。',
220
+ '',
221
+ '强制要求:',
222
+ '- 不要 clear_mind,不要继续发散/收敛,不要调用其它函数,不要输出普通文本。',
223
+ '- content 必须由你基于已经做过的推演自行形成;运行时不会替你程序化转译或代写结论。',
224
+ '- 最终 content 只保留稳定共识、关键未知项、最重要的下一步;未获独立支撑的离谱想法必须当噪音丢弃。',
225
+ ].join('\n');
226
+ }
227
+ const retryLine = args.attempt <= 1
228
+ ? 'FBR context state: 🟡 caution'
229
+ : `FBR context is still tight; this is reminder ${args.attempt} requiring you to close through a conclusion function.`;
230
+ return [
231
+ retryLine,
232
+ '',
233
+ 'This FBR is entering final closure early because of context pressure. Treat that as a signal that problem complexity, reasoning cost, or accumulated noise is no longer suitable for continued divergence/convergence.',
234
+ '',
235
+ 'You must now end this FBR by calling exactly one of:',
236
+ `- \`${exports.FBR_LOW_NOISE_CONCLUSION_TOOL_NAME}({ content })\``,
237
+ `- \`${exports.FBR_UNREASONABLE_SITUATION_TOOL_NAME}({ content })\``,
238
+ '',
239
+ 'Choose as follows:',
240
+ '- If the divergence/convergence already performed still supports stable consensus, call the low-noise highly-informative conclusion function.',
241
+ '- If the existing reasoning remains contradictory, under-evidenced, missing key context, or context pressure itself shows the problem is too complex, call the unreasonable-situation function.',
242
+ '',
243
+ 'Hard requirements:',
244
+ '- Do not clear_mind, do not keep diverging/converging, do not call any other function, and do not output plain text.',
245
+ '- The content must be formed by you from the reasoning already performed; the runtime will not programmatically translate or write the conclusion for you.',
246
+ '- Keep only stable consensus, key unknowns, and the single most important next steps; discard unsupported wild ideas as noise.',
247
+ ].join('\n');
248
+ }
249
+ function buildProgrammaticFbrContextCriticalContent(args) {
250
+ if (args.language === 'zh') {
251
+ return [
252
+ '当前 FBR 问题过于复杂,不能继续负责地扩展推理,也不能在剩余上下文内形成可靠的低噪结论。',
253
+ '',
254
+ '原因:',
255
+ '- 上下文已经达到告急水平;这本身应视为问题复杂度、证据需求或推理分支数量超过当前 FBR 可控范围的信号。',
256
+ '- Dominds 不会在告急状态下程序化总结对话、抽取已有推演或替模型转译结论;那会显著提高遗漏、失真和幻觉风险。',
257
+ '',
258
+ '建议:',
259
+ '- 将诉请拆解为更小、更清晰的子问题。',
260
+ '- 为每个子问题分别固定 Goal / Facts / Constraints / Evidence / Unknowns 后,各自重新发起 FBR。',
261
+ ].join('\n');
262
+ }
263
+ return [
264
+ 'This FBR problem is too complex to keep expanding reasoning responsibly or produce a reliable low-noise conclusion within the remaining context.',
265
+ '',
266
+ 'Reasons:',
267
+ '- Context has reached the critical level; this should itself be treated as a signal that problem complexity, evidence needs, or branch count exceeded what the current FBR can control.',
268
+ '- Dominds will not programmatically summarize the dialog, extract existing reasoning, or translate it into a conclusion under critical context pressure; doing so would materially increase omission, distortion, and hallucination risk.',
269
+ '',
270
+ 'Suggested next steps:',
271
+ '- Split the request into smaller, clearer subproblems.',
272
+ '- For each subproblem, stabilize Goal / Facts / Constraints / Evidence / Unknowns, then run its own FBR pass.',
273
+ ].join('\n');
274
+ }
199
275
  function buildProgrammaticFbrUnreasonableSituationContent(args) {
200
276
  if (args.language === 'zh') {
201
277
  return [
@@ -308,85 +384,136 @@ function markFbrPromptDelivered(state) {
308
384
  function isFbrFinalizationState(state) {
309
385
  return state.phase === 'finalization';
310
386
  }
387
+ function isFbrContextCautionFinalizationState(state) {
388
+ return state.phase === 'finalization' && state.finalizationReason === 'context_caution';
389
+ }
390
+ function forceFbrContextCautionFinalizationState(state) {
391
+ if (state.phase === 'finalization') {
392
+ return {
393
+ ...state,
394
+ finalizationReason: 'context_caution',
395
+ promptDelivered: false,
396
+ };
397
+ }
398
+ return {
399
+ kind: 'serial',
400
+ effort: state.effort,
401
+ phase: 'finalization',
402
+ iteration: 1,
403
+ promptDelivered: false,
404
+ finalizationReason: 'context_caution',
405
+ };
406
+ }
311
407
  function advanceFbrState(state) {
312
- if (state.phase === 'divergence') {
313
- if (state.iteration < state.effort) {
408
+ switch (state.phase) {
409
+ case 'divergence': {
410
+ if (state.iteration < state.effort) {
411
+ return {
412
+ kind: 'serial',
413
+ effort: state.effort,
414
+ phase: 'divergence',
415
+ iteration: state.iteration + 1,
416
+ promptDelivered: false,
417
+ };
418
+ }
314
419
  return {
315
420
  kind: 'serial',
316
421
  effort: state.effort,
317
- phase: 'divergence',
318
- iteration: state.iteration + 1,
422
+ phase: 'convergence',
423
+ iteration: 1,
319
424
  promptDelivered: false,
320
425
  };
321
426
  }
322
- return {
323
- kind: 'serial',
324
- effort: state.effort,
325
- phase: 'convergence',
326
- iteration: 1,
327
- promptDelivered: false,
328
- };
329
- }
330
- if (state.phase === 'convergence') {
331
- if (state.iteration < state.effort) {
427
+ case 'convergence': {
428
+ if (state.iteration < state.effort) {
429
+ return {
430
+ kind: 'serial',
431
+ effort: state.effort,
432
+ phase: 'convergence',
433
+ iteration: state.iteration + 1,
434
+ promptDelivered: false,
435
+ };
436
+ }
332
437
  return {
333
438
  kind: 'serial',
334
439
  effort: state.effort,
335
- phase: 'convergence',
440
+ phase: 'finalization',
441
+ iteration: 1,
442
+ promptDelivered: false,
443
+ finalizationReason: 'planned',
444
+ };
445
+ }
446
+ case 'finalization': {
447
+ if (state.finalizationReason === 'context_caution') {
448
+ return {
449
+ kind: 'serial',
450
+ effort: state.effort,
451
+ phase: 'finalization',
452
+ iteration: state.iteration + 1,
453
+ promptDelivered: false,
454
+ finalizationReason: 'context_caution',
455
+ };
456
+ }
457
+ if (state.iteration >= state.effort) {
458
+ return undefined;
459
+ }
460
+ return {
461
+ kind: 'serial',
462
+ effort: state.effort,
463
+ phase: 'finalization',
336
464
  iteration: state.iteration + 1,
337
465
  promptDelivered: false,
466
+ finalizationReason: 'planned',
338
467
  };
339
468
  }
340
- return {
341
- kind: 'serial',
342
- effort: state.effort,
343
- phase: 'finalization',
344
- iteration: 1,
345
- promptDelivered: false,
346
- };
347
- }
348
- if (state.iteration >= state.effort) {
349
- return undefined;
469
+ default: {
470
+ const _exhaustive = state;
471
+ return _exhaustive;
472
+ }
350
473
  }
351
- return {
352
- kind: 'serial',
353
- effort: state.effort,
354
- phase: 'finalization',
355
- iteration: state.iteration + 1,
356
- promptDelivered: false,
357
- };
358
474
  }
359
475
  function buildFbrPromptForState(args) {
360
- if (args.state.phase === 'divergence') {
361
- return (0, inter_dialog_format_1.formatAssignmentFromAskerDialog)({
362
- callName: 'freshBootsReasoning',
363
- fromAgentId: args.fromAgentId,
364
- toAgentId: args.toAgentId,
365
- tellaskContent: (0, fbr_body_1.appendDistinctPerspectiveFbrBody)({
366
- body: args.tellaskContent,
476
+ switch (args.state.phase) {
477
+ case 'divergence':
478
+ return (0, inter_dialog_format_1.formatAssignmentFromAskerDialog)({
479
+ callName: 'freshBootsReasoning',
480
+ fromAgentId: args.fromAgentId,
481
+ toAgentId: args.toAgentId,
482
+ tellaskContent: (0, fbr_body_1.appendDistinctPerspectiveFbrBody)({
483
+ body: args.tellaskContent,
484
+ iteration: args.state.iteration,
485
+ total: args.state.effort,
486
+ language: args.language,
487
+ isFinalRound: args.state.iteration === args.state.effort,
488
+ }),
489
+ language: args.language,
490
+ collectiveTargets: args.collectiveTargets,
491
+ fbrRound: {
492
+ iteration: args.state.iteration,
493
+ total: args.state.effort,
494
+ },
495
+ });
496
+ case 'convergence':
497
+ return buildFbrConvergencePrompt({
367
498
  iteration: args.state.iteration,
368
499
  total: args.state.effort,
369
500
  language: args.language,
370
- isFinalRound: args.state.iteration === args.state.effort,
371
- }),
372
- language: args.language,
373
- collectiveTargets: args.collectiveTargets,
374
- fbrRound: {
375
- iteration: args.state.iteration,
501
+ });
502
+ case 'finalization':
503
+ if (args.state.finalizationReason === 'context_caution') {
504
+ return buildFbrContextCautionFinalizationPrompt({
505
+ attempt: args.state.iteration,
506
+ language: args.language,
507
+ });
508
+ }
509
+ return buildFbrFinalizationPrompt({
510
+ attempt: args.state.iteration,
376
511
  total: args.state.effort,
377
- },
378
- });
379
- }
380
- if (args.state.phase === 'convergence') {
381
- return buildFbrConvergencePrompt({
382
- iteration: args.state.iteration,
383
- total: args.state.effort,
384
- language: args.language,
385
- });
512
+ language: args.language,
513
+ });
514
+ default: {
515
+ const _exhaustive = args.state;
516
+ return _exhaustive;
517
+ }
386
518
  }
387
- return buildFbrFinalizationPrompt({
388
- attempt: args.state.iteration,
389
- total: args.state.effort,
390
- language: args.language,
391
- });
392
519
  }
@@ -223,6 +223,7 @@ async function loadAgentMinds(agentId, dialog, options) {
223
223
  ctrl_1.addReminderTool,
224
224
  ctrl_1.deleteReminderTool,
225
225
  ctrl_1.updateReminderTool,
226
+ ctrl_1.migrateReminderTool,
226
227
  ctrl_1.clearMindTool,
227
228
  ctrl_1.recallTaskdocTool,
228
229
  ];
@@ -2234,17 +2234,34 @@ function parseDialogLatestFile(value) {
2234
2234
  if (typeof fbrStateRaw.iteration !== 'number' || !Number.isInteger(fbrStateRaw.iteration)) {
2235
2235
  return null;
2236
2236
  }
2237
- if (fbrStateRaw.iteration < 1 || fbrStateRaw.iteration > fbrStateRaw.effort) {
2237
+ if (fbrStateRaw.iteration < 1) {
2238
2238
  return null;
2239
2239
  }
2240
2240
  if (typeof fbrStateRaw.promptDelivered !== 'boolean')
2241
2241
  return null;
2242
+ if (phase !== 'finalization' && fbrStateRaw.iteration > fbrStateRaw.effort) {
2243
+ return null;
2244
+ }
2245
+ if (phase !== 'finalization') {
2246
+ return {
2247
+ kind: 'serial',
2248
+ effort: fbrStateRaw.effort,
2249
+ phase,
2250
+ iteration: fbrStateRaw.iteration,
2251
+ promptDelivered: fbrStateRaw.promptDelivered,
2252
+ };
2253
+ }
2254
+ const finalizationReason = fbrStateRaw.finalizationReason;
2255
+ if (finalizationReason !== 'planned' && finalizationReason !== 'context_caution') {
2256
+ return null;
2257
+ }
2242
2258
  return {
2243
2259
  kind: 'serial',
2244
2260
  effort: fbrStateRaw.effort,
2245
2261
  phase,
2246
2262
  iteration: fbrStateRaw.iteration,
2247
2263
  promptDelivered: fbrStateRaw.promptDelivered,
2264
+ finalizationReason,
2248
2265
  };
2249
2266
  })();
2250
2267
  if (fbrState === null)
@@ -56,6 +56,15 @@ export type ReminderMaintenanceReferenceItem = Readonly<{
56
56
  meta?: unknown;
57
57
  }>;
58
58
  export declare function formatReminderMaintenanceReference(language: LanguageCode, reminders: readonly ReminderMaintenanceReferenceItem[]): string | undefined;
59
+ export declare function formatSharedReminderUpdateImpactNotice(language: LanguageCode, args: {
60
+ reminderId: string;
61
+ scope: 'task' | 'agent' | 'runtime';
62
+ audience: 'updater' | 'peer';
63
+ }): string;
64
+ export declare function formatSharedReminderMigrationImpactNotice(language: LanguageCode, args: {
65
+ reminderId: string;
66
+ scope: 'task' | 'agent' | 'runtime';
67
+ }): string;
59
68
  export declare function formatReminderItemGuide(language: LanguageCode, reminderId: string, content: string, options?: {
60
69
  meta?: unknown;
61
70
  scope?: 'dialog' | 'task' | 'agent' | 'runtime';
@@ -12,6 +12,8 @@ exports.formatDiligenceAutoContinuePrompt = formatDiligenceAutoContinuePrompt;
12
12
  exports.formatReminderContextGuide = formatReminderContextGuide;
13
13
  exports.formatReminderContextFooter = formatReminderContextFooter;
14
14
  exports.formatReminderMaintenanceReference = formatReminderMaintenanceReference;
15
+ exports.formatSharedReminderUpdateImpactNotice = formatSharedReminderUpdateImpactNotice;
16
+ exports.formatSharedReminderMigrationImpactNotice = formatSharedReminderMigrationImpactNotice;
15
17
  exports.formatReminderItemGuide = formatReminderItemGuide;
16
18
  exports.formatQ4HDiligencePushBudgetExhausted = formatQ4HDiligencePushBudgetExhausted;
17
19
  exports.formatDomindsNoteTellaskForTeammatesOnly = formatDomindsNoteTellaskForTeammatesOnly;
@@ -562,6 +564,60 @@ function formatReminderMaintenanceReference(language, reminders) {
562
564
  ...lines,
563
565
  ].join('\n');
564
566
  }
567
+ function formatSharedReminderUpdateImpactNotice(language, args) {
568
+ const reminderId = args.reminderId;
569
+ const scope = args.scope;
570
+ if (language === 'zh') {
571
+ const scopeName = scope === 'task' ? '任务范围' : scope === 'agent' ? '智能体范围' : '运行时范围';
572
+ const impactedDialogs = scope === 'task'
573
+ ? '当前进行时存在同一智能体在当前差遣牒任务内的其它并行对话'
574
+ : '当前进行时存在同一智能体的其它并行对话';
575
+ if (args.audience === 'updater') {
576
+ return `共享范围影响:你刚更新的 reminder_id=${reminderId} 是${scopeName}提醒项,不是当前对话私有;${impactedDialogs},其它能看到这条提醒项的对话也会看到这次更新。请考虑使用 migrate_reminder({ "reminder_id": "${reminderId}", "scope": "dialog" }) 确保提醒项的影响范围合理;若新内容只应影响当前对话,迁移后系统会从共享范围撤下,并保留为仅本对话可见的提醒项。`;
577
+ }
578
+ return [
579
+ `${formatSystemNoticePrefix(language)} 共享范围提醒项已更新`,
580
+ '',
581
+ `reminder_id=${reminderId} 是${scopeName}提醒项,不是当前对话私有;${impactedDialogs}。同一智能体的某个并行对话刚更新了它,你所在对话也会看到这次更新。`,
582
+ '这条共享提醒项这次实际上由另一对话维护;你应自行判断它与本对话当前上下文是否有关,只采纳确实相关的部分。',
583
+ `请把它作为最新共享参考。若这次更新看起来只适合更新者所在对话,不要在本对话替它修正共享内容;可提醒更新者在其对话中使用 migrate_reminder({ "reminder_id": "${reminderId}", "scope": "dialog" }) 迁回对话范围,从而从其它并行对话撤下。本对话若另有私有状态,请另建对话范围提醒项。`,
584
+ ].join('\n');
585
+ }
586
+ const scopeName = scope === 'task' ? 'task-scope' : scope === 'agent' ? 'agent-scope' : 'runtime-scope';
587
+ const impactedDialogs = scope === 'task'
588
+ ? 'The current in-flight work has other parallel dialogs for the same agent and Taskdoc'
589
+ : 'The current in-flight work has other parallel dialogs for the same agent';
590
+ if (args.audience === 'updater') {
591
+ return `Shared-scope impact: the reminder you just updated, reminder_id=${reminderId}, is ${scopeName}, not private to the current dialog. ${impactedDialogs}, so other dialogs that can see this reminder will see this update too. Consider running migrate_reminder({ "reminder_id": "${reminderId}", "scope": "dialog" }) to make sure the reminder's impact scope is appropriate; if the new content should affect only the current dialog, Dominds will withdraw it from shared scope and keep it visible only in this dialog after migration.`;
592
+ }
593
+ return [
594
+ `${formatSystemNoticePrefix(language)} Shared-scope reminder updated`,
595
+ '',
596
+ `reminder_id=${reminderId} is ${scopeName}, not private to the current dialog. ${impactedDialogs}. Another parallel dialog for the same agent just updated it, so this dialog will see the update too.`,
597
+ 'This shared reminder was actually maintained by another dialog this time; decide for yourself whether it is relevant to this dialog context, and use only the parts that are truly relevant.',
598
+ `Use it as the latest shared reference. If this update appears to fit only the updater's dialog, do not correct the shared content from this dialog; you may ask the updater to run migrate_reminder({ "reminder_id": "${reminderId}", "scope": "dialog" }) in that dialog so Dominds withdraws it from other parallel dialogs. If this dialog has its own private state, create a separate dialog-scope reminder here.`,
599
+ ].join('\n');
600
+ }
601
+ function formatSharedReminderMigrationImpactNotice(language, args) {
602
+ const reminderId = args.reminderId;
603
+ const scope = args.scope;
604
+ if (language === 'zh') {
605
+ const scopeName = scope === 'task' ? '任务范围' : scope === 'agent' ? '智能体范围' : '运行时范围';
606
+ return [
607
+ `${formatSystemNoticePrefix(language)} 共享范围提醒项已迁回其它对话`,
608
+ '',
609
+ `reminder_id=${reminderId} 原本是${scopeName}提醒项;更新者对话已将它迁回自己的对话范围,因此它不再是你所在对话可见的共享参考。`,
610
+ '若本对话仍需要类似内容,请按本对话当前状态另建对话范围或任务范围提醒项;不要假设迁走后的内容仍适用于这里。',
611
+ ].join('\n');
612
+ }
613
+ const scopeName = scope === 'task' ? 'task-scope' : scope === 'agent' ? 'agent-scope' : 'runtime-scope';
614
+ return [
615
+ `${formatSystemNoticePrefix(language)} Shared-scope reminder migrated back to another dialog`,
616
+ '',
617
+ `reminder_id=${reminderId} was ${scopeName}. The updater dialog has moved it back into its own dialog scope, so it is no longer a shared reference visible to this dialog.`,
618
+ 'If this dialog still needs similar content, create a dialog-scope or task-scope reminder that matches this dialog now; do not assume the migrated content still applies here.',
619
+ ].join('\n');
620
+ }
565
621
  function formatReminderItemGuide(language, reminderId, content, options) {
566
622
  // `options.meta` is persisted JSON coming from tools. Runtime shape checks are unavoidable here
567
623
  // to keep reminder ownership/management loosely coupled and extensible.
@@ -615,12 +671,12 @@ function formatReminderItemGuide(language, reminderId, content, options) {
615
671
  }
616
672
  const scopeLabel = scope === 'task' ? '(任务范围)' : scope === 'agent' ? '(智能体范围)' : '';
617
673
  const scopeGuide = scope === 'task'
618
- ? `${projectionNote}你设置了任务范围提醒项,Dominds 会在当前差遣牒任务内、所有由你主理的对话里提醒你。请把它当作当前任务的手头工作提示,不要自动当成系统下发的下一步动作。`
674
+ ? `${projectionNote}你设置了任务范围提醒项,Dominds 会在当前差遣牒任务内的相关对话里提醒你。请把它当作当前任务的手头工作提示,不要自动当成系统下发的下一步动作。`
619
675
  : scope === 'agent'
620
- ? `${projectionNote}你设置了智能体范围提醒项,Dominds 会在所有由你主理的对话里提醒你。它只适合紧急、短期、全局刺眼提醒;不要用来记录普通任务状态,也不要自动当成系统下发的下一步动作。`
676
+ ? `${projectionNote}你设置了智能体范围提醒项,Dominds 会在由你主理的后续对话里提醒你。它只适合紧急、短期、全局刺眼提醒;不要用来记录普通任务状态,也不要自动当成系统下发的下一步动作。`
621
677
  : `${projectionNote}你设置了提醒项,Dominds 会在需要时提醒你。请把它当作用来保留当前对话里容易丢的手头工作信息的提示,不要自动当成系统下发的下一步动作。`;
622
678
  const scopeMaintenance = scope === 'task'
623
- ? '你应保持简洁、及时更新;不再需要时就删除。若它只对当前对话有效,应改写成 dialog 范围提醒;若需要全队同步当前任务状态,应写入差遣牒 progress,而不是扩大提醒范围。'
679
+ ? '你应保持简洁、及时更新;不再需要时就删除。若它只对当前对话有效,应改写成对话范围提醒;若需要全队同步当前任务状态,应写入差遣牒 progress,而不是扩大提醒范围。'
624
680
  : scope === 'agent'
625
681
  ? '你应主动保持极少量、短期、强相关;不再需要时必须删除。普通任务进展不要放在 agent 范围,当前任务内跨对话可见请改用 task 范围。'
626
682
  : '你应保持简洁、及时更新;不再需要时就删除。若后续准备换程,也可以把它整理成接续包。';
@@ -669,9 +725,9 @@ ${content}`;
669
725
  }
670
726
  const scopeLabel = scope === 'task' ? ' (TASK SCOPE)' : scope === 'agent' ? ' (AGENT SCOPE)' : '';
671
727
  const scopeGuide = scope === 'task'
672
- ? `${enProjectionPrefix}You set a task-scope reminder so Dominds can remind you in every dialog you lead for the current Taskdoc. Treat it as a current-work reference for this task, not as an automatically assigned next action.`
728
+ ? `${enProjectionPrefix}You set a task-scope reminder so Dominds can remind you across relevant dialogs for the current Taskdoc. Treat it as a current-work reference for this task, not as an automatically assigned next action.`
673
729
  : scope === 'agent'
674
- ? `${enProjectionPrefix}You set an agent-scope reminder so Dominds can remind you in every dialog you lead. This is only for urgent, short-lived, globally visible cues; do not use it for ordinary task state, and do not treat it as an automatically assigned next action.`
730
+ ? `${enProjectionPrefix}You set an agent-scope reminder so Dominds can remind you across later dialogs you lead. This is only for urgent, short-lived, globally visible cues; do not use it for ordinary task state, and do not treat it as an automatically assigned next action.`
675
731
  : `${enProjectionPrefix}You set a reminder so Dominds can remind you when needed. Treat it as a current-work reference for easy-to-lose details in the current dialog, not as an automatically assigned next action.`;
676
732
  const scopeMaintenance = scope === 'task'
677
733
  ? 'Keep it concise, refresh it when needed, and delete it when obsolete. If it is only useful for the current dialog, rewrite it into dialog scope; if the team must synchronize current task state, update Taskdoc progress instead of broadening reminder scope.'
@@ -0,0 +1,20 @@
1
+ import type { LanguageCode } from '@longrun-ai/kernel/types/language';
2
+ import type { Dialog } from '../dialog';
3
+ export type SharedReminderUpdateImpactScope = 'task' | 'agent' | 'runtime';
4
+ export type SharedReminderUpdateImpactDispatch = Readonly<{
5
+ scope: SharedReminderUpdateImpactScope;
6
+ peerDialogCount: number;
7
+ dispatchedDialogCount: number;
8
+ }>;
9
+ export declare function dispatchSharedReminderUpdateImpact(args: {
10
+ updater: Dialog;
11
+ reminderId: string;
12
+ scope: SharedReminderUpdateImpactScope;
13
+ language: LanguageCode;
14
+ }): Promise<SharedReminderUpdateImpactDispatch | undefined>;
15
+ export declare function dispatchSharedReminderMigrationImpact(args: {
16
+ updater: Dialog;
17
+ reminderId: string;
18
+ scope: SharedReminderUpdateImpactScope;
19
+ language: LanguageCode;
20
+ }): Promise<SharedReminderUpdateImpactDispatch | undefined>;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dispatchSharedReminderUpdateImpact = dispatchSharedReminderUpdateImpact;
4
+ exports.dispatchSharedReminderMigrationImpact = dispatchSharedReminderMigrationImpact;
5
+ const id_1 = require("@longrun-ai/kernel/utils/id");
6
+ const dialog_global_registry_1 = require("../dialog-global-registry");
7
+ const driver_messages_1 = require("./driver-messages");
8
+ function sharedReminderUpdateImpactsDialog(args) {
9
+ if (args.candidate.id.equals(args.updater.id)) {
10
+ return false;
11
+ }
12
+ if (args.candidate.agentId !== args.updater.agentId) {
13
+ return false;
14
+ }
15
+ return args.scope === 'task' ? args.candidate.taskDocPath === args.updater.taskDocPath : true;
16
+ }
17
+ function collectSharedReminderUpdatePeerDialogs(args) {
18
+ const peers = [];
19
+ for (const candidate of dialog_global_registry_1.globalDialogRegistry.getLoadedInFlightDialogsForSharedReminderImpact()) {
20
+ if (sharedReminderUpdateImpactsDialog({
21
+ scope: args.scope,
22
+ updater: args.updater,
23
+ candidate,
24
+ })) {
25
+ peers.push(candidate);
26
+ }
27
+ }
28
+ return peers;
29
+ }
30
+ async function queueSharedReminderUpdateImpactPrompt(args) {
31
+ await args.targetDialog.queueRuntimeGuidePrompt({
32
+ prompt: (0, driver_messages_1.formatSharedReminderUpdateImpactNotice)(args.language, {
33
+ reminderId: args.reminderId,
34
+ scope: args.scope,
35
+ audience: 'peer',
36
+ }),
37
+ msgId: (0, id_1.generateShortId)(),
38
+ grammar: 'markdown',
39
+ userLanguageCode: args.language,
40
+ skipTaskdoc: true,
41
+ });
42
+ dialog_global_registry_1.globalDialogRegistry.queueRootDrive(args.targetDialog.id.rootId, {
43
+ source: 'shared_reminder_update_impact',
44
+ reason: `reminder_id:${args.reminderId}`,
45
+ });
46
+ }
47
+ async function queueSharedReminderMigrationImpactPrompt(args) {
48
+ await args.targetDialog.queueRuntimeGuidePrompt({
49
+ prompt: (0, driver_messages_1.formatSharedReminderMigrationImpactNotice)(args.language, {
50
+ reminderId: args.reminderId,
51
+ scope: args.scope,
52
+ }),
53
+ msgId: (0, id_1.generateShortId)(),
54
+ grammar: 'markdown',
55
+ userLanguageCode: args.language,
56
+ skipTaskdoc: true,
57
+ });
58
+ dialog_global_registry_1.globalDialogRegistry.queueRootDrive(args.targetDialog.id.rootId, {
59
+ source: 'shared_reminder_migration_impact',
60
+ reason: `migrated_reminder_id:${args.reminderId}`,
61
+ });
62
+ }
63
+ async function dispatchSharedReminderUpdateImpact(args) {
64
+ const peerDialogs = collectSharedReminderUpdatePeerDialogs({
65
+ updater: args.updater,
66
+ scope: args.scope,
67
+ });
68
+ if (peerDialogs.length === 0) {
69
+ return undefined;
70
+ }
71
+ let dispatchedDialogCount = 0;
72
+ for (const peerDialog of peerDialogs) {
73
+ await queueSharedReminderUpdateImpactPrompt({
74
+ targetDialog: peerDialog,
75
+ reminderId: args.reminderId,
76
+ scope: args.scope,
77
+ language: args.language,
78
+ });
79
+ dispatchedDialogCount += 1;
80
+ }
81
+ return {
82
+ scope: args.scope,
83
+ peerDialogCount: peerDialogs.length,
84
+ dispatchedDialogCount,
85
+ };
86
+ }
87
+ async function dispatchSharedReminderMigrationImpact(args) {
88
+ const peerDialogs = collectSharedReminderUpdatePeerDialogs({
89
+ updater: args.updater,
90
+ scope: args.scope,
91
+ });
92
+ if (peerDialogs.length === 0) {
93
+ return undefined;
94
+ }
95
+ let dispatchedDialogCount = 0;
96
+ for (const peerDialog of peerDialogs) {
97
+ await queueSharedReminderMigrationImpactPrompt({
98
+ targetDialog: peerDialog,
99
+ reminderId: args.reminderId,
100
+ scope: args.scope,
101
+ language: args.language,
102
+ });
103
+ dispatchedDialogCount += 1;
104
+ }
105
+ return {
106
+ scope: args.scope,
107
+ peerDialogCount: peerDialogs.length,
108
+ dispatchedDialogCount,
109
+ };
110
+ }
@@ -225,6 +225,7 @@ function buildIntrinsicControlToolset(dialog) {
225
225
  ctrl_1.addReminderTool,
226
226
  ctrl_1.deleteReminderTool,
227
227
  ctrl_1.updateReminderTool,
228
+ ctrl_1.migrateReminderTool,
228
229
  ctrl_1.clearMindTool,
229
230
  ctrl_1.recallTaskdocTool,
230
231
  ];
@@ -118,6 +118,7 @@ function manualSpecFor(toolsetId) {
118
118
  (0, registry_1.registerTool)(ctrl_1.addReminderTool);
119
119
  (0, registry_1.registerTool)(ctrl_1.deleteReminderTool);
120
120
  (0, registry_1.registerTool)(ctrl_1.updateReminderTool);
121
+ (0, registry_1.registerTool)(ctrl_1.migrateReminderTool);
121
122
  (0, registry_1.registerTool)(ctrl_1.clearMindTool);
122
123
  (0, registry_1.registerTool)(ctrl_1.doMindTool);
123
124
  (0, registry_1.registerTool)(ctrl_1.changeMindTool);
@@ -190,6 +191,7 @@ for (const tool of team_mgmt_1.teamMgmtTools) {
190
191
  ctrl_1.addReminderTool,
191
192
  ctrl_1.deleteReminderTool,
192
193
  ctrl_1.updateReminderTool,
194
+ ctrl_1.migrateReminderTool,
193
195
  ctrl_1.clearMindTool,
194
196
  ctrl_1.doMindTool,
195
197
  ctrl_1.changeMindTool,
@@ -1,3 +1,4 @@
1
+ export declare const MAX_CMD_RUNNER_OUTPUT_WAIT_TIMEOUT_MS: number;
1
2
  export type CmdRunnerSpawnSpec = Readonly<{
2
3
  command: string;
3
4
  args: string[];
@@ -38,6 +39,8 @@ export type CmdRunnerRequest = Readonly<{
38
39
  type: 'get_output';
39
40
  stdout: boolean;
40
41
  stderr: boolean;
42
+ waitForNewOutput: boolean;
43
+ timeoutMs?: number;
41
44
  }> | Readonly<{
42
45
  type: 'stop';
43
46
  entirePg: boolean;
@@ -45,7 +48,9 @@ export type CmdRunnerRequest = Readonly<{
45
48
  export type CmdRunnerStreamSnapshot = Readonly<{
46
49
  content: string;
47
50
  linesScrolledOut: number;
51
+ version: number;
48
52
  }>;
53
+ export type CmdRunnerOutputWaitStatus = 'output' | 'timeout' | 'exited';
49
54
  export type CmdRunnerStatusPayload = Readonly<{
50
55
  daemonPid: number;
51
56
  daemonCommandLine: string;
@@ -69,6 +74,7 @@ export type CmdRunnerResponse = (Readonly<{
69
74
  }> & CmdRunnerStatusPayload) | (Readonly<{
70
75
  type: 'output';
71
76
  ok: true;
77
+ waitStatus?: CmdRunnerOutputWaitStatus;
72
78
  }> & CmdRunnerStatusPayload) | (Readonly<{
73
79
  type: 'stop_result';
74
80
  ok: true;