dominds 1.12.0 → 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 (121) hide show
  1. package/dist/dialog.js +8 -0
  2. package/dist/llm/gen/mock.d.ts +1 -1
  3. package/dist/llm/gen/mock.js +1 -1
  4. package/dist/llm/kernel-driver/drive.js +1 -0
  5. package/dist/priming.js +6 -3
  6. package/dist/runtime/driver-messages.d.ts +1 -0
  7. package/dist/runtime/driver-messages.js +15 -6
  8. package/dist/shared-reminders.js +1 -9
  9. package/dist/tool.d.ts +2 -1
  10. package/dist/tool.js +12 -0
  11. package/dist/tools/app-reminders.js +2 -0
  12. package/dist/tools/ctrl.js +97 -26
  13. package/dist/tools/os.js +179 -75
  14. package/dist/tools/prompts/control/en/errors.md +10 -6
  15. package/dist/tools/prompts/control/en/index.md +7 -2
  16. package/dist/tools/prompts/control/en/principles.md +28 -9
  17. package/dist/tools/prompts/control/en/scenarios.md +13 -0
  18. package/dist/tools/prompts/control/en/tools.md +4 -3
  19. package/dist/tools/prompts/control/zh/errors.md +10 -6
  20. package/dist/tools/prompts/control/zh/index.md +7 -2
  21. package/dist/tools/prompts/control/zh/principles.md +28 -9
  22. package/dist/tools/prompts/control/zh/scenarios.md +13 -0
  23. package/dist/tools/prompts/control/zh/tools.md +4 -3
  24. package/dist/tools/prompts/os/en/tools.md +1 -1
  25. package/dist/tools/prompts/os/zh/tools.md +1 -1
  26. package/package.json +1 -1
  27. package/webapp/dist/assets/{_basePickBy-DMF7NBah.js → _basePickBy-B1lGEusm.js} +3 -3
  28. package/webapp/dist/assets/{_basePickBy-DMF7NBah.js.map → _basePickBy-B1lGEusm.js.map} +1 -1
  29. package/webapp/dist/assets/{_baseUniq-DeiPg60R.js → _baseUniq-SGAsMSaE.js} +2 -2
  30. package/webapp/dist/assets/{_baseUniq-DeiPg60R.js.map → _baseUniq-SGAsMSaE.js.map} +1 -1
  31. package/webapp/dist/assets/{arc-f0CvrI__.js → arc-B2joU0eL.js} +2 -2
  32. package/webapp/dist/assets/{arc-f0CvrI__.js.map → arc-B2joU0eL.js.map} +1 -1
  33. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CrjP1jdI.js → architectureDiagram-2XIMDMQ5-CsuG-Xa3.js} +7 -7
  34. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CrjP1jdI.js.map → architectureDiagram-2XIMDMQ5-CsuG-Xa3.js.map} +1 -1
  35. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-BQMfXYC9.js → blockDiagram-WCTKOSBZ-D8_SVEGn.js} +7 -7
  36. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-BQMfXYC9.js.map → blockDiagram-WCTKOSBZ-D8_SVEGn.js.map} +1 -1
  37. package/webapp/dist/assets/{c4Diagram-IC4MRINW-UmHA8MkS.js → c4Diagram-IC4MRINW-D_lhLw36.js} +3 -3
  38. package/webapp/dist/assets/{c4Diagram-IC4MRINW-UmHA8MkS.js.map → c4Diagram-IC4MRINW-D_lhLw36.js.map} +1 -1
  39. package/webapp/dist/assets/{channel-DC4CexVY.js → channel-BI76pqQS.js} +2 -2
  40. package/webapp/dist/assets/{channel-DC4CexVY.js.map → channel-BI76pqQS.js.map} +1 -1
  41. package/webapp/dist/assets/{chunk-4BX2VUAB-DdX7m7QE.js → chunk-4BX2VUAB-BVI27QNV.js} +2 -2
  42. package/webapp/dist/assets/{chunk-4BX2VUAB-DdX7m7QE.js.map → chunk-4BX2VUAB-BVI27QNV.js.map} +1 -1
  43. package/webapp/dist/assets/{chunk-55IACEB6-DmhQbxLG.js → chunk-55IACEB6-D2ECkhpq.js} +2 -2
  44. package/webapp/dist/assets/{chunk-55IACEB6-DmhQbxLG.js.map → chunk-55IACEB6-D2ECkhpq.js.map} +1 -1
  45. package/webapp/dist/assets/{chunk-FMBD7UC4-SJ7NGBwq.js → chunk-FMBD7UC4-BAtzNqV5.js} +2 -2
  46. package/webapp/dist/assets/{chunk-FMBD7UC4-SJ7NGBwq.js.map → chunk-FMBD7UC4-BAtzNqV5.js.map} +1 -1
  47. package/webapp/dist/assets/{chunk-JSJVCQXG-DCLKNp5s.js → chunk-JSJVCQXG-BYyIDBzB.js} +2 -2
  48. package/webapp/dist/assets/{chunk-JSJVCQXG-DCLKNp5s.js.map → chunk-JSJVCQXG-BYyIDBzB.js.map} +1 -1
  49. package/webapp/dist/assets/{chunk-KX2RTZJC-CCgbTx2V.js → chunk-KX2RTZJC-Dt3XFfSl.js} +2 -2
  50. package/webapp/dist/assets/{chunk-KX2RTZJC-CCgbTx2V.js.map → chunk-KX2RTZJC-Dt3XFfSl.js.map} +1 -1
  51. package/webapp/dist/assets/{chunk-NQ4KR5QH-1wLPI2Hu.js → chunk-NQ4KR5QH-CZmmNdX5.js} +4 -4
  52. package/webapp/dist/assets/{chunk-NQ4KR5QH-1wLPI2Hu.js.map → chunk-NQ4KR5QH-CZmmNdX5.js.map} +1 -1
  53. package/webapp/dist/assets/{chunk-QZHKN3VN-C6JKbhyt.js → chunk-QZHKN3VN-BI_lqvsU.js} +2 -2
  54. package/webapp/dist/assets/{chunk-QZHKN3VN-C6JKbhyt.js.map → chunk-QZHKN3VN-BI_lqvsU.js.map} +1 -1
  55. package/webapp/dist/assets/{chunk-WL4C6EOR-Cs1vNkue.js → chunk-WL4C6EOR-Cd-rWL8V.js} +6 -6
  56. package/webapp/dist/assets/{chunk-WL4C6EOR-Cs1vNkue.js.map → chunk-WL4C6EOR-Cd-rWL8V.js.map} +1 -1
  57. package/webapp/dist/assets/{classDiagram-VBA2DB6C-DVGl2GYa.js → classDiagram-VBA2DB6C-CGVpNFjf.js} +7 -7
  58. package/webapp/dist/assets/{classDiagram-VBA2DB6C-DVGl2GYa.js.map → classDiagram-VBA2DB6C-CGVpNFjf.js.map} +1 -1
  59. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-DVGl2GYa.js → classDiagram-v2-RAHNMMFH-CGVpNFjf.js} +7 -7
  60. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-DVGl2GYa.js.map → classDiagram-v2-RAHNMMFH-CGVpNFjf.js.map} +1 -1
  61. package/webapp/dist/assets/{clone-DZkqssLU.js → clone-BcAwA2lT.js} +2 -2
  62. package/webapp/dist/assets/{clone-DZkqssLU.js.map → clone-BcAwA2lT.js.map} +1 -1
  63. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-B0iqLjQo.js → cose-bilkent-S5V4N54A-CfkPOIie.js} +2 -2
  64. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-B0iqLjQo.js.map → cose-bilkent-S5V4N54A-CfkPOIie.js.map} +1 -1
  65. package/webapp/dist/assets/{dagre-KLK3FWXG-CPyJxHzG.js → dagre-KLK3FWXG-ETpwT3pg.js} +7 -7
  66. package/webapp/dist/assets/{dagre-KLK3FWXG-CPyJxHzG.js.map → dagre-KLK3FWXG-ETpwT3pg.js.map} +1 -1
  67. package/webapp/dist/assets/{diagram-E7M64L7V-CJFjs8vW.js → diagram-E7M64L7V-CAkt3_Wu.js} +8 -8
  68. package/webapp/dist/assets/{diagram-E7M64L7V-CJFjs8vW.js.map → diagram-E7M64L7V-CAkt3_Wu.js.map} +1 -1
  69. package/webapp/dist/assets/{diagram-IFDJBPK2-BroetsVc.js → diagram-IFDJBPK2-BUoOrHGY.js} +7 -7
  70. package/webapp/dist/assets/{diagram-IFDJBPK2-BroetsVc.js.map → diagram-IFDJBPK2-BUoOrHGY.js.map} +1 -1
  71. package/webapp/dist/assets/{diagram-P4PSJMXO-Bh1Ix0CA.js → diagram-P4PSJMXO-CITRT5KI.js} +7 -7
  72. package/webapp/dist/assets/{diagram-P4PSJMXO-Bh1Ix0CA.js.map → diagram-P4PSJMXO-CITRT5KI.js.map} +1 -1
  73. package/webapp/dist/assets/{erDiagram-INFDFZHY-y3jE2GhO.js → erDiagram-INFDFZHY-Cjpy0ose.js} +5 -5
  74. package/webapp/dist/assets/{erDiagram-INFDFZHY-y3jE2GhO.js.map → erDiagram-INFDFZHY-Cjpy0ose.js.map} +1 -1
  75. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Dbj0amdk.js → flowDiagram-PKNHOUZH-CBmrK8ST.js} +7 -7
  76. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Dbj0amdk.js.map → flowDiagram-PKNHOUZH-CBmrK8ST.js.map} +1 -1
  77. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-z46SRQdq.js → ganttDiagram-A5KZAMGK-CLoJRKb7.js} +3 -3
  78. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-z46SRQdq.js.map → ganttDiagram-A5KZAMGK-CLoJRKb7.js.map} +1 -1
  79. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-Byh8x6U3.js → gitGraphDiagram-K3NZZRJ6-DcAa_Q3i.js} +8 -8
  80. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-Byh8x6U3.js.map → gitGraphDiagram-K3NZZRJ6-DcAa_Q3i.js.map} +1 -1
  81. package/webapp/dist/assets/{graph-1b2bXlyQ.js → graph-CyYArI_M.js} +3 -3
  82. package/webapp/dist/assets/{graph-1b2bXlyQ.js.map → graph-CyYArI_M.js.map} +1 -1
  83. package/webapp/dist/assets/{index-DuC83Z7v.js → index-B219Q97D.js} +118 -43
  84. package/webapp/dist/assets/{index-DuC83Z7v.js.map → index-B219Q97D.js.map} +1 -1
  85. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DeJTilk1.js → infoDiagram-LFFYTUFH-CXY1BDG-.js} +6 -6
  86. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DeJTilk1.js.map → infoDiagram-LFFYTUFH-CXY1BDG-.js.map} +1 -1
  87. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-9wW_cCA_.js → ishikawaDiagram-PHBUUO56-CCgHez0F.js} +2 -2
  88. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-9wW_cCA_.js.map → ishikawaDiagram-PHBUUO56-CCgHez0F.js.map} +1 -1
  89. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-Ds6Mi8Fd.js → journeyDiagram-4ABVD52K-jFEOb3_9.js} +5 -5
  90. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-Ds6Mi8Fd.js.map → journeyDiagram-4ABVD52K-jFEOb3_9.js.map} +1 -1
  91. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-21p94fVM.js → kanban-definition-K7BYSVSG-g9DIRWk3.js} +3 -3
  92. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-21p94fVM.js.map → kanban-definition-K7BYSVSG-g9DIRWk3.js.map} +1 -1
  93. package/webapp/dist/assets/{layout-oxTVuSAI.js → layout-BvoIJLam.js} +5 -5
  94. package/webapp/dist/assets/{layout-oxTVuSAI.js.map → layout-BvoIJLam.js.map} +1 -1
  95. package/webapp/dist/assets/{linear-C-ktuT2j.js → linear-WhxKIgP6.js} +2 -2
  96. package/webapp/dist/assets/{linear-C-ktuT2j.js.map → linear-WhxKIgP6.js.map} +1 -1
  97. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-C2OBFt0m.js → mindmap-definition-YRQLILUH-BXxTVKab.js} +4 -4
  98. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-C2OBFt0m.js.map → mindmap-definition-YRQLILUH-BXxTVKab.js.map} +1 -1
  99. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-BnlbMX50.js → pieDiagram-SKSYHLDU-BVfKuFkc.js} +8 -8
  100. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-BnlbMX50.js.map → pieDiagram-SKSYHLDU-BVfKuFkc.js.map} +1 -1
  101. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-CCZwkFSq.js → quadrantDiagram-337W2JSQ-DjOan1Ul.js} +3 -3
  102. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-CCZwkFSq.js.map → quadrantDiagram-337W2JSQ-DjOan1Ul.js.map} +1 -1
  103. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CknHzpb9.js → requirementDiagram-Z7DCOOCP-CdkkhNJu.js} +4 -4
  104. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CknHzpb9.js.map → requirementDiagram-Z7DCOOCP-CdkkhNJu.js.map} +1 -1
  105. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-dnzSk8ya.js → sankeyDiagram-WA2Y5GQK-Cc7UCE1M.js} +2 -2
  106. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-dnzSk8ya.js.map → sankeyDiagram-WA2Y5GQK-Cc7UCE1M.js.map} +1 -1
  107. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-CYPr_LFs.js → sequenceDiagram-2WXFIKYE-CAf-TzzV.js} +4 -4
  108. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-CYPr_LFs.js.map → sequenceDiagram-2WXFIKYE-CAf-TzzV.js.map} +1 -1
  109. package/webapp/dist/assets/{stateDiagram-RAJIS63D-CY72bpXz.js → stateDiagram-RAJIS63D-CjQh2yGU.js} +9 -9
  110. package/webapp/dist/assets/{stateDiagram-RAJIS63D-CY72bpXz.js.map → stateDiagram-RAJIS63D-CjQh2yGU.js.map} +1 -1
  111. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BVaL7PC4.js → stateDiagram-v2-FVOUBMTO-BINESHF-.js} +5 -5
  112. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BVaL7PC4.js.map → stateDiagram-v2-FVOUBMTO-BINESHF-.js.map} +1 -1
  113. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DaVyxe1k.js → timeline-definition-YZTLITO2-FCh1aV2p.js} +3 -3
  114. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DaVyxe1k.js.map → timeline-definition-YZTLITO2-FCh1aV2p.js.map} +1 -1
  115. package/webapp/dist/assets/{treemap-KZPCXAKY-DDbREGp8.js → treemap-KZPCXAKY-J-UTxKUf.js} +5 -5
  116. package/webapp/dist/assets/{treemap-KZPCXAKY-DDbREGp8.js.map → treemap-KZPCXAKY-J-UTxKUf.js.map} +1 -1
  117. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-BDQOvFmI.js → vennDiagram-LZ73GAT5-T1yQlS2L.js} +2 -2
  118. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-BDQOvFmI.js.map → vennDiagram-LZ73GAT5-T1yQlS2L.js.map} +1 -1
  119. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BdduRgQG.js → xychartDiagram-JWTSCODW-KYLvRsLH.js} +3 -3
  120. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BdduRgQG.js.map → xychartDiagram-JWTSCODW-KYLvRsLH.js.map} +1 -1
  121. package/webapp/dist/index.html +1 -1
package/dist/dialog.js CHANGED
@@ -64,6 +64,9 @@ function getGlobalDialogMutex(dialogId) {
64
64
  globalDialogMutexes.set(key, created);
65
65
  return created;
66
66
  }
67
+ function compareVisibleReminderTargetOrder(a, b) {
68
+ return (0, tool_1.compareReminderDisplayOrder)(a.reminder, b.reminder);
69
+ }
67
70
  /**
68
71
  * Abstract base class for all dialog types.
69
72
  * Contains common properties and methods shared between RootDialog and SubDialog.
@@ -394,6 +397,9 @@ class Dialog {
394
397
  agentId: this.agentId,
395
398
  });
396
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);
397
403
  return targets;
398
404
  }
399
405
  async listVisibleReminders() {
@@ -493,11 +499,13 @@ class Dialog {
493
499
  ...this.reminders.map((reminder) => (0, tool_1.cloneReminder)(reminder)),
494
500
  ...sharedReminders,
495
501
  ];
502
+ visibleReminders.sort(tool_1.compareReminderDisplayOrder);
496
503
  const reminders = visibleReminders.map((r) => ({
497
504
  content: r.content,
498
505
  meta: r.meta,
499
506
  reminder_id: r.id,
500
507
  echoback: (0, tool_1.reminderEchoBackEnabled)(r),
508
+ scope: r.scope,
501
509
  }));
502
510
  // Emit full_reminders_update event with complete reminder list including metadata
503
511
  const fullRemindersEvt = {
@@ -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
  */
@@ -505,6 +505,7 @@ async function renderRemindersForContext(dlg) {
505
505
  role: 'assistant',
506
506
  content: (0, driver_messages_1.formatReminderItemGuide)(language, reminder.id, reminder.content, {
507
507
  meta: reminder.meta,
508
+ scope: reminder.scope,
508
509
  }),
509
510
  });
510
511
  }
package/dist/priming.js CHANGED
@@ -176,8 +176,11 @@ function parseReminderSnapshots(frontmatter) {
176
176
  throw new Error(`${context}.echoback must be a boolean when provided`);
177
177
  }
178
178
  const scope = item['scope'];
179
- if (scope !== undefined && scope !== 'dialog' && scope !== 'agent_shared') {
180
- throw new Error(`${context}.scope must be "dialog" or "agent_shared" when provided`);
179
+ if (scope !== undefined &&
180
+ scope !== 'dialog' &&
181
+ scope !== 'personal' &&
182
+ scope !== 'agent_shared') {
183
+ throw new Error(`${context}.scope must be "dialog", "personal", or "agent_shared" when provided`);
181
184
  }
182
185
  const createdAt = item['createdAt'];
183
186
  if (createdAt !== undefined && typeof createdAt !== 'string') {
@@ -190,7 +193,7 @@ function parseReminderSnapshots(frontmatter) {
190
193
  ownerName: typeof ownerName === 'string' ? ownerName.trim() : undefined,
191
194
  meta,
192
195
  echoback,
193
- scope: scope === 'dialog' || scope === 'agent_shared' ? scope : undefined,
196
+ scope: scope === 'dialog' || scope === 'personal' || scope === 'agent_shared' ? scope : undefined,
194
197
  createdAt: typeof createdAt === 'string' ? createdAt : undefined,
195
198
  priority,
196
199
  });
@@ -11,6 +11,7 @@ export declare function formatNewCourseStartPrompt(language: LanguageCode, args:
11
11
  export declare function formatDiligenceAutoContinuePrompt(language: LanguageCode, diligenceText: string): string;
12
12
  export declare function formatReminderItemGuide(language: LanguageCode, reminderId: string, content: string, options?: {
13
13
  meta?: unknown;
14
+ scope?: 'dialog' | 'personal' | 'agent_shared';
14
15
  }): string;
15
16
  export declare function formatQ4HDiligencePushBudgetExhausted(language: LanguageCode, args: {
16
17
  maxInjectCount: number;
@@ -156,6 +156,7 @@ function formatReminderItemGuide(language, reminderId, content, options) {
156
156
  // `options.meta` is persisted JSON coming from tools. Runtime shape checks are unavoidable here
157
157
  // to keep reminder ownership/management loosely coupled and extensible.
158
158
  const metaValue = options && 'meta' in options ? options.meta : undefined;
159
+ const scope = options?.scope;
159
160
  const isContinuationPackageReminder = isRecord(metaValue) && metaValue['kind'] === 'continuation_package';
160
161
  const isPendingTellaskReminder = isRecord(metaValue) && metaValue['kind'] === 'pending_tellask';
161
162
  const pendingTellaskCount = isPendingTellaskReminder && typeof metaValue['pendingCount'] === 'number'
@@ -235,11 +236,15 @@ function formatReminderItemGuide(language, reminderId, content, options) {
235
236
  ].join('\n');
236
237
  }
237
238
  return [
238
- `提醒项 [${reminderId}]`,
239
+ `提醒项 [${reminderId}]${scope === 'personal' ? '(个人范围)' : ''}`,
239
240
  '',
240
- '这是我给自己的显眼提示,用于保留当前对话里容易丢的工作信息;我不把它自动当成系统下发的下一步动作。',
241
+ scope === 'personal'
242
+ ? '这是我给自己的个人范围显眼提示;在所有由我主理的后续对话里都会看到它。我不把它自动当成系统下发的下一步动作。'
243
+ : '这是我给自己的显眼提示,用于保留当前对话里容易丢的工作信息;我不把它自动当成系统下发的下一步动作。',
241
244
  '',
242
- '我应保持简洁、及时更新;不再需要时就删除。若后续准备换程,也可以把它整理成接续包。',
245
+ scope === 'personal'
246
+ ? '我应保持简洁、及时更新;不再需要时就删除。若它只对当前对话有效,应改写成 dialog 范围提醒而不是长期堆在个人范围里。'
247
+ : '我应保持简洁、及时更新;不再需要时就删除。若后续准备换程,也可以把它整理成接续包。',
243
248
  '',
244
249
  `如果我要更新这条提醒项,可执行:update_reminder({ "reminder_id": "${reminderId}", "content": "..." })`,
245
250
  deleteInstruction,
@@ -283,11 +288,15 @@ ${deleteInstruction}
283
288
  ---
284
289
  ${content}`;
285
290
  }
286
- return `REMINDER [${reminderId}]
291
+ return `REMINDER [${reminderId}]${scope === 'personal' ? ' (PERSONAL SCOPE)' : ''}
287
292
 
288
- This is my conspicuous self-reminder for easy-to-lose work details in the current dialog. I do not treat it as an automatically assigned next action.
293
+ ${scope === 'personal'
294
+ ? 'This is my conspicuous personal-scope reminder. I will keep seeing it in all later dialogs I lead, and I do not treat it as an automatically assigned next action.'
295
+ : 'This is my conspicuous self-reminder for easy-to-lose work details in the current dialog. I do not treat it as an automatically assigned next action.'}
289
296
 
290
- I should keep it concise, refresh it when needed, and delete it when obsolete. If I am preparing a new course, I can also rewrite it into a continuation package.
297
+ ${scope === 'personal'
298
+ ? 'I should keep it concise, refresh it when needed, and delete it when obsolete. If it is only useful for the current dialog, I should rewrite it into dialog scope instead of letting personal scope accumulate noise.'
299
+ : 'I should keep it concise, refresh it when needed, and delete it when obsolete. If I am preparing a new course, I can also rewrite it into a continuation package.'}
291
300
 
292
301
  If I need to update this reminder, run: update_reminder({ "reminder_id": "${reminderId}", "content": "..." })
293
302
  ${deleteInstruction}
@@ -96,14 +96,6 @@ function materializeStoredReminder(snapshot) {
96
96
  function cloneReminderList(reminders) {
97
97
  return reminders.map((reminder) => (0, tool_1.cloneReminder)(reminder));
98
98
  }
99
- function compareSharedReminders(a, b) {
100
- const aCreatedAt = a.createdAt ?? '';
101
- const bCreatedAt = b.createdAt ?? '';
102
- if (aCreatedAt !== bCreatedAt) {
103
- return aCreatedAt.localeCompare(bCreatedAt);
104
- }
105
- return a.id.localeCompare(b.id);
106
- }
107
99
  async function writeReminderSnapshotFile(filePath, snapshot) {
108
100
  const json = JSON.stringify(snapshot, null, 2);
109
101
  const tempFile = `${filePath}.${process.pid}.${(0, node_crypto_1.randomUUID)()}.tmp`;
@@ -133,7 +125,7 @@ async function readSharedRemindersUnlocked(agentId) {
133
125
  const raw = await fs.readFile(path.join(dirPath, fileName), 'utf-8');
134
126
  return materializeStoredReminder(JSON.parse(raw));
135
127
  }));
136
- reminders.sort(compareSharedReminders);
128
+ reminders.sort(tool_1.compareReminderDisplayOrder);
137
129
  return reminders;
138
130
  }
139
131
  async function writeSharedRemindersUnlocked(agentId, reminders) {
package/dist/tool.d.ts CHANGED
@@ -33,7 +33,7 @@ export interface ReminderOptions {
33
33
  readonly echoback?: boolean;
34
34
  readonly scope?: ReminderScope;
35
35
  }
36
- export type ReminderScope = 'dialog' | 'agent_shared';
36
+ export type ReminderScope = 'dialog' | 'personal' | 'agent_shared';
37
37
  export type ReminderPriority = 'high' | 'medium' | 'low';
38
38
  export interface Reminder extends ReminderOptions {
39
39
  readonly id: string;
@@ -58,6 +58,7 @@ export declare function materializeReminder(input: Readonly<{
58
58
  priority?: ReminderPriority;
59
59
  }>): Reminder;
60
60
  export declare function cloneReminder(reminder: Reminder): Reminder;
61
+ export declare function compareReminderDisplayOrder(a: Reminder, b: Reminder): number;
61
62
  export declare function getReminderOwnerName(reminder: Pick<Reminder, 'owner'>): string | undefined;
62
63
  export declare function reminderOwnedBy(reminder: Reminder, owner: ReminderOwner | string): boolean;
63
64
  export type ReminderTreatment = 'drop' | 'keep' | 'update';
package/dist/tool.js CHANGED
@@ -6,6 +6,7 @@ exports.reminderIsListed = reminderIsListed;
6
6
  exports.generateReminderId = generateReminderId;
7
7
  exports.materializeReminder = materializeReminder;
8
8
  exports.cloneReminder = cloneReminder;
9
+ exports.compareReminderDisplayOrder = compareReminderDisplayOrder;
9
10
  exports.getReminderOwnerName = getReminderOwnerName;
10
11
  exports.reminderOwnedBy = reminderOwnedBy;
11
12
  exports.validateArgs = validateArgs;
@@ -54,6 +55,17 @@ function cloneReminder(reminder) {
54
55
  priority: reminder.priority,
55
56
  });
56
57
  }
58
+ // Reminder presentation order is a framework-level concern distinct from owner semantics.
59
+ // Keep it centralized so dialog-local reminders and agent-shared reminders stay in the same
60
+ // newest-first order everywhere they are merged, rendered, or injected.
61
+ function compareReminderDisplayOrder(a, b) {
62
+ const aCreatedAt = a.createdAt ?? '';
63
+ const bCreatedAt = b.createdAt ?? '';
64
+ if (aCreatedAt !== bCreatedAt) {
65
+ return bCreatedAt.localeCompare(aCreatedAt);
66
+ }
67
+ return b.id.localeCompare(a.id);
68
+ }
57
69
  function getReminderOwnerName(reminder) {
58
70
  return reminder.owner?.name;
59
71
  }
@@ -161,6 +161,7 @@ function fallbackRenderedReminder(reminder) {
161
161
  role: 'assistant',
162
162
  content: (0, driver_messages_1.formatReminderItemGuide)(language, reminder.id, reminder.content, {
163
163
  meta: reminder.meta,
164
+ scope: reminder.scope,
164
165
  }),
165
166
  };
166
167
  }
@@ -171,6 +172,7 @@ async function persistAndPublishReminders(dlg) {
171
172
  meta: isRecord(reminder.meta) ? reminder.meta : undefined,
172
173
  reminder_id: reminder.id,
173
174
  echoback: (0, tool_1.reminderEchoBackEnabled)(reminder),
175
+ scope: reminder.scope,
174
176
  }));
175
177
  const evt = { type: 'full_reminders_update', reminders };
176
178
  (0, evt_registry_1.postDialogEvent)(dlg, evt);
@@ -70,6 +70,13 @@ const work_language_1 = require("../runtime/work-language");
70
70
  const shared_reminders_1 = require("../shared-reminders");
71
71
  const tool_1 = require("../tool");
72
72
  const task_package_1 = require("../utils/task-package");
73
+ class InvalidReminderPositionError extends Error {
74
+ constructor(positionHuman, totalPlusOne) {
75
+ super(`Invalid reminder position ${positionHuman} (max ${String(totalPlusOne)})`);
76
+ this.positionHuman = positionHuman;
77
+ this.totalPlusOne = totalPlusOne;
78
+ }
79
+ }
73
80
  function isRecord(value) {
74
81
  return typeof value === 'object' && value !== null && !Array.isArray(value);
75
82
  }
@@ -139,16 +146,41 @@ function formatManualUpdateBlockedError(language, altInstruction) {
139
146
  : `Error: This reminder cannot be edited via update_reminder. Follow instead: ${altInstruction}`;
140
147
  }
141
148
  function listListedReminderIndices(reminders) {
149
+ return listListedReminderIndicesBy(reminders, () => true);
150
+ }
151
+ function listListedReminderIndicesBy(reminders, predicate) {
142
152
  const indices = [];
143
153
  for (let index = 0; index < reminders.length; index += 1) {
144
154
  const reminder = reminders[index];
145
- if (!reminder || !(0, tool_1.reminderIsListed)(reminder)) {
155
+ if (!reminder || !(0, tool_1.reminderIsListed)(reminder) || !predicate(reminder)) {
146
156
  continue;
147
157
  }
148
158
  indices.push(index);
149
159
  }
150
160
  return indices;
151
161
  }
162
+ function computeReminderInsertIndex(reminders, positionValue, predicate) {
163
+ const listedIndices = listListedReminderIndicesBy(reminders, predicate);
164
+ let insertIndex = reminders.length;
165
+ if (positionValue === undefined) {
166
+ return insertIndex;
167
+ }
168
+ if (typeof positionValue !== 'number' || !Number.isInteger(positionValue)) {
169
+ throw new Error('invalid_add_position_format');
170
+ }
171
+ const position = positionValue - 1;
172
+ if (position < 0 || position > listedIndices.length) {
173
+ throw new InvalidReminderPositionError(String(positionValue), listedIndices.length + 1);
174
+ }
175
+ if (position < listedIndices.length) {
176
+ const targetIndex = listedIndices[position];
177
+ if (targetIndex === undefined) {
178
+ throw new InvalidReminderPositionError(String(positionValue), listedIndices.length + 1);
179
+ }
180
+ insertIndex = targetIndex;
181
+ }
182
+ return insertIndex;
183
+ }
152
184
  function getContinuationPackageContextHealthLevel(snapshot) {
153
185
  if (snapshot?.kind !== 'available') {
154
186
  return undefined;
@@ -219,7 +251,8 @@ function getCtrlMessages(language) {
219
251
  return {
220
252
  invalidFormatDelete: '参数格式不对。用法:delete_reminder({ reminder_id: string })',
221
253
  reminderDoesNotExist: (reminderId) => `提醒项 '${reminderId}' 不存在。`,
222
- invalidFormatAdd: '参数格式不对。用法:add_reminder({ content: string, position: number })position=0 表示追加)',
254
+ invalidFormatAdd: '参数格式不对。用法:add_reminder({ content: string, position?: number, scope?: "dialog" | "personal" })(省略 position 表示追加)',
255
+ personalPositionUnsupported: 'personal 范围提醒当前只支持追加,不能指定 position。',
223
256
  reminderContentEmpty: '提醒内容不能为空',
224
257
  invalidReminderPosition: (positionHuman, totalPlusOne) => `位置 ${positionHuman} 无效。有效范围:1-${totalPlusOne}`,
225
258
  invalidFormatUpdate: '参数格式不对。用法:update_reminder({ reminder_id: string, content: string })',
@@ -251,7 +284,8 @@ function getCtrlMessages(language) {
251
284
  return {
252
285
  invalidFormatDelete: 'Error: Invalid args. Use: delete_reminder({ reminder_id: string })',
253
286
  reminderDoesNotExist: (reminderId) => `Error: Reminder '${reminderId}' does not exist.`,
254
- invalidFormatAdd: 'Error: Invalid args. Use: add_reminder({ content: string, position: number }) (position=0 means append).',
287
+ invalidFormatAdd: 'Error: Invalid args. Use: add_reminder({ content: string, position?: number, scope?: "dialog" | "personal" }) (omit position to append).',
288
+ personalPositionUnsupported: 'Error: personal-scope reminders currently support append only; do not pass position.',
255
289
  reminderContentEmpty: 'Error: Reminder content cannot be empty',
256
290
  invalidReminderPosition: (positionHuman, totalPlusOne) => `Error: Invalid reminder position ${positionHuman}. Valid range: 1-${totalPlusOne}`,
257
291
  invalidFormatUpdate: 'Error: Invalid args. Use: update_reminder({ reminder_id: string, content: string })',
@@ -329,10 +363,10 @@ exports.deleteReminderTool = {
329
363
  exports.addReminderTool = {
330
364
  type: 'func',
331
365
  name: 'add_reminder',
332
- description: 'Add a reminder, optionally inserting at a 1-based position.',
366
+ description: 'Add a reminder, optionally inserting at a 1-based position and choosing dialog or personal scope.',
333
367
  descriptionI18n: {
334
- en: 'Add a reminder, optionally inserting at a 1-based position.',
335
- zh: '添加提醒,可选指定 1-based 插入位置。',
368
+ en: 'Add a reminder, optionally inserting at a 1-based position and choosing dialog or personal scope.',
369
+ zh: '添加提醒,可选指定 1-based 插入位置,并可选择对话或个人范围。',
336
370
  },
337
371
  parameters: {
338
372
  type: 'object',
@@ -341,6 +375,11 @@ exports.addReminderTool = {
341
375
  properties: {
342
376
  content: { type: 'string', description: 'Reminder content.' },
343
377
  position: { type: 'integer', description: 'Insert position (1-based). Defaults to append.' },
378
+ scope: {
379
+ type: 'string',
380
+ enum: ['dialog', 'personal'],
381
+ description: 'Reminder visibility scope. Defaults to dialog.',
382
+ },
344
383
  },
345
384
  },
346
385
  argsValidation: 'dominds',
@@ -351,25 +390,16 @@ exports.addReminderTool = {
351
390
  const reminderContent = typeof contentValue === 'string' ? contentValue.trim() : '';
352
391
  if (!reminderContent)
353
392
  return t.reminderContentEmpty;
354
- const listedIndices = listListedReminderIndices(dlg.reminders);
355
- const positionValue = args['position'];
356
- let insertIndex = dlg.reminders.length;
357
- if (positionValue !== undefined) {
358
- if (typeof positionValue !== 'number' || !Number.isInteger(positionValue)) {
359
- return t.invalidFormatAdd;
360
- }
361
- const position = positionValue - 1;
362
- if (position < 0 || position > listedIndices.length) {
363
- return t.invalidReminderPosition(String(positionValue), listedIndices.length + 1);
364
- }
365
- if (position < listedIndices.length) {
366
- const targetIndex = listedIndices[position];
367
- if (targetIndex === undefined) {
368
- return t.invalidReminderPosition(String(positionValue), listedIndices.length + 1);
369
- }
370
- insertIndex = targetIndex;
371
- }
393
+ const scopeValue = args['scope'];
394
+ const reminderScope = scopeValue === undefined
395
+ ? 'dialog'
396
+ : scopeValue === 'dialog' || scopeValue === 'personal'
397
+ ? scopeValue
398
+ : null;
399
+ if (reminderScope === null) {
400
+ return t.invalidFormatAdd;
372
401
  }
402
+ const positionValue = args['position'];
373
403
  const contextHealthLevel = getContinuationPackageContextHealthLevel(dlg.getLastContextHealth());
374
404
  const reminderMeta = contextHealthLevel === undefined
375
405
  ? undefined
@@ -377,8 +407,49 @@ exports.addReminderTool = {
377
407
  createdBy: 'context_health',
378
408
  contextHealthLevel,
379
409
  });
380
- dlg.addReminder(reminderContent, undefined, reminderMeta, insertIndex);
381
- return (0, tool_result_messages_1.formatToolActionResult)(language, 'added');
410
+ if (reminderScope === 'dialog') {
411
+ try {
412
+ const insertIndex = computeReminderInsertIndex(dlg.reminders, positionValue, () => true);
413
+ dlg.addReminder(reminderContent, undefined, reminderMeta, insertIndex, { scope: 'dialog' });
414
+ return (0, tool_result_messages_1.formatToolActionResult)(language, 'added');
415
+ }
416
+ catch (error) {
417
+ if (error instanceof InvalidReminderPositionError) {
418
+ return t.invalidReminderPosition(error.positionHuman, error.totalPlusOne);
419
+ }
420
+ if (error instanceof Error && error.message === 'invalid_add_position_format') {
421
+ return t.invalidFormatAdd;
422
+ }
423
+ throw error;
424
+ }
425
+ }
426
+ try {
427
+ await (0, shared_reminders_1.mutateAgentSharedReminders)(dlg.agentId, (reminders) => {
428
+ if (positionValue !== undefined) {
429
+ throw new Error('personal_add_position_unsupported');
430
+ }
431
+ const reminder = (0, tool_1.materializeReminder)({
432
+ content: reminderContent,
433
+ meta: reminderMeta,
434
+ scope: 'personal',
435
+ });
436
+ reminders.push(reminder);
437
+ });
438
+ dlg.touchReminders();
439
+ return (0, tool_result_messages_1.formatToolActionResult)(language, 'added');
440
+ }
441
+ catch (error) {
442
+ if (error instanceof InvalidReminderPositionError) {
443
+ return t.invalidReminderPosition(error.positionHuman, error.totalPlusOne);
444
+ }
445
+ if (error instanceof Error && error.message === 'invalid_add_position_format') {
446
+ return t.invalidFormatAdd;
447
+ }
448
+ if (error instanceof Error && error.message === 'personal_add_position_unsupported') {
449
+ return t.personalPositionUnsupported;
450
+ }
451
+ throw error;
452
+ }
382
453
  },
383
454
  };
384
455
  exports.updateReminderTool = {