dominds 1.11.2 → 1.12.1

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 (136) hide show
  1. package/dist/apps-host/ipc-types.d.ts +1 -1
  2. package/dist/apps-host/ipc-types.js +4 -7
  3. package/dist/dialog-fork.js +9 -2
  4. package/dist/dialog.d.ts +16 -1
  5. package/dist/dialog.js +115 -43
  6. package/dist/llm/defaults.yaml +3 -3
  7. package/dist/llm/gen/mock.d.ts +1 -1
  8. package/dist/llm/gen/mock.js +1 -1
  9. package/dist/llm/kernel-driver/drive.js +9 -13
  10. package/dist/llm/kernel-driver/runtime.js +12 -4
  11. package/dist/minds/system-prompt-parts.js +2 -2
  12. package/dist/persistence.js +16 -9
  13. package/dist/priming.d.ts +1 -1
  14. package/dist/priming.js +24 -10
  15. package/dist/runtime/driver-messages.d.ts +2 -1
  16. package/dist/runtime/driver-messages.js +34 -25
  17. package/dist/shared-reminders.d.ts +4 -0
  18. package/dist/shared-reminders.js +176 -0
  19. package/dist/tool.d.ts +23 -3
  20. package/dist/tool.js +60 -14
  21. package/dist/tools/app-reminders.js +10 -9
  22. package/dist/tools/ctrl.d.ts +2 -2
  23. package/dist/tools/ctrl.js +188 -110
  24. package/dist/tools/mcp.js +5 -5
  25. package/dist/tools/os.d.ts +1 -0
  26. package/dist/tools/os.js +284 -102
  27. package/dist/tools/pending-tellask-reminder.js +5 -5
  28. package/dist/tools/prompts/control/en/errors.md +10 -6
  29. package/dist/tools/prompts/control/en/index.md +7 -2
  30. package/dist/tools/prompts/control/en/principles.md +28 -9
  31. package/dist/tools/prompts/control/en/scenarios.md +15 -2
  32. package/dist/tools/prompts/control/en/tools.md +12 -11
  33. package/dist/tools/prompts/control/zh/errors.md +10 -6
  34. package/dist/tools/prompts/control/zh/index.md +7 -2
  35. package/dist/tools/prompts/control/zh/principles.md +28 -9
  36. package/dist/tools/prompts/control/zh/scenarios.md +15 -2
  37. package/dist/tools/prompts/control/zh/tools.md +12 -11
  38. package/dist/tools/prompts/os/en/tools.md +1 -1
  39. package/dist/tools/prompts/os/zh/tools.md +1 -1
  40. package/package.json +1 -1
  41. package/webapp/dist/assets/{_basePickBy-VvT_9kRm.js → _basePickBy-B1lGEusm.js} +3 -3
  42. package/webapp/dist/assets/{_basePickBy-VvT_9kRm.js.map → _basePickBy-B1lGEusm.js.map} +1 -1
  43. package/webapp/dist/assets/{_baseUniq-D9_-G6c9.js → _baseUniq-SGAsMSaE.js} +2 -2
  44. package/webapp/dist/assets/{_baseUniq-D9_-G6c9.js.map → _baseUniq-SGAsMSaE.js.map} +1 -1
  45. package/webapp/dist/assets/{arc-BbofkRAx.js → arc-B2joU0eL.js} +2 -2
  46. package/webapp/dist/assets/{arc-BbofkRAx.js.map → arc-B2joU0eL.js.map} +1 -1
  47. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-Dn2yTFsM.js → architectureDiagram-2XIMDMQ5-CsuG-Xa3.js} +7 -7
  48. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-Dn2yTFsM.js.map → architectureDiagram-2XIMDMQ5-CsuG-Xa3.js.map} +1 -1
  49. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-BT13QjyS.js → blockDiagram-WCTKOSBZ-D8_SVEGn.js} +7 -7
  50. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-BT13QjyS.js.map → blockDiagram-WCTKOSBZ-D8_SVEGn.js.map} +1 -1
  51. package/webapp/dist/assets/{c4Diagram-IC4MRINW-CDSHxATH.js → c4Diagram-IC4MRINW-D_lhLw36.js} +3 -3
  52. package/webapp/dist/assets/{c4Diagram-IC4MRINW-CDSHxATH.js.map → c4Diagram-IC4MRINW-D_lhLw36.js.map} +1 -1
  53. package/webapp/dist/assets/{channel-frrfgRkc.js → channel-BI76pqQS.js} +2 -2
  54. package/webapp/dist/assets/{channel-frrfgRkc.js.map → channel-BI76pqQS.js.map} +1 -1
  55. package/webapp/dist/assets/{chunk-4BX2VUAB-DfC5GXR7.js → chunk-4BX2VUAB-BVI27QNV.js} +2 -2
  56. package/webapp/dist/assets/{chunk-4BX2VUAB-DfC5GXR7.js.map → chunk-4BX2VUAB-BVI27QNV.js.map} +1 -1
  57. package/webapp/dist/assets/{chunk-55IACEB6-DSJQfcDq.js → chunk-55IACEB6-D2ECkhpq.js} +2 -2
  58. package/webapp/dist/assets/{chunk-55IACEB6-DSJQfcDq.js.map → chunk-55IACEB6-D2ECkhpq.js.map} +1 -1
  59. package/webapp/dist/assets/{chunk-FMBD7UC4-BWQBo1hf.js → chunk-FMBD7UC4-BAtzNqV5.js} +2 -2
  60. package/webapp/dist/assets/{chunk-FMBD7UC4-BWQBo1hf.js.map → chunk-FMBD7UC4-BAtzNqV5.js.map} +1 -1
  61. package/webapp/dist/assets/{chunk-JSJVCQXG-BzT1-gT-.js → chunk-JSJVCQXG-BYyIDBzB.js} +2 -2
  62. package/webapp/dist/assets/{chunk-JSJVCQXG-BzT1-gT-.js.map → chunk-JSJVCQXG-BYyIDBzB.js.map} +1 -1
  63. package/webapp/dist/assets/{chunk-KX2RTZJC-Bn-AG8vE.js → chunk-KX2RTZJC-Dt3XFfSl.js} +2 -2
  64. package/webapp/dist/assets/{chunk-KX2RTZJC-Bn-AG8vE.js.map → chunk-KX2RTZJC-Dt3XFfSl.js.map} +1 -1
  65. package/webapp/dist/assets/{chunk-NQ4KR5QH-yj2oxjjl.js → chunk-NQ4KR5QH-CZmmNdX5.js} +4 -4
  66. package/webapp/dist/assets/{chunk-NQ4KR5QH-yj2oxjjl.js.map → chunk-NQ4KR5QH-CZmmNdX5.js.map} +1 -1
  67. package/webapp/dist/assets/{chunk-QZHKN3VN-CEKD-_TP.js → chunk-QZHKN3VN-BI_lqvsU.js} +2 -2
  68. package/webapp/dist/assets/{chunk-QZHKN3VN-CEKD-_TP.js.map → chunk-QZHKN3VN-BI_lqvsU.js.map} +1 -1
  69. package/webapp/dist/assets/{chunk-WL4C6EOR-Dp55vgWB.js → chunk-WL4C6EOR-Cd-rWL8V.js} +6 -6
  70. package/webapp/dist/assets/{chunk-WL4C6EOR-Dp55vgWB.js.map → chunk-WL4C6EOR-Cd-rWL8V.js.map} +1 -1
  71. package/webapp/dist/assets/{classDiagram-VBA2DB6C-D4N8D7Nj.js → classDiagram-VBA2DB6C-CGVpNFjf.js} +7 -7
  72. package/webapp/dist/assets/{classDiagram-VBA2DB6C-D4N8D7Nj.js.map → classDiagram-VBA2DB6C-CGVpNFjf.js.map} +1 -1
  73. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-D4N8D7Nj.js → classDiagram-v2-RAHNMMFH-CGVpNFjf.js} +7 -7
  74. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-D4N8D7Nj.js.map → classDiagram-v2-RAHNMMFH-CGVpNFjf.js.map} +1 -1
  75. package/webapp/dist/assets/{clone-DQAXOciv.js → clone-BcAwA2lT.js} +2 -2
  76. package/webapp/dist/assets/{clone-DQAXOciv.js.map → clone-BcAwA2lT.js.map} +1 -1
  77. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-Dn19M4ir.js → cose-bilkent-S5V4N54A-CfkPOIie.js} +2 -2
  78. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-Dn19M4ir.js.map → cose-bilkent-S5V4N54A-CfkPOIie.js.map} +1 -1
  79. package/webapp/dist/assets/{dagre-KLK3FWXG-C92c6zqC.js → dagre-KLK3FWXG-ETpwT3pg.js} +7 -7
  80. package/webapp/dist/assets/{dagre-KLK3FWXG-C92c6zqC.js.map → dagre-KLK3FWXG-ETpwT3pg.js.map} +1 -1
  81. package/webapp/dist/assets/{diagram-E7M64L7V-Cjyz7QMT.js → diagram-E7M64L7V-CAkt3_Wu.js} +8 -8
  82. package/webapp/dist/assets/{diagram-E7M64L7V-Cjyz7QMT.js.map → diagram-E7M64L7V-CAkt3_Wu.js.map} +1 -1
  83. package/webapp/dist/assets/{diagram-IFDJBPK2-D8dhOH6X.js → diagram-IFDJBPK2-BUoOrHGY.js} +7 -7
  84. package/webapp/dist/assets/{diagram-IFDJBPK2-D8dhOH6X.js.map → diagram-IFDJBPK2-BUoOrHGY.js.map} +1 -1
  85. package/webapp/dist/assets/{diagram-P4PSJMXO-DWPLWoKQ.js → diagram-P4PSJMXO-CITRT5KI.js} +7 -7
  86. package/webapp/dist/assets/{diagram-P4PSJMXO-DWPLWoKQ.js.map → diagram-P4PSJMXO-CITRT5KI.js.map} +1 -1
  87. package/webapp/dist/assets/{erDiagram-INFDFZHY-Liu3Eiqm.js → erDiagram-INFDFZHY-Cjpy0ose.js} +5 -5
  88. package/webapp/dist/assets/{erDiagram-INFDFZHY-Liu3Eiqm.js.map → erDiagram-INFDFZHY-Cjpy0ose.js.map} +1 -1
  89. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-BcJzc7PE.js → flowDiagram-PKNHOUZH-CBmrK8ST.js} +7 -7
  90. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-BcJzc7PE.js.map → flowDiagram-PKNHOUZH-CBmrK8ST.js.map} +1 -1
  91. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-Dj17R6YC.js → ganttDiagram-A5KZAMGK-CLoJRKb7.js} +3 -3
  92. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-Dj17R6YC.js.map → ganttDiagram-A5KZAMGK-CLoJRKb7.js.map} +1 -1
  93. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BAmgWHuB.js → gitGraphDiagram-K3NZZRJ6-DcAa_Q3i.js} +8 -8
  94. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BAmgWHuB.js.map → gitGraphDiagram-K3NZZRJ6-DcAa_Q3i.js.map} +1 -1
  95. package/webapp/dist/assets/{graph-G5shJbct.js → graph-CyYArI_M.js} +3 -3
  96. package/webapp/dist/assets/{graph-G5shJbct.js.map → graph-CyYArI_M.js.map} +1 -1
  97. package/webapp/dist/assets/{index-BEmR85VP.js → index-B219Q97D.js} +123 -45
  98. package/webapp/dist/assets/index-B219Q97D.js.map +1 -0
  99. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-B55ho_w2.js → infoDiagram-LFFYTUFH-CXY1BDG-.js} +6 -6
  100. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-B55ho_w2.js.map → infoDiagram-LFFYTUFH-CXY1BDG-.js.map} +1 -1
  101. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-D0bkA7bh.js → ishikawaDiagram-PHBUUO56-CCgHez0F.js} +2 -2
  102. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-D0bkA7bh.js.map → ishikawaDiagram-PHBUUO56-CCgHez0F.js.map} +1 -1
  103. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-COLepLN1.js → journeyDiagram-4ABVD52K-jFEOb3_9.js} +5 -5
  104. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-COLepLN1.js.map → journeyDiagram-4ABVD52K-jFEOb3_9.js.map} +1 -1
  105. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-Cj4QwKRR.js → kanban-definition-K7BYSVSG-g9DIRWk3.js} +3 -3
  106. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-Cj4QwKRR.js.map → kanban-definition-K7BYSVSG-g9DIRWk3.js.map} +1 -1
  107. package/webapp/dist/assets/{layout-eWbM7aoc.js → layout-BvoIJLam.js} +5 -5
  108. package/webapp/dist/assets/{layout-eWbM7aoc.js.map → layout-BvoIJLam.js.map} +1 -1
  109. package/webapp/dist/assets/{linear-D4qe60-s.js → linear-WhxKIgP6.js} +2 -2
  110. package/webapp/dist/assets/{linear-D4qe60-s.js.map → linear-WhxKIgP6.js.map} +1 -1
  111. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ICouzfF0.js → mindmap-definition-YRQLILUH-BXxTVKab.js} +4 -4
  112. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ICouzfF0.js.map → mindmap-definition-YRQLILUH-BXxTVKab.js.map} +1 -1
  113. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-D4ZVmXtl.js → pieDiagram-SKSYHLDU-BVfKuFkc.js} +8 -8
  114. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-D4ZVmXtl.js.map → pieDiagram-SKSYHLDU-BVfKuFkc.js.map} +1 -1
  115. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-1ymuNQzm.js → quadrantDiagram-337W2JSQ-DjOan1Ul.js} +3 -3
  116. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-1ymuNQzm.js.map → quadrantDiagram-337W2JSQ-DjOan1Ul.js.map} +1 -1
  117. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CTK5MmAU.js → requirementDiagram-Z7DCOOCP-CdkkhNJu.js} +4 -4
  118. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CTK5MmAU.js.map → requirementDiagram-Z7DCOOCP-CdkkhNJu.js.map} +1 -1
  119. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-BYqSklsK.js → sankeyDiagram-WA2Y5GQK-Cc7UCE1M.js} +2 -2
  120. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-BYqSklsK.js.map → sankeyDiagram-WA2Y5GQK-Cc7UCE1M.js.map} +1 -1
  121. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-BrXIJ8YR.js → sequenceDiagram-2WXFIKYE-CAf-TzzV.js} +4 -4
  122. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-BrXIJ8YR.js.map → sequenceDiagram-2WXFIKYE-CAf-TzzV.js.map} +1 -1
  123. package/webapp/dist/assets/{stateDiagram-RAJIS63D-BO202mAM.js → stateDiagram-RAJIS63D-CjQh2yGU.js} +9 -9
  124. package/webapp/dist/assets/{stateDiagram-RAJIS63D-BO202mAM.js.map → stateDiagram-RAJIS63D-CjQh2yGU.js.map} +1 -1
  125. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-hN3JtobY.js → stateDiagram-v2-FVOUBMTO-BINESHF-.js} +5 -5
  126. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-hN3JtobY.js.map → stateDiagram-v2-FVOUBMTO-BINESHF-.js.map} +1 -1
  127. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BmxM2CZh.js → timeline-definition-YZTLITO2-FCh1aV2p.js} +3 -3
  128. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BmxM2CZh.js.map → timeline-definition-YZTLITO2-FCh1aV2p.js.map} +1 -1
  129. package/webapp/dist/assets/{treemap-KZPCXAKY-Btqy2bjG.js → treemap-KZPCXAKY-J-UTxKUf.js} +5 -5
  130. package/webapp/dist/assets/{treemap-KZPCXAKY-Btqy2bjG.js.map → treemap-KZPCXAKY-J-UTxKUf.js.map} +1 -1
  131. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-C5MQpm3y.js → vennDiagram-LZ73GAT5-T1yQlS2L.js} +2 -2
  132. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-C5MQpm3y.js.map → vennDiagram-LZ73GAT5-T1yQlS2L.js.map} +1 -1
  133. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-DppnWtyj.js → xychartDiagram-JWTSCODW-KYLvRsLH.js} +3 -3
  134. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-DppnWtyj.js.map → xychartDiagram-JWTSCODW-KYLvRsLH.js.map} +1 -1
  135. package/webapp/dist/index.html +1 -1
  136. package/webapp/dist/assets/index-BEmR85VP.js.map +0 -1
@@ -98,7 +98,7 @@ export type AppsHostKernelReminderRenderMessage = Readonly<{
98
98
  ctx: Readonly<{
99
99
  dialogId: string;
100
100
  reminder: DomindsAppReminderState;
101
- reminderNo: number;
101
+ reminderId: string;
102
102
  workLanguage: LanguageCode;
103
103
  }>;
104
104
  }>;
@@ -319,15 +319,12 @@ function parseAppsHostMessageFromKernel(v) {
319
319
  if (!isRecord(ctx))
320
320
  throw new Error('Invalid reminder_render message: ctx must be object');
321
321
  const dialogId = asString(ctx['dialogId']);
322
- const reminderNoRaw = ctx['reminderNo'];
323
- const reminderNo = typeof reminderNoRaw === 'number' && Number.isFinite(reminderNoRaw)
324
- ? Math.floor(reminderNoRaw)
325
- : null;
322
+ const reminderId = asString(ctx['reminderId']);
326
323
  const workLanguage = asLanguageCode(ctx['workLanguage']);
327
324
  if (!dialogId)
328
325
  throw new Error('Invalid reminder_render message: ctx.dialogId required');
329
- if (reminderNo === null || reminderNo <= 0) {
330
- throw new Error('Invalid reminder_render message: ctx.reminderNo must be positive integer');
326
+ if (!reminderId) {
327
+ throw new Error('Invalid reminder_render message: ctx.reminderId required');
331
328
  }
332
329
  if (!workLanguage)
333
330
  throw new Error('Invalid reminder_render message: ctx.workLanguage invalid');
@@ -339,7 +336,7 @@ function parseAppsHostMessageFromKernel(v) {
339
336
  ctx: {
340
337
  dialogId,
341
338
  reminder: parseReminderState(ctx['reminder'], 'reminder_render.ctx.reminder'),
342
- reminderNo,
339
+ reminderId,
343
340
  workLanguage,
344
341
  },
345
342
  };
@@ -10,6 +10,7 @@ const storage_1 = require("@longrun-ai/kernel/types/storage");
10
10
  const time_1 = require("@longrun-ai/kernel/utils/time");
11
11
  const dialog_1 = require("./dialog");
12
12
  const persistence_1 = require("./persistence");
13
+ const tool_1 = require("./tool");
13
14
  const id_1 = require("./utils/id");
14
15
  const FORK_BASELINE_ANCHOR = (0, storage_1.toRootGenerationAnchor)({
15
16
  rootCourse: 1,
@@ -30,12 +31,16 @@ function anchorAtOrBefore(candidate, cutoff) {
30
31
  return compareRootAnchor(candidate, cutoff) <= 0;
31
32
  }
32
33
  function cloneReminderSnapshot(snapshot) {
33
- return {
34
+ return (0, tool_1.materializeReminder)({
35
+ id: snapshot.id,
34
36
  content: snapshot.content,
35
37
  owner: undefined,
36
38
  meta: snapshot.meta,
37
39
  echoback: snapshot.echoback,
38
- };
40
+ scope: snapshot.scope ?? 'dialog',
41
+ createdAt: snapshot.createdAt,
42
+ priority: snapshot.priority,
43
+ });
39
44
  }
40
45
  function cloneQuestions(questions) {
41
46
  return questions.map((question) => ({
@@ -425,10 +430,12 @@ async function appendForkBaselineState(plan, baselineSubdialogCreatedRecords) {
425
430
  type: 'reminders_reconciled_record',
426
431
  ...FORK_BASELINE_ANCHOR,
427
432
  reminders: plan.reminders.map((reminder) => ({
433
+ id: reminder.id,
428
434
  content: reminder.content,
429
435
  ownerName: reminder.owner?.name,
430
436
  meta: reminder.meta,
431
437
  echoback: reminder.echoback,
438
+ scope: reminder.scope ?? 'dialog',
432
439
  createdAt: reminder.createdAt ?? baselineTs,
433
440
  priority: reminder.priority ?? 'medium',
434
441
  })),
package/dist/dialog.d.ts CHANGED
@@ -107,6 +107,16 @@ export interface DialogInitParams {
107
107
  contextHealth?: ContextHealthSnapshot;
108
108
  };
109
109
  }
110
+ export type VisibleReminderTarget = Readonly<{
111
+ source: 'dialog';
112
+ index: number;
113
+ reminder: Reminder;
114
+ }> | Readonly<{
115
+ source: 'agent_shared';
116
+ index: number;
117
+ reminder: Reminder;
118
+ agentId: string;
119
+ }>;
110
120
  /**
111
121
  * Assignment from supdialog for subdialogs
112
122
  */
@@ -161,6 +171,7 @@ export declare abstract class Dialog {
161
171
  getLastContextHealth(): ContextHealthSnapshot | undefined;
162
172
  getLastContextHealthGenseq(): number | undefined;
163
173
  get remindersVer(): number;
174
+ touchReminders(): void;
164
175
  get supdialog(): Dialog | undefined;
165
176
  getUiLanguage(): LanguageCode;
166
177
  setUiLanguage(language: LanguageCode): void;
@@ -250,10 +261,14 @@ export declare abstract class Dialog {
250
261
  * Post a dialog event using the standard event registry.
251
262
  */
252
263
  postEvent(event: DialogEvent): void;
253
- addReminder(content: string, owner?: ReminderOwner, meta?: JsonValue, position?: number, options?: ReminderOptions): void;
264
+ addReminder(content: string, owner?: ReminderOwner, meta?: JsonValue, position?: number, options?: ReminderOptions): Reminder;
254
265
  deleteReminder(index: number): Reminder;
255
266
  updateReminder(index: number, content: string, meta?: JsonValue, options?: ReminderOptions): Reminder;
256
267
  clearReminders(): void;
268
+ listVisibleReminderTargets(): Promise<VisibleReminderTarget[]>;
269
+ listVisibleReminders(): Promise<Reminder[]>;
270
+ resolveReminderTargetById(reminderId: string): Promise<VisibleReminderTarget | null>;
271
+ private processReminderCollection;
257
272
  /**
258
273
  * Process reminder updates before LLM generation.
259
274
  * Calls updateReminder on each tool that owns reminders to allow them to update/drop/keep their reminders.
package/dist/dialog.js CHANGED
@@ -10,6 +10,7 @@ const async_fifo_mutex_1 = require("./runtime/async-fifo-mutex");
10
10
  const driver_messages_1 = require("./runtime/driver-messages");
11
11
  const inter_dialog_format_1 = require("./runtime/inter-dialog-format");
12
12
  const work_language_1 = require("./runtime/work-language");
13
+ const shared_reminders_1 = require("./shared-reminders");
13
14
  const tool_1 = require("./tool");
14
15
  const id_2 = require("./utils/id");
15
16
  class DialogID {
@@ -63,6 +64,9 @@ function getGlobalDialogMutex(dialogId) {
63
64
  globalDialogMutexes.set(key, created);
64
65
  return created;
65
66
  }
67
+ function compareVisibleReminderTargetOrder(a, b) {
68
+ return (0, tool_1.compareReminderDisplayOrder)(a.reminder, b.reminder);
69
+ }
66
70
  /**
67
71
  * Abstract base class for all dialog types.
68
72
  * Contains common properties and methods shared between RootDialog and SubDialog.
@@ -146,6 +150,10 @@ class Dialog {
146
150
  get remindersVer() {
147
151
  return this._remindersVer;
148
152
  }
153
+ touchReminders() {
154
+ this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
155
+ this._remindersVer++;
156
+ }
149
157
  get supdialog() {
150
158
  return undefined;
151
159
  }
@@ -325,29 +333,27 @@ class Dialog {
325
333
  //
326
334
  // Reminder management methods
327
335
  addReminder(content, owner, meta, position, options) {
328
- const reminder = {
336
+ const reminder = (0, tool_1.materializeReminder)({
329
337
  content,
330
338
  owner,
331
339
  meta,
332
340
  echoback: options?.echoback,
333
- };
341
+ scope: options?.scope ?? 'dialog',
342
+ });
334
343
  const insertIndex = position !== undefined ? position : this.reminders.length;
335
344
  if (insertIndex < 0 || insertIndex > this.reminders.length) {
336
345
  throw new Error(`Invalid reminder position ${insertIndex}. Valid range: 0-${this.reminders.length}`);
337
346
  }
338
347
  this.reminders.splice(insertIndex, 0, reminder);
339
- this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
340
- // Increment version for conditional event emission in driver
341
- this._remindersVer++;
348
+ this.touchReminders();
349
+ return reminder;
342
350
  }
343
351
  deleteReminder(index) {
344
352
  if (index < 0 || index >= this.reminders.length) {
345
353
  throw new Error(`Reminder index ${index} does not exist. Available reminders: 0-${this.reminders.length - 1}`);
346
354
  }
347
355
  const deleted = this.reminders.splice(index, 1)[0];
348
- this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
349
- // Increment version for conditional event emission in driver
350
- this._remindersVer++;
356
+ this.touchReminders();
351
357
  return deleted;
352
358
  }
353
359
  updateReminder(index, content, meta, options) {
@@ -355,34 +361,67 @@ class Dialog {
355
361
  throw new Error(`Reminder index ${index} does not exist. Available reminders: 0-${this.reminders.length - 1}`);
356
362
  }
357
363
  const oldReminder = this.reminders[index];
358
- const updatedReminder = {
364
+ const updatedReminder = (0, tool_1.materializeReminder)({
365
+ id: oldReminder.id,
359
366
  content,
360
367
  owner: oldReminder.owner,
361
368
  meta: meta !== undefined ? meta : oldReminder.meta,
362
369
  echoback: options?.echoback ?? oldReminder.echoback,
363
- };
370
+ scope: oldReminder.scope,
371
+ createdAt: oldReminder.createdAt,
372
+ priority: oldReminder.priority,
373
+ });
364
374
  this.reminders[index] = updatedReminder;
365
- this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
366
- // Increment version for conditional event emission in driver
367
- this._remindersVer++;
375
+ this.touchReminders();
368
376
  return oldReminder;
369
377
  }
370
378
  clearReminders() {
371
379
  this.reminders.length = 0;
372
- this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
373
- // Increment version for conditional event emission in driver
374
- this._remindersVer++;
380
+ this.touchReminders();
375
381
  }
376
- /**
377
- * Process reminder updates before LLM generation.
378
- * Calls updateReminder on each tool that owns reminders to allow them to update/drop/keep their reminders.
379
- * Returns reminder contents with metadata for the frontend.
380
- */
381
- async processReminderUpdates() {
382
+ async listVisibleReminderTargets() {
383
+ const targets = this.reminders.map((reminder, index) => ({
384
+ source: 'dialog',
385
+ index,
386
+ reminder,
387
+ }));
388
+ const sharedReminders = await (0, shared_reminders_1.loadAgentSharedReminders)(this.agentId);
389
+ for (let index = 0; index < sharedReminders.length; index += 1) {
390
+ const reminder = sharedReminders[index];
391
+ if (!reminder)
392
+ continue;
393
+ targets.push({
394
+ source: 'agent_shared',
395
+ index,
396
+ reminder,
397
+ agentId: this.agentId,
398
+ });
399
+ }
400
+ // Visible reminders are always merged into a single newest-first stream regardless of
401
+ // storage scope, so UI rendering, reminder injection, and reminder-id targeting agree.
402
+ targets.sort(compareVisibleReminderTargetOrder);
403
+ return targets;
404
+ }
405
+ async listVisibleReminders() {
406
+ return (await this.listVisibleReminderTargets()).map((target) => target.reminder);
407
+ }
408
+ async resolveReminderTargetById(reminderId) {
409
+ const trimmed = reminderId.trim();
410
+ if (trimmed === '')
411
+ return null;
412
+ const visibleTargets = await this.listVisibleReminderTargets();
413
+ for (const target of visibleTargets) {
414
+ if (target.reminder.id === trimmed) {
415
+ return target;
416
+ }
417
+ }
418
+ return null;
419
+ }
420
+ async processReminderCollection(reminders) {
421
+ let changed = false;
382
422
  const indicesToRemove = [];
383
- for (let i = 0; i < this.reminders.length; i++) {
384
- const reminder = this.reminders[i];
385
- // Skip if the reminder has no owner or the owner doesn't have an updateReminder method
423
+ for (let i = 0; i < reminders.length; i++) {
424
+ const reminder = reminders[i];
386
425
  if (!reminder.owner || !reminder.owner.updateReminder) {
387
426
  continue;
388
427
  }
@@ -391,34 +430,53 @@ class Dialog {
391
430
  switch (result.treatment) {
392
431
  case 'drop':
393
432
  indicesToRemove.push(i);
433
+ changed = true;
394
434
  break;
395
- case 'update':
396
- if (result.updatedContent !== undefined) {
397
- const updatedReminder = {
398
- content: result.updatedContent,
399
- owner: reminder.owner,
400
- meta: result.updatedMeta !== undefined ? result.updatedMeta : reminder.meta,
401
- echoback: reminder.echoback,
402
- };
403
- this.reminders[i] = updatedReminder;
435
+ case 'update': {
436
+ const nextContent = result.updatedContent ?? reminder.content;
437
+ const nextMeta = result.updatedMeta !== undefined ? result.updatedMeta : reminder.meta;
438
+ const updatedReminder = (0, tool_1.materializeReminder)({
439
+ id: reminder.id,
440
+ content: nextContent,
441
+ owner: reminder.owner,
442
+ meta: nextMeta,
443
+ echoback: reminder.echoback,
444
+ scope: reminder.scope,
445
+ createdAt: reminder.createdAt,
446
+ priority: reminder.priority,
447
+ });
448
+ const contentChanged = updatedReminder.content !== reminder.content;
449
+ const metaChanged = updatedReminder.meta !== reminder.meta;
450
+ if (contentChanged || metaChanged) {
451
+ reminders[i] = updatedReminder;
452
+ changed = true;
404
453
  }
405
454
  break;
455
+ }
406
456
  case 'keep':
407
- // No action needed
408
457
  break;
409
458
  }
410
459
  }
411
460
  catch (error) {
412
461
  log_1.log.error(`Error updating reminder from tool ${reminder.owner}:`, error);
413
- // Continue processing other reminders even if one fails
414
462
  }
415
463
  }
416
- // Remove reminders marked for deletion (in reverse order to maintain indices)
417
464
  for (let i = indicesToRemove.length - 1; i >= 0; i--) {
418
- this.reminders.splice(indicesToRemove[i], 1);
465
+ reminders.splice(indicesToRemove[i], 1);
419
466
  }
420
- if (indicesToRemove.length > 0) {
421
- this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
467
+ return changed;
468
+ }
469
+ /**
470
+ * Process reminder updates before LLM generation.
471
+ * Calls updateReminder on each tool that owns reminders to allow them to update/drop/keep their reminders.
472
+ * Returns reminder contents with metadata for the frontend.
473
+ */
474
+ async processReminderUpdates() {
475
+ const sharedReminders = await (0, shared_reminders_1.loadAgentSharedReminders)(this.agentId);
476
+ const localChanged = await this.processReminderCollection(this.reminders);
477
+ const sharedChanged = await this.processReminderCollection(sharedReminders);
478
+ if (localChanged || sharedChanged) {
479
+ this.touchReminders();
422
480
  }
423
481
  // Centralized persistence - called when emitting event.
424
482
  // Must be awaited to preserve ordering (avoid out-of-date writes winning).
@@ -428,12 +486,26 @@ class Dialog {
428
486
  catch (err) {
429
487
  log_1.log.warn('Failed to persist reminders', err, { dialogId: this.id.valueOf() });
430
488
  }
431
- const reminderNoByIndex = (0, tool_1.computeReminderNoByIndex)(this.reminders);
432
- const reminders = this.reminders.map((r, index) => ({
489
+ try {
490
+ await (0, shared_reminders_1.replaceAgentSharedReminders)(this.agentId, sharedReminders);
491
+ }
492
+ catch (err) {
493
+ log_1.log.warn('Failed to persist agent-shared reminders', err, {
494
+ dialogId: this.id.valueOf(),
495
+ agentId: this.agentId,
496
+ });
497
+ }
498
+ const visibleReminders = [
499
+ ...this.reminders.map((reminder) => (0, tool_1.cloneReminder)(reminder)),
500
+ ...sharedReminders,
501
+ ];
502
+ visibleReminders.sort(tool_1.compareReminderDisplayOrder);
503
+ const reminders = visibleReminders.map((r) => ({
433
504
  content: r.content,
434
505
  meta: r.meta,
435
- reminder_no: reminderNoByIndex.get(index),
506
+ reminder_id: r.id,
436
507
  echoback: (0, tool_1.reminderEchoBackEnabled)(r),
508
+ scope: r.scope,
437
509
  }));
438
510
  // Emit full_reminders_update event with complete reminder list including metadata
439
511
  const fullRemindersEvt = {
@@ -1,8 +1,8 @@
1
1
  # Optional provider-level retry controls for kernel dialog driving:
2
- # - llm_retry_max_retries: extra retries after the initial attempt (default 5).
2
+ # - llm_retry_max_retries: extra retries after the initial attempt (default 99; ~41.2h total retry window with current backoff defaults).
3
3
  # - llm_retry_initial_delay_ms: delay before the 1st retry (default 1000).
4
- # - llm_retry_backoff_multiplier: exponential factor between retries (default 2; e.g. 1.5).
5
- # - llm_retry_max_delay_ms: upper bound for retry delay (default 30000).
4
+ # - llm_retry_backoff_multiplier: exponential factor between retries (default 1.5).
5
+ # - llm_retry_max_delay_ms: upper bound for retry delay (default 1800000 / 30m).
6
6
  # - tool_result_max_chars: optional transport-level cap for a single tool-result text payload
7
7
  # before Dominds projects it into the provider request. Use this when a provider/gateway enforces
8
8
  # a stricter per-item string limit than Dominds' built-in defaults.
@@ -49,7 +49,7 @@
49
49
  *
50
50
  * // Turn 2: Tool error (func_result_msg with role='tool'), LLM self-corrects
51
51
  * # docs/e2e-story-test/reminders.md: Tool syntax error recovery
52
- * - message: "Error: Invalid args. Use: add_reminder({ content: string, position: number }) (position=0 means append)."
52
+ * - message: "Error: Invalid args. Use: add_reminder({ content: string, position?: number, scope?: \"dialog\" | \"personal\" }) (omit position to append)."
53
53
  * role: "tool"
54
54
  * response: "Call the function tool `add_reminder` with {\"content\":\"Goals...\",\"position\":1}"
55
55
  */
@@ -50,7 +50,7 @@
50
50
  *
51
51
  * // Turn 2: Tool error (func_result_msg with role='tool'), LLM self-corrects
52
52
  * # docs/e2e-story-test/reminders.md: Tool syntax error recovery
53
- * - message: "Error: Invalid args. Use: add_reminder({ content: string, position: number }) (position=0 means append)."
53
+ * - message: "Error: Invalid args. Use: add_reminder({ content: string, position?: number, scope?: \"dialog\" | \"personal\" }) (omit position to append)."
54
54
  * role: "tool"
55
55
  * response: "Call the function tool `add_reminder` with {\"content\":\"Goals...\",\"position\":1}"
56
56
  */
@@ -28,10 +28,10 @@ const reply_guidance_1 = require("./reply-guidance");
28
28
  const runtime_1 = require("./runtime");
29
29
  const tellask_special_1 = require("./tellask-special");
30
30
  const KERNEL_DRIVER_DEFAULT_RETRY_POLICY = {
31
- maxRetries: 5,
31
+ maxRetries: 99, // long total retry window to survive major down-time by llm providers
32
32
  initialDelayMs: 1000,
33
- backoffMultiplier: 2,
34
- maxDelayMs: 30000,
33
+ backoffMultiplier: 1.5,
34
+ maxDelayMs: 30 * 60 * 1000, // 30 minutes
35
35
  };
36
36
  const KERNEL_DRIVER_EMPTY_LLM_RESPONSE_ERROR_CODE = 'DOMINDS_LLM_EMPTY_RESPONSE';
37
37
  class KernelDriverInterruptedError extends Error {
@@ -487,29 +487,25 @@ function resolveUpNextPrompt(dlg) {
487
487
  };
488
488
  }
489
489
  async function renderRemindersForContext(dlg) {
490
- if (dlg.reminders.length === 0)
490
+ const reminders = await dlg.listVisibleReminders();
491
+ if (reminders.length === 0)
491
492
  return [];
492
493
  const language = (0, work_language_1.getWorkLanguage)();
493
- const reminderNoByIndex = (0, tool_1.computeReminderNoByIndex)(dlg.reminders);
494
494
  const rendered = [];
495
- for (let index = 0; index < dlg.reminders.length; index += 1) {
496
- const reminder = dlg.reminders[index];
495
+ for (const reminder of reminders) {
497
496
  if (!reminder || !(0, tool_1.reminderEchoBackEnabled)(reminder)) {
498
497
  continue;
499
498
  }
500
- const reminderNo = reminderNoByIndex.get(index);
501
- if (reminderNo === undefined) {
502
- continue;
503
- }
504
499
  if (reminder.owner) {
505
- rendered.push(await reminder.owner.renderReminder(dlg, reminder, reminderNo - 1));
500
+ rendered.push(await reminder.owner.renderReminder(dlg, reminder));
506
501
  continue;
507
502
  }
508
503
  rendered.push({
509
504
  type: 'transient_guide_msg',
510
505
  role: 'assistant',
511
- content: (0, driver_messages_1.formatReminderItemGuide)(language, reminderNo, reminder.content, {
506
+ content: (0, driver_messages_1.formatReminderItemGuide)(language, reminder.id, reminder.content, {
512
507
  meta: reminder.meta,
508
+ scope: reminder.scope,
513
509
  }),
514
510
  });
515
511
  }
@@ -354,10 +354,18 @@ async function sleepWithAbort(ms, abortSignal) {
354
354
  if (abortSignal?.aborted) {
355
355
  throw new Error('AbortError');
356
356
  }
357
- await new Promise((resolve) => setTimeout(resolve, ms));
358
- if (abortSignal?.aborted) {
359
- throw new Error('AbortError');
360
- }
357
+ await new Promise((resolve, reject) => {
358
+ const timer = setTimeout(() => {
359
+ abortSignal?.removeEventListener('abort', onAbort);
360
+ resolve();
361
+ }, ms);
362
+ const onAbort = () => {
363
+ clearTimeout(timer);
364
+ abortSignal?.removeEventListener('abort', onAbort);
365
+ reject(new Error('AbortError'));
366
+ };
367
+ abortSignal?.addEventListener('abort', onAbort, { once: true });
368
+ });
361
369
  }
362
370
  function normalizeRetryInitialDelayMs(value) {
363
371
  if (!Number.isFinite(value))
@@ -167,7 +167,7 @@ function getMemoryPromptCopy(ctx) {
167
167
  progressLine: '- 更新 `progress` 时:它必须始终是可供全队扫读的完整当前快照,而不是只追加自己这一轮的零散笔记。',
168
168
  injectedTaskdocLine: '- 重要:差遣牒内容会被系统以内联形式注入到上下文中(本轮生成视角下即为最新;注入内容不包括全局约束)。需要回顾时请直接基于上下文里的差遣牒内容回顾与决策,不要试图用通用文件工具读取 `*.tsk/` 下的文件(会被拒绝)。',
169
169
  constraintsLine: '- 约定:`constraints` 只写任务特有的硬要求,不得写入系统提示/工具文档里已明确且由系统强制执行的通用规则(例如 `*.tsk/` 封装禁止通用文件工具)。一经发现重复,必须删除并告知用户。',
170
- remindersLine: '- 提醒项(即编号提醒,工作集):当前对话的高频工作记录/关键细节(偏私有,不作为全队公告);默认保持少量(常见 1–3 条),优先 `update_reminder` 压缩/合并,不再需要就 `delete_reminder`。准备 `clear_mind` 开启新一程对话时,默认整理成“结构化接续包提醒项”;其中只保留差遣牒未覆盖、但恢复工作容易丢的细节(如第一步、关键定位、运行/验证信息、临时 ids/路径)。若系统已把当前程切到吃紧/告急处置态,则允许先保留多条粗略提醒项把信息带过桥;当前程只做保信息 + clear_mind;只有系统实际开启新一程后,第一步才是以清醒头脑复核并整理这些接续包/粗略提醒项:删除冗余、纠正偏激或失真的过桥思路、压缩成高质量提醒项。',
170
+ remindersLine: '- 提醒项(以 `reminder_id` 标识,工作集):当前对话的高频工作记录/关键细节(偏私有,不作为全队公告);默认保持少量(常见 1–3 条),优先 `update_reminder` 压缩/合并,不再需要就 `delete_reminder`。准备 `clear_mind` 开启新一程对话时,默认整理成“结构化接续包提醒项”;其中只保留差遣牒未覆盖、但恢复工作容易丢的细节(如第一步、关键定位、运行/验证信息、临时 ids/路径)。若系统已把当前程切到吃紧/告急处置态,则允许先保留多条粗略提醒项把信息带过桥;当前程只做保信息 + clear_mind;只有系统实际开启新一程后,第一步才是以清醒头脑复核并整理这些接续包/粗略提醒项:删除冗余、纠正偏激或失真的过桥思路、压缩成高质量提醒项。',
171
171
  teamMemoryLine: '- 团队记忆:稳定的团队约定/工程规约(跨任务共享)。',
172
172
  personalMemoryLine: '- 个人记忆:稳定的个人习惯/偏好与职责域知识;记忆会在每次生成时自动注入上下文,应保持少量且准确(关键文档/代码的精确路径 + 最小必要事实)。不要记录具体任务状态。',
173
173
  subdialogDutyLine: `你当前处于支线对话:此处不允许 \`change_mind\`。当你判断需要更新差遣牒(尤其是 progress 公告牌)时,请在合适时机直接诉请差遣牒维护人 \`@${ctx.taskdocMaintainerId}\` 执行更新,并给出你已合并好的“新全文/替换稿”(用于替换对应章节全文)。不要声称已更新,除非看到回执。`,
@@ -191,7 +191,7 @@ function getMemoryPromptCopy(ctx) {
191
191
  progressLine: '- When updating `progress`, keep it as a complete, team-scannable current snapshot instead of appending only your own latest notes.',
192
192
  injectedTaskdocLine: '- Important: the Taskdoc content is injected inline into the context (the latest as of this generation; injected content excludes global constraints). Review the injected Taskdoc instead of trying to read files under `*.tsk/` via general file tools (they will be rejected).',
193
193
  constraintsLine: '- Convention: Taskdoc `constraints` must contain task-specific requirements only; do not include global, system-enforced rules already stated in system prompt/tool docs (e.g. `.tsk/` encapsulation bans general file tools). If duplication is found, you MUST remove it and notify the user.',
194
- remindersLine: '- Reminders (i.e. numbered reminders, working set): your high-frequency per-dialog worklog + critical details (not a team bulletin board); keep it small by default (often 1–3 items), prefer `update_reminder` to compress/merge, and delete when obsolete. When preparing `clear_mind` to start a new course, default to a structured continuation-package reminder that keeps only details not already covered by Taskdoc but easy to lose during resume (first step, key pointers, run/verify info, volatile ids/paths). If the system has already put the current course into caution/critical remediation, rough multi-reminder bridge notes are acceptable; in the current course, only preserve volatile information and clear_mind. Only after the system actually starts the new course does the mandatory first step become reviewing and rewriting those continuation/rough reminders with a clear head: remove redundancy, correct biased or distorted bridge notes, and compress them into high-quality reminders.',
194
+ remindersLine: '- Reminders (addressed by `reminder_id`, working set): your high-frequency per-dialog worklog + critical details (not a team bulletin board); keep it small by default (often 1–3 items), prefer `update_reminder` to compress/merge, and delete when obsolete. When preparing `clear_mind` to start a new course, default to a structured continuation-package reminder that keeps only details not already covered by Taskdoc but easy to lose during resume (first step, key pointers, run/verify info, volatile ids/paths). If the system has already put the current course into caution/critical remediation, rough multi-reminder bridge notes are acceptable; in the current course, only preserve volatile information and clear_mind. Only after the system actually starts the new course does the mandatory first step become reviewing and rewriting those continuation/rough reminders with a clear head: remove redundancy, correct biased or distorted bridge notes, and compress them into high-quality reminders.',
195
195
  teamMemoryLine: '- Team memory: stable shared conventions (cross-task).',
196
196
  personalMemoryLine: '- Personal memory: stable personal habits/preferences and responsibility-scope knowledge. Memory is automatically injected into context on each generation: keep it small and accurate (exact key doc/code paths + minimal key facts); do not store per-task state.',
197
197
  subdialogDutyLine: `You are currently in a subdialog: \`change_mind\` is not allowed here. When Taskdoc should be updated (especially the shared progress bulletin board), tellask the Taskdoc maintainer \`@${ctx.taskdocMaintainerId}\` with a fully merged replacement draft (full-section replacement). Do not claim it is updated until you see a receipt.`,
@@ -52,6 +52,7 @@ const log_1 = require("./log");
52
52
  const async_fifo_mutex_1 = require("./runtime/async-fifo-mutex");
53
53
  const reply_prompt_copy_1 = require("./runtime/reply-prompt-copy");
54
54
  const work_language_1 = require("./runtime/work-language");
55
+ const tool_1 = require("./tool");
55
56
  const registry_1 = require("./tools/registry");
56
57
  function getErrorCode(error) {
57
58
  if (typeof error !== 'object' || error === null)
@@ -63,22 +64,25 @@ function isRecord(value) {
63
64
  return typeof value === 'object' && value !== null;
64
65
  }
65
66
  function serializeReminderSnapshot(reminder) {
66
- const persistedReminder = reminder;
67
67
  return {
68
+ id: reminder.id,
68
69
  content: reminder.content,
69
70
  ownerName: reminder.owner?.name,
70
71
  meta: reminder.meta,
71
72
  echoback: reminder.echoback,
72
- createdAt: persistedReminder.createdAt ?? (0, time_1.formatUnifiedTimestamp)(new Date()),
73
- priority: persistedReminder.priority ?? 'medium',
73
+ scope: reminder.scope ?? 'dialog',
74
+ createdAt: reminder.createdAt ?? (0, time_1.formatUnifiedTimestamp)(new Date()),
75
+ priority: reminder.priority ?? 'medium',
74
76
  };
75
77
  }
76
78
  function cloneReminderSnapshot(snapshot) {
77
79
  return {
80
+ id: snapshot.id,
78
81
  content: snapshot.content,
79
82
  ownerName: snapshot.ownerName,
80
83
  meta: snapshot.meta,
81
84
  echoback: snapshot.echoback,
85
+ scope: snapshot.scope,
82
86
  createdAt: snapshot.createdAt,
83
87
  priority: snapshot.priority,
84
88
  };
@@ -3471,14 +3475,15 @@ class DialogPersistence {
3471
3475
  await fs.promises.mkdir(dialogPath, { recursive: true });
3472
3476
  const remindersFilePath = path.join(dialogPath, 'reminders.json');
3473
3477
  const reminderState = {
3474
- reminders: reminders.map((r, index) => ({
3475
- id: `reminder-${index}`,
3478
+ reminders: reminders.map((r) => ({
3479
+ id: r.id,
3476
3480
  content: r.content,
3477
3481
  ownerName: r.owner ? r.owner.name : undefined,
3478
3482
  meta: r.meta,
3479
3483
  echoback: r.echoback,
3480
- createdAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
3481
- priority: 'medium',
3484
+ scope: r.scope ?? 'dialog',
3485
+ createdAt: r.createdAt ?? (0, time_1.formatUnifiedTimestamp)(new Date()),
3486
+ priority: r.priority ?? 'medium',
3482
3487
  })),
3483
3488
  updatedAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
3484
3489
  };
@@ -3505,16 +3510,18 @@ class DialogPersistence {
3505
3510
  const reminderState = JSON.parse(content);
3506
3511
  return reminderState.reminders.map((r) => {
3507
3512
  const ownerNameFromFile = typeof r.ownerName === 'string' ? r.ownerName : undefined;
3513
+ // Reminder metadata is owner-private. Rebind strictly through persisted ownerName.
3508
3514
  const owner = ownerNameFromFile ? (0, registry_1.getReminderOwner)(ownerNameFromFile) : undefined;
3509
- return {
3515
+ return (0, tool_1.materializeReminder)({
3510
3516
  id: r.id,
3511
3517
  content: r.content,
3512
3518
  owner,
3513
3519
  meta: r.meta,
3514
3520
  echoback: r.echoback,
3521
+ scope: r.scope ?? 'dialog',
3515
3522
  createdAt: r.createdAt,
3516
3523
  priority: r.priority,
3517
- };
3524
+ });
3518
3525
  });
3519
3526
  }
3520
3527
  catch (error) {
package/dist/priming.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { PersistedDialogRecord } from '@longrun-ai/kernel/types/storage';
3
3
  import type { DialogPrimingInput, DialogStatusKind } from '@longrun-ai/kernel/types/wire';
4
4
  import type { Dialog } from './dialog';
5
5
  import { DialogID } from './dialog';
6
- import type { Reminder } from './tool';
6
+ import { type Reminder } from './tool';
7
7
  type StripTs<T> = T extends {
8
8
  ts: string;
9
9
  } ? Omit<T, 'ts'> : never;