dominds 0.7.2 → 0.7.4
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-global-registry.js +58 -3
- package/dist/dialog.js +17 -0
- package/dist/evt-registry.js +53 -14
- package/dist/llm/driver-v2/context.js +2 -1
- package/dist/llm/driver-v2/core.js +1 -118
- package/dist/llm/driver-v2/orchestrator.js +65 -38
- package/dist/llm/driver-v2/round.js +117 -31
- package/dist/llm/driver-v2/runtime-utils.js +1 -0
- package/dist/llm/driver-v2/supdialog-response.js +5 -18
- package/dist/llm/driver-v2/tellask-bridge.js +66 -4
- package/dist/persistence.js +80 -9
- package/dist/server/websocket-handler.js +48 -29
- package/dist/static/assets/{_baseUniq-C04fddeD.js → _baseUniq-C_6DmNp6.js} +2 -2
- package/dist/static/assets/{_baseUniq-C04fddeD.js.map → _baseUniq-C_6DmNp6.js.map} +1 -1
- package/dist/static/assets/{arc-qmZerooe.js → arc-CbWoOhl1.js} +2 -2
- package/dist/static/assets/{arc-qmZerooe.js.map → arc-CbWoOhl1.js.map} +1 -1
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DPAwJ19g.js → architectureDiagram-VXUJARFQ-CTckhB9O.js} +6 -6
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DPAwJ19g.js.map → architectureDiagram-VXUJARFQ-CTckhB9O.js.map} +1 -1
- package/dist/static/assets/{blockDiagram-VD42YOAC-M0jbEJ-1.js → blockDiagram-VD42YOAC-mX558EDN.js} +7 -7
- package/dist/static/assets/{blockDiagram-VD42YOAC-M0jbEJ-1.js.map → blockDiagram-VD42YOAC-mX558EDN.js.map} +1 -1
- package/dist/static/assets/{c4Diagram-YG6GDRKO-DlF8gwFw.js → c4Diagram-YG6GDRKO-Bti3To3b.js} +3 -3
- package/dist/static/assets/{c4Diagram-YG6GDRKO-DlF8gwFw.js.map → c4Diagram-YG6GDRKO-Bti3To3b.js.map} +1 -1
- package/dist/static/assets/{channel-B2Ph7be3.js → channel-Dxi4rUwG.js} +2 -2
- package/dist/static/assets/{channel-B2Ph7be3.js.map → channel-Dxi4rUwG.js.map} +1 -1
- package/dist/static/assets/{chunk-4BX2VUAB-BZ2L6PK1.js → chunk-4BX2VUAB-CAbdAd2-.js} +2 -2
- package/dist/static/assets/{chunk-4BX2VUAB-BZ2L6PK1.js.map → chunk-4BX2VUAB-CAbdAd2-.js.map} +1 -1
- package/dist/static/assets/{chunk-55IACEB6-COXFmnJW.js → chunk-55IACEB6-D4r4rpB1.js} +2 -2
- package/dist/static/assets/{chunk-55IACEB6-COXFmnJW.js.map → chunk-55IACEB6-D4r4rpB1.js.map} +1 -1
- package/dist/static/assets/{chunk-B4BG7PRW-B1HiWlBq.js → chunk-B4BG7PRW-sNmEhJCQ.js} +5 -5
- package/dist/static/assets/{chunk-B4BG7PRW-B1HiWlBq.js.map → chunk-B4BG7PRW-sNmEhJCQ.js.map} +1 -1
- package/dist/static/assets/{chunk-DI55MBZ5-BO3wQRnL.js → chunk-DI55MBZ5-BSutc2-e.js} +4 -4
- package/dist/static/assets/{chunk-DI55MBZ5-BO3wQRnL.js.map → chunk-DI55MBZ5-BSutc2-e.js.map} +1 -1
- package/dist/static/assets/{chunk-FMBD7UC4-BdavRHSy.js → chunk-FMBD7UC4-DafIeMhA.js} +2 -2
- package/dist/static/assets/{chunk-FMBD7UC4-BdavRHSy.js.map → chunk-FMBD7UC4-DafIeMhA.js.map} +1 -1
- package/dist/static/assets/{chunk-QN33PNHL-DchoUNF7.js → chunk-QN33PNHL-1EobqGS_.js} +2 -2
- package/dist/static/assets/{chunk-QN33PNHL-DchoUNF7.js.map → chunk-QN33PNHL-1EobqGS_.js.map} +1 -1
- package/dist/static/assets/{chunk-QZHKN3VN-Dr3uVTtK.js → chunk-QZHKN3VN-C4U4YGsG.js} +2 -2
- package/dist/static/assets/{chunk-QZHKN3VN-Dr3uVTtK.js.map → chunk-QZHKN3VN-C4U4YGsG.js.map} +1 -1
- package/dist/static/assets/{chunk-TZMSLE5B-BhOcHZNs.js → chunk-TZMSLE5B-BAuDx0ol.js} +2 -2
- package/dist/static/assets/{chunk-TZMSLE5B-BhOcHZNs.js.map → chunk-TZMSLE5B-BAuDx0ol.js.map} +1 -1
- package/dist/static/assets/{classDiagram-2ON5EDUG-Dep-MR6W.js → classDiagram-2ON5EDUG-B0n34y1v.js} +6 -6
- package/dist/static/assets/{classDiagram-2ON5EDUG-Dep-MR6W.js.map → classDiagram-2ON5EDUG-B0n34y1v.js.map} +1 -1
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-Dep-MR6W.js → classDiagram-v2-WZHVMYZB-B0n34y1v.js} +6 -6
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-Dep-MR6W.js.map → classDiagram-v2-WZHVMYZB-B0n34y1v.js.map} +1 -1
- package/dist/static/assets/{clone-DzoL-dSX.js → clone-DMVEoZzo.js} +2 -2
- package/dist/static/assets/{clone-DzoL-dSX.js.map → clone-DMVEoZzo.js.map} +1 -1
- package/dist/static/assets/{cose-bilkent-S5V4N54A-Bqu_DqDB.js → cose-bilkent-S5V4N54A-BM7Q-IjT.js} +2 -2
- package/dist/static/assets/{cose-bilkent-S5V4N54A-Bqu_DqDB.js.map → cose-bilkent-S5V4N54A-BM7Q-IjT.js.map} +1 -1
- package/dist/static/assets/{dagre-6UL2VRFP-49InNTzs.js → dagre-6UL2VRFP-DsBBLjwD.js} +7 -7
- package/dist/static/assets/{dagre-6UL2VRFP-49InNTzs.js.map → dagre-6UL2VRFP-DsBBLjwD.js.map} +1 -1
- package/dist/static/assets/{diagram-PSM6KHXK-C1IsQq8m.js → diagram-PSM6KHXK-uinTtuhJ.js} +7 -7
- package/dist/static/assets/{diagram-PSM6KHXK-C1IsQq8m.js.map → diagram-PSM6KHXK-uinTtuhJ.js.map} +1 -1
- package/dist/static/assets/{diagram-QEK2KX5R-DyJeSg_Y.js → diagram-QEK2KX5R-ChxmtmD8.js} +6 -6
- package/dist/static/assets/{diagram-QEK2KX5R-DyJeSg_Y.js.map → diagram-QEK2KX5R-ChxmtmD8.js.map} +1 -1
- package/dist/static/assets/{diagram-S2PKOQOG-aeLjjldp.js → diagram-S2PKOQOG-2cukzOFZ.js} +6 -6
- package/dist/static/assets/{diagram-S2PKOQOG-aeLjjldp.js.map → diagram-S2PKOQOG-2cukzOFZ.js.map} +1 -1
- package/dist/static/assets/{erDiagram-Q2GNP2WA-BUcv4AUq.js → erDiagram-Q2GNP2WA-CwIFDwop.js} +5 -5
- package/dist/static/assets/{erDiagram-Q2GNP2WA-BUcv4AUq.js.map → erDiagram-Q2GNP2WA-CwIFDwop.js.map} +1 -1
- package/dist/static/assets/{flowDiagram-NV44I4VS-DfmTKlf_.js → flowDiagram-NV44I4VS-jKMMhPpA.js} +6 -6
- package/dist/static/assets/{flowDiagram-NV44I4VS-DfmTKlf_.js.map → flowDiagram-NV44I4VS-jKMMhPpA.js.map} +1 -1
- package/dist/static/assets/{ganttDiagram-JELNMOA3-BpJE8Lhp.js → ganttDiagram-JELNMOA3-0onO7ppU.js} +3 -3
- package/dist/static/assets/{ganttDiagram-JELNMOA3-BpJE8Lhp.js.map → ganttDiagram-JELNMOA3-0onO7ppU.js.map} +1 -1
- package/dist/static/assets/{gitGraphDiagram-NY62KEGX-DmznjSYb.js → gitGraphDiagram-NY62KEGX-CxBFzFla.js} +7 -7
- package/dist/static/assets/{gitGraphDiagram-NY62KEGX-DmznjSYb.js.map → gitGraphDiagram-NY62KEGX-CxBFzFla.js.map} +1 -1
- package/dist/static/assets/{graph-CcKyIZaL.js → graph-DuuInXXc.js} +3 -3
- package/dist/static/assets/{graph-CcKyIZaL.js.map → graph-DuuInXXc.js.map} +1 -1
- package/dist/static/assets/{index-CQr8MdPI.js → index-CIEJ2QXv.js} +311 -228
- package/dist/static/assets/index-CIEJ2QXv.js.map +1 -0
- package/dist/static/assets/{infoDiagram-WHAUD3N6-DwRPjndM.js → infoDiagram-WHAUD3N6-TznEGa7r.js} +5 -5
- package/dist/static/assets/{infoDiagram-WHAUD3N6-DwRPjndM.js.map → infoDiagram-WHAUD3N6-TznEGa7r.js.map} +1 -1
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-BRAFSgVa.js → journeyDiagram-XKPGCS4Q-BHyegEi7.js} +5 -5
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-BRAFSgVa.js.map → journeyDiagram-XKPGCS4Q-BHyegEi7.js.map} +1 -1
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-DlJ7-fgN.js → kanban-definition-3W4ZIXB7-Cb42cM0l.js} +3 -3
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-DlJ7-fgN.js.map → kanban-definition-3W4ZIXB7-Cb42cM0l.js.map} +1 -1
- package/dist/static/assets/{layout-CcW5-Iee.js → layout-BmWDm7l3.js} +5 -5
- package/dist/static/assets/{layout-CcW5-Iee.js.map → layout-BmWDm7l3.js.map} +1 -1
- package/dist/static/assets/{linear-sKdPIuOH.js → linear-CnzPs1-w.js} +2 -2
- package/dist/static/assets/{linear-sKdPIuOH.js.map → linear-CnzPs1-w.js.map} +1 -1
- package/dist/static/assets/{min-CQ0AYqmk.js → min-B10Xh5Ux.js} +3 -3
- package/dist/static/assets/{min-CQ0AYqmk.js.map → min-B10Xh5Ux.js.map} +1 -1
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-CTRwSlu8.js → mindmap-definition-VGOIOE7T-CrN1eydc.js} +4 -4
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-CTRwSlu8.js.map → mindmap-definition-VGOIOE7T-CrN1eydc.js.map} +1 -1
- package/dist/static/assets/{pieDiagram-ADFJNKIX-DmD5KRKE.js → pieDiagram-ADFJNKIX-B30qa_F6.js} +7 -7
- package/dist/static/assets/{pieDiagram-ADFJNKIX-DmD5KRKE.js.map → pieDiagram-ADFJNKIX-B30qa_F6.js.map} +1 -1
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-C5sqZOBF.js → quadrantDiagram-AYHSOK5B-CqcwrOFK.js} +3 -3
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-C5sqZOBF.js.map → quadrantDiagram-AYHSOK5B-CqcwrOFK.js.map} +1 -1
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DBAUwM-7.js → requirementDiagram-UZGBJVZJ-D_pK_WHp.js} +4 -4
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DBAUwM-7.js.map → requirementDiagram-UZGBJVZJ-D_pK_WHp.js.map} +1 -1
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-CkaxkOo7.js → sankeyDiagram-TZEHDZUN-DCWsFfhe.js} +2 -2
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-CkaxkOo7.js.map → sankeyDiagram-TZEHDZUN-DCWsFfhe.js.map} +1 -1
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-CJ6wMDXh.js → sequenceDiagram-WL72ISMW-bYELxg0L.js} +4 -4
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-CJ6wMDXh.js.map → sequenceDiagram-WL72ISMW-bYELxg0L.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-C66ZP2NW.js → stateDiagram-FKZM4ZOC-DETJEZs6.js} +9 -9
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-C66ZP2NW.js.map → stateDiagram-FKZM4ZOC-DETJEZs6.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-DdoOy271.js → stateDiagram-v2-4FDKWEC3-DEfNRBx4.js} +5 -5
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-DdoOy271.js.map → stateDiagram-v2-4FDKWEC3-DEfNRBx4.js.map} +1 -1
- package/dist/static/assets/{timeline-definition-IT6M3QCI-2A2Mqedz.js → timeline-definition-IT6M3QCI-BRvufh0i.js} +3 -3
- package/dist/static/assets/{timeline-definition-IT6M3QCI-2A2Mqedz.js.map → timeline-definition-IT6M3QCI-BRvufh0i.js.map} +1 -1
- package/dist/static/assets/{treemap-KMMF4GRG-CTbGSr5o.js → treemap-KMMF4GRG-D4s4uF2T.js} +4 -4
- package/dist/static/assets/{treemap-KMMF4GRG-CTbGSr5o.js.map → treemap-KMMF4GRG-D4s4uF2T.js.map} +1 -1
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-C_S3XXZI.js → xychartDiagram-PRI3JC2R-eBEH5utX.js} +3 -3
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-C_S3XXZI.js.map → xychartDiagram-PRI3JC2R-eBEH5utX.js.map} +1 -1
- package/dist/static/index.html +1 -1
- package/package.json +1 -1
- package/dist/static/assets/index-CQr8MdPI.js.map +0 -1
|
@@ -14,6 +14,36 @@ const core_1 = require("./core");
|
|
|
14
14
|
const policy_1 = require("./policy");
|
|
15
15
|
const supdialog_response_1 = require("./supdialog-response");
|
|
16
16
|
const defaultCriticalCountdownGenerations = 5;
|
|
17
|
+
async function loadPendingDiagnosticsSnapshot(args) {
|
|
18
|
+
const ownerDialogIdObj = new dialog_1.DialogID(args.ownerDialogId, args.rootId);
|
|
19
|
+
try {
|
|
20
|
+
const pending = await persistence_1.DialogPersistence.loadPendingSubdialogs(ownerDialogIdObj);
|
|
21
|
+
const matchedSubdialogIds = pending
|
|
22
|
+
.filter((record) => record.subdialogId === args.expectedSubdialogId)
|
|
23
|
+
.map((record) => record.subdialogId);
|
|
24
|
+
return {
|
|
25
|
+
kind: 'loaded',
|
|
26
|
+
ownerDialogId: args.ownerDialogId,
|
|
27
|
+
totalCount: pending.length,
|
|
28
|
+
matchedSubdialogIds,
|
|
29
|
+
records: pending.map((record) => ({
|
|
30
|
+
subdialogId: record.subdialogId,
|
|
31
|
+
callType: record.callType,
|
|
32
|
+
targetAgentId: record.targetAgentId,
|
|
33
|
+
tellaskSession: record.tellaskSession,
|
|
34
|
+
createdAt: record.createdAt,
|
|
35
|
+
tellaskHeadSummary: record.tellaskHead.trim().slice(0, 160),
|
|
36
|
+
})),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
return {
|
|
41
|
+
kind: 'error',
|
|
42
|
+
ownerDialogId: args.ownerDialogId,
|
|
43
|
+
error: err instanceof Error ? err.message : String(err),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
17
47
|
const contextHealthRoundStateByDialogKey = new Map();
|
|
18
48
|
function getContextHealthRoundState(dialog) {
|
|
19
49
|
const key = dialog.id.key();
|
|
@@ -76,7 +106,7 @@ function resolveEffectivePrompt(dialog, humanPrompt) {
|
|
|
76
106
|
return {
|
|
77
107
|
content: upNext.prompt,
|
|
78
108
|
msgId: upNext.msgId,
|
|
79
|
-
grammar: 'markdown',
|
|
109
|
+
grammar: upNext.grammar ?? 'markdown',
|
|
80
110
|
userLanguageCode: upNext.userLanguageCode === 'zh' || upNext.userLanguageCode === 'en'
|
|
81
111
|
? upNext.userLanguageCode
|
|
82
112
|
: undefined,
|
|
@@ -131,6 +161,24 @@ async function executeDriveRound(args) {
|
|
|
131
161
|
dialogId: dialog.id.valueOf(),
|
|
132
162
|
});
|
|
133
163
|
}
|
|
164
|
+
// Queued/auto drive (without fresh human input) must not proceed while dialog is
|
|
165
|
+
// suspended by pending Q4H or subdialogs. This prevents duplicate generations when
|
|
166
|
+
// multiple wake-ups race around the same subdialog completion boundary.
|
|
167
|
+
if (!humanPrompt) {
|
|
168
|
+
const suspension = await dialog.getSuspensionStatus();
|
|
169
|
+
if (!suspension.canDrive) {
|
|
170
|
+
log_1.log.info('driver-v2 skip queued auto-drive while dialog is suspended', {
|
|
171
|
+
dialogId: dialog.id.valueOf(),
|
|
172
|
+
rootId: dialog.id.rootId,
|
|
173
|
+
selfId: dialog.id.selfId,
|
|
174
|
+
waitInQue,
|
|
175
|
+
hasQueuedUpNext: dialog.hasUpNext(),
|
|
176
|
+
waitingQ4H: suspension.q4h,
|
|
177
|
+
waitingSubdialogs: suspension.subdialogs,
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
134
182
|
const minds = await (0, load_1.loadAgentMinds)(dialog.agentId, dialog);
|
|
135
183
|
const policy = (0, policy_1.buildDriverV2Policy)({
|
|
136
184
|
dlg: dialog,
|
|
@@ -212,47 +260,85 @@ async function executeDriveRound(args) {
|
|
|
212
260
|
}
|
|
213
261
|
release();
|
|
214
262
|
}
|
|
215
|
-
if (followUp) {
|
|
216
|
-
args.scheduleDrive(dialog, {
|
|
217
|
-
waitInQue: true,
|
|
218
|
-
humanPrompt: {
|
|
219
|
-
content: followUp.prompt,
|
|
220
|
-
msgId: followUp.msgId,
|
|
221
|
-
grammar: 'markdown',
|
|
222
|
-
userLanguageCode: followUp.userLanguageCode === 'zh' || followUp.userLanguageCode === 'en'
|
|
223
|
-
? followUp.userLanguageCode
|
|
224
|
-
: undefined,
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
263
|
if (dialog instanceof dialog_1.SubDialog &&
|
|
230
264
|
driveResult &&
|
|
231
265
|
!driveResult.interrupted &&
|
|
232
266
|
driveResult.lastAssistantSayingContent !== null) {
|
|
233
|
-
|
|
234
|
-
if (!suspension.canDrive) {
|
|
235
|
-
log_1.log.info('driver-v2 skip supplying subdialog response because dialog is still suspended', {
|
|
236
|
-
rootId: dialog.id.rootId,
|
|
237
|
-
selfId: dialog.id.selfId,
|
|
238
|
-
waitingQ4H: suspension.q4h,
|
|
239
|
-
waitingSubdialogs: suspension.subdialogs,
|
|
240
|
-
});
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
267
|
+
let supplied = false;
|
|
243
268
|
if (subdialogReplyTarget) {
|
|
244
|
-
await (0, supdialog_response_1.supplySubdialogResponseToSpecificCallerIfPendingV2)({
|
|
269
|
+
supplied = await (0, supdialog_response_1.supplySubdialogResponseToSpecificCallerIfPendingV2)({
|
|
245
270
|
subdialog: dialog,
|
|
246
271
|
responseText: driveResult.lastAssistantSayingContent,
|
|
247
272
|
target: subdialogReplyTarget,
|
|
248
273
|
scheduleDrive: args.scheduleDrive,
|
|
249
274
|
});
|
|
250
|
-
|
|
275
|
+
if (!supplied) {
|
|
276
|
+
supplied = await (0, supdialog_response_1.supplySubdialogResponseToAssignedCallerIfPendingV2)({
|
|
277
|
+
subdialog: dialog,
|
|
278
|
+
responseText: driveResult.lastAssistantSayingContent,
|
|
279
|
+
scheduleDrive: args.scheduleDrive,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
251
282
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
283
|
+
else {
|
|
284
|
+
supplied = await (0, supdialog_response_1.supplySubdialogResponseToAssignedCallerIfPendingV2)({
|
|
285
|
+
subdialog: dialog,
|
|
286
|
+
responseText: driveResult.lastAssistantSayingContent,
|
|
287
|
+
scheduleDrive: args.scheduleDrive,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
if (!supplied && subdialogReplyTarget) {
|
|
291
|
+
const assignment = dialog.assignmentFromSup;
|
|
292
|
+
const ownerDialogIds = Array.from(new Set([subdialogReplyTarget.ownerDialogId, assignment.callerDialogId]));
|
|
293
|
+
const pendingSnapshots = await Promise.all(ownerDialogIds.map(async (ownerDialogId) => loadPendingDiagnosticsSnapshot({
|
|
294
|
+
rootId: dialog.id.rootId,
|
|
295
|
+
ownerDialogId,
|
|
296
|
+
expectedSubdialogId: dialog.id.selfId,
|
|
297
|
+
})));
|
|
298
|
+
const streamErr = `Subdialog response supply invariant violation: ` +
|
|
299
|
+
`subdialog=${dialog.id.selfId} root=${dialog.id.rootId} ` +
|
|
300
|
+
`targetOwner=${subdialogReplyTarget.ownerDialogId} targetCallType=${subdialogReplyTarget.callType} targetCallId=${subdialogReplyTarget.callId} ` +
|
|
301
|
+
`assignmentCaller=${assignment.callerDialogId} assignmentCallId=${assignment.callId} ` +
|
|
302
|
+
`pendingSnapshots=${pendingSnapshots.length}`;
|
|
303
|
+
try {
|
|
304
|
+
await dialog.streamError(streamErr);
|
|
305
|
+
}
|
|
306
|
+
catch (streamErrPost) {
|
|
307
|
+
log_1.log.warn('driver-v2 failed to emit stream_error_evt for response supply violation', {
|
|
308
|
+
rootId: dialog.id.rootId,
|
|
309
|
+
selfId: dialog.id.selfId,
|
|
310
|
+
targetOwnerDialogId: subdialogReplyTarget.ownerDialogId,
|
|
311
|
+
targetCallType: subdialogReplyTarget.callType,
|
|
312
|
+
targetCallId: subdialogReplyTarget.callId,
|
|
313
|
+
assignmentCallerDialogId: assignment.callerDialogId,
|
|
314
|
+
assignmentCallId: assignment.callId,
|
|
315
|
+
pendingSnapshots,
|
|
316
|
+
error: streamErrPost instanceof Error ? streamErrPost.message : String(streamErrPost),
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
log_1.log.error('driver-v2 subdialog produced response but found no pending caller to supply', {
|
|
320
|
+
rootId: dialog.id.rootId,
|
|
321
|
+
selfId: dialog.id.selfId,
|
|
322
|
+
targetOwnerDialogId: subdialogReplyTarget.ownerDialogId,
|
|
323
|
+
targetCallType: subdialogReplyTarget.callType,
|
|
324
|
+
targetCallId: subdialogReplyTarget.callId,
|
|
325
|
+
assignmentCallerDialogId: assignment.callerDialogId,
|
|
326
|
+
assignmentCallId: assignment.callId,
|
|
327
|
+
pendingSnapshots,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (followUp) {
|
|
332
|
+
args.scheduleDrive(dialog, {
|
|
333
|
+
waitInQue: true,
|
|
334
|
+
humanPrompt: {
|
|
335
|
+
content: followUp.prompt,
|
|
336
|
+
msgId: followUp.msgId,
|
|
337
|
+
grammar: followUp.grammar ?? 'markdown',
|
|
338
|
+
userLanguageCode: followUp.userLanguageCode === 'zh' || followUp.userLanguageCode === 'en'
|
|
339
|
+
? followUp.userLanguageCode
|
|
340
|
+
: undefined,
|
|
341
|
+
},
|
|
256
342
|
});
|
|
257
343
|
}
|
|
258
344
|
}
|
|
@@ -181,6 +181,7 @@ async function suspendForKeepGoingBudgetExhausted(options) {
|
|
|
181
181
|
bodyContent: question.bodyContent,
|
|
182
182
|
askedAt: question.askedAt,
|
|
183
183
|
callId: question.callId,
|
|
184
|
+
remainingCallIds: question.remainingCallIds,
|
|
184
185
|
callSiteRef: question.callSiteRef,
|
|
185
186
|
rootId: dlg.id.rootId,
|
|
186
187
|
agentId: dlg.agentId,
|
|
@@ -9,9 +9,7 @@ const dialog_instance_registry_1 = require("../../dialog-instance-registry");
|
|
|
9
9
|
const log_1 = require("../../log");
|
|
10
10
|
const persistence_1 = require("../../persistence");
|
|
11
11
|
const runtime_language_1 = require("../../shared/runtime-language");
|
|
12
|
-
const id_1 = require("../../shared/utils/id");
|
|
13
12
|
const inter_dialog_format_1 = require("../../shared/utils/inter-dialog-format");
|
|
14
|
-
const time_1 = require("../../shared/utils/time");
|
|
15
13
|
const pending_tellask_reminder_1 = require("../../tools/pending-tellask-reminder");
|
|
16
14
|
const subdialog_txn_1 = require("./subdialog-txn");
|
|
17
15
|
async function syncPendingTellaskReminderBestEffort(dlg, where) {
|
|
@@ -98,20 +96,6 @@ async function supplyResponseToSupdialogV2(args) {
|
|
|
98
96
|
if (tellaskHead.trim() === '') {
|
|
99
97
|
tellaskHead = responseText.slice(0, 100) + (responseText.length > 100 ? '...' : '');
|
|
100
98
|
}
|
|
101
|
-
const completedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
|
|
102
|
-
const responseId = (0, id_1.generateShortId)();
|
|
103
|
-
await persistence_1.DialogPersistence.appendSubdialogResponse(parentDialog.id, {
|
|
104
|
-
responseId,
|
|
105
|
-
subdialogId: subdialogId.selfId,
|
|
106
|
-
response: responseText,
|
|
107
|
-
completedAt,
|
|
108
|
-
status,
|
|
109
|
-
callType,
|
|
110
|
-
tellaskHead,
|
|
111
|
-
responderId,
|
|
112
|
-
originMemberId,
|
|
113
|
-
callId: callId ?? '',
|
|
114
|
-
});
|
|
115
99
|
await persistence_1.DialogPersistence.savePendingSubdialogs(parentDialog.id, filteredPending);
|
|
116
100
|
const hasQ4H = await parentDialog.hasPendingQ4H();
|
|
117
101
|
const shouldRevive = !hasQ4H && filteredPending.length === 0;
|
|
@@ -134,7 +118,7 @@ async function supplyResponseToSupdialogV2(args) {
|
|
|
134
118
|
originMemberId: result.originMemberId ?? parentDialog.agentId,
|
|
135
119
|
});
|
|
136
120
|
// Keep in-memory dialog context in sync with live teammate-response events immediately.
|
|
137
|
-
//
|
|
121
|
+
// v2 context assembly now relies on dialog msgs + persisted teammate_response_record only.
|
|
138
122
|
const immediateMirror = {
|
|
139
123
|
type: 'tellask_result_msg',
|
|
140
124
|
role: 'tool',
|
|
@@ -153,7 +137,10 @@ async function supplyResponseToSupdialogV2(args) {
|
|
|
153
137
|
if (result.shouldRevive) {
|
|
154
138
|
log_1.log.info(`All Type ${callType} subdialogs complete, parent ${parentDialog.id.selfId} auto-reviving`);
|
|
155
139
|
if (parentDialog instanceof dialog_1.RootDialog) {
|
|
156
|
-
dialog_global_registry_1.globalDialogRegistry.markNeedsDrive(parentDialog.id.rootId
|
|
140
|
+
dialog_global_registry_1.globalDialogRegistry.markNeedsDrive(parentDialog.id.rootId, {
|
|
141
|
+
source: 'driver_v2_supply_response',
|
|
142
|
+
reason: `all_pending_subdialogs_resolved:type_${callType}`,
|
|
143
|
+
});
|
|
157
144
|
}
|
|
158
145
|
scheduleDrive(parentDialog, {
|
|
159
146
|
waitInQue: true,
|
|
@@ -46,7 +46,6 @@ const inter_dialog_format_1 = require("../../shared/utils/inter-dialog-format");
|
|
|
46
46
|
const time_1 = require("../../shared/utils/time");
|
|
47
47
|
const team_1 = require("../../team");
|
|
48
48
|
const pending_tellask_reminder_1 = require("../../tools/pending-tellask-reminder");
|
|
49
|
-
const id_2 = require("../../utils/id");
|
|
50
49
|
const subdialog_txn_1 = require("./subdialog-txn");
|
|
51
50
|
function showErrorToAi(err) {
|
|
52
51
|
try {
|
|
@@ -419,13 +418,21 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
|
|
|
419
418
|
const isQ4H = firstMention === 'human';
|
|
420
419
|
if (isQ4H) {
|
|
421
420
|
try {
|
|
422
|
-
const
|
|
421
|
+
const normalizedCallId = callId.trim();
|
|
422
|
+
if (normalizedCallId === '') {
|
|
423
|
+
throw new Error(`Q4H call invariant violation: empty callId (rootId=${dlg.id.rootId} selfId=${dlg.id.selfId})`);
|
|
424
|
+
}
|
|
425
|
+
const questionId = `q4h-${dlg.id.rootId}-${dlg.id.selfId}-c${dlg.currentCourse}-${normalizedCallId}`;
|
|
426
|
+
const normalizedRemainingCallIds = Array.from(new Set((options?.q4hRemainingCallIds ?? [])
|
|
427
|
+
.map((value) => value.trim())
|
|
428
|
+
.filter((value) => value !== '' && value !== normalizedCallId)));
|
|
423
429
|
const question = {
|
|
424
430
|
id: questionId,
|
|
425
431
|
tellaskHead: tellaskHead.trim(),
|
|
426
432
|
bodyContent: body.trim(),
|
|
427
433
|
askedAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
428
|
-
callId:
|
|
434
|
+
callId: normalizedCallId,
|
|
435
|
+
remainingCallIds: normalizedRemainingCallIds.length > 0 ? normalizedRemainingCallIds : undefined,
|
|
429
436
|
callSiteRef: {
|
|
430
437
|
course: dlg.currentCourse,
|
|
431
438
|
messageIndex: dlg.msgs.length,
|
|
@@ -441,6 +448,7 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
|
|
|
441
448
|
bodyContent: question.bodyContent,
|
|
442
449
|
askedAt: question.askedAt,
|
|
443
450
|
callId: question.callId,
|
|
451
|
+
remainingCallIds: question.remainingCallIds,
|
|
444
452
|
callSiteRef: question.callSiteRef,
|
|
445
453
|
rootId: dlg.id.rootId,
|
|
446
454
|
agentId: dlg.agentId,
|
|
@@ -1076,7 +1084,61 @@ async function executeTellaskCalls(args) {
|
|
|
1076
1084
|
const callbacks = ensureCallbacks(args.callbacks);
|
|
1077
1085
|
const malformedToolOutputs = await emitMalformedTellaskResponses(dlg, collectedCalls);
|
|
1078
1086
|
const validCalls = collectedCalls.filter((call) => call.validation.kind === 'valid');
|
|
1079
|
-
const
|
|
1087
|
+
const q4hCalls = validCalls.filter((call) => call.validation.firstMention === 'human');
|
|
1088
|
+
const nonQ4HCalls = validCalls
|
|
1089
|
+
.filter((call) => call.validation.firstMention !== 'human')
|
|
1090
|
+
.map((call) => ({ ...call }));
|
|
1091
|
+
let mergedQ4HCall = null;
|
|
1092
|
+
if (q4hCalls.length === 1) {
|
|
1093
|
+
mergedQ4HCall = { ...q4hCalls[0] };
|
|
1094
|
+
}
|
|
1095
|
+
else if (q4hCalls.length > 1) {
|
|
1096
|
+
const primary = q4hCalls[0];
|
|
1097
|
+
const remainingCallIds = q4hCalls
|
|
1098
|
+
.slice(1)
|
|
1099
|
+
.map((call) => call.callId.trim())
|
|
1100
|
+
.filter((callId) => callId !== '');
|
|
1101
|
+
const language = (0, runtime_language_1.getWorkLanguage)();
|
|
1102
|
+
const intro = language === 'zh'
|
|
1103
|
+
? `我这次有 ${q4hCalls.length} 个问题,想请你一次性回复:`
|
|
1104
|
+
: `I have ${q4hCalls.length} questions this round. Please answer them in one response:`;
|
|
1105
|
+
const mergedBody = [
|
|
1106
|
+
intro,
|
|
1107
|
+
...q4hCalls.map((call, index) => {
|
|
1108
|
+
const body = call.body.trim();
|
|
1109
|
+
const normalizedBody = body !== ''
|
|
1110
|
+
? body
|
|
1111
|
+
: language === 'zh'
|
|
1112
|
+
? '请结合当前上下文补充这一项。'
|
|
1113
|
+
: 'Please provide this item based on the current context.';
|
|
1114
|
+
return language === 'zh'
|
|
1115
|
+
? `问题 ${index + 1}:\n${normalizedBody}`
|
|
1116
|
+
: `Question ${index + 1}:\n${normalizedBody}`;
|
|
1117
|
+
}),
|
|
1118
|
+
].join('\n\n');
|
|
1119
|
+
mergedQ4HCall = {
|
|
1120
|
+
...primary,
|
|
1121
|
+
body: mergedBody,
|
|
1122
|
+
q4hRemainingCallIds: remainingCallIds.length > 0 ? remainingCallIds : undefined,
|
|
1123
|
+
};
|
|
1124
|
+
log_1.log.info('Q4H multi-question normalized into a single prompt', {
|
|
1125
|
+
rootId: dlg.id.rootId,
|
|
1126
|
+
selfId: dlg.id.selfId,
|
|
1127
|
+
mergedCount: q4hCalls.length,
|
|
1128
|
+
primaryCallId: primary.callId,
|
|
1129
|
+
remainingCallIds,
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
const executionCalls = mergedQ4HCall
|
|
1133
|
+
? [...nonQ4HCalls, mergedQ4HCall]
|
|
1134
|
+
: nonQ4HCalls;
|
|
1135
|
+
const results = [];
|
|
1136
|
+
for (const call of executionCalls) {
|
|
1137
|
+
const result = await executeTellaskCall(dlg, agent, call.validation.firstMention, call.tellaskHead, call.body, call.callId, callbacks, {
|
|
1138
|
+
q4hRemainingCallIds: call.q4hRemainingCallIds,
|
|
1139
|
+
});
|
|
1140
|
+
results.push(result);
|
|
1141
|
+
}
|
|
1080
1142
|
const suspend = results.some((result) => result.suspend);
|
|
1081
1143
|
const toolOutputs = [...malformedToolOutputs, ...results.flatMap((result) => result.toolOutputs)];
|
|
1082
1144
|
const subdialogsCreated = results.flatMap((result) => result.subdialogsCreated);
|
package/dist/persistence.js
CHANGED
|
@@ -298,6 +298,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
298
298
|
*/
|
|
299
299
|
async createSubDialog(supdialog, targetAgentId, tellaskHead, tellaskBody, options) {
|
|
300
300
|
const generatedId = (0, id_1.generateDialogID)();
|
|
301
|
+
const nowTs = (0, time_1.formatUnifiedTimestamp)(new Date());
|
|
301
302
|
// For subdialogs, use the supdialog's root dialog ID as the root
|
|
302
303
|
const subdialogId = new dialog_1.DialogID(generatedId, supdialog.id.rootId);
|
|
303
304
|
// Prepare subdialog store
|
|
@@ -316,7 +317,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
316
317
|
id: subdialogId.selfId,
|
|
317
318
|
agentId: targetAgentId,
|
|
318
319
|
taskDocPath: supdialog.taskDocPath,
|
|
319
|
-
createdAt:
|
|
320
|
+
createdAt: nowTs,
|
|
320
321
|
supdialogId: supdialog.id.selfId,
|
|
321
322
|
tellaskSession: options.tellaskSession,
|
|
322
323
|
assignmentFromSup: {
|
|
@@ -334,7 +335,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
334
335
|
kind: 'replace',
|
|
335
336
|
next: {
|
|
336
337
|
currentCourse: 1,
|
|
337
|
-
lastModified:
|
|
338
|
+
lastModified: nowTs,
|
|
338
339
|
status: 'active',
|
|
339
340
|
messageCount: 0,
|
|
340
341
|
functionCallCount: 0,
|
|
@@ -364,6 +365,26 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
364
365
|
targetAgentId,
|
|
365
366
|
tellaskHead,
|
|
366
367
|
tellaskBody,
|
|
368
|
+
subDialogNode: {
|
|
369
|
+
selfId: subdialogId.selfId,
|
|
370
|
+
rootId: subdialogId.rootId,
|
|
371
|
+
supdialogId: supdialog.id.selfId,
|
|
372
|
+
agentId: targetAgentId,
|
|
373
|
+
taskDocPath: supdialog.taskDocPath,
|
|
374
|
+
status: 'running',
|
|
375
|
+
currentCourse: 1,
|
|
376
|
+
createdAt: nowTs,
|
|
377
|
+
lastModified: nowTs,
|
|
378
|
+
runState: { kind: 'idle_waiting_user' },
|
|
379
|
+
tellaskSession: options.tellaskSession,
|
|
380
|
+
assignmentFromSup: {
|
|
381
|
+
tellaskHead,
|
|
382
|
+
tellaskBody,
|
|
383
|
+
originMemberId: options.originMemberId,
|
|
384
|
+
callerDialogId: options.callerDialogId,
|
|
385
|
+
callId: options.callId,
|
|
386
|
+
},
|
|
387
|
+
},
|
|
367
388
|
};
|
|
368
389
|
// Post subdialog_created_evt to PARENT's PubChan so frontend can receive it
|
|
369
390
|
// The frontend subscribes to the parent's events, not the subdialog's
|
|
@@ -1052,7 +1073,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1052
1073
|
// Events are already in chronological order from JSONL file (append-only pattern)
|
|
1053
1074
|
// Send each persistence event directly to the requesting WebSocket
|
|
1054
1075
|
for (const event of persistenceEvents) {
|
|
1055
|
-
await this.sendEventDirectlyToWebSocket(ws, dialog, currentCourse, event);
|
|
1076
|
+
await this.sendEventDirectlyToWebSocket(ws, dialog, currentCourse, event, status);
|
|
1056
1077
|
}
|
|
1057
1078
|
// Rehydrate reminders from dialog state
|
|
1058
1079
|
const dialogState = await DialogPersistence.restoreDialog(dialog.id, status);
|
|
@@ -1071,7 +1092,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1071
1092
|
* Send a single persistence event directly to a WebSocket connection
|
|
1072
1093
|
* CRITICAL: Avoid PubChan completely for dialog restoration to the single client's display_dialog request
|
|
1073
1094
|
*/
|
|
1074
|
-
async sendEventDirectlyToWebSocket(ws, dialog, course, event) {
|
|
1095
|
+
async sendEventDirectlyToWebSocket(ws, dialog, course, event, status) {
|
|
1075
1096
|
switch (event.type) {
|
|
1076
1097
|
case 'human_text_record': {
|
|
1077
1098
|
const genseq = event.genseq;
|
|
@@ -1604,25 +1625,67 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1604
1625
|
}
|
|
1605
1626
|
case 'quest_for_sup_record': {
|
|
1606
1627
|
// Handle subdialog creation requests
|
|
1628
|
+
const subdialogId = new dialog_1.DialogID(event.subDialogId, dialog.id.rootId);
|
|
1629
|
+
const loadOrder = [
|
|
1630
|
+
status,
|
|
1631
|
+
'running',
|
|
1632
|
+
'completed',
|
|
1633
|
+
'archived',
|
|
1634
|
+
].filter((candidate, index, arr) => arr.indexOf(candidate) === index);
|
|
1635
|
+
let foundStatus = null;
|
|
1636
|
+
let subMeta = null;
|
|
1637
|
+
let subLatest = null;
|
|
1638
|
+
for (const candidateStatus of loadOrder) {
|
|
1639
|
+
const candidateMeta = await DialogPersistence.loadDialogMetadata(subdialogId, candidateStatus);
|
|
1640
|
+
if (!candidateMeta || !isSubdialogMetadataFile(candidateMeta))
|
|
1641
|
+
continue;
|
|
1642
|
+
foundStatus = candidateStatus;
|
|
1643
|
+
subMeta = candidateMeta;
|
|
1644
|
+
subLatest = await DialogPersistence.loadDialogLatest(subdialogId, candidateStatus);
|
|
1645
|
+
break;
|
|
1646
|
+
}
|
|
1647
|
+
if (!foundStatus || !subMeta) {
|
|
1648
|
+
throw new Error(`subdialog_created_evt replay invariant violation: metadata missing for ${subdialogId.valueOf()}`);
|
|
1649
|
+
}
|
|
1650
|
+
const derivedSupdialogId = subMeta.assignmentFromSup?.callerDialogId &&
|
|
1651
|
+
subMeta.assignmentFromSup.callerDialogId.trim() !== ''
|
|
1652
|
+
? subMeta.assignmentFromSup.callerDialogId
|
|
1653
|
+
: typeof subMeta.supdialogId === 'string' && subMeta.supdialogId.trim() !== ''
|
|
1654
|
+
? subMeta.supdialogId
|
|
1655
|
+
: dialog.id.selfId;
|
|
1607
1656
|
const subdialogCreatedEvent = {
|
|
1608
1657
|
type: 'subdialog_created_evt',
|
|
1609
1658
|
course,
|
|
1610
1659
|
dialog: {
|
|
1611
1660
|
// Add dialog field for proper event routing
|
|
1612
|
-
selfId:
|
|
1613
|
-
rootId:
|
|
1661
|
+
selfId: subdialogId.selfId,
|
|
1662
|
+
rootId: subdialogId.rootId,
|
|
1614
1663
|
},
|
|
1615
1664
|
parentDialog: {
|
|
1616
1665
|
selfId: dialog.id.selfId,
|
|
1617
1666
|
rootId: dialog.id.rootId,
|
|
1618
1667
|
},
|
|
1619
1668
|
subDialog: {
|
|
1620
|
-
selfId:
|
|
1621
|
-
rootId:
|
|
1669
|
+
selfId: subdialogId.selfId,
|
|
1670
|
+
rootId: subdialogId.rootId,
|
|
1622
1671
|
},
|
|
1623
|
-
targetAgentId:
|
|
1672
|
+
targetAgentId: subMeta.agentId,
|
|
1624
1673
|
tellaskHead: event.tellaskHead,
|
|
1625
1674
|
tellaskBody: event.tellaskBody,
|
|
1675
|
+
subDialogNode: {
|
|
1676
|
+
selfId: subMeta.id,
|
|
1677
|
+
rootId: subdialogId.rootId,
|
|
1678
|
+
supdialogId: derivedSupdialogId,
|
|
1679
|
+
agentId: subMeta.agentId,
|
|
1680
|
+
taskDocPath: subMeta.taskDocPath,
|
|
1681
|
+
status: foundStatus,
|
|
1682
|
+
currentCourse: subLatest?.currentCourse || 1,
|
|
1683
|
+
createdAt: subMeta.createdAt,
|
|
1684
|
+
lastModified: subLatest?.lastModified || subMeta.createdAt,
|
|
1685
|
+
runState: subLatest?.runState,
|
|
1686
|
+
tellaskSession: subMeta.tellaskSession,
|
|
1687
|
+
assignmentFromSup: subMeta.assignmentFromSup,
|
|
1688
|
+
},
|
|
1626
1689
|
timestamp: event.ts,
|
|
1627
1690
|
};
|
|
1628
1691
|
if (ws.readyState === 1) {
|
|
@@ -2451,6 +2514,14 @@ class DialogPersistence {
|
|
|
2451
2514
|
throw new Error(`Q4H duplicate call id violation: dialog=${dialogId.valueOf()} status=${status} callId=${normalizedCallId} existingQuestionId=${byCallId.id} incomingQuestionId=${questionId} existingAskedAt=${byCallId.askedAt} incomingAskedAt=${question.askedAt}`);
|
|
2452
2515
|
}
|
|
2453
2516
|
}
|
|
2517
|
+
if (previousQuestions.length > 0) {
|
|
2518
|
+
const existingIds = previousQuestions.map((q) => q.id).join(',');
|
|
2519
|
+
const existingCallIds = previousQuestions
|
|
2520
|
+
.map((q) => (typeof q.callId === 'string' ? q.callId.trim() : ''))
|
|
2521
|
+
.filter((value) => value !== '')
|
|
2522
|
+
.join(',');
|
|
2523
|
+
throw new Error(`Q4H multi-pending violation: dialog=${dialogId.valueOf()} status=${status} existingCount=${previousQuestions.length} existingQuestionIds=${existingIds} existingCallIds=${existingCallIds} incomingQuestionId=${questionId} incomingCallId=${normalizedCallId ?? ''}`);
|
|
2524
|
+
}
|
|
2454
2525
|
return { kind: 'append', question };
|
|
2455
2526
|
}, status);
|
|
2456
2527
|
}
|
|
@@ -390,9 +390,11 @@ async function maybeTriggerImmediateDiligencePrompt(rootDialog) {
|
|
|
390
390
|
if (!suspension.canDrive) {
|
|
391
391
|
return;
|
|
392
392
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
393
|
+
if ((0, driver_entry_1.getActiveDriverEngine)() === 'v1') {
|
|
394
|
+
const queuedResponses = await persistence_1.DialogPersistence.loadSubdialogResponsesQueue(rootDialog.id);
|
|
395
|
+
if (queuedResponses.length > 0) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
396
398
|
}
|
|
397
399
|
const team = await team_1.Team.load();
|
|
398
400
|
const prepared = await (0, runtime_utils_1.maybePrepareDiligenceAutoContinuePrompt)({
|
|
@@ -755,31 +757,29 @@ async function handleDisplayDialog(ws, packet) {
|
|
|
755
757
|
catch (err) {
|
|
756
758
|
log.warn(`Failed to send dlg_run_state_evt for ${dialogIdObj.valueOf()}:`, err);
|
|
757
759
|
}
|
|
758
|
-
// Emit Q4H
|
|
759
|
-
//
|
|
760
|
+
// Emit one Q4H snapshot to ensure frontend has current global questions state.
|
|
761
|
+
// Do NOT replay per-question `new_q4h_asked` events here: those are real-time
|
|
762
|
+
// incremental events and replaying them on display refresh can create duplicate
|
|
763
|
+
// delivery paths and blur event semantics.
|
|
760
764
|
try {
|
|
761
765
|
const allQuestions = await persistence_1.DialogPersistence.loadAllQ4HState();
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
},
|
|
780
|
-
};
|
|
781
|
-
ws.send(JSON.stringify(newQ4HEvent));
|
|
782
|
-
}
|
|
766
|
+
const response = {
|
|
767
|
+
type: 'q4h_state_response',
|
|
768
|
+
questions: allQuestions.map((q) => ({
|
|
769
|
+
id: q.id,
|
|
770
|
+
selfId: q.selfId,
|
|
771
|
+
rootId: q.rootId,
|
|
772
|
+
agentId: q.agentId,
|
|
773
|
+
taskDocPath: q.taskDocPath,
|
|
774
|
+
tellaskHead: q.tellaskHead,
|
|
775
|
+
bodyContent: q.bodyContent,
|
|
776
|
+
askedAt: q.askedAt,
|
|
777
|
+
callId: q.callId,
|
|
778
|
+
remainingCallIds: q.remainingCallIds,
|
|
779
|
+
callSiteRef: q.callSiteRef,
|
|
780
|
+
})),
|
|
781
|
+
};
|
|
782
|
+
ws.send(JSON.stringify(response));
|
|
783
783
|
}
|
|
784
784
|
catch (err) {
|
|
785
785
|
log.warn(`Failed to emit Q4H state for ${dialogIdObj}:`, err);
|
|
@@ -818,6 +818,7 @@ async function handleGetQ4HState(ws, _packet) {
|
|
|
818
818
|
bodyContent: q.bodyContent,
|
|
819
819
|
askedAt: q.askedAt,
|
|
820
820
|
callId: q.callId,
|
|
821
|
+
remainingCallIds: q.remainingCallIds,
|
|
821
822
|
callSiteRef: q.callSiteRef,
|
|
822
823
|
}));
|
|
823
824
|
// Send single response packet with all questions (not PubChan events)
|
|
@@ -1157,6 +1158,22 @@ async function handleUserAnswer2Q4H(ws, packet) {
|
|
|
1157
1158
|
selfId: dialogId,
|
|
1158
1159
|
};
|
|
1159
1160
|
(0, evt_registry_1.postDialogEvent)(dialog, answeredEvent);
|
|
1161
|
+
const hasPendingSubdialogs = await dialog.hasPendingSubdialogs();
|
|
1162
|
+
if (hasPendingSubdialogs) {
|
|
1163
|
+
dialog.queueUpNextPrompt({
|
|
1164
|
+
prompt: content,
|
|
1165
|
+
msgId,
|
|
1166
|
+
grammar: 'tellask',
|
|
1167
|
+
userLanguageCode,
|
|
1168
|
+
});
|
|
1169
|
+
log.info('Deferred Q4H answer until pending subdialogs resolve', {
|
|
1170
|
+
rootId: dialog.id.rootId,
|
|
1171
|
+
selfId: dialog.id.selfId,
|
|
1172
|
+
questionId,
|
|
1173
|
+
msgId,
|
|
1174
|
+
});
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1160
1177
|
// Resume the dialog with the user's answer.
|
|
1161
1178
|
await (0, driver_entry_1.driveDialogStream)(dialog, { content, msgId, grammar: 'tellask', userLanguageCode, origin: 'user' }, true);
|
|
1162
1179
|
}
|
|
@@ -1182,9 +1199,11 @@ function setupWebSocketServer(httpServer, clients, auth, serverWorkLanguage) {
|
|
|
1182
1199
|
}
|
|
1183
1200
|
}
|
|
1184
1201
|
});
|
|
1185
|
-
// Broadcast
|
|
1186
|
-
//
|
|
1187
|
-
|
|
1202
|
+
// Broadcast global dialog events to all connected clients:
|
|
1203
|
+
// - Q4H updates are rtws-global state in WebUI
|
|
1204
|
+
// - subdialog creation must refresh hierarchy/list even when current subscription is elsewhere
|
|
1205
|
+
// - dlg_touched_evt keeps dialog list timestamps/reordering in sync across clients
|
|
1206
|
+
(0, evt_registry_1.setGlobalDialogEventBroadcaster)((evt) => {
|
|
1188
1207
|
const data = JSON.stringify(evt);
|
|
1189
1208
|
for (const ws of clients) {
|
|
1190
1209
|
if (ws.readyState === 1) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aV as isObjectLike, br as baseGetTag, aE as isArray, aT as Symbol$1, bs as arrayLikeKeys, bt as baseKeys, aD as isArrayLike, bu as memoize, bv as isArguments, bw as MapCache, bm as eq, bx as Uint8Array, aW as getTag, a$ as isBuffer, b2 as Stack, by as isTypedArray, aZ as isObject, bz as isLength, bp as isIndex, aF as identity, bn as baseFor, bA as Set } from "./index-
|
|
1
|
+
import { aV as isObjectLike, br as baseGetTag, aE as isArray, aT as Symbol$1, bs as arrayLikeKeys, bt as baseKeys, aD as isArrayLike, bu as memoize, bv as isArguments, bw as MapCache, bm as eq, bx as Uint8Array, aW as getTag, a$ as isBuffer, b2 as Stack, by as isTypedArray, aZ as isObject, bz as isLength, bp as isIndex, aF as identity, bn as baseFor, bA as Set } from "./index-CIEJ2QXv.js";
|
|
2
2
|
var symbolTag$1 = "[object Symbol]";
|
|
3
3
|
function isSymbol(value) {
|
|
4
4
|
return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag$1;
|
|
@@ -658,4 +658,4 @@ export {
|
|
|
658
658
|
hasIn as x,
|
|
659
659
|
toString as y
|
|
660
660
|
};
|
|
661
|
-
//# sourceMappingURL=_baseUniq-
|
|
661
|
+
//# sourceMappingURL=_baseUniq-C_6DmNp6.js.map
|