dominds 1.19.3 → 1.20.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.
- package/README.md +1 -0
- package/dist/access-control.js +2 -2
- package/dist/dialog.d.ts +6 -1
- package/dist/dialog.js +13 -4
- package/dist/docs/context-health.md +39 -13
- package/dist/docs/context-health.zh.md +14 -7
- package/dist/docs/idle-reminder-wake.md +227 -0
- package/dist/docs/idle-reminder-wake.zh.md +227 -0
- package/dist/llm/client.d.ts +2 -0
- package/dist/llm/client.js +32 -2
- package/dist/llm/defaults.yaml +51 -10
- package/dist/llm/gen/codex.js +15 -0
- package/dist/llm/kernel-driver/drive.js +6 -0
- package/dist/llm/kernel-driver/flow.js +9 -0
- package/dist/llm/kernel-driver/idle-reminder-wake.d.ts +4 -0
- package/dist/llm/kernel-driver/idle-reminder-wake.js +351 -0
- package/dist/llm/kernel-driver/types.d.ts +1 -1
- package/dist/minds/load.js +2 -1
- package/dist/minds/minds-i18n.js +2 -2
- package/dist/minds/system-prompt-parts.js +56 -20
- package/dist/minds/system-prompt.js +10 -10
- package/dist/runtime/driver-messages.d.ts +3 -0
- package/dist/runtime/driver-messages.js +91 -8
- package/dist/server/setup-routes.js +5 -5
- package/dist/tool.d.ts +8 -0
- package/dist/tools/builtins.js +4 -2
- package/dist/tools/ctrl.d.ts +2 -0
- package/dist/tools/ctrl.js +253 -67
- package/dist/tools/os.js +198 -0
- package/dist/tools/prompts/control/en/errors.md +2 -2
- package/dist/tools/prompts/control/en/index.md +1 -1
- package/dist/tools/prompts/control/en/principles.md +15 -14
- package/dist/tools/prompts/control/en/scenarios.md +6 -0
- package/dist/tools/prompts/control/en/tools.md +37 -4
- package/dist/tools/prompts/control/zh/errors.md +2 -2
- package/dist/tools/prompts/control/zh/index.md +1 -1
- package/dist/tools/prompts/control/zh/principles.md +15 -14
- package/dist/tools/prompts/control/zh/scenarios.md +6 -0
- package/dist/tools/prompts/control/zh/tools.md +37 -4
- package/dist/tools/prompts/personal_memory/en/principles.md +1 -1
- package/dist/tools/prompts/personal_memory/zh/principles.md +1 -1
- package/dist/tools/prompts/team_memory/en/principles.md +1 -1
- package/dist/tools/prompts/team_memory/zh/principles.md +1 -1
- package/dist/tools/team_mgmt.js +5 -8
- package/dist/utils/task-package.d.ts +7 -0
- package/dist/utils/task-package.js +46 -23
- package/dist/utils/taskdoc.js +21 -17
- package/package.json +4 -4
- package/webapp/dist/assets/{_basePickBy-Dnh413xT.js → _basePickBy-B7M9Q0Fa.js} +3 -3
- package/webapp/dist/assets/_basePickBy-B7M9Q0Fa.js.map +1 -0
- package/webapp/dist/assets/{_baseUniq-DWzYqpN_.js → _baseUniq-DAeYoL6j.js} +2 -2
- package/webapp/dist/assets/_baseUniq-DAeYoL6j.js.map +1 -0
- package/webapp/dist/assets/{arc-vfBkNCOx.js → arc-Bh4nDbNR.js} +2 -2
- package/webapp/dist/assets/arc-Bh4nDbNR.js.map +1 -0
- package/webapp/dist/assets/{architectureDiagram-VXUJARFQ-DiUEBXOa.js → architectureDiagram-2XIMDMQ5-CxqmdsIm.js} +26 -8
- package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-CxqmdsIm.js.map +1 -0
- package/webapp/dist/assets/{blockDiagram-VD42YOAC-BqK1KM2m.js → blockDiagram-WCTKOSBZ-CxIWLtpt.js} +187 -170
- package/webapp/dist/assets/blockDiagram-WCTKOSBZ-CxIWLtpt.js.map +1 -0
- package/webapp/dist/assets/{c4Diagram-YG6GDRKO-ClHNu1Uo.js → c4Diagram-IC4MRINW-1qErOIgG.js} +4 -4
- package/webapp/dist/assets/c4Diagram-IC4MRINW-1qErOIgG.js.map +1 -0
- package/webapp/dist/assets/{channel-BbWLVc8W.js → channel-DkgZHNUe.js} +2 -2
- package/webapp/dist/assets/channel-DkgZHNUe.js.map +1 -0
- package/webapp/dist/assets/{chunk-4BX2VUAB-CItdSmZH.js → chunk-4BX2VUAB-BmdMbU9v.js} +2 -2
- package/webapp/dist/assets/chunk-4BX2VUAB-BmdMbU9v.js.map +1 -0
- package/webapp/dist/assets/{chunk-55IACEB6-DSCX9WCf.js → chunk-55IACEB6-D6LDTDBy.js} +2 -2
- package/webapp/dist/assets/chunk-55IACEB6-D6LDTDBy.js.map +1 -0
- package/webapp/dist/assets/{chunk-FMBD7UC4-BJ1vT2se.js → chunk-FMBD7UC4-C-BdCe4C.js} +2 -2
- package/webapp/dist/assets/chunk-FMBD7UC4-C-BdCe4C.js.map +1 -0
- package/webapp/dist/assets/{chunk-TZMSLE5B-D2g6Tj7Z.js → chunk-JSJVCQXG-WA_BLIm9.js} +14 -6
- package/webapp/dist/assets/chunk-JSJVCQXG-WA_BLIm9.js.map +1 -0
- package/webapp/dist/assets/{chunk-QN33PNHL-CGyezTSD.js → chunk-KX2RTZJC-CA7sDJO5.js} +2 -2
- package/webapp/dist/assets/chunk-KX2RTZJC-CA7sDJO5.js.map +1 -0
- package/webapp/dist/assets/{chunk-DI55MBZ5-CRMf6XZu.js → chunk-NQ4KR5QH-wlvxalE3.js} +9 -7
- package/webapp/dist/assets/chunk-NQ4KR5QH-wlvxalE3.js.map +1 -0
- package/webapp/dist/assets/{chunk-QZHKN3VN-9xs15j8C.js → chunk-QZHKN3VN-Bo1VMcph.js} +2 -2
- package/webapp/dist/assets/chunk-QZHKN3VN-Bo1VMcph.js.map +1 -0
- package/webapp/dist/assets/{chunk-B4BG7PRW-5CRXFeD9.js → chunk-WL4C6EOR-B-Pk44be.js} +171 -121
- package/webapp/dist/assets/chunk-WL4C6EOR-B-Pk44be.js.map +1 -0
- package/webapp/dist/assets/{classDiagram-2ON5EDUG-BQFGGJNm.js → classDiagram-VBA2DB6C-BqKuyb49.js} +7 -6
- package/webapp/dist/assets/classDiagram-VBA2DB6C-BqKuyb49.js.map +1 -0
- package/webapp/dist/assets/{classDiagram-v2-WZHVMYZB-BQFGGJNm.js → classDiagram-v2-RAHNMMFH-BqKuyb49.js} +7 -6
- package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-BqKuyb49.js.map +1 -0
- package/webapp/dist/assets/{clone-DOfPd4cz.js → clone-BX5z8WVZ.js} +2 -2
- package/webapp/dist/assets/clone-BX5z8WVZ.js.map +1 -0
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BYN-vqm8.js → cose-bilkent-S5V4N54A-B-s11SgN.js} +2 -2
- package/webapp/dist/assets/cose-bilkent-S5V4N54A-B-s11SgN.js.map +1 -0
- package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
- package/webapp/dist/assets/{dagre-6UL2VRFP-ClEaFABE.js → dagre-KLK3FWXG-DmQFV2qK.js} +7 -7
- package/webapp/dist/assets/dagre-KLK3FWXG-DmQFV2qK.js.map +1 -0
- package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
- package/webapp/dist/assets/{diagram-PSM6KHXK-CM4hLE_0.js → diagram-E7M64L7V-QRaBfST8.js} +10 -10
- package/webapp/dist/assets/diagram-E7M64L7V-QRaBfST8.js.map +1 -0
- package/webapp/dist/assets/{diagram-QEK2KX5R-BZjGFX-2.js → diagram-IFDJBPK2-lrWn1Obo.js} +9 -8
- package/webapp/dist/assets/diagram-IFDJBPK2-lrWn1Obo.js.map +1 -0
- package/webapp/dist/assets/{diagram-S2PKOQOG-Bvw01OOG.js → diagram-P4PSJMXO-sTU7Hh-Y.js} +8 -8
- package/webapp/dist/assets/diagram-P4PSJMXO-sTU7Hh-Y.js.map +1 -0
- package/webapp/dist/assets/{erDiagram-Q2GNP2WA-ctHu5zQL.js → erDiagram-INFDFZHY-Cx6jc9Wq.js} +96 -75
- package/webapp/dist/assets/erDiagram-INFDFZHY-Cx6jc9Wq.js.map +1 -0
- package/webapp/dist/assets/{flowDiagram-NV44I4VS-m7ofIhri.js → flowDiagram-PKNHOUZH-DfGI49Dz.js} +98 -81
- package/webapp/dist/assets/flowDiagram-PKNHOUZH-DfGI49Dz.js.map +1 -0
- package/webapp/dist/assets/{ganttDiagram-JELNMOA3-D9wS5Veb.js → ganttDiagram-A5KZAMGK-nrcHWWaM.js} +28 -3
- package/webapp/dist/assets/ganttDiagram-A5KZAMGK-nrcHWWaM.js.map +1 -0
- package/webapp/dist/assets/{gitGraphDiagram-V2S2FVAM-B86qqJx7.js → gitGraphDiagram-K3NZZRJ6-D8ivAqd6.js} +38 -46
- package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-D8ivAqd6.js.map +1 -0
- package/webapp/dist/assets/graph-R5G-y8tB.js +782 -0
- package/webapp/dist/assets/graph-R5G-y8tB.js.map +1 -0
- package/webapp/dist/assets/{index-tinPEZoH.js → index--fy89xGh.js} +1034 -1059
- package/webapp/dist/assets/{index-tinPEZoH.js.map → index--fy89xGh.js.map} +1 -1
- package/webapp/dist/assets/{index-BGdI3lWA.css → index-DZFkLLVz.css} +1 -1
- package/webapp/dist/assets/{infoDiagram-HS3SLOUP-DwRPUctP.js → infoDiagram-LFFYTUFH-PIoZHr7s.js} +7 -7
- package/webapp/dist/assets/infoDiagram-LFFYTUFH-PIoZHr7s.js.map +1 -0
- package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
- package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-oCM-LYk1.js +966 -0
- package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-oCM-LYk1.js.map +1 -0
- package/webapp/dist/assets/{journeyDiagram-XKPGCS4Q-B91ZO-ec.js → journeyDiagram-4ABVD52K-C2qidjQ5.js} +5 -5
- package/webapp/dist/assets/journeyDiagram-4ABVD52K-C2qidjQ5.js.map +1 -0
- package/webapp/dist/assets/{kanban-definition-3W4ZIXB7-CoogrZ07.js → kanban-definition-K7BYSVSG-Du0TC8WS.js} +5 -3
- package/webapp/dist/assets/kanban-definition-K7BYSVSG-Du0TC8WS.js.map +1 -0
- package/webapp/dist/assets/{layout-BrzQmqFJ.js → layout-VmEo1OEB.js} +5 -5
- package/webapp/dist/assets/layout-VmEo1OEB.js.map +1 -0
- package/webapp/dist/assets/{linear-C6H7K9Zy.js → linear-B662YHAc.js} +2 -2
- package/webapp/dist/assets/linear-B662YHAc.js.map +1 -0
- package/webapp/dist/assets/{mindmap-definition-VGOIOE7T-UDHZQkNZ.js → mindmap-definition-YRQLILUH-D7arZj95.js} +7 -5
- package/webapp/dist/assets/mindmap-definition-YRQLILUH-D7arZj95.js.map +1 -0
- package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
- package/webapp/dist/assets/{pieDiagram-ADFJNKIX-M81uyQ1J.js → pieDiagram-SKSYHLDU-DvjPP4PA.js} +8 -8
- package/webapp/dist/assets/pieDiagram-SKSYHLDU-DvjPP4PA.js.map +1 -0
- package/webapp/dist/assets/{quadrantDiagram-AYHSOK5B-ClzIh9Gb.js → quadrantDiagram-337W2JSQ-B_JUGMj_.js} +3 -3
- package/webapp/dist/assets/quadrantDiagram-337W2JSQ-B_JUGMj_.js.map +1 -0
- package/webapp/dist/assets/{requirementDiagram-UZGBJVZJ-DLK3A-pn.js → requirementDiagram-Z7DCOOCP-DF0mpvE3.js} +16 -6
- package/webapp/dist/assets/requirementDiagram-Z7DCOOCP-DF0mpvE3.js.map +1 -0
- package/webapp/dist/assets/{sankeyDiagram-TZEHDZUN-CYqju8I1.js → sankeyDiagram-WA2Y5GQK-CoXlxv00.js} +2 -2
- package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-CoXlxv00.js.map +1 -0
- package/webapp/dist/assets/{sequenceDiagram-WL72ISMW-2guv6eOd.js → sequenceDiagram-2WXFIKYE-DYqT5Pg7.js} +601 -201
- package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-DYqT5Pg7.js.map +1 -0
- package/webapp/dist/assets/{stateDiagram-FKZM4ZOC-iujqSp0X.js → stateDiagram-RAJIS63D-D9b1mN8-.js} +9 -9
- package/webapp/dist/assets/stateDiagram-RAJIS63D-D9b1mN8-.js.map +1 -0
- package/webapp/dist/assets/{stateDiagram-v2-4FDKWEC3-BxzY81ky.js → stateDiagram-v2-FVOUBMTO-DNzgudL_.js} +5 -5
- package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-DNzgudL_.js.map +1 -0
- package/webapp/dist/assets/{timeline-definition-IT6M3QCI-DjCFSC8d.js → timeline-definition-YZTLITO2-CkyKUY7A.js} +3 -3
- package/webapp/dist/assets/timeline-definition-YZTLITO2-CkyKUY7A.js.map +1 -0
- package/webapp/dist/assets/{treemap-GDKQZRPO-iaBzDWCP.js → treemap-KZPCXAKY-CZd09kF-.js} +37 -24
- package/webapp/dist/assets/treemap-KZPCXAKY-CZd09kF-.js.map +1 -0
- package/webapp/dist/assets/vennDiagram-LZ73GAT5-BxVF5Olo.js +2487 -0
- package/webapp/dist/assets/vennDiagram-LZ73GAT5-BxVF5Olo.js.map +1 -0
- package/webapp/dist/assets/{xychartDiagram-PRI3JC2R-R6Jl1c89.js → xychartDiagram-JWTSCODW-BRwRloPc.js} +4 -4
- package/webapp/dist/assets/xychartDiagram-JWTSCODW-BRwRloPc.js.map +1 -0
- package/webapp/dist/index.html +2 -2
- package/webapp/dist/assets/_basePickBy-Dnh413xT.js.map +0 -1
- package/webapp/dist/assets/_baseUniq-DWzYqpN_.js.map +0 -1
- package/webapp/dist/assets/arc-vfBkNCOx.js.map +0 -1
- package/webapp/dist/assets/architectureDiagram-VXUJARFQ-DiUEBXOa.js.map +0 -1
- package/webapp/dist/assets/blockDiagram-VD42YOAC-BqK1KM2m.js.map +0 -1
- package/webapp/dist/assets/c4Diagram-YG6GDRKO-ClHNu1Uo.js.map +0 -1
- package/webapp/dist/assets/channel-BbWLVc8W.js.map +0 -1
- package/webapp/dist/assets/chunk-4BX2VUAB-CItdSmZH.js.map +0 -1
- package/webapp/dist/assets/chunk-55IACEB6-DSCX9WCf.js.map +0 -1
- package/webapp/dist/assets/chunk-B4BG7PRW-5CRXFeD9.js.map +0 -1
- package/webapp/dist/assets/chunk-DI55MBZ5-CRMf6XZu.js.map +0 -1
- package/webapp/dist/assets/chunk-FMBD7UC4-BJ1vT2se.js.map +0 -1
- package/webapp/dist/assets/chunk-QN33PNHL-CGyezTSD.js.map +0 -1
- package/webapp/dist/assets/chunk-QZHKN3VN-9xs15j8C.js.map +0 -1
- package/webapp/dist/assets/chunk-TZMSLE5B-D2g6Tj7Z.js.map +0 -1
- package/webapp/dist/assets/classDiagram-2ON5EDUG-BQFGGJNm.js.map +0 -1
- package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-BQFGGJNm.js.map +0 -1
- package/webapp/dist/assets/clone-DOfPd4cz.js.map +0 -1
- package/webapp/dist/assets/cose-bilkent-S5V4N54A-BYN-vqm8.js.map +0 -1
- package/webapp/dist/assets/dagre-6UL2VRFP-ClEaFABE.js.map +0 -1
- package/webapp/dist/assets/diagram-PSM6KHXK-CM4hLE_0.js.map +0 -1
- package/webapp/dist/assets/diagram-QEK2KX5R-BZjGFX-2.js.map +0 -1
- package/webapp/dist/assets/diagram-S2PKOQOG-Bvw01OOG.js.map +0 -1
- package/webapp/dist/assets/erDiagram-Q2GNP2WA-ctHu5zQL.js.map +0 -1
- package/webapp/dist/assets/flowDiagram-NV44I4VS-m7ofIhri.js.map +0 -1
- package/webapp/dist/assets/ganttDiagram-JELNMOA3-D9wS5Veb.js.map +0 -1
- package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-B86qqJx7.js.map +0 -1
- package/webapp/dist/assets/graph-u844GGQC.js +0 -425
- package/webapp/dist/assets/graph-u844GGQC.js.map +0 -1
- package/webapp/dist/assets/infoDiagram-HS3SLOUP-DwRPUctP.js.map +0 -1
- package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-B91ZO-ec.js.map +0 -1
- package/webapp/dist/assets/kanban-definition-3W4ZIXB7-CoogrZ07.js.map +0 -1
- package/webapp/dist/assets/layout-BrzQmqFJ.js.map +0 -1
- package/webapp/dist/assets/linear-C6H7K9Zy.js.map +0 -1
- package/webapp/dist/assets/mindmap-definition-VGOIOE7T-UDHZQkNZ.js.map +0 -1
- package/webapp/dist/assets/pieDiagram-ADFJNKIX-M81uyQ1J.js.map +0 -1
- package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-ClzIh9Gb.js.map +0 -1
- package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-DLK3A-pn.js.map +0 -1
- package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-CYqju8I1.js.map +0 -1
- package/webapp/dist/assets/sequenceDiagram-WL72ISMW-2guv6eOd.js.map +0 -1
- package/webapp/dist/assets/stateDiagram-FKZM4ZOC-iujqSp0X.js.map +0 -1
- package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3-BxzY81ky.js.map +0 -1
- package/webapp/dist/assets/timeline-definition-IT6M3QCI-DjCFSC8d.js.map +0 -1
- package/webapp/dist/assets/treemap-GDKQZRPO-iaBzDWCP.js.map +0 -1
- package/webapp/dist/assets/xychartDiagram-PRI3JC2R-R6Jl1c89.js.map +0 -1
package/README.md
CHANGED
|
@@ -295,6 +295,7 @@ Result: fewer bad side effects, higher plan fidelity, and more first‑try succe
|
|
|
295
295
|
- **[FBR](docs/fbr.md)** — Fresh Boots Reasoning (`freshBootsReasoning`) design and enhancements
|
|
296
296
|
- **[Context Health](docs/context-health.md)** — Measuring/maintaining context quality
|
|
297
297
|
- **[Diligence Push](docs/diligence-push.md)** — Auto-continue (diligence) mechanism
|
|
298
|
+
- **[Idle Reminder Wake](docs/idle-reminder-wake.md)** — Runtime wakeups from owner-managed reminder events
|
|
298
299
|
- **[Showing-by-Doing](docs/showing-by-doing.md)** — A dialog-creation prelude that makes Tellask feel real
|
|
299
300
|
- **[Design](docs/design.md)** — Architecture and key abstractions
|
|
300
301
|
- **[Roadmap](docs/roadmap.md)** — Major-version plan and evolution
|
package/dist/access-control.js
CHANGED
|
@@ -312,12 +312,12 @@ function getAccessDeniedMessage(operation, targetPath, language = 'en') {
|
|
|
312
312
|
lines.push('');
|
|
313
313
|
if (language === 'zh') {
|
|
314
314
|
lines.push(`- 说明:\`*.tsk/\` 是封装差遣牒。通用文件工具无法读/写/列目录/删除其中内容(硬编码无条件拒绝)。`);
|
|
315
|
-
lines.push(`-
|
|
315
|
+
lines.push(`- 提示:少量追加请使用 \`mind_more\`(默认 progress:\`mind_more({\"items\":[\"...\"]})\`);整章替换请使用 \`change_mind\`(顶层:\`change_mind({\"selector\":\"goals|constraints|progress\",\"content\":\"...\"})\`;额外章节:\`change_mind({\"category\":\"<category>\",\"selector\":\"<selector>\",\"content\":\"...\"})\`)。`);
|
|
316
316
|
lines.push(`- 提示:读取额外章节请使用函数工具 \`recall_taskdoc\`:\`recall_taskdoc({\"category\":\"<category>\",\"selector\":\"<selector>\"})\`。`);
|
|
317
317
|
}
|
|
318
318
|
else {
|
|
319
319
|
lines.push(`- Note: \`*.tsk/\` is an encapsulated Taskdoc. It is hard-denied for all general file tools.`);
|
|
320
|
-
lines.push(`- Hint: For updates, use
|
|
320
|
+
lines.push(`- Hint: For small append-only updates, use \`mind_more\` (defaults to progress: \`mind_more({\"items\":[\"...\"]})\`); for full-section replacements, use \`change_mind\` (top-level: \`change_mind({\"selector\":\"goals|constraints|progress\",\"content\":\"...\"})\`; extra sections: \`change_mind({\"category\":\"<category>\",\"selector\":\"<selector>\",\"content\":\"...\"})\`).`);
|
|
321
321
|
lines.push(`- Hint: To read extra sections, use \`recall_taskdoc({\"category\":\"<category>\",\"selector\":\"<selector>\"})\`.`);
|
|
322
322
|
}
|
|
323
323
|
}
|
package/dist/dialog.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ import { ChatMessage, FuncResultMsg, TellaskCarryoverMsg, TellaskResultMsg } fro
|
|
|
21
21
|
import type { ToolResultImageIngest, UserImageIngest } from './llm/gen';
|
|
22
22
|
import type { JsonValue } from './tool';
|
|
23
23
|
import { Reminder, ReminderOptions, ReminderOwner } from './tool';
|
|
24
|
+
export declare class InvalidReminderIndexError extends Error {
|
|
25
|
+
readonly index: number;
|
|
26
|
+
readonly total: number;
|
|
27
|
+
constructor(index: number, total: number);
|
|
28
|
+
}
|
|
24
29
|
type NewCourseHookResult = {
|
|
25
30
|
kind: 'continue';
|
|
26
31
|
prompt: DialogRuntimePrompt;
|
|
@@ -357,7 +362,7 @@ export declare abstract class Dialog {
|
|
|
357
362
|
/**
|
|
358
363
|
* Start a new course - clears conversational noise, Q4H, and increments course counter.
|
|
359
364
|
* Queues a new-course prompt for the driver to consume on the next drive cycle.
|
|
360
|
-
* This is the single entry point for mental clarity operations
|
|
365
|
+
* This is the single entry point for mental clarity operations that start a new course.
|
|
361
366
|
*/
|
|
362
367
|
startNewCourse(newCoursePrompt: string, options?: {
|
|
363
368
|
runControl?: DialogRunControlSpec;
|
package/dist/dialog.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DialogStore = exports.MainDialog = exports.SideDialog = exports.Dialog = exports.DialogID = void 0;
|
|
3
|
+
exports.DialogStore = exports.MainDialog = exports.SideDialog = exports.Dialog = exports.DialogID = exports.InvalidReminderIndexError = void 0;
|
|
4
4
|
exports.buildSideDialogAskerStack = buildSideDialogAskerStack;
|
|
5
5
|
const id_1 = require("@longrun-ai/kernel/utils/id");
|
|
6
6
|
const time_1 = require("@longrun-ai/kernel/utils/time");
|
|
@@ -14,6 +14,15 @@ const work_language_1 = require("./runtime/work-language");
|
|
|
14
14
|
const shared_reminders_1 = require("./shared-reminders");
|
|
15
15
|
const tool_1 = require("./tool");
|
|
16
16
|
const id_2 = require("./utils/id");
|
|
17
|
+
class InvalidReminderIndexError extends Error {
|
|
18
|
+
constructor(index, total) {
|
|
19
|
+
super(`Reminder target index ${index} is stale; current reminder count is ${total}`);
|
|
20
|
+
this.name = 'InvalidReminderIndexError';
|
|
21
|
+
this.index = index;
|
|
22
|
+
this.total = total;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.InvalidReminderIndexError = InvalidReminderIndexError;
|
|
17
26
|
class DialogID {
|
|
18
27
|
constructor(selfId, rootId) {
|
|
19
28
|
this.selfId = selfId;
|
|
@@ -423,7 +432,7 @@ class Dialog {
|
|
|
423
432
|
}
|
|
424
433
|
deleteReminder(index) {
|
|
425
434
|
if (index < 0 || index >= this.reminders.length) {
|
|
426
|
-
throw new
|
|
435
|
+
throw new InvalidReminderIndexError(index, this.reminders.length);
|
|
427
436
|
}
|
|
428
437
|
const deleted = this.reminders.splice(index, 1)[0];
|
|
429
438
|
this.touchReminders();
|
|
@@ -431,7 +440,7 @@ class Dialog {
|
|
|
431
440
|
}
|
|
432
441
|
updateReminder(index, content, meta, options) {
|
|
433
442
|
if (index < 0 || index >= this.reminders.length) {
|
|
434
|
-
throw new
|
|
443
|
+
throw new InvalidReminderIndexError(index, this.reminders.length);
|
|
435
444
|
}
|
|
436
445
|
const oldReminder = this.reminders[index];
|
|
437
446
|
const updatedReminder = (0, tool_1.materializeReminder)({
|
|
@@ -1035,7 +1044,7 @@ class Dialog {
|
|
|
1035
1044
|
/**
|
|
1036
1045
|
* Start a new course - clears conversational noise, Q4H, and increments course counter.
|
|
1037
1046
|
* Queues a new-course prompt for the driver to consume on the next drive cycle.
|
|
1038
|
-
* This is the single entry point for mental clarity operations
|
|
1047
|
+
* This is the single entry point for mental clarity operations that start a new course.
|
|
1039
1048
|
*/
|
|
1040
1049
|
async startNewCourse(newCoursePrompt, options) {
|
|
1041
1050
|
const trimmedPrompt = newCoursePrompt.trim();
|
|
@@ -25,7 +25,11 @@ Dominds already has:
|
|
|
25
25
|
(UI-visible and rendered as a normal user instruction).
|
|
26
26
|
- In **critical**, enforce stability via a **countdown remediation** (max 5 turns):
|
|
27
27
|
- Each turn injects a **recorded role=user prompt** (UI-visible as a user prompt) that instructs
|
|
28
|
-
|
|
28
|
+
Main Dialogs to first record current-dialog discussion details that are not yet documented but the
|
|
29
|
+
next course needs to know into the appropriate Taskdoc sections, then curate continuation-package
|
|
30
|
+
reminders (`update_reminder`/`add_reminder`) and `clear_mind`. Side Dialogs are instructed not to
|
|
31
|
+
maintain Taskdoc or draft update proposals; they maintain sufficiently detailed continuation-package
|
|
32
|
+
reminders instead, with no technical length limit, then `clear_mind`.
|
|
29
33
|
- The prompt includes a countdown signal (how many reminders remain before auto-`clear_mind`).
|
|
30
34
|
- When the countdown reaches 0, Dominds **automatically** executes `clear_mind` (no Q4H; no
|
|
31
35
|
suspension) to keep long-running autonomy stable.
|
|
@@ -135,10 +139,16 @@ Rules:
|
|
|
135
139
|
- Do not let the agent branch on subjective self-assessment such as “clear-headed” vs “muddled”.
|
|
136
140
|
- When the current course is not under `caution` / `critical` remediation, prefer compressing into
|
|
137
141
|
one structured continuation-package reminder.
|
|
138
|
-
- When the system has put the current course into `caution` / `critical` remediation,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
- When the system has put the current course into `caution` / `critical` remediation, the driver splits
|
|
143
|
+
prompts by dialog scope:
|
|
144
|
+
- Main Dialog: first fill Taskdoc with current-dialog discussion details that are not yet documented
|
|
145
|
+
but the next course needs to know; then preserve details still not covered by Taskdoc but easy to
|
|
146
|
+
lose during resume.
|
|
147
|
+
- Side Dialog: do not maintain Taskdoc and do not draft Taskdoc update proposals; directly maintain
|
|
148
|
+
sufficiently detailed continuation-package reminders. Reminder length has no technical limit, so
|
|
149
|
+
prefer being complete.
|
|
150
|
+
- Multiple rough bridge reminders are acceptable. Once the system actually starts the next course,
|
|
151
|
+
the first step is to review, merge, and delete redundancy.
|
|
142
152
|
- Do not duplicate Taskdoc content except for a short bridge when strictly needed.
|
|
143
153
|
- Do not paste long raw logs/tool outputs into the continuation package.
|
|
144
154
|
|
|
@@ -157,7 +167,10 @@ Current behavior:
|
|
|
157
167
|
- On entering `caution`, Dominds inserts the prompt once (entry injection).
|
|
158
168
|
- While still `caution`, Dominds reinserts the prompt on a cadence (default: every **10**
|
|
159
169
|
generations; configurable per model).
|
|
160
|
-
- Each inserted prompt
|
|
170
|
+
- Each inserted prompt is split by the program according to dialog scope, so the agent does not decide
|
|
171
|
+
whether it is in the Main Dialog or a Side Dialog:
|
|
172
|
+
- Main Dialog: update Taskdoc first with `mind_more` / `change_mind`, then curate reminders (at least one call)
|
|
173
|
+
- Side Dialog: do not maintain Taskdoc and do not draft Taskdoc update proposals; directly curate sufficiently detailed reminders (at least one call)
|
|
161
174
|
- `update_reminder` (preferred) / `add_reminder`
|
|
162
175
|
- Default to one structured continuation-package reminder; if the current course is already under remediation and one structured reminder cannot be produced directly from already observed facts, rough multi-reminder carry-over is acceptable
|
|
163
176
|
- Then `clear_mind` when it becomes scannable/actionable
|
|
@@ -167,9 +180,13 @@ Current behavior:
|
|
|
167
180
|
When `level === 'critical'`, the driver enters a **countdown remediation** (max **5** turns):
|
|
168
181
|
|
|
169
182
|
- On each turn, the driver records a **role=user prompt** (persisted as a user message) that is
|
|
170
|
-
visible in the UI as a user prompt.
|
|
171
|
-
-
|
|
172
|
-
|
|
183
|
+
visible in the UI as a user prompt. The prompt is scope-specific:
|
|
184
|
+
- Main Dialog prompt: first write undocumented discussion details that the next course needs to know
|
|
185
|
+
into the appropriate Taskdoc sections with `mind_more` / `change_mind`, then curate reminders via
|
|
186
|
+
`update_reminder` / `add_reminder`, and call `clear_mind`.
|
|
187
|
+
- Side Dialog prompt: do not maintain Taskdoc and do not draft Taskdoc update proposals; directly
|
|
188
|
+
maintain sufficiently detailed continuation-package reminders with no technical length limit, then
|
|
189
|
+
call `clear_mind`.
|
|
173
190
|
- The prompt includes a countdown: after **N** turns the system will automatically clear.
|
|
174
191
|
- When the countdown reaches 0, the driver **automatically calls** `clear_mind` (with empty args; no
|
|
175
192
|
requirement on `reminder_content`), starting a new course without suspending.
|
|
@@ -234,9 +251,18 @@ Additional constraints:
|
|
|
234
251
|
- v3 remediation:
|
|
235
252
|
- `caution`: driver inserts a persisted role=user prompt (UI-visible user instruction).
|
|
236
253
|
On entering `caution` it inserts once; while still `caution` it reinserts on a cadence (default: every
|
|
237
|
-
10 generations; configurable per model). Each time, the agent must
|
|
238
|
-
|
|
254
|
+
10 generations; configurable per model). Each time, the agent must first record undocumented
|
|
255
|
+
discussion details the next course needs to know into Taskdoc, then call at least one of
|
|
256
|
+
`update_reminder` / `add_reminder` and preserve a continuation package. In a Side Dialog, the
|
|
257
|
+
prompt says not to maintain Taskdoc or draft Taskdoc update proposals; instead, maintain sufficiently
|
|
258
|
+
detailed continuation-package reminders directly.
|
|
259
|
+
A single structured reminder is preferred when the current course is not under remediation pressure;
|
|
260
|
+
during remediation, multiple rough reminders are acceptable if they can be written directly from
|
|
261
|
+
already observed facts without further reading/analysis. In the new course the agent should
|
|
262
|
+
reconcile them first, then `clear_mind` when ready.
|
|
239
263
|
- `critical`: driver runs a countdown remediation (max 5 turns) using **recorded role=user prompts**.
|
|
240
|
-
Each prompt includes a countdown
|
|
241
|
-
|
|
264
|
+
Each prompt includes a countdown. Main Dialog prompts instruct Taskdoc update, reminder curation,
|
|
265
|
+
then `clear_mind`; Side Dialog prompts instruct detailed reminder curation only, then `clear_mind`.
|
|
266
|
+
When the countdown reaches 0, the driver auto-executes `clear_mind` and starts a new course (no Q4H,
|
|
267
|
+
no suspension).
|
|
242
268
|
- UI shows context health with green/yellow/red (and “unknown” handling when usage is unavailable).
|
|
@@ -19,7 +19,7 @@ Dominds 已具备以下功能:
|
|
|
19
19
|
- 当对话上下文"过大"时,执行简短的、可执行的、可回归测试的 **v3 恢复**工作流:
|
|
20
20
|
- 在 **caution(警告)** 级别,记录一条自动插入的 **role=user prompt** 作为正常的、持久化的用户消息(UI 可见并渲染为正常的用户指令)。
|
|
21
21
|
- 在 **critical(严重)** 级别,通过**倒计时恢复**(最多 5 轮)强制执行稳定性:
|
|
22
|
-
- 每轮注入一条**记录的角色为 user 的 prompt**(UI 可见为用户 prompt
|
|
22
|
+
- 每轮注入一条**记录的角色为 user 的 prompt**(UI 可见为用户 prompt)。主线对话提示智能体先把当前对话历史中尚未落实到文档、且下一程需要知会的讨论细节落到差遣牒合适章节,再整理接续包提醒项(`update_reminder`/`add_reminder`),然后执行 `clear_mind`;支线对话提示智能体不要维护差遣牒、也不要整理更新提案,只维护足够详尽的接续包提醒项(长度无技术限制),然后执行 `clear_mind`。
|
|
23
23
|
- prompt 包含倒计时信号(在进行自动 `clear_mind` 之前还剩多少轮)。
|
|
24
24
|
- 当倒计时归零时,Dominds **自动**执行 `clear_mind`(无需 Q4H;无需暂停)以保持长期运行的自主性。
|
|
25
25
|
|
|
@@ -112,7 +112,10 @@ Dominds 计算比率:
|
|
|
112
112
|
- 普通提醒项保持简短且少量。
|
|
113
113
|
- 不允许智能体靠主观感觉判断自己“头脑清楚”还是“已经发乱”;这两种说法没有可靠、可审计的客观判据。
|
|
114
114
|
- 机制性分流规则只有一个:看**系统是否已将当前程置于上下文健康处置态**。若当前没有 `caution/critical` 处置指令,则默认优先压缩成一个结构化接续包提醒项。
|
|
115
|
-
- 一旦系统已将当前程置于 `caution/critical`
|
|
115
|
+
- 一旦系统已将当前程置于 `caution/critical` 处置态,驱动程序按对话范围分流提示:
|
|
116
|
+
- 主线对话:先把当前对话历史中尚未落实到文档、且下一程需要知会的讨论细节写入差遣牒合适章节;随后只把差遣牒仍未覆盖、但恢复工作容易丢的细节放入接续包。
|
|
117
|
+
- 支线对话:不要维护差遣牒,也不要整理差遣牒更新提案;直接维护足够详尽的接续包提醒项,提醒项长度没有技术限制,宁可完整一些。
|
|
118
|
+
- 此时允许多条粗略提醒项过桥;系统真正开启新一程后,第一步再复核、合并并删除冗余。
|
|
116
119
|
- 除非确有必要,不要重复差遣牒已覆盖的内容。
|
|
117
120
|
- 不要把长原始日志/大段 tool output 直接塞进接续包。
|
|
118
121
|
|
|
@@ -126,7 +129,9 @@ Dominds 计算比率:
|
|
|
126
129
|
|
|
127
130
|
- 进入 `caution` 时,Dominds 插入一次提示(入口注入)。
|
|
128
131
|
- 保持在 `caution` 状态时,Dominds 按节奏重新插入(默认:每 **10** 次生成;可按模型配置)。
|
|
129
|
-
-
|
|
132
|
+
- 每次插入的提示都由程序按范围分流,不要求智能体自己判断主线/支线:
|
|
133
|
+
- 主线对话:先使用 `mind_more` / `change_mind` 补齐差遣牒,再整理提醒项(至少一次调用)
|
|
134
|
+
- 支线对话:不维护差遣牒,也不整理差遣牒更新提案;直接整理足够详尽的提醒项(至少一次调用)
|
|
130
135
|
- `update_reminder`(首选)/ `add_reminder`
|
|
131
136
|
- 在提醒项内维护接续包草稿
|
|
132
137
|
- 当可扫描/可操作时执行 `clear_mind`
|
|
@@ -135,14 +140,16 @@ Dominds 计算比率:
|
|
|
135
140
|
|
|
136
141
|
当 `level === 'critical'` 时,驱动程序进入**倒计时恢复**(最多 **5** 轮):
|
|
137
142
|
|
|
138
|
-
- 每轮,驱动程序记录一条 **role=user prompt**(持久化为用户消息),在 UI 中作为用户 prompt
|
|
139
|
-
-
|
|
143
|
+
- 每轮,驱动程序记录一条 **role=user prompt**(持久化为用户消息),在 UI 中作为用户 prompt 可见。提示按范围分开:
|
|
144
|
+
- 主线对话提示:先用 `mind_more` / `change_mind` 把未落文档、且下一程需要知会的讨论细节写入差遣牒合适章节,再通过 `update_reminder` / `add_reminder` 整理提醒项并调用 `clear_mind`。
|
|
145
|
+
- 支线对话提示:不要维护差遣牒,也不要整理差遣牒更新提案;直接维护足够详尽的接续包提醒项,提醒项长度没有技术限制,然后调用 `clear_mind`。
|
|
140
146
|
- 提示包含倒计时:经过 **N** 轮后系统将自动清空。
|
|
141
147
|
- 当倒计时归零时,驱动程序**自动调用** `clear_mind`(带空参数;不要求 `reminder_content`),开始新一程且无需暂停。
|
|
142
148
|
|
|
143
149
|
理由:
|
|
144
150
|
|
|
145
151
|
- `caution` 已经在提醒项中尽力推动接续包草稿的编写。
|
|
152
|
+
- 告急提示仍要求主线先补差遣牒;支线则以详尽提醒项保存讨论细节,避免维护人提案在上下文吃紧时额外增加心智负担。
|
|
146
153
|
- 在 `critical` 状态下,我们更倾向于保持对话长期运行而无需人工干预。
|
|
147
154
|
|
|
148
155
|
## UI(Webapp)预期
|
|
@@ -193,6 +200,6 @@ Dominds 计算比率:
|
|
|
193
200
|
- 未配置时 `optimal_max_tokens` 默认为 `100_000`。
|
|
194
201
|
- 未配置时 `critical_max_tokens` 默认为 `floor(modelContextLimitTokens * 0.9)`。
|
|
195
202
|
- v3 恢复:
|
|
196
|
-
- `caution`:驱动程序插入持久化的 role=user prompt(UI 可见的用户指令)。进入 `caution` 时插入一次;保持在 `caution` 状态时按节奏重新插入(默认:每 10
|
|
197
|
-
- `critical`:驱动程序使用**记录的角色为 user 的 prompt** 运行倒计时恢复(最多 5
|
|
203
|
+
- `caution`:驱动程序插入持久化的 role=user prompt(UI 可见的用户指令)。进入 `caution` 时插入一次;保持在 `caution` 状态时按节奏重新插入(默认:每 10 次生成;可按模型配置)。主线提示要求先把未落文档、且下一程需要知会的讨论细节补进差遣牒,再至少调用 `update_reminder` / `add_reminder` 之一维护接续包草稿;支线提示要求不要维护差遣牒/更新提案,直接维护足够详尽的接续包提醒项;然后在就绪时执行 `clear_mind`。
|
|
204
|
+
- `critical`:驱动程序使用**记录的角色为 user 的 prompt** 运行倒计时恢复(最多 5 轮)。每次提示包含倒计时;主线提示指示先补差遣牒,再整理提醒项并 `clear_mind`;支线提示指示只维护详尽提醒项并 `clear_mind`。当倒计时归零时,驱动程序自动执行 `clear_mind` 并开始新一程(无 Q4H,无暂停)。
|
|
198
205
|
- UI 显示上下文健康状态:绿色/黄色/红色(以及使用情况不可用时的"未知"处理)。
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Idle Reminder Wake Design
|
|
2
|
+
|
|
3
|
+
Chinese version: [中文版](./idle-reminder-wake.zh.md)
|
|
4
|
+
|
|
5
|
+
This document defines a driver-level background coroutine mechanism: after a dialog enters `idle_waiting_user`, the runtime may wait for wake-worthy events from reminder owners. If an event arrives while the dialog is still idle, the runtime packages the event into a system-notice `role=user` message and continues driving the dialog.
|
|
6
|
+
|
|
7
|
+
This is a design document. It defines semantics, owner interfaces, cancellation, and the current implementation target; it does not prescribe the final code split.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Background
|
|
12
|
+
|
|
13
|
+
Reminder owners already own the meaning of their reminders. For example, the `shell_cmd` daemon reminder can discover that a daemon has exited during the next reminder update and turn the reminder into a terminal snapshot.
|
|
14
|
+
|
|
15
|
+
The missing link is idle-time wakeup. If a daemon exits while the dialog is idle, Dominds currently notices only when the dialog is opened, reminders are displayed, or a later drive happens. From the user's perspective, the long-running command has completed, but the dialog does not automatically wake up or explain that the process exited.
|
|
16
|
+
|
|
17
|
+
The `shell_cmd` tool should not directly drive dialogs to solve this. The driver is the only component that should decide whether a dialog continues running. A reminder owner should only explain when one of its reminders has produced an environment event worth waking the model for.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Goals
|
|
22
|
+
|
|
23
|
+
- Start a cancelable background await task only after the dialog truly enters `idle_waiting_user`.
|
|
24
|
+
- Let reminder owners expose wake-worthy events such as daemon exit.
|
|
25
|
+
- After an event arrives, briefly aggregate nearby events before forming one runtime `role=user` system notice.
|
|
26
|
+
- If the dialog is still idle after aggregation, continue through the normal driver path.
|
|
27
|
+
- Cancel the existing idle await task whenever any new drive starts.
|
|
28
|
+
- Preserve owner metadata encapsulation: framework code routes by owner but does not reinterpret owner meta.
|
|
29
|
+
- Guarantee idempotence: the same environment event must not insert duplicate system notices.
|
|
30
|
+
|
|
31
|
+
## Non-Goals
|
|
32
|
+
|
|
33
|
+
- Do not treat every reminder content change as a wake signal.
|
|
34
|
+
- Do not let reminder owners call `driveDialogStream` directly.
|
|
35
|
+
- Do not represent the idle await task as an `activeRun`, because the UI must not see environment waiting as proceeding.
|
|
36
|
+
- Do not auto-wake blocked, stopped, dead, completed, or archived dialogs.
|
|
37
|
+
- Do not wake on every daemon stdout/stderr growth; the current scenario only covers daemon lifecycle exit.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Core Decisions
|
|
42
|
+
|
|
43
|
+
### 1. The driver owns the idle wake lifecycle
|
|
44
|
+
|
|
45
|
+
After `driveDialogStreamCore` finally sets display state to `idle_waiting_user`, the outer driver starts a dialog-scoped idle wake task.
|
|
46
|
+
|
|
47
|
+
The task:
|
|
48
|
+
|
|
49
|
+
- does not hold the dialog mutex
|
|
50
|
+
- does not create an active run
|
|
51
|
+
- does not change display state
|
|
52
|
+
- only waits for owner-provided wake events
|
|
53
|
+
- is canceled before a new drive begins
|
|
54
|
+
|
|
55
|
+
This keeps "waiting for an environment event" separate from "actively working" and avoids confusing user-visible run-control semantics.
|
|
56
|
+
|
|
57
|
+
### 2. Reminder owners only report wake events
|
|
58
|
+
|
|
59
|
+
`ReminderOwner` gains an optional interface:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
export type ReminderWakeEvent = Readonly<{
|
|
63
|
+
eventId: string;
|
|
64
|
+
reminderId: string;
|
|
65
|
+
content: string;
|
|
66
|
+
updatedContent?: string;
|
|
67
|
+
updatedMeta?: JsonValue;
|
|
68
|
+
}>;
|
|
69
|
+
|
|
70
|
+
export interface ReminderOwner {
|
|
71
|
+
readonly name: string;
|
|
72
|
+
updateReminder(dlg: Dialog, reminder: Reminder): Promise<ReminderUpdateResult>;
|
|
73
|
+
renderReminder(dlg: Dialog, reminder: Reminder): Promise<ChatMessage>;
|
|
74
|
+
|
|
75
|
+
waitForReminderWakeEvent?(
|
|
76
|
+
dlg: Dialog,
|
|
77
|
+
reminders: readonly Reminder[],
|
|
78
|
+
signal: AbortSignal,
|
|
79
|
+
): Promise<ReminderWakeEvent | readonly ReminderWakeEvent[] | null>;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`content` is owner-formatted system-notice text and must start with `【系统提示】` or `[System notice]`. It is not real user input, but because providers commonly lack a dedicated environment role, it is persisted through the runtime prompt path as a `role=user` message.
|
|
84
|
+
|
|
85
|
+
`eventId` is a stable idempotence key in the owner's domain. The owner must be able to record, in reminder meta or owner-owned state, that the event has already been delivered.
|
|
86
|
+
|
|
87
|
+
### 3. The first event opens a short aggregation window
|
|
88
|
+
|
|
89
|
+
The driver should not drive immediately after the first wake event. It should:
|
|
90
|
+
|
|
91
|
+
1. await the first wake event
|
|
92
|
+
2. open an aggregation window of about 500 ms
|
|
93
|
+
3. collect other wake events that arrive in the same idle wake task
|
|
94
|
+
4. stably sort and deduplicate the events
|
|
95
|
+
5. package them into one runtime prompt
|
|
96
|
+
|
|
97
|
+
This prevents several daemons that exit close together from causing several consecutive drive rounds. The user and model see one combined environment-status message instead of fragmented notices.
|
|
98
|
+
|
|
99
|
+
### 4. Wake must re-check fresh state
|
|
100
|
+
|
|
101
|
+
After the aggregation window, the driver must re-read persistence and verify:
|
|
102
|
+
|
|
103
|
+
- the dialog still exists and is running
|
|
104
|
+
- display state is still `idle_waiting_user`
|
|
105
|
+
- execution marker is not dead and not an interrupted state requiring human resume
|
|
106
|
+
- no pending Q4H exists
|
|
107
|
+
- no blocking pending sideDialog exists
|
|
108
|
+
- no active run exists
|
|
109
|
+
|
|
110
|
+
Only then may the driver continue with the wake prompt. Otherwise the wake is dropped, while owner idempotence/state updates may still be retained.
|
|
111
|
+
|
|
112
|
+
### 5. Any drive cancels the idle wake task
|
|
113
|
+
|
|
114
|
+
Before any new drive begins, runtime must cancel the dialog's existing idle wake task. This includes:
|
|
115
|
+
|
|
116
|
+
- user messages
|
|
117
|
+
- manual Continue / Resume All
|
|
118
|
+
- Q4H-answer resume
|
|
119
|
+
- sideDialog-response resume
|
|
120
|
+
- Diligence Push / other runtime auto-drive
|
|
121
|
+
- the wake drive from this mechanism
|
|
122
|
+
|
|
123
|
+
After cancellation, the old task must not produce side effects even if one of its promises resolves.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Wake Message Format
|
|
128
|
+
|
|
129
|
+
Owner event `content` should state facts without inventing a user request.
|
|
130
|
+
|
|
131
|
+
Daemon exit example:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
【系统提示】
|
|
135
|
+
后台进程已退出。这是 runtime 环境事件,不是新的用户指令。
|
|
136
|
+
|
|
137
|
+
- PID: 12345
|
|
138
|
+
- 命令: pnpm run build
|
|
139
|
+
- 退出状态: code 0, signal null
|
|
140
|
+
|
|
141
|
+
请根据当前任务上下文判断是否需要查看最终 stdout/stderr 或向用户汇报结果;不要只回复“收到”。
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
When the driver aggregates multiple events, it should preserve each factual block and add a shared prefix:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
【系统提示】
|
|
148
|
+
以下是对话空闲期间发生的 runtime 环境事件。这些事件不是新的用户指令。
|
|
149
|
+
|
|
150
|
+
1. 后台进程已退出 ...
|
|
151
|
+
2. 后台进程已退出 ...
|
|
152
|
+
|
|
153
|
+
请结合当前任务上下文继续推进;若这些事件不影响当前工作,不要发送占位式确认。
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Current Target: Shell Daemon Exit
|
|
159
|
+
|
|
160
|
+
`shellCmdReminderOwner` implements `waitForReminderWakeEvent`.
|
|
161
|
+
|
|
162
|
+
Semantics:
|
|
163
|
+
|
|
164
|
+
- It only watches daemon reminders owned by this owner.
|
|
165
|
+
- It only emits a wake event when a daemon transitions from running to exited/gone.
|
|
166
|
+
- stdout/stderr growth does not emit a wake event.
|
|
167
|
+
- If reminder meta already marks the corresponding exit event as delivered, it returns `null`.
|
|
168
|
+
- When the event arrives, the owner also provides terminal reminder `updatedContent` / `updatedMeta`, and the driver persists them before delivering the wake prompt.
|
|
169
|
+
|
|
170
|
+
Required meta additions:
|
|
171
|
+
|
|
172
|
+
- `originRootId`: needed to restore the origin dialog.
|
|
173
|
+
- `originDialogId`: existing field; continues to mean self id.
|
|
174
|
+
- `exitWakeEventId`: stable event id, for example `shellCmd:daemonExited:<pid>:<startTime>`.
|
|
175
|
+
- `exitWakeNotifiedAt`: timestamp when runtime accepted and delivered the event.
|
|
176
|
+
|
|
177
|
+
If the daemon runner can provide an awaitable exit signal, use that as the primary path. If the current implementation can only use local IPC status checks, polling must stay encapsulated inside the owner; the driver must not gain daemon-specific scanning logic.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Cancellation And Concurrency
|
|
182
|
+
|
|
183
|
+
There is at most one idle wake task per dialog.
|
|
184
|
+
|
|
185
|
+
Suggested runtime state:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
type IdleReminderWakeTask = Readonly<{
|
|
189
|
+
dialogKey: string;
|
|
190
|
+
controller: AbortController;
|
|
191
|
+
startedAt: string;
|
|
192
|
+
}>;
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The first preflight step of a new drive cancels the old task. Cancellation is idempotent.
|
|
196
|
+
|
|
197
|
+
After an idle wake task resolves, it must also verify that it is still the current task. If it has been replaced or canceled, it returns without side effects.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Crash Recovery
|
|
202
|
+
|
|
203
|
+
The idle wake task itself is not persisted. After backend restart, Dominds does not recover in-flight waiting promises.
|
|
204
|
+
|
|
205
|
+
The first normal driver/display/reminder update after restart still corrects reminder terminal state. If restart-time proactive waking is needed, Dominds can add bootstrap logic that reinstalls idle wake tasks for running idle dialogs. That capability is not required for the current mechanism to be complete.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Observability And Error Handling
|
|
210
|
+
|
|
211
|
+
Owner wait interfaces are loud by default:
|
|
212
|
+
|
|
213
|
+
- Non-cancel errors should be structured logs with `rootId`, `selfId`, `ownerName`, `reminderId`, and `eventId` when available.
|
|
214
|
+
- Owners must not swallow unreasonable states, such as the same event id mapping to conflicting content.
|
|
215
|
+
- If the driver finds that an aggregated wake can no longer revive the dialog, it should record debug/warn diagnostics, but it must not surface the dropped wake as a user-visible message.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Implementation Order
|
|
220
|
+
|
|
221
|
+
1. Add `ReminderWakeEvent` and optional `ReminderOwner.waitForReminderWakeEvent?` types.
|
|
222
|
+
2. Add driver-side idle wake task management: start/cancel/race/500 ms aggregation/fresh state checks.
|
|
223
|
+
3. Cancel the dialog's idle wake task in every drive preflight.
|
|
224
|
+
4. Start an idle wake task after the driver finally lands on `idle_waiting_user`.
|
|
225
|
+
5. Implement daemon-exit wake events in `shellCmdReminderOwner`.
|
|
226
|
+
6. Add `originRootId` and wake idempotence fields to daemon reminder meta.
|
|
227
|
+
7. Add tests: single daemon exit wake, multiple daemon exits aggregated within 500 ms, user message cancellation, blocked dialogs not waking, and idempotence.
|