dominds 1.16.10 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dialog-display-state.js +22 -1
- package/dist/dialog-instance-registry.js +47 -0
- package/dist/dialog-interruption.d.ts +1 -0
- package/dist/dialog-interruption.js +19 -0
- package/dist/dialog.d.ts +2 -1
- package/dist/dialog.js +37 -1
- package/dist/llm/kernel-driver/drive.js +1 -0
- package/dist/llm/kernel-driver/flow.js +5 -3
- package/dist/llm/kernel-driver/loop.js +5 -2
- package/dist/persistence.d.ts +3 -1
- package/dist/persistence.js +174 -37
- package/dist/runtime/interjection-pause-stop.js +1 -1
- package/package.json +4 -4
- package/webapp/dist/assets/{_basePickBy-BKgfg72Q.js → _basePickBy-DCLDUO6G.js} +3 -3
- package/webapp/dist/assets/{_basePickBy-BKgfg72Q.js.map → _basePickBy-DCLDUO6G.js.map} +1 -1
- package/webapp/dist/assets/{_baseUniq-DKhs7H5s.js → _baseUniq-V58PJT8b.js} +2 -2
- package/webapp/dist/assets/{_baseUniq-DKhs7H5s.js.map → _baseUniq-V58PJT8b.js.map} +1 -1
- package/webapp/dist/assets/{arc-Tykg3Fx4.js → arc-6cLC3ft0.js} +2 -2
- package/webapp/dist/assets/{arc-Tykg3Fx4.js.map → arc-6cLC3ft0.js.map} +1 -1
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BAyn6_in.js → architectureDiagram-2XIMDMQ5-DZCDnc5k.js} +7 -7
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BAyn6_in.js.map → architectureDiagram-2XIMDMQ5-DZCDnc5k.js.map} +1 -1
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-CGbo6x6_.js → blockDiagram-WCTKOSBZ-B3x8CjfT.js} +7 -7
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-CGbo6x6_.js.map → blockDiagram-WCTKOSBZ-B3x8CjfT.js.map} +1 -1
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-CUizxwo0.js → c4Diagram-IC4MRINW-BG5ES2pq.js} +3 -3
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-CUizxwo0.js.map → c4Diagram-IC4MRINW-BG5ES2pq.js.map} +1 -1
- package/webapp/dist/assets/{channel-DvP7WrjO.js → channel-CKCjdwdQ.js} +2 -2
- package/webapp/dist/assets/{channel-DvP7WrjO.js.map → channel-CKCjdwdQ.js.map} +1 -1
- package/webapp/dist/assets/{chunk-4BX2VUAB-cgnNaqgV.js → chunk-4BX2VUAB-BMUaxm65.js} +2 -2
- package/webapp/dist/assets/{chunk-4BX2VUAB-cgnNaqgV.js.map → chunk-4BX2VUAB-BMUaxm65.js.map} +1 -1
- package/webapp/dist/assets/{chunk-55IACEB6-BEUsguTg.js → chunk-55IACEB6-CZLjFLTA.js} +2 -2
- package/webapp/dist/assets/{chunk-55IACEB6-BEUsguTg.js.map → chunk-55IACEB6-CZLjFLTA.js.map} +1 -1
- package/webapp/dist/assets/{chunk-FMBD7UC4-B2p0efxm.js → chunk-FMBD7UC4-C6OhtkjK.js} +2 -2
- package/webapp/dist/assets/{chunk-FMBD7UC4-B2p0efxm.js.map → chunk-FMBD7UC4-C6OhtkjK.js.map} +1 -1
- package/webapp/dist/assets/{chunk-JSJVCQXG-Bd09WM0B.js → chunk-JSJVCQXG-BL3lMwkX.js} +2 -2
- package/webapp/dist/assets/{chunk-JSJVCQXG-Bd09WM0B.js.map → chunk-JSJVCQXG-BL3lMwkX.js.map} +1 -1
- package/webapp/dist/assets/{chunk-KX2RTZJC-DaLNbvSI.js → chunk-KX2RTZJC-SieIRb1A.js} +2 -2
- package/webapp/dist/assets/{chunk-KX2RTZJC-DaLNbvSI.js.map → chunk-KX2RTZJC-SieIRb1A.js.map} +1 -1
- package/webapp/dist/assets/{chunk-NQ4KR5QH-6dsWbn61.js → chunk-NQ4KR5QH-Dj9V3OHv.js} +4 -4
- package/webapp/dist/assets/{chunk-NQ4KR5QH-6dsWbn61.js.map → chunk-NQ4KR5QH-Dj9V3OHv.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QZHKN3VN-C0e1qWr4.js → chunk-QZHKN3VN-DPuk0WWI.js} +2 -2
- package/webapp/dist/assets/{chunk-QZHKN3VN-C0e1qWr4.js.map → chunk-QZHKN3VN-DPuk0WWI.js.map} +1 -1
- package/webapp/dist/assets/{chunk-WL4C6EOR-ChheG0OU.js → chunk-WL4C6EOR-COmZsUPA.js} +6 -6
- package/webapp/dist/assets/{chunk-WL4C6EOR-ChheG0OU.js.map → chunk-WL4C6EOR-COmZsUPA.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-uUAnWHsS.js → classDiagram-VBA2DB6C-D0LskUiI.js} +7 -7
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-uUAnWHsS.js.map → classDiagram-VBA2DB6C-D0LskUiI.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-uUAnWHsS.js → classDiagram-v2-RAHNMMFH-D0LskUiI.js} +7 -7
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-uUAnWHsS.js.map → classDiagram-v2-RAHNMMFH-D0LskUiI.js.map} +1 -1
- package/webapp/dist/assets/{clone-BiXgC0aE.js → clone-DF4VAArJ.js} +2 -2
- package/webapp/dist/assets/{clone-BiXgC0aE.js.map → clone-DF4VAArJ.js.map} +1 -1
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-C-h7F7gA.js → cose-bilkent-S5V4N54A-BLS39Y5M.js} +2 -2
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-C-h7F7gA.js.map → cose-bilkent-S5V4N54A-BLS39Y5M.js.map} +1 -1
- package/webapp/dist/assets/{dagre-KLK3FWXG-5B3k91Lo.js → dagre-KLK3FWXG-BNcB5hir.js} +7 -7
- package/webapp/dist/assets/{dagre-KLK3FWXG-5B3k91Lo.js.map → dagre-KLK3FWXG-BNcB5hir.js.map} +1 -1
- package/webapp/dist/assets/{diagram-E7M64L7V-CFtPXaNS.js → diagram-E7M64L7V-C1k_RR0F.js} +8 -8
- package/webapp/dist/assets/{diagram-E7M64L7V-CFtPXaNS.js.map → diagram-E7M64L7V-C1k_RR0F.js.map} +1 -1
- package/webapp/dist/assets/{diagram-IFDJBPK2-CUuPPDwe.js → diagram-IFDJBPK2-IbfvdUeO.js} +7 -7
- package/webapp/dist/assets/{diagram-IFDJBPK2-CUuPPDwe.js.map → diagram-IFDJBPK2-IbfvdUeO.js.map} +1 -1
- package/webapp/dist/assets/{diagram-P4PSJMXO-D7oYhsVm.js → diagram-P4PSJMXO-DMHGiNIM.js} +7 -7
- package/webapp/dist/assets/{diagram-P4PSJMXO-D7oYhsVm.js.map → diagram-P4PSJMXO-DMHGiNIM.js.map} +1 -1
- package/webapp/dist/assets/{erDiagram-INFDFZHY-DUDHdT_e.js → erDiagram-INFDFZHY-DdHLX_b6.js} +5 -5
- package/webapp/dist/assets/{erDiagram-INFDFZHY-DUDHdT_e.js.map → erDiagram-INFDFZHY-DdHLX_b6.js.map} +1 -1
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CT7lC5J1.js → flowDiagram-PKNHOUZH-BfFizksz.js} +7 -7
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CT7lC5J1.js.map → flowDiagram-PKNHOUZH-BfFizksz.js.map} +1 -1
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BhlcqqDR.js → ganttDiagram-A5KZAMGK-CqevCVU5.js} +3 -3
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BhlcqqDR.js.map → ganttDiagram-A5KZAMGK-CqevCVU5.js.map} +1 -1
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-CYLYfqiB.js → gitGraphDiagram-K3NZZRJ6-BOOwupHL.js} +8 -8
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-CYLYfqiB.js.map → gitGraphDiagram-K3NZZRJ6-BOOwupHL.js.map} +1 -1
- package/webapp/dist/assets/{graph-twAxd7MO.js → graph-nrSDteEc.js} +3 -3
- package/webapp/dist/assets/{graph-twAxd7MO.js.map → graph-nrSDteEc.js.map} +1 -1
- package/webapp/dist/assets/{index-Bc1jJvgU.js → index-Cakki4rP.js} +67 -61
- package/webapp/dist/assets/{index-Bc1jJvgU.js.map → index-Cakki4rP.js.map} +1 -1
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-BAA1VoC0.js → infoDiagram-LFFYTUFH-D9wzGbBd.js} +6 -6
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-BAA1VoC0.js.map → infoDiagram-LFFYTUFH-D9wzGbBd.js.map} +1 -1
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-CyPvSx5W.js → ishikawaDiagram-PHBUUO56-Cw505dkV.js} +2 -2
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-CyPvSx5W.js.map → ishikawaDiagram-PHBUUO56-Cw505dkV.js.map} +1 -1
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-CbOLT63I.js → journeyDiagram-4ABVD52K-DB9-Kk7L.js} +5 -5
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-CbOLT63I.js.map → journeyDiagram-4ABVD52K-DB9-Kk7L.js.map} +1 -1
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-CUS-wMLR.js → kanban-definition-K7BYSVSG-D6f5d594.js} +3 -3
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-CUS-wMLR.js.map → kanban-definition-K7BYSVSG-D6f5d594.js.map} +1 -1
- package/webapp/dist/assets/{layout-C0HW4ZHi.js → layout-C66Gu-9j.js} +5 -5
- package/webapp/dist/assets/{layout-C0HW4ZHi.js.map → layout-C66Gu-9j.js.map} +1 -1
- package/webapp/dist/assets/{linear-DNEgfkh6.js → linear-WEG-0mNF.js} +2 -2
- package/webapp/dist/assets/{linear-DNEgfkh6.js.map → linear-WEG-0mNF.js.map} +1 -1
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-D5URwhNx.js → mindmap-definition-YRQLILUH-C5o4PZoW.js} +4 -4
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-D5URwhNx.js.map → mindmap-definition-YRQLILUH-C5o4PZoW.js.map} +1 -1
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-BQbBOUPk.js → pieDiagram-SKSYHLDU-CvE77iES.js} +8 -8
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-BQbBOUPk.js.map → pieDiagram-SKSYHLDU-CvE77iES.js.map} +1 -1
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-B_dFbPid.js → quadrantDiagram-337W2JSQ-0WD_Zxhv.js} +3 -3
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-B_dFbPid.js.map → quadrantDiagram-337W2JSQ-0WD_Zxhv.js.map} +1 -1
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CtWDUSB3.js → requirementDiagram-Z7DCOOCP-VSa_hUdb.js} +4 -4
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CtWDUSB3.js.map → requirementDiagram-Z7DCOOCP-VSa_hUdb.js.map} +1 -1
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-CqRH7yj4.js → sankeyDiagram-WA2Y5GQK-vPNok4nN.js} +2 -2
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-CqRH7yj4.js.map → sankeyDiagram-WA2Y5GQK-vPNok4nN.js.map} +1 -1
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-B1-5-5Qx.js → sequenceDiagram-2WXFIKYE-DX4cZf9x.js} +4 -4
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-B1-5-5Qx.js.map → sequenceDiagram-2WXFIKYE-DX4cZf9x.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-9krZSpaD.js → stateDiagram-RAJIS63D-nqNJSdDU.js} +9 -9
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-9krZSpaD.js.map → stateDiagram-RAJIS63D-nqNJSdDU.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DDLC-q0s.js → stateDiagram-v2-FVOUBMTO-BuZBSDCT.js} +5 -5
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DDLC-q0s.js.map → stateDiagram-v2-FVOUBMTO-BuZBSDCT.js.map} +1 -1
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-C64HbHNO.js → timeline-definition-YZTLITO2--gWaXe_R.js} +3 -3
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-C64HbHNO.js.map → timeline-definition-YZTLITO2--gWaXe_R.js.map} +1 -1
- package/webapp/dist/assets/{treemap-KZPCXAKY-TEywEA7B.js → treemap-KZPCXAKY-CAx-L6KX.js} +5 -5
- package/webapp/dist/assets/{treemap-KZPCXAKY-TEywEA7B.js.map → treemap-KZPCXAKY-CAx-L6KX.js.map} +1 -1
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-CT9sZ6ft.js → vennDiagram-LZ73GAT5-BQD4mief.js} +2 -2
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-CT9sZ6ft.js.map → vennDiagram-LZ73GAT5-BQD4mief.js.map} +1 -1
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-CEAg_tiv.js → xychartDiagram-JWTSCODW-D-wcj8Yx.js} +3 -3
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-CEAg_tiv.js.map → xychartDiagram-JWTSCODW-D-wcj8Yx.js.map} +1 -1
- package/webapp/dist/index.html +1 -1
|
@@ -417,6 +417,13 @@ async function computeIdleDisplayState(dlg) {
|
|
|
417
417
|
continueEnabled: isStoppedReasonResumable(latest.executionMarker.reason),
|
|
418
418
|
};
|
|
419
419
|
}
|
|
420
|
+
if (latest?.pendingCourseStartPrompt) {
|
|
421
|
+
return {
|
|
422
|
+
kind: 'stopped',
|
|
423
|
+
reason: { kind: 'pending_course_start' },
|
|
424
|
+
continueEnabled: true,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
420
427
|
const hasQ4H = await dlg.hasPendingQ4H();
|
|
421
428
|
const hasSubdialogs = await dlg.hasPendingSubdialogs();
|
|
422
429
|
if (hasQ4H && hasSubdialogs) {
|
|
@@ -449,6 +456,13 @@ async function computeIdleDisplayStateFromPersistence(dialogId) {
|
|
|
449
456
|
continueEnabled: isStoppedReasonResumable(latest.executionMarker.reason),
|
|
450
457
|
};
|
|
451
458
|
}
|
|
459
|
+
if (latest?.pendingCourseStartPrompt) {
|
|
460
|
+
return {
|
|
461
|
+
kind: 'stopped',
|
|
462
|
+
reason: { kind: 'pending_course_start' },
|
|
463
|
+
continueEnabled: true,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
452
466
|
const q4h = await persistence_1.DialogPersistence.loadQuestions4HumanState(dialogId, 'running');
|
|
453
467
|
const pendingSubdialogs = await persistence_1.DialogPersistence.loadPendingSubdialogs(dialogId, 'running');
|
|
454
468
|
const hasQ4H = q4h.length > 0;
|
|
@@ -502,6 +516,13 @@ async function refreshRunControlProjectionFromPersistenceFacts(dialogId, trigger
|
|
|
502
516
|
continueEnabled: isStoppedReasonResumable(latest.executionMarker.reason),
|
|
503
517
|
};
|
|
504
518
|
}
|
|
519
|
+
if (latest.pendingCourseStartPrompt) {
|
|
520
|
+
return {
|
|
521
|
+
kind: 'stopped',
|
|
522
|
+
reason: { kind: 'pending_course_start' },
|
|
523
|
+
continueEnabled: true,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
505
526
|
const q4h = await persistence_1.DialogPersistence.loadQuestions4HumanState(dialogId, 'running');
|
|
506
527
|
const pendingSubdialogs = await persistence_1.DialogPersistence.loadPendingSubdialogs(dialogId, 'running');
|
|
507
528
|
const hasQ4H = q4h.length > 0;
|
|
@@ -605,7 +626,7 @@ async function reconcileDisplayStatesAfterRestart() {
|
|
|
605
626
|
if (!nextIdle) {
|
|
606
627
|
continue;
|
|
607
628
|
}
|
|
608
|
-
const next = nextIdle.kind === 'blocked'
|
|
629
|
+
const next = nextIdle.kind === 'blocked' || nextIdle.kind === 'stopped' || nextIdle.kind === 'dead'
|
|
609
630
|
? nextIdle
|
|
610
631
|
: {
|
|
611
632
|
kind: 'stopped',
|
|
@@ -24,6 +24,39 @@ function clampNonNegativeFiniteInt(value, fallback) {
|
|
|
24
24
|
return fallback;
|
|
25
25
|
return Math.max(0, Math.floor(value));
|
|
26
26
|
}
|
|
27
|
+
async function resolvePendingCourseStartPromptForRestore(args) {
|
|
28
|
+
const pending = args.latest?.pendingCourseStartPrompt;
|
|
29
|
+
if (!pending) {
|
|
30
|
+
return { pendingCourseStartPrompt: undefined };
|
|
31
|
+
}
|
|
32
|
+
const alreadyPersisted = args.messages.some((message) => {
|
|
33
|
+
return message.type === 'prompting_msg' && message.msgId === pending.msgId;
|
|
34
|
+
});
|
|
35
|
+
if (alreadyPersisted) {
|
|
36
|
+
if (args.status === 'running') {
|
|
37
|
+
await persistence_1.DialogPersistence.clearPendingCourseStartPrompt(args.dialogId, pending.msgId, args.status);
|
|
38
|
+
}
|
|
39
|
+
return { pendingCourseStartPrompt: undefined };
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
pendingCourseStartPrompt: {
|
|
43
|
+
content: pending.content,
|
|
44
|
+
msgId: pending.msgId,
|
|
45
|
+
grammar: 'markdown',
|
|
46
|
+
origin: 'runtime',
|
|
47
|
+
...(pending.userLanguageCode === undefined
|
|
48
|
+
? {}
|
|
49
|
+
: { userLanguageCode: pending.userLanguageCode }),
|
|
50
|
+
...(pending.tellaskReplyDirective === undefined
|
|
51
|
+
? {}
|
|
52
|
+
: { tellaskReplyDirective: pending.tellaskReplyDirective }),
|
|
53
|
+
...(pending.skipTaskdoc === undefined ? {} : { skipTaskdoc: pending.skipTaskdoc }),
|
|
54
|
+
...(pending.subdialogReplyTarget === undefined
|
|
55
|
+
? {}
|
|
56
|
+
: { subdialogReplyTarget: pending.subdialogReplyTarget }),
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
27
60
|
async function getOrRestoreRootDialog(rootId, status) {
|
|
28
61
|
const existing = dialog_global_registry_1.globalDialogRegistry.get(rootId);
|
|
29
62
|
if (existing) {
|
|
@@ -41,6 +74,12 @@ async function getOrRestoreRootDialog(rootId, status) {
|
|
|
41
74
|
return undefined;
|
|
42
75
|
}
|
|
43
76
|
const latest = await persistence_1.DialogPersistence.loadDialogLatest(rootDialogId, status);
|
|
77
|
+
const { pendingCourseStartPrompt } = await resolvePendingCourseStartPromptForRestore({
|
|
78
|
+
dialogId: rootDialogId,
|
|
79
|
+
status,
|
|
80
|
+
messages: rootState.messages,
|
|
81
|
+
latest,
|
|
82
|
+
});
|
|
44
83
|
let diligencePushMax = diligence_1.DEFAULT_DILIGENCE_PUSH_MAX;
|
|
45
84
|
try {
|
|
46
85
|
const team = await team_1.Team.load();
|
|
@@ -56,6 +95,7 @@ async function getOrRestoreRootDialog(rootId, status) {
|
|
|
56
95
|
reminders: rootState.reminders,
|
|
57
96
|
currentCourse: rootState.currentCourse,
|
|
58
97
|
contextHealth: rootState.contextHealth,
|
|
98
|
+
pendingCourseStartPrompt,
|
|
59
99
|
});
|
|
60
100
|
const persistedDisableDiligencePush = latest && typeof latest.disableDiligencePush === 'boolean'
|
|
61
101
|
? latest.disableDiligencePush
|
|
@@ -97,6 +137,12 @@ async function ensureDialogLoaded(rootDialog, targetId, status, visitedSelfIds =
|
|
|
97
137
|
if (!state)
|
|
98
138
|
return undefined;
|
|
99
139
|
const latest = await persistence_1.DialogPersistence.loadDialogLatest(targetId, status);
|
|
140
|
+
const { pendingCourseStartPrompt } = await resolvePendingCourseStartPromptForRestore({
|
|
141
|
+
dialogId: targetId,
|
|
142
|
+
status,
|
|
143
|
+
messages: state.messages,
|
|
144
|
+
latest,
|
|
145
|
+
});
|
|
100
146
|
const assignmentFromSup = state.metadata.assignmentFromSup;
|
|
101
147
|
if (!assignmentFromSup)
|
|
102
148
|
return undefined;
|
|
@@ -112,6 +158,7 @@ async function ensureDialogLoaded(rootDialog, targetId, status, visitedSelfIds =
|
|
|
112
158
|
reminders: state.reminders,
|
|
113
159
|
currentCourse: state.currentCourse,
|
|
114
160
|
contextHealth: state.contextHealth,
|
|
161
|
+
pendingCourseStartPrompt,
|
|
115
162
|
});
|
|
116
163
|
subdialog.disableDiligencePush = latest?.disableDiligencePush ?? false;
|
|
117
164
|
if (subdialog.sessionSlug) {
|
|
@@ -16,3 +16,4 @@ import type { DialogInterruptionReason } from '@longrun-ai/kernel/types/display-
|
|
|
16
16
|
* provider/model and should keep protecting the system.
|
|
17
17
|
*/
|
|
18
18
|
export declare function isInterruptionReasonManualResumeEligible(reason: DialogInterruptionReason): boolean;
|
|
19
|
+
export declare function doesInterruptionReasonRequireExplicitResume(reason: DialogInterruptionReason): boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isInterruptionReasonManualResumeEligible = isInterruptionReasonManualResumeEligible;
|
|
4
|
+
exports.doesInterruptionReasonRequireExplicitResume = doesInterruptionReasonRequireExplicitResume;
|
|
4
5
|
/**
|
|
5
6
|
* Decides whether a finalized stopped dialog should expose manual Continue.
|
|
6
7
|
*
|
|
@@ -22,6 +23,24 @@ function isInterruptionReasonManualResumeEligible(reason) {
|
|
|
22
23
|
case 'user_stop':
|
|
23
24
|
case 'emergency_stop':
|
|
24
25
|
case 'server_restart':
|
|
26
|
+
case 'pending_course_start':
|
|
27
|
+
case 'fork_continue_ready':
|
|
28
|
+
case 'system_stop':
|
|
29
|
+
case 'llm_retry_stopped':
|
|
30
|
+
return true;
|
|
31
|
+
default: {
|
|
32
|
+
const _exhaustive = reason;
|
|
33
|
+
return _exhaustive;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function doesInterruptionReasonRequireExplicitResume(reason) {
|
|
38
|
+
switch (reason.kind) {
|
|
39
|
+
case 'pending_course_start':
|
|
40
|
+
return false;
|
|
41
|
+
case 'user_stop':
|
|
42
|
+
case 'emergency_stop':
|
|
43
|
+
case 'server_restart':
|
|
25
44
|
case 'fork_continue_ready':
|
|
26
45
|
case 'system_stop':
|
|
27
46
|
case 'llm_retry_stopped':
|
package/dist/dialog.d.ts
CHANGED
|
@@ -106,6 +106,7 @@ export interface DialogInitParams {
|
|
|
106
106
|
createdAt?: string;
|
|
107
107
|
updatedAt?: string;
|
|
108
108
|
contextHealth?: ContextHealthSnapshot;
|
|
109
|
+
pendingCourseStartPrompt?: DialogPrompt;
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
112
|
export type VisibleReminderTarget = Readonly<{
|
|
@@ -678,7 +679,7 @@ export declare abstract class DialogStore {
|
|
|
678
679
|
/**
|
|
679
680
|
* Start a new course in storage
|
|
680
681
|
*/
|
|
681
|
-
startNewCourse(_dialog: Dialog, _newCoursePrompt:
|
|
682
|
+
startNewCourse(_dialog: Dialog, _newCoursePrompt: DialogPrompt): Promise<void>;
|
|
682
683
|
/**
|
|
683
684
|
* Handle stream error
|
|
684
685
|
*/
|
package/dist/dialog.js
CHANGED
|
@@ -67,6 +67,38 @@ function getGlobalDialogMutex(dialogId) {
|
|
|
67
67
|
function compareVisibleReminderTargetOrder(a, b) {
|
|
68
68
|
return (0, tool_1.compareReminderDisplayOrder)(a.reminder, b.reminder);
|
|
69
69
|
}
|
|
70
|
+
function buildSubdialogAssignmentPromptMeta(subdialog) {
|
|
71
|
+
const assignment = subdialog.assignmentFromSup;
|
|
72
|
+
switch (assignment.callName) {
|
|
73
|
+
case 'tellask':
|
|
74
|
+
return {
|
|
75
|
+
tellaskReplyDirective: {
|
|
76
|
+
expectedReplyCallName: 'replyTellask',
|
|
77
|
+
targetCallId: assignment.callId,
|
|
78
|
+
tellaskContent: assignment.tellaskContent,
|
|
79
|
+
},
|
|
80
|
+
subdialogReplyTarget: {
|
|
81
|
+
ownerDialogId: assignment.callerDialogId,
|
|
82
|
+
callType: 'B',
|
|
83
|
+
callId: assignment.callId,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
case 'tellaskSessionless':
|
|
87
|
+
case 'freshBootsReasoning':
|
|
88
|
+
return {
|
|
89
|
+
tellaskReplyDirective: {
|
|
90
|
+
expectedReplyCallName: 'replyTellaskSessionless',
|
|
91
|
+
targetCallId: assignment.callId,
|
|
92
|
+
tellaskContent: assignment.tellaskContent,
|
|
93
|
+
},
|
|
94
|
+
subdialogReplyTarget: {
|
|
95
|
+
ownerDialogId: assignment.callerDialogId,
|
|
96
|
+
callType: 'C',
|
|
97
|
+
callId: assignment.callId,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
70
102
|
/**
|
|
71
103
|
* Abstract base class for all dialog types.
|
|
72
104
|
* Contains common properties and methods shared between RootDialog and SubDialog.
|
|
@@ -132,6 +164,9 @@ class Dialog {
|
|
|
132
164
|
this._lastUserLanguageCode = (0, work_language_1.getWorkLanguage)();
|
|
133
165
|
this._lastContextHealth = initialState?.contextHealth;
|
|
134
166
|
this._lastContextHealthGenseq = undefined;
|
|
167
|
+
if (initialState?.pendingCourseStartPrompt) {
|
|
168
|
+
this.setNewCourseStartPrompt(initialState.pendingCourseStartPrompt);
|
|
169
|
+
}
|
|
135
170
|
this.resetCourseLanguageNotice();
|
|
136
171
|
}
|
|
137
172
|
setLastContextHealth(snapshot) {
|
|
@@ -844,6 +879,7 @@ class Dialog {
|
|
|
844
879
|
grammar: 'markdown',
|
|
845
880
|
userLanguageCode: this._lastUserLanguageCode,
|
|
846
881
|
origin: 'runtime',
|
|
882
|
+
...(this instanceof SubDialog ? buildSubdialogAssignmentPromptMeta(this) : {}),
|
|
847
883
|
};
|
|
848
884
|
const runControlSpec = options?.runControl ?? this._activeRunControlSpec;
|
|
849
885
|
let nextPrompt = basePrompt;
|
|
@@ -863,7 +899,7 @@ class Dialog {
|
|
|
863
899
|
await this.dlgStore.clearQuestions4Human(this);
|
|
864
900
|
// Delegate to DialogStore for course start persistence
|
|
865
901
|
if (this.dlgStore) {
|
|
866
|
-
await this.dlgStore.startNewCourse(this, nextPrompt
|
|
902
|
+
await this.dlgStore.startNewCourse(this, nextPrompt);
|
|
867
903
|
}
|
|
868
904
|
const storeCourse = this.dlgStore
|
|
869
905
|
? await this.dlgStore.loadCurrentCourse(this.id)
|
|
@@ -1465,6 +1465,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1465
1465
|
content: replyGuidance.promptContent,
|
|
1466
1466
|
});
|
|
1467
1467
|
await dlg.persistUserMessage(replyGuidance.promptContent, currentPrompt.msgId, 'markdown', origin, persistedUserLanguageCode, q4hAnswerCallId, replyGuidance.persistedTellaskReplyDirective);
|
|
1468
|
+
await persistence_1.DialogPersistence.clearPendingCourseStartPrompt(dlg.id, currentPrompt.msgId, dlg.status);
|
|
1468
1469
|
}
|
|
1469
1470
|
if (renderPromptAsRuntimeGuideBubble) {
|
|
1470
1471
|
(0, evt_registry_1.postDialogEvent)(dlg, {
|
|
@@ -6,6 +6,7 @@ const run_control_1 = require("../../apps/run-control");
|
|
|
6
6
|
const dialog_1 = require("../../dialog");
|
|
7
7
|
const dialog_display_state_1 = require("../../dialog-display-state");
|
|
8
8
|
const dialog_global_registry_1 = require("../../dialog-global-registry");
|
|
9
|
+
const dialog_interruption_1 = require("../../dialog-interruption");
|
|
9
10
|
const evt_registry_1 = require("../../evt-registry");
|
|
10
11
|
const log_1 = require("../../log");
|
|
11
12
|
const load_1 = require("../../minds/load");
|
|
@@ -415,6 +416,7 @@ async function executeDriveRound(args) {
|
|
|
415
416
|
if (latest &&
|
|
416
417
|
latest.executionMarker &&
|
|
417
418
|
latest.executionMarker.kind === 'interrupted' &&
|
|
419
|
+
(0, dialog_interruption_1.doesInterruptionReasonRequireExplicitResume)(latest.executionMarker.reason) &&
|
|
418
420
|
!allowResumeFromInterrupted) {
|
|
419
421
|
log_1.log.debug('kernel-driver skip drive for interrupted dialog without explicit resume/user prompt', undefined, {
|
|
420
422
|
dialogId: dialog.id.valueOf(),
|
|
@@ -473,7 +475,7 @@ async function executeDriveRound(args) {
|
|
|
473
475
|
// `allowResumeFromInterrupted` covers multiple stop reasons, but the interjection-pause case
|
|
474
476
|
// is semantically special. Clicking Continue here does NOT mean "blindly clear stopped and
|
|
475
477
|
// drive". We must re-read the fresh persistence facts first because there are three distinct
|
|
476
|
-
// true-source cases behind the same visible
|
|
478
|
+
// true-source cases behind the same visible resumption panel:
|
|
477
479
|
// - no active reply obligation / not suspended anymore -> continue real driving now
|
|
478
480
|
// - active reply obligation + suspended -> restore true blocked state
|
|
479
481
|
// - active reply obligation + still proceeding entitlement (for example queued upNext) ->
|
|
@@ -634,10 +636,10 @@ async function executeDriveRound(args) {
|
|
|
634
636
|
dlg: dialog,
|
|
635
637
|
prompt: effectivePrompt,
|
|
636
638
|
});
|
|
637
|
-
// Only park into the special interjection
|
|
639
|
+
// Only park into the special interjection resumption-panel state when this user turn has
|
|
638
640
|
// suppressed a still-pending inter-dialog reply obligation that must be reasserted later.
|
|
639
641
|
// User interjections without a parked original task should simply finish and fall back to the
|
|
640
|
-
// dialog's true underlying state, without showing the special
|
|
642
|
+
// dialog's true underlying state, without showing the special resumption panel.
|
|
641
643
|
//
|
|
642
644
|
// Q4H answers are explicitly outside this branch even though they also come from the human.
|
|
643
645
|
// They belong to the askHuman reply channel and must continue the suspended askHuman round,
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.runBackendDriver = runBackendDriver;
|
|
4
4
|
const dialog_display_state_1 = require("../../dialog-display-state");
|
|
5
5
|
const dialog_global_registry_1 = require("../../dialog-global-registry");
|
|
6
|
+
const dialog_interruption_1 = require("../../dialog-interruption");
|
|
6
7
|
const log_1 = require("../../log");
|
|
7
8
|
const persistence_1 = require("../../persistence");
|
|
8
9
|
const engine_1 = require("./engine");
|
|
@@ -25,10 +26,12 @@ async function driveQueuedDialogsOnce() {
|
|
|
25
26
|
const latest = await persistence_1.DialogPersistence.loadDialogLatest(rootDialog.id, 'running');
|
|
26
27
|
const executionMarker = latest?.executionMarker;
|
|
27
28
|
const stopRequested = (0, dialog_display_state_1.getStopRequestedReason)(rootDialog.id);
|
|
28
|
-
|
|
29
|
+
const interruptedRequiresExplicitResume = executionMarker?.kind === 'interrupted' &&
|
|
30
|
+
(0, dialog_interruption_1.doesInterruptionReasonRequireExplicitResume)(executionMarker.reason);
|
|
31
|
+
if (interruptedRequiresExplicitResume || stopRequested !== undefined) {
|
|
29
32
|
dialog_global_registry_1.globalDialogRegistry.markNotNeedingDrive(rootDialog.id.rootId, {
|
|
30
33
|
source: 'kernel_driver_backend_loop',
|
|
31
|
-
reason:
|
|
34
|
+
reason: interruptedRequiresExplicitResume
|
|
32
35
|
? 'execution_marker_blocked:interrupted'
|
|
33
36
|
: `stop_requested:${stopRequested}`,
|
|
34
37
|
});
|
package/dist/persistence.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { ContextHealthSnapshot } from '@longrun-ai/kernel/types/context-health';
|
|
8
8
|
import type { NativeToolCallPayload, WebSearchCallAction, WebSearchCallSource } from '@longrun-ai/kernel/types/dialog';
|
|
9
|
+
import type { DialogPrompt } from '@longrun-ai/kernel/types/drive-intent';
|
|
9
10
|
import type { LanguageCode } from '@longrun-ai/kernel/types/language';
|
|
10
11
|
import type { DialogLatestFile, DialogMetadataFile, HumanQuestion, PendingSubdialogStateRecord, PersistedDialogRecord, ProviderData, ReasoningPayload, ReconciledRecordWriteTarget, RootDialogMetadataFile, RootGenerationAnchor, SubdialogMetadataFile, SubdialogRegistryStateRecord, SubdialogResponseStateRecord, TellaskCallRecordName, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
|
|
11
12
|
import type { DialogsQuarantinedMessage, DialogStatusKind } from '@longrun-ai/kernel/types/wire';
|
|
@@ -126,7 +127,7 @@ export declare class DiskFileDialogStore extends DialogStore {
|
|
|
126
127
|
/**
|
|
127
128
|
* Start new course (append-only JSONL + exceptional reminder persistence)
|
|
128
129
|
*/
|
|
129
|
-
startNewCourse(dialog: Dialog,
|
|
130
|
+
startNewCourse(dialog: Dialog, newCoursePrompt: DialogPrompt): Promise<void>;
|
|
130
131
|
/**
|
|
131
132
|
* Persist reminder state (exceptional overwrite pattern)
|
|
132
133
|
* Note: Event emission is handled by processReminderUpdates() in Dialog
|
|
@@ -561,6 +562,7 @@ export declare class DialogPersistence {
|
|
|
561
562
|
private static flushLatestWriteBack;
|
|
562
563
|
static setNeedsDrive(dialogId: DialogID, needsDrive: boolean, status?: DialogStatusKind): Promise<void>;
|
|
563
564
|
static getNeedsDrive(dialogId: DialogID, status?: DialogStatusKind): Promise<boolean>;
|
|
565
|
+
static clearPendingCourseStartPrompt(dialogId: DialogID, msgId: string, status?: DialogStatusKind): Promise<void>;
|
|
564
566
|
static setDeferredReplyReassertion(dialogId: DialogID, deferredReplyReassertion: DialogLatestFile['deferredReplyReassertion'], status?: DialogStatusKind): Promise<void>;
|
|
565
567
|
static getDeferredReplyReassertion(dialogId: DialogID, status?: DialogStatusKind): Promise<DialogLatestFile['deferredReplyReassertion']>;
|
|
566
568
|
/**
|
package/dist/persistence.js
CHANGED
|
@@ -311,6 +311,8 @@ function parseDialogInterruptionReason(value) {
|
|
|
311
311
|
return { kind: 'emergency_stop' };
|
|
312
312
|
case 'server_restart':
|
|
313
313
|
return { kind: 'server_restart' };
|
|
314
|
+
case 'pending_course_start':
|
|
315
|
+
return { kind: 'pending_course_start' };
|
|
314
316
|
case 'fork_continue_ready':
|
|
315
317
|
return { kind: 'fork_continue_ready' };
|
|
316
318
|
case 'system_stop': {
|
|
@@ -837,6 +839,104 @@ function isSubdialogMetadataFile(value) {
|
|
|
837
839
|
function isDialogMetadataFile(value) {
|
|
838
840
|
return isRootDialogMetadataFile(value) || isSubdialogMetadataFile(value);
|
|
839
841
|
}
|
|
842
|
+
function parseTellaskReplyDirective(value) {
|
|
843
|
+
if (!isRecord(value))
|
|
844
|
+
return null;
|
|
845
|
+
const expectedReplyCallName = value.expectedReplyCallName;
|
|
846
|
+
const targetCallId = value.targetCallId;
|
|
847
|
+
const tellaskContent = value.tellaskContent;
|
|
848
|
+
if (expectedReplyCallName !== 'replyTellask' &&
|
|
849
|
+
expectedReplyCallName !== 'replyTellaskSessionless' &&
|
|
850
|
+
expectedReplyCallName !== 'replyTellaskBack') {
|
|
851
|
+
return null;
|
|
852
|
+
}
|
|
853
|
+
if (typeof targetCallId !== 'string' || typeof tellaskContent !== 'string') {
|
|
854
|
+
return null;
|
|
855
|
+
}
|
|
856
|
+
if (expectedReplyCallName === 'replyTellaskBack') {
|
|
857
|
+
const targetDialogId = value.targetDialogId;
|
|
858
|
+
if (typeof targetDialogId !== 'string')
|
|
859
|
+
return null;
|
|
860
|
+
return {
|
|
861
|
+
expectedReplyCallName,
|
|
862
|
+
targetCallId,
|
|
863
|
+
targetDialogId,
|
|
864
|
+
tellaskContent,
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
return {
|
|
868
|
+
expectedReplyCallName,
|
|
869
|
+
targetCallId,
|
|
870
|
+
tellaskContent,
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
function parseDialogSubdialogReplyTarget(value) {
|
|
874
|
+
if (!isRecord(value))
|
|
875
|
+
return null;
|
|
876
|
+
const ownerDialogId = value.ownerDialogId;
|
|
877
|
+
const callType = value.callType;
|
|
878
|
+
const callId = value.callId;
|
|
879
|
+
if (typeof ownerDialogId !== 'string' || typeof callId !== 'string') {
|
|
880
|
+
return null;
|
|
881
|
+
}
|
|
882
|
+
if (callType !== 'A' && callType !== 'B' && callType !== 'C') {
|
|
883
|
+
return null;
|
|
884
|
+
}
|
|
885
|
+
return {
|
|
886
|
+
ownerDialogId,
|
|
887
|
+
callType,
|
|
888
|
+
callId,
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
function parseDialogPendingCourseStartPrompt(value) {
|
|
892
|
+
if (!isRecord(value))
|
|
893
|
+
return null;
|
|
894
|
+
if (typeof value.content !== 'string' || typeof value.msgId !== 'string') {
|
|
895
|
+
return null;
|
|
896
|
+
}
|
|
897
|
+
if (value.grammar !== 'markdown' || value.origin !== 'runtime') {
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
const userLanguageCodeRaw = value.userLanguageCode;
|
|
901
|
+
if (userLanguageCodeRaw !== undefined &&
|
|
902
|
+
(typeof userLanguageCodeRaw !== 'string' || !(0, language_1.isLanguageCode)(userLanguageCodeRaw))) {
|
|
903
|
+
return null;
|
|
904
|
+
}
|
|
905
|
+
const skipTaskdocRaw = value.skipTaskdoc;
|
|
906
|
+
if (skipTaskdocRaw !== undefined && typeof skipTaskdocRaw !== 'boolean') {
|
|
907
|
+
return null;
|
|
908
|
+
}
|
|
909
|
+
const tellaskReplyDirective = value.tellaskReplyDirective === undefined
|
|
910
|
+
? undefined
|
|
911
|
+
: parseTellaskReplyDirective(value.tellaskReplyDirective);
|
|
912
|
+
if (value.tellaskReplyDirective !== undefined && tellaskReplyDirective === null) {
|
|
913
|
+
return null;
|
|
914
|
+
}
|
|
915
|
+
const subdialogReplyTarget = value.subdialogReplyTarget === undefined
|
|
916
|
+
? undefined
|
|
917
|
+
: parseDialogSubdialogReplyTarget(value.subdialogReplyTarget);
|
|
918
|
+
if (value.subdialogReplyTarget !== undefined && subdialogReplyTarget === null) {
|
|
919
|
+
return null;
|
|
920
|
+
}
|
|
921
|
+
const userLanguageCode = userLanguageCodeRaw;
|
|
922
|
+
const skipTaskdoc = skipTaskdocRaw;
|
|
923
|
+
const normalizedTellaskReplyDirective = tellaskReplyDirective === null ? undefined : tellaskReplyDirective;
|
|
924
|
+
const normalizedSubdialogReplyTarget = subdialogReplyTarget === null ? undefined : subdialogReplyTarget;
|
|
925
|
+
return {
|
|
926
|
+
content: value.content,
|
|
927
|
+
msgId: value.msgId,
|
|
928
|
+
grammar: 'markdown',
|
|
929
|
+
origin: 'runtime',
|
|
930
|
+
...(userLanguageCode === undefined ? {} : { userLanguageCode }),
|
|
931
|
+
...(normalizedTellaskReplyDirective === undefined
|
|
932
|
+
? {}
|
|
933
|
+
: { tellaskReplyDirective: normalizedTellaskReplyDirective }),
|
|
934
|
+
...(skipTaskdoc === undefined ? {} : { skipTaskdoc }),
|
|
935
|
+
...(normalizedSubdialogReplyTarget === undefined
|
|
936
|
+
? {}
|
|
937
|
+
: { subdialogReplyTarget: normalizedSubdialogReplyTarget }),
|
|
938
|
+
};
|
|
939
|
+
}
|
|
840
940
|
function parseDialogLatestFile(value) {
|
|
841
941
|
if (!isRecord(value))
|
|
842
942
|
return null;
|
|
@@ -1006,48 +1106,16 @@ function parseDialogLatestFile(value) {
|
|
|
1006
1106
|
if (deferredReplyReassertionRaw.reason !== 'user_interjection_with_parked_original_task') {
|
|
1007
1107
|
return null;
|
|
1008
1108
|
}
|
|
1009
|
-
const
|
|
1010
|
-
if (
|
|
1109
|
+
const directive = parseTellaskReplyDirective(deferredReplyReassertionRaw.directive);
|
|
1110
|
+
if (directive === null)
|
|
1011
1111
|
return null;
|
|
1012
1112
|
const resumeGuideSurfacedRaw = deferredReplyReassertionRaw.resumeGuideSurfaced;
|
|
1013
1113
|
if (resumeGuideSurfacedRaw !== undefined && typeof resumeGuideSurfacedRaw !== 'boolean') {
|
|
1014
1114
|
return null;
|
|
1015
1115
|
}
|
|
1016
|
-
const expectedReplyCallName = directiveRaw.expectedReplyCallName;
|
|
1017
|
-
const targetCallId = directiveRaw.targetCallId;
|
|
1018
|
-
const tellaskContent = directiveRaw.tellaskContent;
|
|
1019
|
-
if (expectedReplyCallName !== 'replyTellask' &&
|
|
1020
|
-
expectedReplyCallName !== 'replyTellaskSessionless' &&
|
|
1021
|
-
expectedReplyCallName !== 'replyTellaskBack') {
|
|
1022
|
-
return null;
|
|
1023
|
-
}
|
|
1024
|
-
if (typeof targetCallId !== 'string' || typeof tellaskContent !== 'string') {
|
|
1025
|
-
return null;
|
|
1026
|
-
}
|
|
1027
|
-
if (expectedReplyCallName === 'replyTellaskBack') {
|
|
1028
|
-
const targetDialogId = directiveRaw.targetDialogId;
|
|
1029
|
-
if (typeof targetDialogId !== 'string')
|
|
1030
|
-
return null;
|
|
1031
|
-
return {
|
|
1032
|
-
reason: 'user_interjection_with_parked_original_task',
|
|
1033
|
-
directive: {
|
|
1034
|
-
expectedReplyCallName,
|
|
1035
|
-
targetCallId,
|
|
1036
|
-
targetDialogId,
|
|
1037
|
-
tellaskContent,
|
|
1038
|
-
},
|
|
1039
|
-
...(resumeGuideSurfacedRaw === undefined
|
|
1040
|
-
? {}
|
|
1041
|
-
: { resumeGuideSurfaced: resumeGuideSurfacedRaw }),
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
1116
|
return {
|
|
1045
1117
|
reason: 'user_interjection_with_parked_original_task',
|
|
1046
|
-
directive
|
|
1047
|
-
expectedReplyCallName,
|
|
1048
|
-
targetCallId,
|
|
1049
|
-
tellaskContent,
|
|
1050
|
-
},
|
|
1118
|
+
directive,
|
|
1051
1119
|
...(resumeGuideSurfacedRaw === undefined
|
|
1052
1120
|
? {}
|
|
1053
1121
|
: { resumeGuideSurfaced: resumeGuideSurfacedRaw }),
|
|
@@ -1055,6 +1123,14 @@ function parseDialogLatestFile(value) {
|
|
|
1055
1123
|
})();
|
|
1056
1124
|
if (deferredReplyReassertion === null)
|
|
1057
1125
|
return null;
|
|
1126
|
+
const pendingCourseStartPromptRaw = value.pendingCourseStartPrompt;
|
|
1127
|
+
const pendingCourseStartPrompt = (() => {
|
|
1128
|
+
if (pendingCourseStartPromptRaw === undefined)
|
|
1129
|
+
return undefined;
|
|
1130
|
+
return parseDialogPendingCourseStartPrompt(pendingCourseStartPromptRaw);
|
|
1131
|
+
})();
|
|
1132
|
+
if (pendingCourseStartPrompt === null)
|
|
1133
|
+
return null;
|
|
1058
1134
|
return {
|
|
1059
1135
|
currentCourse,
|
|
1060
1136
|
lastModified: value.lastModified,
|
|
@@ -1068,6 +1144,7 @@ function parseDialogLatestFile(value) {
|
|
|
1068
1144
|
executionMarker,
|
|
1069
1145
|
fbrState,
|
|
1070
1146
|
deferredReplyReassertion,
|
|
1147
|
+
pendingCourseStartPrompt,
|
|
1071
1148
|
disableDiligencePush: value.disableDiligencePush,
|
|
1072
1149
|
diligencePushRemainingBudget: value.diligencePushRemainingBudget,
|
|
1073
1150
|
};
|
|
@@ -2070,16 +2147,49 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2070
2147
|
/**
|
|
2071
2148
|
* Start new course (append-only JSONL + exceptional reminder persistence)
|
|
2072
2149
|
*/
|
|
2073
|
-
async startNewCourse(dialog,
|
|
2150
|
+
async startNewCourse(dialog, newCoursePrompt) {
|
|
2074
2151
|
const previousCourse = dialog.currentCourse;
|
|
2075
2152
|
const newCourse = previousCourse + 1;
|
|
2153
|
+
if (newCoursePrompt.origin !== 'runtime') {
|
|
2154
|
+
throw new Error(`startNewCourse invariant violation: pending new-course prompt must have runtime origin for dialog=${dialog.id.valueOf()}`);
|
|
2155
|
+
}
|
|
2076
2156
|
// Persist reminders state for new course (exceptional overwrite)
|
|
2077
2157
|
// Use the currently attached dialog's reminders to avoid stale state
|
|
2078
2158
|
await this.persistReminders(dialog, dialog.reminders || []);
|
|
2079
2159
|
// Update latest.yaml with new course (lastModified is set by persistence layer)
|
|
2080
2160
|
await DialogPersistence.mutateDialogLatest(this.dialogId, () => ({
|
|
2081
2161
|
kind: 'patch',
|
|
2082
|
-
patch: {
|
|
2162
|
+
patch: {
|
|
2163
|
+
currentCourse: newCourse,
|
|
2164
|
+
needsDrive: true,
|
|
2165
|
+
displayState: {
|
|
2166
|
+
kind: 'stopped',
|
|
2167
|
+
reason: { kind: 'pending_course_start' },
|
|
2168
|
+
continueEnabled: true,
|
|
2169
|
+
},
|
|
2170
|
+
executionMarker: {
|
|
2171
|
+
kind: 'interrupted',
|
|
2172
|
+
reason: { kind: 'pending_course_start' },
|
|
2173
|
+
},
|
|
2174
|
+
pendingCourseStartPrompt: {
|
|
2175
|
+
content: newCoursePrompt.content,
|
|
2176
|
+
msgId: newCoursePrompt.msgId,
|
|
2177
|
+
grammar: 'markdown',
|
|
2178
|
+
origin: 'runtime',
|
|
2179
|
+
...(newCoursePrompt.userLanguageCode === undefined
|
|
2180
|
+
? {}
|
|
2181
|
+
: { userLanguageCode: newCoursePrompt.userLanguageCode }),
|
|
2182
|
+
...(newCoursePrompt.tellaskReplyDirective === undefined
|
|
2183
|
+
? {}
|
|
2184
|
+
: { tellaskReplyDirective: newCoursePrompt.tellaskReplyDirective }),
|
|
2185
|
+
...(newCoursePrompt.skipTaskdoc === undefined
|
|
2186
|
+
? {}
|
|
2187
|
+
: { skipTaskdoc: newCoursePrompt.skipTaskdoc }),
|
|
2188
|
+
...(newCoursePrompt.subdialogReplyTarget === undefined
|
|
2189
|
+
? {}
|
|
2190
|
+
: { subdialogReplyTarget: newCoursePrompt.subdialogReplyTarget }),
|
|
2191
|
+
},
|
|
2192
|
+
},
|
|
2083
2193
|
}));
|
|
2084
2194
|
// Post course update event
|
|
2085
2195
|
const courseUpdateEvt = {
|
|
@@ -5778,6 +5888,33 @@ class DialogPersistence {
|
|
|
5778
5888
|
const latest = await this.loadDialogLatest(dialogId, status);
|
|
5779
5889
|
return latest?.needsDrive === true;
|
|
5780
5890
|
}
|
|
5891
|
+
static async clearPendingCourseStartPrompt(dialogId, msgId, status = 'running') {
|
|
5892
|
+
const normalizedMsgId = msgId.trim();
|
|
5893
|
+
if (normalizedMsgId === '') {
|
|
5894
|
+
throw new Error(`clearPendingCourseStartPrompt invariant violation: empty msgId for dialog=${dialogId.valueOf()}`);
|
|
5895
|
+
}
|
|
5896
|
+
await this.mutateDialogLatest(dialogId, (previous) => {
|
|
5897
|
+
const pending = previous.pendingCourseStartPrompt;
|
|
5898
|
+
if (!pending || pending.msgId !== normalizedMsgId) {
|
|
5899
|
+
return { kind: 'noop' };
|
|
5900
|
+
}
|
|
5901
|
+
return {
|
|
5902
|
+
kind: 'patch',
|
|
5903
|
+
patch: {
|
|
5904
|
+
pendingCourseStartPrompt: undefined,
|
|
5905
|
+
needsDrive: false,
|
|
5906
|
+
displayState: previous.displayState?.kind === 'stopped' &&
|
|
5907
|
+
previous.displayState.reason.kind === 'pending_course_start'
|
|
5908
|
+
? { kind: 'idle_waiting_user' }
|
|
5909
|
+
: previous.displayState,
|
|
5910
|
+
executionMarker: previous.executionMarker?.kind === 'interrupted' &&
|
|
5911
|
+
previous.executionMarker.reason.kind === 'pending_course_start'
|
|
5912
|
+
? undefined
|
|
5913
|
+
: previous.executionMarker,
|
|
5914
|
+
},
|
|
5915
|
+
};
|
|
5916
|
+
}, status);
|
|
5917
|
+
}
|
|
5781
5918
|
static async setDeferredReplyReassertion(dialogId, deferredReplyReassertion, status = 'running') {
|
|
5782
5919
|
await this.mutateDialogLatest(dialogId, () => ({ kind: 'patch', patch: { deferredReplyReassertion } }), status);
|
|
5783
5920
|
}
|
|
@@ -10,7 +10,7 @@ const USER_INTERJECTION_PAUSE_STOP_DETAIL = 'user_interjection_pause_resume_orig
|
|
|
10
10
|
//
|
|
11
11
|
// Not every user interjection should use this reason. If there is no parked original task to
|
|
12
12
|
// resume afterwards, the interjection should simply complete and the dialog should fall back to
|
|
13
|
-
// its true underlying state without showing this
|
|
13
|
+
// its true underlying state without showing this resumption panel.
|
|
14
14
|
//
|
|
15
15
|
// In particular, askHuman answers are NOT "user interjections" for this purpose. A prompt carrying
|
|
16
16
|
// a real `q4hAnswerCallId` belongs to the askHuman reply channel and must never be routed through
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dominds",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Dominds CLI and aggregation shell for the LongRun AI kernel/runtime packages.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"ws": "^8.19.0",
|
|
53
53
|
"yaml": "^2.8.2",
|
|
54
54
|
"zod": "^4.3.6",
|
|
55
|
-
"@longrun-ai/shell": "1.8.
|
|
56
|
-
"@longrun-ai/
|
|
57
|
-
"@longrun-ai/
|
|
55
|
+
"@longrun-ai/shell": "1.8.15",
|
|
56
|
+
"@longrun-ai/codex-auth": "0.12.1",
|
|
57
|
+
"@longrun-ai/kernel": "1.8.15"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^25.3.5",
|