dominds 1.13.2 → 1.15.2
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/bootstrap/global-dialog-event-broadcaster.d.ts +18 -0
- package/dist/bootstrap/global-dialog-event-broadcaster.js +81 -0
- package/dist/dialog-fork.js +13 -12
- package/dist/dialog.d.ts +61 -50
- package/dist/dialog.js +284 -78
- package/dist/docs/dialog-system.md +12 -0
- package/dist/docs/dialog-system.zh.md +12 -0
- package/dist/docs/dominds-terminology.md +17 -0
- package/dist/docs/issues/global-dialog-event-broadcaster-missing.md +128 -0
- package/dist/docs/llm-provider-isolation.md +35 -0
- package/dist/docs/llm-provider-isolation.zh.md +35 -0
- package/dist/llm/client.d.ts +2 -1
- package/dist/llm/defaults.yaml +118 -4
- package/dist/llm/gen/anthropic.js +2 -4
- package/dist/llm/gen/codex.d.ts +11 -0
- package/dist/llm/gen/codex.js +41 -31
- package/dist/llm/gen/failure-classifier.js +17 -0
- package/dist/llm/gen/mock.js +45 -21
- package/dist/llm/gen/openai-compatible.d.ts +2 -0
- package/dist/llm/gen/openai-compatible.js +43 -38
- package/dist/llm/gen/openai.d.ts +3 -1
- package/dist/llm/gen/openai.js +888 -71
- package/dist/llm/gen/tool-call-context.d.ts +7 -2
- package/dist/llm/gen/tool-call-context.js +55 -13
- package/dist/llm/gen.d.ts +60 -3
- package/dist/llm/kernel-driver/context.js +1 -1
- package/dist/llm/kernel-driver/drive.js +374 -348
- package/dist/llm/kernel-driver/flow.js +3 -3
- package/dist/llm/kernel-driver/guardrails.d.ts +1 -1
- package/dist/llm/kernel-driver/guardrails.js +4 -4
- package/dist/llm/kernel-driver/runtime.js +11 -29
- package/dist/llm/kernel-driver/subdialog.js +56 -5
- package/dist/llm/kernel-driver/tellask-special.d.ts +38 -12
- package/dist/llm/kernel-driver/tellask-special.js +489 -180
- package/dist/llm/kernel-driver/types.d.ts +1 -1
- package/dist/persistence.d.ts +30 -62
- package/dist/persistence.js +978 -986
- package/dist/priming.js +398 -365
- package/dist/recovery/reply-special.js +3 -3
- package/dist/runtime/inter-dialog-format.d.ts +1 -1
- package/dist/runtime/inter-dialog-format.js +1 -1
- package/dist/runtime/reply-prompt-copy.js +4 -4
- package/dist/server/setup-routes.js +26 -5
- package/dist/server/snippets-routes.d.ts +1 -0
- package/dist/server/snippets-routes.js +20 -9
- package/dist/server/websocket-handler.js +58 -25
- package/dist/shared/utils/fbr.js +12 -8
- package/dist/shared/utils/inter-dialog-format.js +6 -4
- package/dist/team.d.ts +24 -13
- package/dist/team.js +123 -32
- package/dist/tool.d.ts +26 -0
- package/dist/tool.js +97 -0
- package/dist/tools/team_mgmt.js +18 -0
- package/package.json +2 -2
- package/webapp/dist/assets/{_basePickBy-CBOtd63g.js → _basePickBy-DsirmCgI.js} +3 -3
- package/webapp/dist/assets/_basePickBy-DsirmCgI.js.map +1 -0
- package/webapp/dist/assets/{_baseUniq-mfoKz4Wm.js → _baseUniq-tR6G8loB.js} +2 -2
- package/webapp/dist/assets/_baseUniq-tR6G8loB.js.map +1 -0
- package/webapp/dist/assets/{arc-Dq0WZLyu.js → arc-CzxpASkZ.js} +2 -2
- package/webapp/dist/assets/arc-CzxpASkZ.js.map +1 -0
- package/webapp/dist/assets/{architectureDiagram-VXUJARFQ-CNmygmp3.js → architectureDiagram-2XIMDMQ5-BSH7H5oI.js} +26 -8
- package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-BSH7H5oI.js.map +1 -0
- package/webapp/dist/assets/{blockDiagram-VD42YOAC-DvE0lybt.js → blockDiagram-WCTKOSBZ-DpLIr7yO.js} +187 -170
- package/webapp/dist/assets/blockDiagram-WCTKOSBZ-DpLIr7yO.js.map +1 -0
- package/webapp/dist/assets/{c4Diagram-YG6GDRKO-CR7zJ2_u.js → c4Diagram-IC4MRINW-WuYKgWfY.js} +4 -4
- package/webapp/dist/assets/c4Diagram-IC4MRINW-WuYKgWfY.js.map +1 -0
- package/webapp/dist/assets/{channel-DrTrnYx4.js → channel-B-v9dqLN.js} +2 -2
- package/webapp/dist/assets/channel-B-v9dqLN.js.map +1 -0
- package/webapp/dist/assets/{chunk-4BX2VUAB-CVuJEIeN.js → chunk-4BX2VUAB-MtFUfKZy.js} +2 -2
- package/webapp/dist/assets/chunk-4BX2VUAB-MtFUfKZy.js.map +1 -0
- package/webapp/dist/assets/{chunk-55IACEB6-BxUoXApB.js → chunk-55IACEB6-rY9AJdzj.js} +2 -2
- package/webapp/dist/assets/chunk-55IACEB6-rY9AJdzj.js.map +1 -0
- package/webapp/dist/assets/{chunk-FMBD7UC4-TX-LVAaV.js → chunk-FMBD7UC4-B-RtOs7e.js} +2 -2
- package/webapp/dist/assets/chunk-FMBD7UC4-B-RtOs7e.js.map +1 -0
- package/webapp/dist/assets/{chunk-TZMSLE5B-Cw689yRl.js → chunk-JSJVCQXG-Da1d3uS4.js} +14 -6
- package/webapp/dist/assets/chunk-JSJVCQXG-Da1d3uS4.js.map +1 -0
- package/webapp/dist/assets/{chunk-QN33PNHL-D1uiKlOO.js → chunk-KX2RTZJC-DH9UrpuG.js} +2 -2
- package/webapp/dist/assets/chunk-KX2RTZJC-DH9UrpuG.js.map +1 -0
- package/webapp/dist/assets/{chunk-DI55MBZ5-SAhxUTqQ.js → chunk-NQ4KR5QH-CK365lrr.js} +9 -7
- package/webapp/dist/assets/chunk-NQ4KR5QH-CK365lrr.js.map +1 -0
- package/webapp/dist/assets/{chunk-QZHKN3VN-BxuV0Oba.js → chunk-QZHKN3VN-BCaWPGDm.js} +2 -2
- package/webapp/dist/assets/chunk-QZHKN3VN-BCaWPGDm.js.map +1 -0
- package/webapp/dist/assets/{chunk-B4BG7PRW-DpMa3-9L.js → chunk-WL4C6EOR-DDCnEwft.js} +171 -121
- package/webapp/dist/assets/chunk-WL4C6EOR-DDCnEwft.js.map +1 -0
- package/webapp/dist/assets/{classDiagram-2ON5EDUG-BTTGianr.js → classDiagram-VBA2DB6C-CvMBU4WA.js} +7 -6
- package/webapp/dist/assets/classDiagram-VBA2DB6C-CvMBU4WA.js.map +1 -0
- package/webapp/dist/assets/{classDiagram-v2-WZHVMYZB-BTTGianr.js → classDiagram-v2-RAHNMMFH-CvMBU4WA.js} +7 -6
- package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-CvMBU4WA.js.map +1 -0
- package/webapp/dist/assets/{clone-Dk8cAI3I.js → clone-r98jR0MC.js} +2 -2
- package/webapp/dist/assets/clone-r98jR0MC.js.map +1 -0
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BjJnzB2N.js → cose-bilkent-S5V4N54A-t6J60Ogk.js} +2 -2
- package/webapp/dist/assets/cose-bilkent-S5V4N54A-t6J60Ogk.js.map +1 -0
- package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
- package/webapp/dist/assets/{dagre-6UL2VRFP-VF-xGhAf.js → dagre-KLK3FWXG-BlqmY2DV.js} +7 -7
- package/webapp/dist/assets/dagre-KLK3FWXG-BlqmY2DV.js.map +1 -0
- package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
- package/webapp/dist/assets/{diagram-PSM6KHXK-Ba5U0oRY.js → diagram-E7M64L7V-FwCHeIUD.js} +10 -10
- package/webapp/dist/assets/diagram-E7M64L7V-FwCHeIUD.js.map +1 -0
- package/webapp/dist/assets/{diagram-QEK2KX5R-DoYCnEw_.js → diagram-IFDJBPK2-NhtmkuZG.js} +9 -8
- package/webapp/dist/assets/diagram-IFDJBPK2-NhtmkuZG.js.map +1 -0
- package/webapp/dist/assets/{diagram-S2PKOQOG-CkK4SRyE.js → diagram-P4PSJMXO-B9FcmokX.js} +8 -8
- package/webapp/dist/assets/diagram-P4PSJMXO-B9FcmokX.js.map +1 -0
- package/webapp/dist/assets/{erDiagram-Q2GNP2WA-DkI5eYww.js → erDiagram-INFDFZHY-DHKmWvtB.js} +96 -75
- package/webapp/dist/assets/erDiagram-INFDFZHY-DHKmWvtB.js.map +1 -0
- package/webapp/dist/assets/{flowDiagram-NV44I4VS-wOdPUQ7Y.js → flowDiagram-PKNHOUZH-C7Zi8I7T.js} +98 -81
- package/webapp/dist/assets/flowDiagram-PKNHOUZH-C7Zi8I7T.js.map +1 -0
- package/webapp/dist/assets/{ganttDiagram-JELNMOA3-BtRWgkUH.js → ganttDiagram-A5KZAMGK-Cv2T8tz_.js} +28 -3
- package/webapp/dist/assets/ganttDiagram-A5KZAMGK-Cv2T8tz_.js.map +1 -0
- package/webapp/dist/assets/{gitGraphDiagram-V2S2FVAM-Bsz7u1vi.js → gitGraphDiagram-K3NZZRJ6-DztaipJU.js} +38 -46
- package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-DztaipJU.js.map +1 -0
- package/webapp/dist/assets/graph-C5yf62Vs.js +782 -0
- package/webapp/dist/assets/graph-C5yf62Vs.js.map +1 -0
- package/webapp/dist/assets/{index-xvYYeHuy.css → index-YaxF76or.css} +1 -1
- package/webapp/dist/assets/{index-rYmIohM_.js → index-hve5MWPs.js} +1603 -1415
- package/webapp/dist/assets/index-hve5MWPs.js.map +1 -0
- package/webapp/dist/assets/{infoDiagram-HS3SLOUP-BMaxCvH5.js → infoDiagram-LFFYTUFH-VgsbBPZP.js} +7 -7
- package/webapp/dist/assets/infoDiagram-LFFYTUFH-VgsbBPZP.js.map +1 -0
- package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
- package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-C7j3YWdw.js +966 -0
- package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-C7j3YWdw.js.map +1 -0
- package/webapp/dist/assets/{journeyDiagram-XKPGCS4Q-ejyerzmG.js → journeyDiagram-4ABVD52K-OO8sev-Y.js} +5 -5
- package/webapp/dist/assets/journeyDiagram-4ABVD52K-OO8sev-Y.js.map +1 -0
- package/webapp/dist/assets/{kanban-definition-3W4ZIXB7-CYj35TEs.js → kanban-definition-K7BYSVSG-DiYCC1Ig.js} +5 -3
- package/webapp/dist/assets/kanban-definition-K7BYSVSG-DiYCC1Ig.js.map +1 -0
- package/webapp/dist/assets/{layout-7Ql4zmuL.js → layout-DdZSgGdu.js} +5 -5
- package/webapp/dist/assets/layout-DdZSgGdu.js.map +1 -0
- package/webapp/dist/assets/{linear-CVmgVPuZ.js → linear-7-aHtaFi.js} +2 -2
- package/webapp/dist/assets/linear-7-aHtaFi.js.map +1 -0
- package/webapp/dist/assets/{mindmap-definition-VGOIOE7T-DOpxjGVo.js → mindmap-definition-YRQLILUH-IG3I-RdD.js} +7 -5
- package/webapp/dist/assets/mindmap-definition-YRQLILUH-IG3I-RdD.js.map +1 -0
- package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
- package/webapp/dist/assets/{pieDiagram-ADFJNKIX-CLQjpmAG.js → pieDiagram-SKSYHLDU-z68KJT5r.js} +8 -8
- package/webapp/dist/assets/pieDiagram-SKSYHLDU-z68KJT5r.js.map +1 -0
- package/webapp/dist/assets/{quadrantDiagram-AYHSOK5B-ClD_bz7z.js → quadrantDiagram-337W2JSQ-DaENWdO6.js} +3 -3
- package/webapp/dist/assets/quadrantDiagram-337W2JSQ-DaENWdO6.js.map +1 -0
- package/webapp/dist/assets/{requirementDiagram-UZGBJVZJ-DOpb-TWH.js → requirementDiagram-Z7DCOOCP-ROTFv4sa.js} +16 -6
- package/webapp/dist/assets/requirementDiagram-Z7DCOOCP-ROTFv4sa.js.map +1 -0
- package/webapp/dist/assets/{sankeyDiagram-TZEHDZUN-D8Hsj3yx.js → sankeyDiagram-WA2Y5GQK-CK7qtpzw.js} +2 -2
- package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-CK7qtpzw.js.map +1 -0
- package/webapp/dist/assets/{sequenceDiagram-WL72ISMW-CFMNjBER.js → sequenceDiagram-2WXFIKYE-R5lDySeI.js} +601 -201
- package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-R5lDySeI.js.map +1 -0
- package/webapp/dist/assets/{stateDiagram-FKZM4ZOC-BQeDlw0P.js → stateDiagram-RAJIS63D-sr7msF5U.js} +9 -9
- package/webapp/dist/assets/stateDiagram-RAJIS63D-sr7msF5U.js.map +1 -0
- package/webapp/dist/assets/{stateDiagram-v2-4FDKWEC3-DscX61Rs.js → stateDiagram-v2-FVOUBMTO-X663liwS.js} +5 -5
- package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-X663liwS.js.map +1 -0
- package/webapp/dist/assets/{timeline-definition-IT6M3QCI-BcXPSTiw.js → timeline-definition-YZTLITO2-Bw0TdG26.js} +3 -3
- package/webapp/dist/assets/timeline-definition-YZTLITO2-Bw0TdG26.js.map +1 -0
- package/webapp/dist/assets/{treemap-GDKQZRPO-BBr4UV0Z.js → treemap-KZPCXAKY-D_sjKwI7.js} +37 -24
- package/webapp/dist/assets/treemap-KZPCXAKY-D_sjKwI7.js.map +1 -0
- package/webapp/dist/assets/vennDiagram-LZ73GAT5-DhlHIHid.js +2487 -0
- package/webapp/dist/assets/vennDiagram-LZ73GAT5-DhlHIHid.js.map +1 -0
- package/webapp/dist/assets/{xychartDiagram-PRI3JC2R-CS5RAtQE.js → xychartDiagram-JWTSCODW-C65ESjTc.js} +4 -4
- package/webapp/dist/assets/xychartDiagram-JWTSCODW-C65ESjTc.js.map +1 -0
- package/webapp/dist/index.html +2 -2
- package/webapp/dist/assets/_basePickBy-CBOtd63g.js.map +0 -1
- package/webapp/dist/assets/_baseUniq-mfoKz4Wm.js.map +0 -1
- package/webapp/dist/assets/arc-Dq0WZLyu.js.map +0 -1
- package/webapp/dist/assets/architectureDiagram-VXUJARFQ-CNmygmp3.js.map +0 -1
- package/webapp/dist/assets/blockDiagram-VD42YOAC-DvE0lybt.js.map +0 -1
- package/webapp/dist/assets/c4Diagram-YG6GDRKO-CR7zJ2_u.js.map +0 -1
- package/webapp/dist/assets/channel-DrTrnYx4.js.map +0 -1
- package/webapp/dist/assets/chunk-4BX2VUAB-CVuJEIeN.js.map +0 -1
- package/webapp/dist/assets/chunk-55IACEB6-BxUoXApB.js.map +0 -1
- package/webapp/dist/assets/chunk-B4BG7PRW-DpMa3-9L.js.map +0 -1
- package/webapp/dist/assets/chunk-DI55MBZ5-SAhxUTqQ.js.map +0 -1
- package/webapp/dist/assets/chunk-FMBD7UC4-TX-LVAaV.js.map +0 -1
- package/webapp/dist/assets/chunk-QN33PNHL-D1uiKlOO.js.map +0 -1
- package/webapp/dist/assets/chunk-QZHKN3VN-BxuV0Oba.js.map +0 -1
- package/webapp/dist/assets/chunk-TZMSLE5B-Cw689yRl.js.map +0 -1
- package/webapp/dist/assets/classDiagram-2ON5EDUG-BTTGianr.js.map +0 -1
- package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-BTTGianr.js.map +0 -1
- package/webapp/dist/assets/clone-Dk8cAI3I.js.map +0 -1
- package/webapp/dist/assets/cose-bilkent-S5V4N54A-BjJnzB2N.js.map +0 -1
- package/webapp/dist/assets/dagre-6UL2VRFP-VF-xGhAf.js.map +0 -1
- package/webapp/dist/assets/diagram-PSM6KHXK-Ba5U0oRY.js.map +0 -1
- package/webapp/dist/assets/diagram-QEK2KX5R-DoYCnEw_.js.map +0 -1
- package/webapp/dist/assets/diagram-S2PKOQOG-CkK4SRyE.js.map +0 -1
- package/webapp/dist/assets/erDiagram-Q2GNP2WA-DkI5eYww.js.map +0 -1
- package/webapp/dist/assets/flowDiagram-NV44I4VS-wOdPUQ7Y.js.map +0 -1
- package/webapp/dist/assets/ganttDiagram-JELNMOA3-BtRWgkUH.js.map +0 -1
- package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-Bsz7u1vi.js.map +0 -1
- package/webapp/dist/assets/graph-DAMkuTbn.js +0 -425
- package/webapp/dist/assets/graph-DAMkuTbn.js.map +0 -1
- package/webapp/dist/assets/index-rYmIohM_.js.map +0 -1
- package/webapp/dist/assets/infoDiagram-HS3SLOUP-BMaxCvH5.js.map +0 -1
- package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-ejyerzmG.js.map +0 -1
- package/webapp/dist/assets/kanban-definition-3W4ZIXB7-CYj35TEs.js.map +0 -1
- package/webapp/dist/assets/layout-7Ql4zmuL.js.map +0 -1
- package/webapp/dist/assets/linear-CVmgVPuZ.js.map +0 -1
- package/webapp/dist/assets/mindmap-definition-VGOIOE7T-DOpxjGVo.js.map +0 -1
- package/webapp/dist/assets/pieDiagram-ADFJNKIX-CLQjpmAG.js.map +0 -1
- package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-ClD_bz7z.js.map +0 -1
- package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-DOpb-TWH.js.map +0 -1
- package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-D8Hsj3yx.js.map +0 -1
- package/webapp/dist/assets/sequenceDiagram-WL72ISMW-CFMNjBER.js.map +0 -1
- package/webapp/dist/assets/stateDiagram-FKZM4ZOC-BQeDlw0P.js.map +0 -1
- package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3-DscX61Rs.js.map +0 -1
- package/webapp/dist/assets/timeline-definition-IT6M3QCI-BcXPSTiw.js.map +0 -1
- package/webapp/dist/assets/treemap-GDKQZRPO-BBr4UV0Z.js.map +0 -1
- package/webapp/dist/assets/xychartDiagram-PRI3JC2R-CS5RAtQE.js.map +0 -1
package/dist/persistence.js
CHANGED
|
@@ -51,9 +51,81 @@ const evt_registry_1 = require("./evt-registry");
|
|
|
51
51
|
const log_1 = require("./log");
|
|
52
52
|
const async_fifo_mutex_1 = require("./runtime/async-fifo-mutex");
|
|
53
53
|
const reply_prompt_copy_1 = require("./runtime/reply-prompt-copy");
|
|
54
|
-
const work_language_1 = require("./runtime/work-language");
|
|
55
54
|
const tool_1 = require("./tool");
|
|
56
55
|
const registry_1 = require("./tools/registry");
|
|
56
|
+
function isTellaskBusinessCallName(value) {
|
|
57
|
+
return (value === 'tellask' ||
|
|
58
|
+
value === 'tellaskSessionless' ||
|
|
59
|
+
value === 'tellaskBack' ||
|
|
60
|
+
value === 'askHuman' ||
|
|
61
|
+
value === 'freshBootsReasoning');
|
|
62
|
+
}
|
|
63
|
+
function isSuppressedTellaskPlaceholderFuncResult(args) {
|
|
64
|
+
if (!isTellaskBusinessCallName(args.name)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const raw = args.content.trim();
|
|
68
|
+
if (raw === '') {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (raw === 'Q4H 已结束等待状态,请参考 askHuman 结果气泡。' ||
|
|
72
|
+
raw === 'Q4H wait is resolved; refer to the askHuman result bubble.') {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
if (raw.startsWith('Q4H 仍在等待人类回复,已持续 ') ||
|
|
76
|
+
raw.startsWith('Q4H is still waiting for human reply (elapsed ')) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
if (raw.startsWith('支线对话仍在进行中,已持续 ') ||
|
|
80
|
+
raw.startsWith('Sideline dialog is still running (elapsed ')) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
function buildTellaskResultRoute(route, fallback) {
|
|
86
|
+
const effective = route ?? fallback;
|
|
87
|
+
if (!effective)
|
|
88
|
+
return undefined;
|
|
89
|
+
return {
|
|
90
|
+
...(effective.calleeDialogId ? { calleeDialogId: effective.calleeDialogId } : {}),
|
|
91
|
+
...(typeof effective.calleeCourse === 'number'
|
|
92
|
+
? { calleeCourse: (0, storage_1.toCalleeCourseNumber)(effective.calleeCourse) }
|
|
93
|
+
: {}),
|
|
94
|
+
...(typeof effective.calleeGenseq === 'number'
|
|
95
|
+
? { calleeGenseq: (0, storage_1.toCalleeGenerationSeqNumber)(effective.calleeGenseq) }
|
|
96
|
+
: {}),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function requireNonEmptyTrimmedString(value, field, context) {
|
|
100
|
+
if (typeof value !== 'string') {
|
|
101
|
+
throw new Error(`${context} invariant violation: missing ${field}`);
|
|
102
|
+
}
|
|
103
|
+
const trimmed = value.trim();
|
|
104
|
+
if (trimmed === '') {
|
|
105
|
+
throw new Error(`${context} invariant violation: empty ${field}`);
|
|
106
|
+
}
|
|
107
|
+
return trimmed;
|
|
108
|
+
}
|
|
109
|
+
function requireTellaskResultResponderId(result, context) {
|
|
110
|
+
return requireNonEmptyTrimmedString(result.responder?.responderId ?? result.responderId, 'responderId', `${context} (callId=${result.callId}, callName=${result.callName})`);
|
|
111
|
+
}
|
|
112
|
+
function requireTellaskResultContent(result, context) {
|
|
113
|
+
return requireNonEmptyTrimmedString(result.call?.tellaskContent ?? result.tellaskContent, 'tellaskContent', `${context} (callId=${result.callId}, callName=${result.callName})`);
|
|
114
|
+
}
|
|
115
|
+
function resolveTellaskResultMentionList(result, context) {
|
|
116
|
+
const mentionList = result.call?.mentionList ?? result.mentionList;
|
|
117
|
+
if (mentionList === undefined) {
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
if (!Array.isArray(mentionList) || mentionList.some((item) => typeof item !== 'string')) {
|
|
121
|
+
throw new Error(`${context} invariant violation: invalid mentionList ` +
|
|
122
|
+
`(callId=${result.callId}, callName=${result.callName})`);
|
|
123
|
+
}
|
|
124
|
+
return [...mentionList];
|
|
125
|
+
}
|
|
126
|
+
function requireTellaskResultSessionSlug(result, context) {
|
|
127
|
+
return requireNonEmptyTrimmedString(result.call?.sessionSlug ?? result.sessionSlug, 'sessionSlug', `${context} (callId=${result.callId}, callName=${result.callName})`);
|
|
128
|
+
}
|
|
57
129
|
function getErrorCode(error) {
|
|
58
130
|
if (typeof error !== 'object' || error === null)
|
|
59
131
|
return undefined;
|
|
@@ -93,114 +165,315 @@ function cloneRootGenerationAnchor(anchor) {
|
|
|
93
165
|
rootGenseq: anchor.rootGenseq,
|
|
94
166
|
};
|
|
95
167
|
}
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
function readPersistedTellaskStringArg(arguments_, field, callName, callId) {
|
|
107
|
-
const value = arguments_[field];
|
|
108
|
-
if (typeof value !== 'string' || value.trim() === '') {
|
|
109
|
-
throw new Error(`tellask special persistence invariant violation: missing ${field} for ${callName} (callId=${callId})`);
|
|
110
|
-
}
|
|
111
|
-
return value;
|
|
168
|
+
function buildFuncCallRecord(args) {
|
|
169
|
+
return {
|
|
170
|
+
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
171
|
+
type: 'func_call_record',
|
|
172
|
+
genseq: args.genseq,
|
|
173
|
+
id: args.id,
|
|
174
|
+
name: args.name,
|
|
175
|
+
rawArgumentsText: args.rawArgumentsText,
|
|
176
|
+
};
|
|
112
177
|
}
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
178
|
+
function buildFuncResultRecord(funcResult, genseq) {
|
|
179
|
+
return {
|
|
180
|
+
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
181
|
+
type: 'func_result_record',
|
|
182
|
+
id: funcResult.id,
|
|
183
|
+
name: funcResult.name,
|
|
184
|
+
content: funcResult.content,
|
|
185
|
+
contentItems: funcResult.contentItems,
|
|
186
|
+
genseq,
|
|
187
|
+
};
|
|
122
188
|
}
|
|
123
|
-
function
|
|
124
|
-
|
|
189
|
+
function buildTellaskCallRecord(args) {
|
|
190
|
+
return {
|
|
125
191
|
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
126
|
-
type: '
|
|
192
|
+
type: 'tellask_call_record',
|
|
127
193
|
genseq: args.genseq,
|
|
128
194
|
id: args.id,
|
|
195
|
+
name: args.name,
|
|
196
|
+
rawArgumentsText: args.rawArgumentsText,
|
|
197
|
+
deliveryMode: args.deliveryMode,
|
|
129
198
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
199
|
+
}
|
|
200
|
+
function buildTellaskResultRecord(result, genseq) {
|
|
201
|
+
if (!isTellaskBusinessCallName(result.callName)) {
|
|
202
|
+
throw new Error(`buildTellaskResultRecord invariant violation: ${result.callName} is not a tellask business result`);
|
|
203
|
+
}
|
|
204
|
+
const responderId = requireTellaskResultResponderId(result, 'buildTellaskResultRecord');
|
|
205
|
+
const tellaskContent = requireTellaskResultContent(result, 'buildTellaskResultRecord');
|
|
206
|
+
const route = buildTellaskResultRoute(result.route, {
|
|
207
|
+
calleeDialogId: result.calleeDialogId,
|
|
208
|
+
calleeCourse: result.calleeCourse,
|
|
209
|
+
calleeGenseq: result.calleeGenseq,
|
|
210
|
+
});
|
|
211
|
+
const base = {
|
|
212
|
+
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
213
|
+
type: 'tellask_result_record',
|
|
214
|
+
genseq,
|
|
215
|
+
callId: result.callId,
|
|
216
|
+
status: result.status,
|
|
217
|
+
content: result.content,
|
|
218
|
+
...(typeof result.calling_genseq === 'number'
|
|
219
|
+
? { calling_genseq: (0, storage_1.toCallingGenerationSeqNumber)(result.calling_genseq) }
|
|
220
|
+
: {}),
|
|
221
|
+
responder: {
|
|
222
|
+
responderId,
|
|
223
|
+
...((result.responder?.agentId ?? result.agentId)
|
|
224
|
+
? { agentId: result.responder?.agentId ?? result.agentId }
|
|
225
|
+
: {}),
|
|
226
|
+
...((result.responder?.originMemberId ?? result.originMemberId)
|
|
227
|
+
? { originMemberId: result.responder?.originMemberId ?? result.originMemberId }
|
|
228
|
+
: {}),
|
|
229
|
+
},
|
|
230
|
+
...(route ? { route } : {}),
|
|
231
|
+
};
|
|
232
|
+
switch (result.callName) {
|
|
137
233
|
case 'tellask':
|
|
138
234
|
return {
|
|
139
235
|
...base,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
236
|
+
callName: result.callName,
|
|
237
|
+
call: {
|
|
238
|
+
tellaskContent,
|
|
239
|
+
mentionList: resolveTellaskResultMentionList(result, 'buildTellaskResultRecord'),
|
|
240
|
+
sessionSlug: requireTellaskResultSessionSlug(result, 'buildTellaskResultRecord'),
|
|
241
|
+
},
|
|
144
242
|
};
|
|
145
243
|
case 'tellaskSessionless':
|
|
146
244
|
return {
|
|
147
245
|
...base,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
case 'replyTellaskSessionless':
|
|
154
|
-
case 'replyTellaskBack':
|
|
155
|
-
return {
|
|
156
|
-
...base,
|
|
157
|
-
name: args.name,
|
|
158
|
-
replyContent: readPersistedTellaskStringArg(args.arguments_, 'replyContent', args.name, args.id),
|
|
246
|
+
callName: result.callName,
|
|
247
|
+
call: {
|
|
248
|
+
tellaskContent,
|
|
249
|
+
mentionList: resolveTellaskResultMentionList(result, 'buildTellaskResultRecord'),
|
|
250
|
+
},
|
|
159
251
|
};
|
|
252
|
+
case 'tellaskBack':
|
|
160
253
|
case 'askHuman':
|
|
254
|
+
case 'freshBootsReasoning':
|
|
161
255
|
return {
|
|
162
256
|
...base,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const effort = readPersistedTellaskOptionalNumberArg(args.arguments_, 'effort', args.name, args.id);
|
|
168
|
-
return {
|
|
169
|
-
...base,
|
|
170
|
-
name: args.name,
|
|
171
|
-
tellaskContent: readPersistedTellaskStringArg(args.arguments_, 'tellaskContent', args.name, args.id),
|
|
172
|
-
...(effort !== undefined ? { effort } : {}),
|
|
257
|
+
callName: result.callName,
|
|
258
|
+
call: {
|
|
259
|
+
tellaskContent,
|
|
260
|
+
},
|
|
173
261
|
};
|
|
174
|
-
}
|
|
175
262
|
}
|
|
176
263
|
}
|
|
177
|
-
function
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
264
|
+
function buildTellaskCarryoverRecord(result, genseq) {
|
|
265
|
+
return {
|
|
266
|
+
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
267
|
+
type: 'tellask_carryover_record',
|
|
268
|
+
genseq,
|
|
269
|
+
originCourse: (0, storage_1.toCallingCourseNumber)(result.originCourse),
|
|
270
|
+
carryoverCourse: (0, storage_1.toDialogCourseNumber)(result.carryoverCourse),
|
|
271
|
+
responderId: result.responderId,
|
|
272
|
+
callName: result.callName,
|
|
273
|
+
tellaskContent: result.tellaskContent,
|
|
274
|
+
status: result.status,
|
|
275
|
+
response: result.response,
|
|
276
|
+
content: result.content,
|
|
277
|
+
agentId: result.agentId,
|
|
278
|
+
callId: result.callId,
|
|
279
|
+
originMemberId: result.originMemberId,
|
|
280
|
+
...(result.callName === 'tellask'
|
|
281
|
+
? {
|
|
282
|
+
sessionSlug: result.sessionSlug,
|
|
283
|
+
mentionList: result.mentionList,
|
|
284
|
+
}
|
|
285
|
+
: result.callName === 'tellaskSessionless'
|
|
286
|
+
? {
|
|
287
|
+
mentionList: result.mentionList,
|
|
288
|
+
}
|
|
289
|
+
: {}),
|
|
290
|
+
...(result.calleeDialogId ? { calleeDialogId: result.calleeDialogId } : {}),
|
|
291
|
+
...(typeof result.calleeCourse === 'number' ? { calleeCourse: result.calleeCourse } : {}),
|
|
292
|
+
...(typeof result.calleeGenseq === 'number' ? { calleeGenseq: result.calleeGenseq } : {}),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function buildTellaskResultEvent(result, course) {
|
|
296
|
+
if (!isTellaskBusinessCallName(result.callName)) {
|
|
297
|
+
throw new Error(`buildTellaskResultEvent invariant violation: ${result.callName} is not a tellask business result`);
|
|
298
|
+
}
|
|
299
|
+
const responderId = requireTellaskResultResponderId(result, 'buildTellaskResultEvent');
|
|
300
|
+
const tellaskContent = requireTellaskResultContent(result, 'buildTellaskResultEvent');
|
|
301
|
+
const route = buildTellaskResultRoute(result.route, {
|
|
302
|
+
calleeDialogId: result.calleeDialogId,
|
|
303
|
+
calleeCourse: result.calleeCourse,
|
|
304
|
+
calleeGenseq: result.calleeGenseq,
|
|
305
|
+
});
|
|
306
|
+
if (result.callName === 'tellask') {
|
|
307
|
+
const effectiveSessionSlug = requireTellaskResultSessionSlug(result, 'buildTellaskResultEvent');
|
|
308
|
+
return {
|
|
309
|
+
type: 'tellask_result_evt',
|
|
310
|
+
course,
|
|
311
|
+
genseq: result.genseq,
|
|
312
|
+
calling_genseq: typeof result.calling_genseq === 'number'
|
|
313
|
+
? (0, storage_1.toCallingGenerationSeqNumber)(result.calling_genseq)
|
|
314
|
+
: undefined,
|
|
315
|
+
callId: result.callId,
|
|
316
|
+
callName: result.callName,
|
|
317
|
+
status: result.status,
|
|
318
|
+
content: result.content,
|
|
319
|
+
call: {
|
|
320
|
+
tellaskContent,
|
|
321
|
+
mentionList: resolveTellaskResultMentionList(result, 'buildTellaskResultEvent'),
|
|
322
|
+
sessionSlug: effectiveSessionSlug,
|
|
323
|
+
},
|
|
324
|
+
responder: {
|
|
325
|
+
responderId,
|
|
326
|
+
...((result.responder?.agentId ?? result.agentId)
|
|
327
|
+
? { agentId: result.responder?.agentId ?? result.agentId }
|
|
328
|
+
: {}),
|
|
329
|
+
...((result.responder?.originMemberId ?? result.originMemberId)
|
|
330
|
+
? { originMemberId: result.responder?.originMemberId ?? result.originMemberId }
|
|
331
|
+
: {}),
|
|
332
|
+
},
|
|
333
|
+
...(route ? { route } : {}),
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
if (result.callName === 'tellaskSessionless') {
|
|
337
|
+
return {
|
|
338
|
+
type: 'tellask_result_evt',
|
|
339
|
+
course,
|
|
340
|
+
genseq: result.genseq,
|
|
341
|
+
calling_genseq: typeof result.calling_genseq === 'number'
|
|
342
|
+
? (0, storage_1.toCallingGenerationSeqNumber)(result.calling_genseq)
|
|
343
|
+
: undefined,
|
|
344
|
+
callId: result.callId,
|
|
345
|
+
callName: result.callName,
|
|
346
|
+
status: result.status,
|
|
347
|
+
content: result.content,
|
|
348
|
+
call: {
|
|
349
|
+
tellaskContent,
|
|
350
|
+
mentionList: resolveTellaskResultMentionList(result, 'buildTellaskResultEvent'),
|
|
351
|
+
},
|
|
352
|
+
responder: {
|
|
353
|
+
responderId,
|
|
354
|
+
...((result.responder?.agentId ?? result.agentId)
|
|
355
|
+
? { agentId: result.responder?.agentId ?? result.agentId }
|
|
356
|
+
: {}),
|
|
357
|
+
...((result.responder?.originMemberId ?? result.originMemberId)
|
|
358
|
+
? { originMemberId: result.responder?.originMemberId ?? result.originMemberId }
|
|
359
|
+
: {}),
|
|
360
|
+
},
|
|
361
|
+
...(route ? { route } : {}),
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
type: 'tellask_result_evt',
|
|
366
|
+
course,
|
|
367
|
+
genseq: result.genseq,
|
|
368
|
+
calling_genseq: typeof result.calling_genseq === 'number'
|
|
369
|
+
? (0, storage_1.toCallingGenerationSeqNumber)(result.calling_genseq)
|
|
370
|
+
: undefined,
|
|
371
|
+
callId: result.callId,
|
|
372
|
+
callName: result.callName,
|
|
373
|
+
status: result.status,
|
|
374
|
+
content: result.content,
|
|
375
|
+
call: {
|
|
376
|
+
tellaskContent,
|
|
377
|
+
},
|
|
378
|
+
responder: {
|
|
379
|
+
responderId,
|
|
380
|
+
...((result.responder?.agentId ?? result.agentId)
|
|
381
|
+
? { agentId: result.responder?.agentId ?? result.agentId }
|
|
382
|
+
: {}),
|
|
383
|
+
...((result.responder?.originMemberId ?? result.originMemberId)
|
|
384
|
+
? { originMemberId: result.responder?.originMemberId ?? result.originMemberId }
|
|
385
|
+
: {}),
|
|
386
|
+
},
|
|
387
|
+
...(route ? { route } : {}),
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function buildTellaskCarryoverEvent(result, course) {
|
|
391
|
+
if (result.callName === 'tellask') {
|
|
392
|
+
const sessionSlug = result.sessionSlug?.trim();
|
|
393
|
+
if (!sessionSlug) {
|
|
394
|
+
throw new Error(`buildTellaskCarryoverEvent invariant violation: missing sessionSlug for tellask call ${result.callId}`);
|
|
395
|
+
}
|
|
396
|
+
return {
|
|
397
|
+
type: 'tellask_carryover_evt',
|
|
398
|
+
course,
|
|
399
|
+
genseq: result.genseq,
|
|
400
|
+
originCourse: (0, storage_1.toCallingCourseNumber)(result.originCourse),
|
|
401
|
+
carryoverCourse: (0, storage_1.toDialogCourseNumber)(result.carryoverCourse),
|
|
402
|
+
responderId: result.responderId,
|
|
403
|
+
callName: result.callName,
|
|
404
|
+
sessionSlug,
|
|
405
|
+
mentionList: result.mentionList ?? [],
|
|
406
|
+
tellaskContent: result.tellaskContent,
|
|
407
|
+
status: result.status,
|
|
408
|
+
response: result.response,
|
|
409
|
+
content: result.content,
|
|
410
|
+
agentId: result.agentId,
|
|
411
|
+
callId: result.callId,
|
|
412
|
+
originMemberId: result.originMemberId,
|
|
413
|
+
...(result.calleeDialogId ? { calleeDialogId: result.calleeDialogId } : {}),
|
|
414
|
+
...(typeof result.calleeCourse === 'number'
|
|
415
|
+
? { calleeCourse: (0, storage_1.toCalleeCourseNumber)(result.calleeCourse) }
|
|
416
|
+
: {}),
|
|
417
|
+
...(typeof result.calleeGenseq === 'number'
|
|
418
|
+
? { calleeGenseq: (0, storage_1.toCalleeGenerationSeqNumber)(result.calleeGenseq) }
|
|
419
|
+
: {}),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
if (result.callName === 'tellaskSessionless') {
|
|
423
|
+
return {
|
|
424
|
+
type: 'tellask_carryover_evt',
|
|
425
|
+
course,
|
|
426
|
+
genseq: result.genseq,
|
|
427
|
+
originCourse: (0, storage_1.toCallingCourseNumber)(result.originCourse),
|
|
428
|
+
carryoverCourse: (0, storage_1.toDialogCourseNumber)(result.carryoverCourse),
|
|
429
|
+
responderId: result.responderId,
|
|
430
|
+
callName: result.callName,
|
|
431
|
+
mentionList: result.mentionList ?? [],
|
|
432
|
+
tellaskContent: result.tellaskContent,
|
|
433
|
+
status: result.status,
|
|
434
|
+
response: result.response,
|
|
435
|
+
content: result.content,
|
|
436
|
+
agentId: result.agentId,
|
|
437
|
+
callId: result.callId,
|
|
438
|
+
originMemberId: result.originMemberId,
|
|
439
|
+
...(result.calleeDialogId ? { calleeDialogId: result.calleeDialogId } : {}),
|
|
440
|
+
...(typeof result.calleeCourse === 'number'
|
|
441
|
+
? { calleeCourse: (0, storage_1.toCalleeCourseNumber)(result.calleeCourse) }
|
|
442
|
+
: {}),
|
|
443
|
+
...(typeof result.calleeGenseq === 'number'
|
|
444
|
+
? { calleeGenseq: (0, storage_1.toCalleeGenerationSeqNumber)(result.calleeGenseq) }
|
|
445
|
+
: {}),
|
|
446
|
+
};
|
|
203
447
|
}
|
|
448
|
+
return {
|
|
449
|
+
type: 'tellask_carryover_evt',
|
|
450
|
+
course,
|
|
451
|
+
genseq: result.genseq,
|
|
452
|
+
originCourse: (0, storage_1.toCallingCourseNumber)(result.originCourse),
|
|
453
|
+
carryoverCourse: (0, storage_1.toDialogCourseNumber)(result.carryoverCourse),
|
|
454
|
+
responderId: result.responderId,
|
|
455
|
+
callName: result.callName,
|
|
456
|
+
tellaskContent: result.tellaskContent,
|
|
457
|
+
status: result.status,
|
|
458
|
+
response: result.response,
|
|
459
|
+
content: result.content,
|
|
460
|
+
agentId: result.agentId,
|
|
461
|
+
callId: result.callId,
|
|
462
|
+
originMemberId: result.originMemberId,
|
|
463
|
+
...(result.calleeDialogId ? { calleeDialogId: result.calleeDialogId } : {}),
|
|
464
|
+
...(typeof result.calleeCourse === 'number'
|
|
465
|
+
? { calleeCourse: (0, storage_1.toCalleeCourseNumber)(result.calleeCourse) }
|
|
466
|
+
: {}),
|
|
467
|
+
...(typeof result.calleeGenseq === 'number'
|
|
468
|
+
? { calleeGenseq: (0, storage_1.toCalleeGenerationSeqNumber)(result.calleeGenseq) }
|
|
469
|
+
: {}),
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
function formatTellaskCallArguments(record) {
|
|
473
|
+
return record.rawArgumentsText;
|
|
474
|
+
}
|
|
475
|
+
function isReplyTellaskCallRecordName(name) {
|
|
476
|
+
return (name === 'replyTellask' || name === 'replyTellaskSessionless' || name === 'replyTellaskBack');
|
|
204
477
|
}
|
|
205
478
|
function resolveRootGenerationAnchor(dialog) {
|
|
206
479
|
const rootDialog = dialog instanceof dialog_1.SubDialog ? dialog.rootDialog : dialog;
|
|
@@ -643,41 +916,92 @@ function isSubdialogResponseRecord(value) {
|
|
|
643
916
|
}
|
|
644
917
|
// Remove old type definitions - now using kernel/types/storage.ts
|
|
645
918
|
const id_1 = require("./utils/id");
|
|
646
|
-
function
|
|
919
|
+
function parseReplayTellaskCall(record) {
|
|
920
|
+
if (record.deliveryMode !== 'tellask_call_start') {
|
|
921
|
+
return null;
|
|
922
|
+
}
|
|
923
|
+
let parsed;
|
|
924
|
+
try {
|
|
925
|
+
parsed = JSON.parse(record.rawArgumentsText);
|
|
926
|
+
}
|
|
927
|
+
catch (error) {
|
|
928
|
+
throw new Error(`persisted tellask rawArgumentsText is not valid JSON for replay (callId=${record.id}, name=${record.name}): ${error instanceof Error ? error.message : String(error)}`);
|
|
929
|
+
}
|
|
930
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
931
|
+
throw new Error(`persisted tellask rawArgumentsText must decode to an object for replay (callId=${record.id}, name=${record.name})`);
|
|
932
|
+
}
|
|
933
|
+
const args = parsed;
|
|
647
934
|
switch (record.name) {
|
|
648
|
-
case 'tellaskBack':
|
|
935
|
+
case 'tellaskBack': {
|
|
936
|
+
const tellaskContent = args['tellaskContent'];
|
|
937
|
+
if (typeof tellaskContent !== 'string' || tellaskContent.trim() === '') {
|
|
938
|
+
throw new Error(`persisted tellaskBack missing tellaskContent (callId=${record.id})`);
|
|
939
|
+
}
|
|
649
940
|
return {
|
|
650
941
|
callName: 'tellaskBack',
|
|
651
|
-
tellaskContent
|
|
942
|
+
tellaskContent,
|
|
652
943
|
callId: record.id,
|
|
653
944
|
};
|
|
654
|
-
|
|
945
|
+
}
|
|
946
|
+
case 'askHuman': {
|
|
947
|
+
const tellaskContent = args['tellaskContent'];
|
|
948
|
+
if (typeof tellaskContent !== 'string' || tellaskContent.trim() === '') {
|
|
949
|
+
throw new Error(`persisted askHuman missing tellaskContent (callId=${record.id})`);
|
|
950
|
+
}
|
|
655
951
|
return {
|
|
656
952
|
callName: 'askHuman',
|
|
657
|
-
tellaskContent
|
|
953
|
+
tellaskContent,
|
|
658
954
|
callId: record.id,
|
|
659
955
|
};
|
|
660
|
-
|
|
956
|
+
}
|
|
957
|
+
case 'freshBootsReasoning': {
|
|
958
|
+
const tellaskContent = args['tellaskContent'];
|
|
959
|
+
if (typeof tellaskContent !== 'string' || tellaskContent.trim() === '') {
|
|
960
|
+
throw new Error(`persisted freshBootsReasoning missing tellaskContent (callId=${record.id})`);
|
|
961
|
+
}
|
|
661
962
|
return {
|
|
662
963
|
callName: 'freshBootsReasoning',
|
|
663
|
-
tellaskContent
|
|
964
|
+
tellaskContent,
|
|
664
965
|
callId: record.id,
|
|
665
966
|
};
|
|
666
|
-
|
|
967
|
+
}
|
|
968
|
+
case 'tellask': {
|
|
969
|
+
const targetAgentId = args['targetAgentId'];
|
|
970
|
+
const sessionSlug = args['sessionSlug'];
|
|
971
|
+
const tellaskContent = args['tellaskContent'];
|
|
972
|
+
if (typeof targetAgentId !== 'string' || targetAgentId.trim() === '') {
|
|
973
|
+
throw new Error(`persisted tellask missing targetAgentId (callId=${record.id})`);
|
|
974
|
+
}
|
|
975
|
+
if (typeof sessionSlug !== 'string' || sessionSlug.trim() === '') {
|
|
976
|
+
throw new Error(`persisted tellask missing sessionSlug (callId=${record.id})`);
|
|
977
|
+
}
|
|
978
|
+
if (typeof tellaskContent !== 'string' || tellaskContent.trim() === '') {
|
|
979
|
+
throw new Error(`persisted tellask missing tellaskContent (callId=${record.id})`);
|
|
980
|
+
}
|
|
667
981
|
return {
|
|
668
982
|
callName: 'tellask',
|
|
669
|
-
mentionList: [`@${
|
|
670
|
-
sessionSlug
|
|
671
|
-
tellaskContent
|
|
983
|
+
mentionList: [`@${targetAgentId}`],
|
|
984
|
+
sessionSlug,
|
|
985
|
+
tellaskContent,
|
|
672
986
|
callId: record.id,
|
|
673
987
|
};
|
|
674
|
-
|
|
988
|
+
}
|
|
989
|
+
case 'tellaskSessionless': {
|
|
990
|
+
const targetAgentId = args['targetAgentId'];
|
|
991
|
+
const tellaskContent = args['tellaskContent'];
|
|
992
|
+
if (typeof targetAgentId !== 'string' || targetAgentId.trim() === '') {
|
|
993
|
+
throw new Error(`persisted tellaskSessionless missing targetAgentId (callId=${record.id})`);
|
|
994
|
+
}
|
|
995
|
+
if (typeof tellaskContent !== 'string' || tellaskContent.trim() === '') {
|
|
996
|
+
throw new Error(`persisted tellaskSessionless missing tellaskContent (callId=${record.id})`);
|
|
997
|
+
}
|
|
675
998
|
return {
|
|
676
999
|
callName: 'tellaskSessionless',
|
|
677
|
-
mentionList: [`@${
|
|
678
|
-
tellaskContent
|
|
1000
|
+
mentionList: [`@${targetAgentId}`],
|
|
1001
|
+
tellaskContent,
|
|
679
1002
|
callId: record.id,
|
|
680
1003
|
};
|
|
1004
|
+
}
|
|
681
1005
|
case 'replyTellask':
|
|
682
1006
|
case 'replyTellaskSessionless':
|
|
683
1007
|
case 'replyTellaskBack':
|
|
@@ -686,6 +1010,16 @@ function parseReplayTellaskSpecialCall(record) {
|
|
|
686
1010
|
return null;
|
|
687
1011
|
}
|
|
688
1012
|
}
|
|
1013
|
+
function isTellaskCallFunctionName(name) {
|
|
1014
|
+
return (name === 'tellaskBack' ||
|
|
1015
|
+
name === 'tellask' ||
|
|
1016
|
+
name === 'tellaskSessionless' ||
|
|
1017
|
+
name === 'replyTellask' ||
|
|
1018
|
+
name === 'replyTellaskSessionless' ||
|
|
1019
|
+
name === 'replyTellaskBack' ||
|
|
1020
|
+
name === 'askHuman' ||
|
|
1021
|
+
name === 'freshBootsReasoning');
|
|
1022
|
+
}
|
|
689
1023
|
/**
|
|
690
1024
|
* Uses append-only pattern for events, exceptional overwrite for reminders
|
|
691
1025
|
*/
|
|
@@ -844,455 +1178,54 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
844
1178
|
if (!Number.isFinite(genseq) || genseq <= 0) {
|
|
845
1179
|
throw new Error(`receiveFuncResult invariant violation: missing valid genseq for func result ${funcResult.id}`);
|
|
846
1180
|
}
|
|
847
|
-
|
|
848
|
-
const funcResultRecord = {
|
|
849
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
850
|
-
type: 'func_result_record',
|
|
851
|
-
id: funcResult.id,
|
|
852
|
-
name: funcResult.name,
|
|
853
|
-
content: funcResult.content,
|
|
854
|
-
contentItems: funcResult.contentItems,
|
|
855
|
-
genseq,
|
|
856
|
-
};
|
|
1181
|
+
const funcResultRecord = buildFuncResultRecord(funcResult, genseq);
|
|
857
1182
|
await this.appendEvent(dialog, course, funcResultRecord);
|
|
858
1183
|
// Send event to frontend
|
|
859
|
-
|
|
860
|
-
type: 'func_result_evt',
|
|
861
|
-
id: funcResult.id,
|
|
1184
|
+
if (!isSuppressedTellaskPlaceholderFuncResult({
|
|
862
1185
|
name: funcResult.name,
|
|
863
1186
|
content: funcResult.content,
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1187
|
+
})) {
|
|
1188
|
+
const funcResultEvt = {
|
|
1189
|
+
type: 'func_result_evt',
|
|
1190
|
+
id: funcResult.id,
|
|
1191
|
+
name: funcResult.name,
|
|
1192
|
+
content: funcResult.content,
|
|
1193
|
+
contentItems: funcResult.contentItems,
|
|
1194
|
+
course,
|
|
1195
|
+
};
|
|
1196
|
+
(0, evt_registry_1.postDialogEvent)(dialog, funcResultEvt);
|
|
1197
|
+
}
|
|
868
1198
|
}
|
|
869
|
-
|
|
870
|
-
* Receive and handle tellask call results with callId for inline result display
|
|
871
|
-
*
|
|
872
|
-
* Call Types:
|
|
873
|
-
* - tellask-special function call (inline bubble)
|
|
874
|
-
* - Result displays INLINE in the same bubble
|
|
875
|
-
* - Uses callId for correlation between call_start and response
|
|
876
|
-
* - Uses receiveTellaskCallResult() + callId parameter
|
|
877
|
-
*
|
|
878
|
-
* - Tellask sideline response (subdialog response bubble)
|
|
879
|
-
* - Result displays in SEPARATE bubble (subdialog response)
|
|
880
|
-
* - Uses calleeDialogId for correlation
|
|
881
|
-
* - Uses receiveTellaskResponse() instead
|
|
882
|
-
*
|
|
883
|
-
* @param dialog - The dialog receiving the response
|
|
884
|
-
* @param responderId - ID of the tool/agent that responded (e.g., "add_reminder")
|
|
885
|
-
* @param mentionList - Mention list of the original call
|
|
886
|
-
* @param tellaskContent - Tellask content of the original call
|
|
887
|
-
* @param result - The result content to display
|
|
888
|
-
* @param status - Response status ('completed' | 'failed')
|
|
889
|
-
* @param callId - Correlation ID from call_start_evt (REQUIRED for inline display)
|
|
890
|
-
*/
|
|
891
|
-
async receiveTellaskCallResult(dialog, responderId, callName, mentionList, tellaskContent, result, status, callId) {
|
|
1199
|
+
async receiveTellaskResult(dialog, result) {
|
|
892
1200
|
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
893
|
-
const
|
|
894
|
-
|
|
895
|
-
:
|
|
896
|
-
// Persist record WITH callId for replay correlation
|
|
897
|
-
const ev = (() => {
|
|
898
|
-
switch (callName) {
|
|
899
|
-
case 'tellask':
|
|
900
|
-
case 'tellaskSessionless':
|
|
901
|
-
return {
|
|
902
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
903
|
-
type: 'tellask_call_result_record',
|
|
904
|
-
responderId,
|
|
905
|
-
callName,
|
|
906
|
-
mentionList: mentionList ?? [],
|
|
907
|
-
tellaskContent,
|
|
908
|
-
status,
|
|
909
|
-
result,
|
|
910
|
-
calling_genseq,
|
|
911
|
-
callId,
|
|
912
|
-
};
|
|
913
|
-
case 'tellaskBack':
|
|
914
|
-
case 'askHuman':
|
|
915
|
-
case 'freshBootsReasoning':
|
|
916
|
-
return {
|
|
917
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
918
|
-
type: 'tellask_call_result_record',
|
|
919
|
-
responderId,
|
|
920
|
-
callName,
|
|
921
|
-
tellaskContent,
|
|
922
|
-
status,
|
|
923
|
-
result,
|
|
924
|
-
calling_genseq,
|
|
925
|
-
callId,
|
|
926
|
-
};
|
|
927
|
-
}
|
|
928
|
-
})();
|
|
929
|
-
await this.appendEvent(dialog, course, ev);
|
|
930
|
-
// Emit TellaskCallResultEvent WITH callId for UI correlation
|
|
931
|
-
const toolResponseEvt = (() => {
|
|
932
|
-
switch (callName) {
|
|
933
|
-
case 'tellask':
|
|
934
|
-
case 'tellaskSessionless':
|
|
935
|
-
return {
|
|
936
|
-
type: 'tellask_call_result_evt',
|
|
937
|
-
responderId,
|
|
938
|
-
callName,
|
|
939
|
-
mentionList: mentionList ?? [],
|
|
940
|
-
tellaskContent,
|
|
941
|
-
status,
|
|
942
|
-
result,
|
|
943
|
-
course,
|
|
944
|
-
calling_genseq,
|
|
945
|
-
callId,
|
|
946
|
-
};
|
|
947
|
-
case 'tellaskBack':
|
|
948
|
-
case 'askHuman':
|
|
949
|
-
case 'freshBootsReasoning':
|
|
950
|
-
return {
|
|
951
|
-
type: 'tellask_call_result_evt',
|
|
952
|
-
responderId,
|
|
953
|
-
callName,
|
|
954
|
-
tellaskContent,
|
|
955
|
-
status,
|
|
956
|
-
result,
|
|
957
|
-
course,
|
|
958
|
-
calling_genseq,
|
|
959
|
-
callId,
|
|
960
|
-
};
|
|
961
|
-
}
|
|
962
|
-
})();
|
|
963
|
-
(0, evt_registry_1.postDialogEvent)(dialog, toolResponseEvt);
|
|
964
|
-
}
|
|
965
|
-
/**
|
|
966
|
-
* Receive and handle tellask responses (separate bubble for subdialog/supdialog replies)
|
|
967
|
-
*
|
|
968
|
-
* Call Types:
|
|
969
|
-
* - Tellask sideline response
|
|
970
|
-
* - Result displays in SEPARATE bubble (subdialog or supdialog response)
|
|
971
|
-
* - Uses calleeDialogId for correlation (not callId)
|
|
972
|
-
* - Uses this method (receiveTellaskResponse)
|
|
973
|
-
*
|
|
974
|
-
* @param dialog - The dialog receiving the response
|
|
975
|
-
* @param responderId - ID of the responder agent (e.g., "coder")
|
|
976
|
-
* @param mentionList - Mention list of the original tellask
|
|
977
|
-
* @param tellaskContent - Tellask content of the original tellask
|
|
978
|
-
* @param status - Response status ('completed' | 'failed')
|
|
979
|
-
* @param calleeDialogId - ID of the callee dialog (subdialog OR supdialog) for navigation links
|
|
980
|
-
*/
|
|
981
|
-
async receiveTellaskResponse(dialog, responderId, callName, mentionList, tellaskContent, status, calleeDialogId, options) {
|
|
982
|
-
const currentCourse = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
983
|
-
const calling_genseq = dialog.activeGenSeqOrUndefined !== undefined
|
|
984
|
-
? (0, storage_1.toCallingGenerationSeqNumber)(dialog.activeGenSeqOrUndefined)
|
|
985
|
-
: undefined;
|
|
986
|
-
const calleeDialogSelfId = calleeDialogId ? calleeDialogId.selfId : undefined;
|
|
987
|
-
const response = options.response;
|
|
988
|
-
const agentId = options.agentId;
|
|
989
|
-
const callId = options.callId;
|
|
990
|
-
const originMemberId = options.originMemberId;
|
|
991
|
-
const originCourse = options.originCourse;
|
|
992
|
-
const carryoverContent = options.carryoverContent;
|
|
993
|
-
const carryoverText = typeof carryoverContent === 'string' && carryoverContent.trim() !== ''
|
|
994
|
-
? carryoverContent
|
|
995
|
-
: undefined;
|
|
996
|
-
const sessionSlug = typeof options.sessionSlug === 'string' && options.sessionSlug.trim() !== ''
|
|
997
|
-
? options.sessionSlug.trim()
|
|
998
|
-
: undefined;
|
|
999
|
-
const calleeCourse = options.calleeCourse;
|
|
1000
|
-
const calleeGenseq = options.calleeGenseq;
|
|
1001
|
-
const normalizedMentionList = mentionList ?? [];
|
|
1002
|
-
const isCrossCourseCarryover = originCourse !== undefined && originCourse !== currentCourse;
|
|
1003
|
-
if (!isCrossCourseCarryover) {
|
|
1004
|
-
const responseCourse = originCourse ?? currentCourse;
|
|
1005
|
-
const ev = (() => {
|
|
1006
|
-
switch (callName) {
|
|
1007
|
-
case 'tellask':
|
|
1008
|
-
if (!sessionSlug) {
|
|
1009
|
-
throw new Error(`receiveTellaskResponse invariant violation: missing sessionSlug for tellask ` +
|
|
1010
|
-
`(dialogId=${dialog.id.selfId}, callId=${callId})`);
|
|
1011
|
-
}
|
|
1012
|
-
return {
|
|
1013
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1014
|
-
type: 'tellask_response_record',
|
|
1015
|
-
responderId,
|
|
1016
|
-
callName,
|
|
1017
|
-
sessionSlug,
|
|
1018
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1019
|
-
calleeCourse,
|
|
1020
|
-
calleeGenseq,
|
|
1021
|
-
mentionList: normalizedMentionList,
|
|
1022
|
-
tellaskContent,
|
|
1023
|
-
status,
|
|
1024
|
-
calling_genseq,
|
|
1025
|
-
response,
|
|
1026
|
-
agentId,
|
|
1027
|
-
callId,
|
|
1028
|
-
originMemberId,
|
|
1029
|
-
};
|
|
1030
|
-
case 'tellaskSessionless':
|
|
1031
|
-
return {
|
|
1032
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1033
|
-
type: 'tellask_response_record',
|
|
1034
|
-
responderId,
|
|
1035
|
-
callName,
|
|
1036
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1037
|
-
calleeCourse,
|
|
1038
|
-
calleeGenseq,
|
|
1039
|
-
mentionList: normalizedMentionList,
|
|
1040
|
-
tellaskContent,
|
|
1041
|
-
status,
|
|
1042
|
-
calling_genseq,
|
|
1043
|
-
response,
|
|
1044
|
-
agentId,
|
|
1045
|
-
callId,
|
|
1046
|
-
originMemberId,
|
|
1047
|
-
};
|
|
1048
|
-
case 'tellaskBack':
|
|
1049
|
-
case 'freshBootsReasoning':
|
|
1050
|
-
return {
|
|
1051
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1052
|
-
type: 'tellask_response_record',
|
|
1053
|
-
responderId,
|
|
1054
|
-
callName,
|
|
1055
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1056
|
-
calleeCourse,
|
|
1057
|
-
calleeGenseq,
|
|
1058
|
-
tellaskContent,
|
|
1059
|
-
status,
|
|
1060
|
-
calling_genseq,
|
|
1061
|
-
response,
|
|
1062
|
-
agentId,
|
|
1063
|
-
callId,
|
|
1064
|
-
originMemberId,
|
|
1065
|
-
};
|
|
1066
|
-
}
|
|
1067
|
-
})();
|
|
1068
|
-
await this.appendEvent(dialog, responseCourse, ev);
|
|
1069
|
-
const tellaskResponseEvt = (() => {
|
|
1070
|
-
switch (callName) {
|
|
1071
|
-
case 'tellask':
|
|
1072
|
-
if (!sessionSlug) {
|
|
1073
|
-
throw new Error(`receiveTellaskResponse invariant violation: missing sessionSlug for tellask ` +
|
|
1074
|
-
`(dialogId=${dialog.id.selfId}, callId=${callId})`);
|
|
1075
|
-
}
|
|
1076
|
-
return {
|
|
1077
|
-
type: 'tellask_response_evt',
|
|
1078
|
-
responderId,
|
|
1079
|
-
callName,
|
|
1080
|
-
sessionSlug,
|
|
1081
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1082
|
-
calleeCourse,
|
|
1083
|
-
calleeGenseq,
|
|
1084
|
-
mentionList: normalizedMentionList,
|
|
1085
|
-
tellaskContent,
|
|
1086
|
-
status,
|
|
1087
|
-
course: responseCourse,
|
|
1088
|
-
calling_genseq,
|
|
1089
|
-
response,
|
|
1090
|
-
agentId,
|
|
1091
|
-
callId,
|
|
1092
|
-
originMemberId,
|
|
1093
|
-
};
|
|
1094
|
-
case 'tellaskSessionless':
|
|
1095
|
-
return {
|
|
1096
|
-
type: 'tellask_response_evt',
|
|
1097
|
-
responderId,
|
|
1098
|
-
callName,
|
|
1099
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1100
|
-
calleeCourse,
|
|
1101
|
-
calleeGenseq,
|
|
1102
|
-
mentionList: normalizedMentionList,
|
|
1103
|
-
tellaskContent,
|
|
1104
|
-
status,
|
|
1105
|
-
course: responseCourse,
|
|
1106
|
-
calling_genseq,
|
|
1107
|
-
response,
|
|
1108
|
-
agentId,
|
|
1109
|
-
callId,
|
|
1110
|
-
originMemberId,
|
|
1111
|
-
};
|
|
1112
|
-
case 'tellaskBack':
|
|
1113
|
-
case 'freshBootsReasoning':
|
|
1114
|
-
return {
|
|
1115
|
-
type: 'tellask_response_evt',
|
|
1116
|
-
responderId,
|
|
1117
|
-
callName,
|
|
1118
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1119
|
-
calleeCourse,
|
|
1120
|
-
calleeGenseq,
|
|
1121
|
-
tellaskContent,
|
|
1122
|
-
status,
|
|
1123
|
-
course: responseCourse,
|
|
1124
|
-
calling_genseq,
|
|
1125
|
-
response,
|
|
1126
|
-
agentId,
|
|
1127
|
-
callId,
|
|
1128
|
-
originMemberId,
|
|
1129
|
-
};
|
|
1130
|
-
}
|
|
1131
|
-
})();
|
|
1132
|
-
(0, evt_registry_1.postDialogEvent)(dialog, tellaskResponseEvt);
|
|
1133
|
-
return;
|
|
1134
|
-
}
|
|
1135
|
-
if (!originCourse) {
|
|
1136
|
-
throw new Error(`receiveTellaskResponse invariant violation: missing originCourse for cross-course carryover ` +
|
|
1137
|
-
`(dialogId=${dialog.id.selfId}, callId=${callId}, currentCourse=${currentCourse})`);
|
|
1138
|
-
}
|
|
1139
|
-
if (callName === 'tellaskBack') {
|
|
1140
|
-
throw new Error(`tellask carryover does not support tellaskBack (dialogId=${dialog.id.selfId}, callId=${callId})`);
|
|
1201
|
+
const genseq = dialog.activeGenSeqOrUndefined ?? result.genseq;
|
|
1202
|
+
if (!Number.isFinite(genseq) || genseq <= 0) {
|
|
1203
|
+
throw new Error(`receiveTellaskResult invariant violation: missing valid genseq for tellask result ${result.callId}`);
|
|
1141
1204
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1205
|
+
const normalizedResult = genseq === result.genseq
|
|
1206
|
+
? result
|
|
1207
|
+
: {
|
|
1208
|
+
...result,
|
|
1209
|
+
genseq,
|
|
1210
|
+
};
|
|
1211
|
+
const record = buildTellaskResultRecord(normalizedResult, genseq);
|
|
1212
|
+
await this.appendEvent(dialog, course, record);
|
|
1213
|
+
(0, evt_registry_1.postDialogEvent)(dialog, buildTellaskResultEvent(normalizedResult, course));
|
|
1214
|
+
}
|
|
1215
|
+
async receiveTellaskCarryover(dialog, result) {
|
|
1216
|
+
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
1217
|
+
const genseq = dialog.activeGenSeqOrUndefined ?? result.genseq;
|
|
1218
|
+
if (!Number.isFinite(genseq) || genseq <= 0) {
|
|
1219
|
+
throw new Error(`receiveTellaskCarryover invariant violation: missing valid genseq for tellask carryover ${result.callId}`);
|
|
1145
1220
|
}
|
|
1146
|
-
const
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
await this.appendEvent(dialog, originCourse, carryoverCallRecord);
|
|
1155
|
-
const carryoverCallEvent = {
|
|
1156
|
-
type: 'tellask_call_carryover_evt',
|
|
1157
|
-
course: originCourse,
|
|
1158
|
-
responderId,
|
|
1159
|
-
status,
|
|
1160
|
-
callId,
|
|
1161
|
-
carryoverCourse: (0, storage_1.toDialogCourseNumber)(currentCourse),
|
|
1162
|
-
};
|
|
1163
|
-
(0, evt_registry_1.postDialogEvent)(dialog, carryoverCallEvent);
|
|
1164
|
-
const carryoverRecord = (() => {
|
|
1165
|
-
switch (callName) {
|
|
1166
|
-
case 'tellask':
|
|
1167
|
-
if (!sessionSlug) {
|
|
1168
|
-
throw new Error(`receiveTellaskResponse invariant violation: missing sessionSlug for tellask carryover ` +
|
|
1169
|
-
`(dialogId=${dialog.id.selfId}, callId=${callId})`);
|
|
1170
|
-
}
|
|
1171
|
-
return {
|
|
1172
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1173
|
-
type: 'tellask_carryover_result_record',
|
|
1174
|
-
originCourse,
|
|
1175
|
-
responderId,
|
|
1176
|
-
callName,
|
|
1177
|
-
sessionSlug,
|
|
1178
|
-
mentionList: normalizedMentionList,
|
|
1179
|
-
tellaskContent,
|
|
1180
|
-
status,
|
|
1181
|
-
response,
|
|
1182
|
-
content: carryoverText,
|
|
1183
|
-
agentId,
|
|
1184
|
-
callId,
|
|
1185
|
-
originMemberId,
|
|
1186
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1187
|
-
calleeCourse,
|
|
1188
|
-
calleeGenseq,
|
|
1189
|
-
};
|
|
1190
|
-
case 'tellaskSessionless':
|
|
1191
|
-
return {
|
|
1192
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1193
|
-
type: 'tellask_carryover_result_record',
|
|
1194
|
-
originCourse,
|
|
1195
|
-
responderId,
|
|
1196
|
-
callName,
|
|
1197
|
-
mentionList: normalizedMentionList,
|
|
1198
|
-
tellaskContent,
|
|
1199
|
-
status,
|
|
1200
|
-
response,
|
|
1201
|
-
content: carryoverText,
|
|
1202
|
-
agentId,
|
|
1203
|
-
callId,
|
|
1204
|
-
originMemberId,
|
|
1205
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1206
|
-
calleeCourse,
|
|
1207
|
-
calleeGenseq,
|
|
1208
|
-
};
|
|
1209
|
-
case 'freshBootsReasoning':
|
|
1210
|
-
return {
|
|
1211
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1212
|
-
type: 'tellask_carryover_result_record',
|
|
1213
|
-
originCourse,
|
|
1214
|
-
responderId,
|
|
1215
|
-
callName,
|
|
1216
|
-
tellaskContent,
|
|
1217
|
-
status,
|
|
1218
|
-
response,
|
|
1219
|
-
content: carryoverText,
|
|
1220
|
-
agentId,
|
|
1221
|
-
callId,
|
|
1222
|
-
originMemberId,
|
|
1223
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1224
|
-
calleeCourse,
|
|
1225
|
-
calleeGenseq,
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
})();
|
|
1229
|
-
await this.appendEvent(dialog, currentCourse, carryoverRecord);
|
|
1230
|
-
const carryoverEvent = (() => {
|
|
1231
|
-
switch (callName) {
|
|
1232
|
-
case 'tellask':
|
|
1233
|
-
if (!sessionSlug) {
|
|
1234
|
-
throw new Error(`receiveTellaskResponse invariant violation: missing sessionSlug for tellask carryover evt ` +
|
|
1235
|
-
`(dialogId=${dialog.id.selfId}, callId=${callId})`);
|
|
1236
|
-
}
|
|
1237
|
-
return {
|
|
1238
|
-
type: 'tellask_carryover_result_evt',
|
|
1239
|
-
course: currentCourse,
|
|
1240
|
-
originCourse,
|
|
1241
|
-
responderId,
|
|
1242
|
-
callName,
|
|
1243
|
-
sessionSlug,
|
|
1244
|
-
mentionList: normalizedMentionList,
|
|
1245
|
-
tellaskContent,
|
|
1246
|
-
status,
|
|
1247
|
-
response,
|
|
1248
|
-
content: carryoverText,
|
|
1249
|
-
agentId,
|
|
1250
|
-
callId,
|
|
1251
|
-
originMemberId,
|
|
1252
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1253
|
-
calleeCourse,
|
|
1254
|
-
calleeGenseq,
|
|
1255
|
-
};
|
|
1256
|
-
case 'tellaskSessionless':
|
|
1257
|
-
return {
|
|
1258
|
-
type: 'tellask_carryover_result_evt',
|
|
1259
|
-
course: currentCourse,
|
|
1260
|
-
originCourse,
|
|
1261
|
-
responderId,
|
|
1262
|
-
callName,
|
|
1263
|
-
mentionList: normalizedMentionList,
|
|
1264
|
-
tellaskContent,
|
|
1265
|
-
status,
|
|
1266
|
-
response,
|
|
1267
|
-
content: carryoverText,
|
|
1268
|
-
agentId,
|
|
1269
|
-
callId,
|
|
1270
|
-
originMemberId,
|
|
1271
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1272
|
-
calleeCourse,
|
|
1273
|
-
calleeGenseq,
|
|
1274
|
-
};
|
|
1275
|
-
case 'freshBootsReasoning':
|
|
1276
|
-
return {
|
|
1277
|
-
type: 'tellask_carryover_result_evt',
|
|
1278
|
-
course: currentCourse,
|
|
1279
|
-
originCourse,
|
|
1280
|
-
responderId,
|
|
1281
|
-
callName,
|
|
1282
|
-
tellaskContent,
|
|
1283
|
-
status,
|
|
1284
|
-
response,
|
|
1285
|
-
content: carryoverText,
|
|
1286
|
-
agentId,
|
|
1287
|
-
callId,
|
|
1288
|
-
originMemberId,
|
|
1289
|
-
calleeDialogId: calleeDialogSelfId,
|
|
1290
|
-
calleeCourse,
|
|
1291
|
-
calleeGenseq,
|
|
1292
|
-
};
|
|
1293
|
-
}
|
|
1294
|
-
})();
|
|
1295
|
-
(0, evt_registry_1.postDialogEvent)(dialog, carryoverEvent);
|
|
1221
|
+
const normalizedResult = genseq === result.genseq
|
|
1222
|
+
? result
|
|
1223
|
+
: {
|
|
1224
|
+
...result,
|
|
1225
|
+
genseq,
|
|
1226
|
+
};
|
|
1227
|
+
await this.appendEvent(dialog, course, buildTellaskCarryoverRecord(normalizedResult, genseq));
|
|
1228
|
+
(0, evt_registry_1.postDialogEvent)(dialog, buildTellaskCarryoverEvent(normalizedResult, course));
|
|
1296
1229
|
}
|
|
1297
1230
|
/**
|
|
1298
1231
|
* Ensure subdialog directory exists (delegate to DialogPersistence)
|
|
@@ -1306,6 +1239,9 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1306
1239
|
async appendEvent(dialog, course, event) {
|
|
1307
1240
|
await DialogPersistence.appendEvent(this.dialogId, course, attachRootGenerationRef(dialog, event));
|
|
1308
1241
|
}
|
|
1242
|
+
async appendEvents(dialog, course, events) {
|
|
1243
|
+
await DialogPersistence.appendEvents(this.dialogId, course, events.map((event) => attachRootGenerationRef(dialog, event)));
|
|
1244
|
+
}
|
|
1309
1245
|
/**
|
|
1310
1246
|
* Notify start of LLM generation for frontend bubble management
|
|
1311
1247
|
* CRITICAL: This must be called BEFORE any substream events (thinking_start, markdown_start, etc.)
|
|
@@ -1573,6 +1509,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1573
1509
|
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1574
1510
|
type: 'web_search_call_record',
|
|
1575
1511
|
genseq: dialog.activeGenSeq,
|
|
1512
|
+
source: payload.source,
|
|
1576
1513
|
phase: payload.phase,
|
|
1577
1514
|
itemId,
|
|
1578
1515
|
status: payload.status,
|
|
@@ -1583,6 +1520,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1583
1520
|
type: 'web_search_call_evt',
|
|
1584
1521
|
course,
|
|
1585
1522
|
genseq: dialog.activeGenSeq,
|
|
1523
|
+
source: payload.source,
|
|
1586
1524
|
phase: payload.phase,
|
|
1587
1525
|
itemId,
|
|
1588
1526
|
status: payload.status,
|
|
@@ -1590,6 +1528,111 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1590
1528
|
};
|
|
1591
1529
|
(0, evt_registry_1.postDialogEvent)(dialog, evt);
|
|
1592
1530
|
}
|
|
1531
|
+
async nativeToolCall(dialog, payload) {
|
|
1532
|
+
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
1533
|
+
const itemId = 'itemId' in payload && typeof payload.itemId === 'string' ? payload.itemId.trim() : undefined;
|
|
1534
|
+
let record;
|
|
1535
|
+
let evt;
|
|
1536
|
+
if (payload.itemType === 'custom_tool_call') {
|
|
1537
|
+
const callId = payload.callId.trim();
|
|
1538
|
+
if (callId === '') {
|
|
1539
|
+
log_1.log.error('Protocol violation: custom nativeToolCall called without callId; dropping event', new Error('native_tool_call_empty_call_id'), {
|
|
1540
|
+
dialog,
|
|
1541
|
+
itemType: payload.itemType,
|
|
1542
|
+
phase: payload.phase,
|
|
1543
|
+
itemId: payload.itemId,
|
|
1544
|
+
status: payload.status,
|
|
1545
|
+
});
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
if (itemId !== undefined && itemId === '') {
|
|
1549
|
+
log_1.log.error('Protocol violation: custom nativeToolCall called with empty optional itemId; dropping event', new Error('native_tool_call_empty_optional_item_id'), {
|
|
1550
|
+
dialog,
|
|
1551
|
+
itemType: payload.itemType,
|
|
1552
|
+
phase: payload.phase,
|
|
1553
|
+
callId,
|
|
1554
|
+
status: payload.status,
|
|
1555
|
+
});
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
record = {
|
|
1559
|
+
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1560
|
+
type: 'native_tool_call_record',
|
|
1561
|
+
genseq: dialog.activeGenSeq,
|
|
1562
|
+
source: payload.source,
|
|
1563
|
+
itemType: payload.itemType,
|
|
1564
|
+
phase: payload.phase,
|
|
1565
|
+
callId,
|
|
1566
|
+
...(itemId !== undefined && itemId !== '' ? { itemId } : {}),
|
|
1567
|
+
status: payload.status,
|
|
1568
|
+
title: payload.title,
|
|
1569
|
+
summary: payload.summary,
|
|
1570
|
+
detail: payload.detail,
|
|
1571
|
+
};
|
|
1572
|
+
evt = {
|
|
1573
|
+
type: 'native_tool_call_evt',
|
|
1574
|
+
course,
|
|
1575
|
+
genseq: dialog.activeGenSeq,
|
|
1576
|
+
source: payload.source,
|
|
1577
|
+
itemType: payload.itemType,
|
|
1578
|
+
phase: payload.phase,
|
|
1579
|
+
callId,
|
|
1580
|
+
...(itemId !== undefined && itemId !== '' ? { itemId } : {}),
|
|
1581
|
+
status: payload.status,
|
|
1582
|
+
title: payload.title,
|
|
1583
|
+
summary: payload.summary,
|
|
1584
|
+
detail: payload.detail,
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
else {
|
|
1588
|
+
if ('callId' in payload) {
|
|
1589
|
+
log_1.log.error('Protocol violation: non-custom nativeToolCall called with unexpected callId; dropping event', new Error('native_tool_call_unexpected_call_id'), {
|
|
1590
|
+
dialog,
|
|
1591
|
+
itemType: payload.itemType,
|
|
1592
|
+
phase: payload.phase,
|
|
1593
|
+
status: payload.status,
|
|
1594
|
+
});
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1597
|
+
if (itemId === undefined || itemId === '') {
|
|
1598
|
+
log_1.log.error('Protocol violation: non-custom nativeToolCall called without itemId; dropping event', new Error('native_tool_call_empty_item_id'), {
|
|
1599
|
+
dialog,
|
|
1600
|
+
itemType: payload.itemType,
|
|
1601
|
+
phase: payload.phase,
|
|
1602
|
+
status: payload.status,
|
|
1603
|
+
});
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
record = {
|
|
1607
|
+
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1608
|
+
type: 'native_tool_call_record',
|
|
1609
|
+
genseq: dialog.activeGenSeq,
|
|
1610
|
+
source: payload.source,
|
|
1611
|
+
itemType: payload.itemType,
|
|
1612
|
+
phase: payload.phase,
|
|
1613
|
+
itemId,
|
|
1614
|
+
status: payload.status,
|
|
1615
|
+
title: payload.title,
|
|
1616
|
+
summary: payload.summary,
|
|
1617
|
+
detail: payload.detail,
|
|
1618
|
+
};
|
|
1619
|
+
evt = {
|
|
1620
|
+
type: 'native_tool_call_evt',
|
|
1621
|
+
course,
|
|
1622
|
+
genseq: dialog.activeGenSeq,
|
|
1623
|
+
source: payload.source,
|
|
1624
|
+
itemType: payload.itemType,
|
|
1625
|
+
phase: payload.phase,
|
|
1626
|
+
itemId,
|
|
1627
|
+
status: payload.status,
|
|
1628
|
+
title: payload.title,
|
|
1629
|
+
summary: payload.summary,
|
|
1630
|
+
detail: payload.detail,
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
await this.appendEvent(dialog, course, record);
|
|
1634
|
+
(0, evt_registry_1.postDialogEvent)(dialog, evt);
|
|
1635
|
+
}
|
|
1593
1636
|
/**
|
|
1594
1637
|
* Emit stream error for current generation lifecycle (uses active genseq when present)
|
|
1595
1638
|
*/
|
|
@@ -1641,25 +1684,15 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1641
1684
|
* Note: The end_of_user_saying_evt is emitted by the driver after user content
|
|
1642
1685
|
* is rendered and any tellask calls are parsed/executed.
|
|
1643
1686
|
*/
|
|
1644
|
-
async persistUserMessage(dialog, content, msgId, grammar, origin, userLanguageCode,
|
|
1687
|
+
async persistUserMessage(dialog, content, msgId, grammar, origin, userLanguageCode, q4hAnswerCallId, tellaskReplyDirective) {
|
|
1645
1688
|
const course = dialog.currentCourse;
|
|
1646
1689
|
// Use activeGenSeqOrUndefined to handle case when genseq hasn't been initialized yet
|
|
1647
1690
|
const genseq = dialog.activeGenSeqOrUndefined ?? 1;
|
|
1648
|
-
const
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
const normalized = [];
|
|
1654
|
-
for (const raw of q4hAnswerCallIds) {
|
|
1655
|
-
const callId = raw.trim();
|
|
1656
|
-
if (callId === '' || seen.has(callId))
|
|
1657
|
-
continue;
|
|
1658
|
-
seen.add(callId);
|
|
1659
|
-
normalized.push(callId);
|
|
1660
|
-
}
|
|
1661
|
-
return normalized.length > 0 ? normalized : undefined;
|
|
1662
|
-
})();
|
|
1691
|
+
const normalizedQ4HAnswerCallId = typeof q4hAnswerCallId === 'string' && q4hAnswerCallId.trim() !== ''
|
|
1692
|
+
? q4hAnswerCallId.trim()
|
|
1693
|
+
: undefined;
|
|
1694
|
+
// `q4hAnswerCallId` marks continuation glue for a resumed round after askHuman is answered.
|
|
1695
|
+
// The canonical answer fact is persisted separately in tellask result/carryover records.
|
|
1663
1696
|
const humanEv = {
|
|
1664
1697
|
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1665
1698
|
type: 'human_text_record',
|
|
@@ -1669,7 +1702,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1669
1702
|
grammar,
|
|
1670
1703
|
origin,
|
|
1671
1704
|
userLanguageCode,
|
|
1672
|
-
|
|
1705
|
+
q4hAnswerCallId: normalizedQ4HAnswerCallId,
|
|
1673
1706
|
tellaskReplyDirective,
|
|
1674
1707
|
};
|
|
1675
1708
|
await this.appendEvent(dialog, course, humanEv);
|
|
@@ -1737,29 +1770,100 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
1737
1770
|
/**
|
|
1738
1771
|
* Persist a function call to storage
|
|
1739
1772
|
*/
|
|
1740
|
-
async persistFunctionCall(dialog, id, name,
|
|
1773
|
+
async persistFunctionCall(dialog, id, name, rawArgumentsText, genseq) {
|
|
1741
1774
|
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
1742
|
-
const funcCallEvent = {
|
|
1743
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
1744
|
-
type: 'func_call_record',
|
|
1745
|
-
genseq,
|
|
1746
|
-
id,
|
|
1747
|
-
name,
|
|
1748
|
-
arguments: arguments_,
|
|
1749
|
-
};
|
|
1775
|
+
const funcCallEvent = buildFuncCallRecord({ id, name, rawArgumentsText, genseq });
|
|
1750
1776
|
await this.appendEvent(dialog, course, funcCallEvent);
|
|
1751
1777
|
// NOTE: func_call_evt REMOVED - persistence uses FuncCallRecord directly
|
|
1752
1778
|
// UI display uses func_call_requested_evt instead
|
|
1753
1779
|
}
|
|
1754
|
-
async
|
|
1780
|
+
async persistTellaskCall(dialog, id, name, rawArgumentsText, genseq, options) {
|
|
1755
1781
|
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
1756
|
-
const tellaskCallEvent =
|
|
1782
|
+
const tellaskCallEvent = buildTellaskCallRecord({
|
|
1757
1783
|
id,
|
|
1758
1784
|
name,
|
|
1759
|
-
|
|
1785
|
+
rawArgumentsText,
|
|
1760
1786
|
genseq,
|
|
1787
|
+
deliveryMode: options?.deliveryMode ??
|
|
1788
|
+
(isReplyTellaskCallRecordName(name) ? 'func_call_requested' : 'tellask_call_start'),
|
|
1789
|
+
});
|
|
1790
|
+
await this.appendEvent(dialog, course, tellaskCallEvent);
|
|
1791
|
+
if (isReplyTellaskCallRecordName(name)) {
|
|
1792
|
+
const funcCallEvt = {
|
|
1793
|
+
type: 'func_call_requested_evt',
|
|
1794
|
+
funcId: id,
|
|
1795
|
+
funcName: name,
|
|
1796
|
+
arguments: formatTellaskCallArguments(tellaskCallEvent),
|
|
1797
|
+
course,
|
|
1798
|
+
genseq: dialog.activeGenSeqOrUndefined ?? genseq,
|
|
1799
|
+
};
|
|
1800
|
+
(0, evt_registry_1.postDialogEvent)(dialog, funcCallEvt);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
async persistFunctionCallResultPair(dialog, id, name, rawArgumentsText, genseq, result) {
|
|
1804
|
+
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
1805
|
+
const resultGenseq = dialog.activeGenSeqOrUndefined ?? result.genseq;
|
|
1806
|
+
if (!Number.isFinite(resultGenseq) || resultGenseq <= 0) {
|
|
1807
|
+
throw new Error(`persistFunctionCallResultPair invariant violation: missing valid genseq for func result ${result.id}`);
|
|
1808
|
+
}
|
|
1809
|
+
await this.appendEvents(dialog, course, [
|
|
1810
|
+
buildFuncCallRecord({ id, name, rawArgumentsText, genseq }),
|
|
1811
|
+
buildFuncResultRecord(result, resultGenseq),
|
|
1812
|
+
]);
|
|
1813
|
+
if (!isSuppressedTellaskPlaceholderFuncResult({
|
|
1814
|
+
name: result.name,
|
|
1815
|
+
content: result.content,
|
|
1816
|
+
})) {
|
|
1817
|
+
const funcResultEvt = {
|
|
1818
|
+
type: 'func_result_evt',
|
|
1819
|
+
id: result.id,
|
|
1820
|
+
name: result.name,
|
|
1821
|
+
content: result.content,
|
|
1822
|
+
contentItems: result.contentItems,
|
|
1823
|
+
course,
|
|
1824
|
+
};
|
|
1825
|
+
(0, evt_registry_1.postDialogEvent)(dialog, funcResultEvt);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
async persistTellaskCallResultPair(dialog, args) {
|
|
1829
|
+
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
1830
|
+
const resultGenseq = dialog.activeGenSeqOrUndefined ?? args.result.genseq;
|
|
1831
|
+
if (!Number.isFinite(resultGenseq) || resultGenseq <= 0) {
|
|
1832
|
+
throw new Error(`persistTellaskCallResultPair invariant violation: missing valid genseq for tellask result ${args.result.type === 'func_result_msg' ? args.result.id : args.result.callId}`);
|
|
1833
|
+
}
|
|
1834
|
+
const callRecord = buildTellaskCallRecord({
|
|
1835
|
+
id: args.id,
|
|
1836
|
+
name: args.name,
|
|
1837
|
+
rawArgumentsText: args.rawArgumentsText,
|
|
1838
|
+
genseq: args.genseq,
|
|
1839
|
+
deliveryMode: args.deliveryMode,
|
|
1761
1840
|
});
|
|
1762
|
-
|
|
1841
|
+
if (args.result.type === 'func_result_msg') {
|
|
1842
|
+
await this.appendEvents(dialog, course, [
|
|
1843
|
+
callRecord,
|
|
1844
|
+
buildFuncResultRecord(args.result, resultGenseq),
|
|
1845
|
+
]);
|
|
1846
|
+
if (!isSuppressedTellaskPlaceholderFuncResult({
|
|
1847
|
+
name: args.result.name,
|
|
1848
|
+
content: args.result.content,
|
|
1849
|
+
})) {
|
|
1850
|
+
const funcResultEvt = {
|
|
1851
|
+
type: 'func_result_evt',
|
|
1852
|
+
id: args.result.id,
|
|
1853
|
+
name: args.result.name,
|
|
1854
|
+
content: args.result.content,
|
|
1855
|
+
contentItems: args.result.contentItems,
|
|
1856
|
+
course,
|
|
1857
|
+
};
|
|
1858
|
+
(0, evt_registry_1.postDialogEvent)(dialog, funcResultEvt);
|
|
1859
|
+
}
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
await this.appendEvents(dialog, course, [
|
|
1863
|
+
callRecord,
|
|
1864
|
+
buildTellaskResultRecord(args.result, resultGenseq),
|
|
1865
|
+
]);
|
|
1866
|
+
(0, evt_registry_1.postDialogEvent)(dialog, buildTellaskResultEvent(args.result, course));
|
|
1763
1867
|
}
|
|
1764
1868
|
/**
|
|
1765
1869
|
* Update questions for human state (exceptional overwrite pattern)
|
|
@@ -2034,6 +2138,12 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2034
2138
|
}
|
|
2035
2139
|
switch (event.type) {
|
|
2036
2140
|
case 'human_text_record': {
|
|
2141
|
+
if (typeof event.q4hAnswerCallId === 'string' && event.q4hAnswerCallId.trim() !== '') {
|
|
2142
|
+
// Q4H-annotated human_text_record is a technical continuation marker for a resumed drive.
|
|
2143
|
+
// The canonical answer fact already exists in tellask result/carryover records, so UI
|
|
2144
|
+
// replay must not emit it as another user prompt bubble.
|
|
2145
|
+
break;
|
|
2146
|
+
}
|
|
2037
2147
|
const genseq = event.genseq;
|
|
2038
2148
|
const content = event.content || '';
|
|
2039
2149
|
const grammar = 'markdown';
|
|
@@ -2093,7 +2203,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2093
2203
|
grammar,
|
|
2094
2204
|
origin,
|
|
2095
2205
|
userLanguageCode,
|
|
2096
|
-
|
|
2206
|
+
q4hAnswerCallId: event.q4hAnswerCallId,
|
|
2097
2207
|
dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
|
|
2098
2208
|
timestamp: event.ts,
|
|
2099
2209
|
}));
|
|
@@ -2264,28 +2374,16 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2264
2374
|
const content = event.content || '';
|
|
2265
2375
|
if (!content.trim())
|
|
2266
2376
|
break;
|
|
2267
|
-
const dialogIdent = { selfId: dialog.id.selfId, rootId: dialog.id.rootId };
|
|
2268
2377
|
if (ws.readyState === 1) {
|
|
2269
|
-
|
|
2270
|
-
type: '
|
|
2271
|
-
course,
|
|
2272
|
-
genseq: event.genseq,
|
|
2273
|
-
dialog: dialogIdent,
|
|
2274
|
-
timestamp: event.ts,
|
|
2275
|
-
}));
|
|
2276
|
-
ws.send(JSON.stringify({
|
|
2277
|
-
type: 'markdown_chunk_evt',
|
|
2278
|
-
chunk: content,
|
|
2378
|
+
const uiOnlyMarkdownEvt = {
|
|
2379
|
+
type: 'ui_only_markdown_evt',
|
|
2279
2380
|
course,
|
|
2280
2381
|
genseq: event.genseq,
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
}));
|
|
2382
|
+
content,
|
|
2383
|
+
};
|
|
2284
2384
|
ws.send(JSON.stringify({
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
genseq: event.genseq,
|
|
2288
|
-
dialog: dialogIdent,
|
|
2385
|
+
...uiOnlyMarkdownEvt,
|
|
2386
|
+
dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
|
|
2289
2387
|
timestamp: event.ts,
|
|
2290
2388
|
}));
|
|
2291
2389
|
}
|
|
@@ -2297,7 +2395,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2297
2395
|
type: 'func_call_requested_evt',
|
|
2298
2396
|
funcId: event.id,
|
|
2299
2397
|
funcName: event.name,
|
|
2300
|
-
arguments:
|
|
2398
|
+
arguments: event.rawArgumentsText,
|
|
2301
2399
|
course,
|
|
2302
2400
|
genseq: event.genseq,
|
|
2303
2401
|
dialog: {
|
|
@@ -2311,8 +2409,27 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2311
2409
|
}
|
|
2312
2410
|
break;
|
|
2313
2411
|
}
|
|
2314
|
-
case '
|
|
2315
|
-
|
|
2412
|
+
case 'tellask_call_record': {
|
|
2413
|
+
if (event.deliveryMode === 'func_call_requested') {
|
|
2414
|
+
const replyCall = {
|
|
2415
|
+
type: 'func_call_requested_evt',
|
|
2416
|
+
funcId: event.id,
|
|
2417
|
+
funcName: event.name,
|
|
2418
|
+
arguments: formatTellaskCallArguments(event),
|
|
2419
|
+
course,
|
|
2420
|
+
genseq: event.genseq,
|
|
2421
|
+
dialog: {
|
|
2422
|
+
selfId: dialog.id.selfId,
|
|
2423
|
+
rootId: dialog.id.rootId,
|
|
2424
|
+
},
|
|
2425
|
+
timestamp: event.ts,
|
|
2426
|
+
};
|
|
2427
|
+
if (ws.readyState === 1) {
|
|
2428
|
+
ws.send(JSON.stringify(replyCall));
|
|
2429
|
+
}
|
|
2430
|
+
break;
|
|
2431
|
+
}
|
|
2432
|
+
const specialCall = parseReplayTellaskCall(event);
|
|
2316
2433
|
if (!specialCall) {
|
|
2317
2434
|
break;
|
|
2318
2435
|
}
|
|
@@ -2378,6 +2495,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2378
2495
|
}
|
|
2379
2496
|
const webSearchCall = {
|
|
2380
2497
|
type: 'web_search_call_evt',
|
|
2498
|
+
source: event.source,
|
|
2381
2499
|
phase: event.phase,
|
|
2382
2500
|
itemId,
|
|
2383
2501
|
status: event.status,
|
|
@@ -2395,7 +2513,108 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2395
2513
|
}
|
|
2396
2514
|
break;
|
|
2397
2515
|
}
|
|
2516
|
+
case 'native_tool_call_record': {
|
|
2517
|
+
let nativeToolCall;
|
|
2518
|
+
if (event.itemType === 'custom_tool_call') {
|
|
2519
|
+
const callId = typeof event.callId === 'string' ? event.callId.trim() : '';
|
|
2520
|
+
if (callId === '') {
|
|
2521
|
+
log_1.log.error('Protocol violation: persisted custom native_tool_call_record missing callId; skipping WS event', new Error('persisted_native_tool_call_record_missing_call_id'), {
|
|
2522
|
+
dialog,
|
|
2523
|
+
course,
|
|
2524
|
+
genseq: event.genseq,
|
|
2525
|
+
itemType: event.itemType,
|
|
2526
|
+
phase: event.phase,
|
|
2527
|
+
itemId: event.itemId,
|
|
2528
|
+
});
|
|
2529
|
+
break;
|
|
2530
|
+
}
|
|
2531
|
+
if (typeof event.itemId === 'string' && event.itemId.trim() === '') {
|
|
2532
|
+
log_1.log.error('Protocol violation: persisted custom native_tool_call_record carried empty optional itemId; skipping WS event', new Error('persisted_native_tool_call_record_empty_optional_item_id'), {
|
|
2533
|
+
dialog,
|
|
2534
|
+
course,
|
|
2535
|
+
genseq: event.genseq,
|
|
2536
|
+
itemType: event.itemType,
|
|
2537
|
+
phase: event.phase,
|
|
2538
|
+
callId,
|
|
2539
|
+
});
|
|
2540
|
+
break;
|
|
2541
|
+
}
|
|
2542
|
+
nativeToolCall = {
|
|
2543
|
+
type: 'native_tool_call_evt',
|
|
2544
|
+
source: event.source,
|
|
2545
|
+
itemType: event.itemType,
|
|
2546
|
+
phase: event.phase,
|
|
2547
|
+
callId,
|
|
2548
|
+
...(typeof event.itemId === 'string' && event.itemId.trim() !== ''
|
|
2549
|
+
? { itemId: event.itemId.trim() }
|
|
2550
|
+
: {}),
|
|
2551
|
+
status: event.status,
|
|
2552
|
+
title: event.title,
|
|
2553
|
+
summary: event.summary,
|
|
2554
|
+
detail: event.detail,
|
|
2555
|
+
course,
|
|
2556
|
+
genseq: event.genseq,
|
|
2557
|
+
dialog: {
|
|
2558
|
+
selfId: dialog.id.selfId,
|
|
2559
|
+
rootId: dialog.id.rootId,
|
|
2560
|
+
},
|
|
2561
|
+
timestamp: event.ts,
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2564
|
+
else {
|
|
2565
|
+
if ('callId' in event) {
|
|
2566
|
+
log_1.log.error('Protocol violation: persisted non-custom native_tool_call_record carried unexpected callId; skipping WS event', new Error('persisted_native_tool_call_record_unexpected_call_id'), {
|
|
2567
|
+
dialog,
|
|
2568
|
+
course,
|
|
2569
|
+
genseq: event.genseq,
|
|
2570
|
+
itemType: event.itemType,
|
|
2571
|
+
phase: event.phase,
|
|
2572
|
+
callId: event.callId,
|
|
2573
|
+
});
|
|
2574
|
+
break;
|
|
2575
|
+
}
|
|
2576
|
+
const itemId = typeof event.itemId === 'string' ? event.itemId.trim() : '';
|
|
2577
|
+
if (itemId === '') {
|
|
2578
|
+
log_1.log.error('Protocol violation: persisted native_tool_call_record missing itemId; skipping WS event', new Error('persisted_native_tool_call_record_missing_item_id'), {
|
|
2579
|
+
dialog,
|
|
2580
|
+
course,
|
|
2581
|
+
genseq: event.genseq,
|
|
2582
|
+
itemType: event.itemType,
|
|
2583
|
+
phase: event.phase,
|
|
2584
|
+
});
|
|
2585
|
+
break;
|
|
2586
|
+
}
|
|
2587
|
+
nativeToolCall = {
|
|
2588
|
+
type: 'native_tool_call_evt',
|
|
2589
|
+
source: event.source,
|
|
2590
|
+
itemType: event.itemType,
|
|
2591
|
+
phase: event.phase,
|
|
2592
|
+
itemId,
|
|
2593
|
+
status: event.status,
|
|
2594
|
+
title: event.title,
|
|
2595
|
+
summary: event.summary,
|
|
2596
|
+
detail: event.detail,
|
|
2597
|
+
course,
|
|
2598
|
+
genseq: event.genseq,
|
|
2599
|
+
dialog: {
|
|
2600
|
+
selfId: dialog.id.selfId,
|
|
2601
|
+
rootId: dialog.id.rootId,
|
|
2602
|
+
},
|
|
2603
|
+
timestamp: event.ts,
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
if (ws.readyState === 1) {
|
|
2607
|
+
ws.send(JSON.stringify(nativeToolCall));
|
|
2608
|
+
}
|
|
2609
|
+
break;
|
|
2610
|
+
}
|
|
2398
2611
|
case 'func_result_record': {
|
|
2612
|
+
if (isSuppressedTellaskPlaceholderFuncResult({
|
|
2613
|
+
name: event.name,
|
|
2614
|
+
content: event.content,
|
|
2615
|
+
})) {
|
|
2616
|
+
break;
|
|
2617
|
+
}
|
|
2399
2618
|
// Handle function result events from persistence
|
|
2400
2619
|
const funcResult = {
|
|
2401
2620
|
type: 'func_result_evt',
|
|
@@ -2415,6 +2634,45 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2415
2634
|
}
|
|
2416
2635
|
break;
|
|
2417
2636
|
}
|
|
2637
|
+
case 'tellask_result_record': {
|
|
2638
|
+
const base = {
|
|
2639
|
+
type: 'tellask_result_evt',
|
|
2640
|
+
course,
|
|
2641
|
+
genseq: event.genseq,
|
|
2642
|
+
callId: event.callId,
|
|
2643
|
+
status: event.status,
|
|
2644
|
+
content: event.content,
|
|
2645
|
+
...(event.calling_genseq !== undefined ? { calling_genseq: event.calling_genseq } : {}),
|
|
2646
|
+
responder: event.responder,
|
|
2647
|
+
...(event.route ? { route: event.route } : {}),
|
|
2648
|
+
dialog: {
|
|
2649
|
+
selfId: dialog.id.selfId,
|
|
2650
|
+
rootId: dialog.id.rootId,
|
|
2651
|
+
},
|
|
2652
|
+
timestamp: event.ts,
|
|
2653
|
+
};
|
|
2654
|
+
const tellaskResultEvent = event.callName === 'tellask'
|
|
2655
|
+
? {
|
|
2656
|
+
...base,
|
|
2657
|
+
callName: event.callName,
|
|
2658
|
+
call: event.call,
|
|
2659
|
+
}
|
|
2660
|
+
: event.callName === 'tellaskSessionless'
|
|
2661
|
+
? {
|
|
2662
|
+
...base,
|
|
2663
|
+
callName: event.callName,
|
|
2664
|
+
call: event.call,
|
|
2665
|
+
}
|
|
2666
|
+
: {
|
|
2667
|
+
...base,
|
|
2668
|
+
callName: event.callName,
|
|
2669
|
+
call: event.call,
|
|
2670
|
+
};
|
|
2671
|
+
if (ws.readyState === 1) {
|
|
2672
|
+
ws.send(JSON.stringify(tellaskResultEvent));
|
|
2673
|
+
}
|
|
2674
|
+
break;
|
|
2675
|
+
}
|
|
2418
2676
|
case 'quest_for_sup_record': {
|
|
2419
2677
|
// Handle subdialog creation requests
|
|
2420
2678
|
const subdialogId = new dialog_1.DialogID(event.subDialogId, dialog.id.rootId);
|
|
@@ -2470,55 +2728,6 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2470
2728
|
}
|
|
2471
2729
|
break;
|
|
2472
2730
|
}
|
|
2473
|
-
case 'tellask_call_result_record': {
|
|
2474
|
-
// Handle tellask-call inline results
|
|
2475
|
-
const responseEvent = (() => {
|
|
2476
|
-
switch (event.callName) {
|
|
2477
|
-
case 'tellask':
|
|
2478
|
-
case 'tellaskSessionless':
|
|
2479
|
-
return {
|
|
2480
|
-
type: 'tellask_call_result_evt',
|
|
2481
|
-
responderId: event.responderId,
|
|
2482
|
-
callName: event.callName,
|
|
2483
|
-
mentionList: event.mentionList,
|
|
2484
|
-
tellaskContent: event.tellaskContent,
|
|
2485
|
-
status: event.status,
|
|
2486
|
-
result: event.result,
|
|
2487
|
-
callId: event.callId || '',
|
|
2488
|
-
course,
|
|
2489
|
-
calling_genseq: event.calling_genseq,
|
|
2490
|
-
dialog: {
|
|
2491
|
-
selfId: dialog.id.selfId,
|
|
2492
|
-
rootId: dialog.id.rootId,
|
|
2493
|
-
},
|
|
2494
|
-
timestamp: event.ts,
|
|
2495
|
-
};
|
|
2496
|
-
case 'tellaskBack':
|
|
2497
|
-
case 'askHuman':
|
|
2498
|
-
case 'freshBootsReasoning':
|
|
2499
|
-
return {
|
|
2500
|
-
type: 'tellask_call_result_evt',
|
|
2501
|
-
responderId: event.responderId,
|
|
2502
|
-
callName: event.callName,
|
|
2503
|
-
tellaskContent: event.tellaskContent,
|
|
2504
|
-
status: event.status,
|
|
2505
|
-
result: event.result,
|
|
2506
|
-
callId: event.callId || '',
|
|
2507
|
-
course,
|
|
2508
|
-
calling_genseq: event.calling_genseq,
|
|
2509
|
-
dialog: {
|
|
2510
|
-
selfId: dialog.id.selfId,
|
|
2511
|
-
rootId: dialog.id.rootId,
|
|
2512
|
-
},
|
|
2513
|
-
timestamp: event.ts,
|
|
2514
|
-
};
|
|
2515
|
-
}
|
|
2516
|
-
})();
|
|
2517
|
-
if (ws.readyState === 1) {
|
|
2518
|
-
ws.send(JSON.stringify(responseEvent));
|
|
2519
|
-
}
|
|
2520
|
-
break;
|
|
2521
|
-
}
|
|
2522
2731
|
case 'tellask_call_anchor_record': {
|
|
2523
2732
|
const anchorEvent = event.anchorRole === 'assignment'
|
|
2524
2733
|
? {
|
|
@@ -2556,210 +2765,56 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2556
2765
|
}
|
|
2557
2766
|
break;
|
|
2558
2767
|
}
|
|
2559
|
-
case '
|
|
2560
|
-
|
|
2561
|
-
|
|
2768
|
+
case 'subdialog_created_record':
|
|
2769
|
+
case 'reminders_reconciled_record':
|
|
2770
|
+
case 'questions4human_reconciled_record':
|
|
2771
|
+
case 'pending_subdialogs_reconciled_record':
|
|
2772
|
+
case 'subdialog_registry_reconciled_record':
|
|
2773
|
+
case 'subdialog_responses_reconciled_record':
|
|
2774
|
+
break;
|
|
2775
|
+
case 'tellask_carryover_record': {
|
|
2776
|
+
const base = {
|
|
2777
|
+
type: 'tellask_carryover_evt',
|
|
2562
2778
|
course,
|
|
2779
|
+
genseq: event.genseq,
|
|
2780
|
+
originCourse: event.originCourse,
|
|
2781
|
+
carryoverCourse: event.carryoverCourse,
|
|
2563
2782
|
responderId: event.responderId,
|
|
2783
|
+
tellaskContent: event.tellaskContent,
|
|
2564
2784
|
status: event.status,
|
|
2785
|
+
response: event.response,
|
|
2786
|
+
content: event.content,
|
|
2787
|
+
agentId: event.agentId,
|
|
2565
2788
|
callId: event.callId,
|
|
2566
|
-
|
|
2789
|
+
originMemberId: event.originMemberId,
|
|
2790
|
+
...(event.calleeDialogId ? { calleeDialogId: event.calleeDialogId } : {}),
|
|
2791
|
+
...(event.calleeCourse !== undefined ? { calleeCourse: event.calleeCourse } : {}),
|
|
2792
|
+
...(event.calleeGenseq !== undefined ? { calleeGenseq: event.calleeGenseq } : {}),
|
|
2567
2793
|
dialog: {
|
|
2568
2794
|
selfId: dialog.id.selfId,
|
|
2569
2795
|
rootId: dialog.id.rootId,
|
|
2570
2796
|
},
|
|
2571
2797
|
timestamp: event.ts,
|
|
2572
2798
|
};
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
const carryoverEvent = (() => {
|
|
2580
|
-
switch (event.callName) {
|
|
2581
|
-
case 'tellask':
|
|
2582
|
-
return {
|
|
2583
|
-
type: 'tellask_carryover_result_evt',
|
|
2584
|
-
course,
|
|
2585
|
-
originCourse: event.originCourse,
|
|
2586
|
-
responderId: event.responderId,
|
|
2587
|
-
callName: event.callName,
|
|
2588
|
-
sessionSlug: event.sessionSlug,
|
|
2589
|
-
mentionList: event.mentionList,
|
|
2590
|
-
tellaskContent: event.tellaskContent,
|
|
2591
|
-
status: event.status,
|
|
2592
|
-
response: event.response,
|
|
2593
|
-
content: event.content,
|
|
2594
|
-
agentId: event.agentId,
|
|
2595
|
-
callId: event.callId,
|
|
2596
|
-
originMemberId: event.originMemberId,
|
|
2597
|
-
calleeDialogId: event.calleeDialogId,
|
|
2598
|
-
calleeCourse: event.calleeCourse,
|
|
2599
|
-
calleeGenseq: event.calleeGenseq,
|
|
2600
|
-
dialog: {
|
|
2601
|
-
selfId: dialog.id.selfId,
|
|
2602
|
-
rootId: dialog.id.rootId,
|
|
2603
|
-
},
|
|
2604
|
-
timestamp: event.ts,
|
|
2605
|
-
};
|
|
2606
|
-
case 'tellaskSessionless':
|
|
2607
|
-
return {
|
|
2608
|
-
type: 'tellask_carryover_result_evt',
|
|
2609
|
-
course,
|
|
2610
|
-
originCourse: event.originCourse,
|
|
2611
|
-
responderId: event.responderId,
|
|
2612
|
-
callName: event.callName,
|
|
2613
|
-
mentionList: event.mentionList,
|
|
2614
|
-
tellaskContent: event.tellaskContent,
|
|
2615
|
-
status: event.status,
|
|
2616
|
-
response: event.response,
|
|
2617
|
-
content: event.content,
|
|
2618
|
-
agentId: event.agentId,
|
|
2619
|
-
callId: event.callId,
|
|
2620
|
-
originMemberId: event.originMemberId,
|
|
2621
|
-
calleeDialogId: event.calleeDialogId,
|
|
2622
|
-
calleeCourse: event.calleeCourse,
|
|
2623
|
-
calleeGenseq: event.calleeGenseq,
|
|
2624
|
-
dialog: {
|
|
2625
|
-
selfId: dialog.id.selfId,
|
|
2626
|
-
rootId: dialog.id.rootId,
|
|
2627
|
-
},
|
|
2628
|
-
timestamp: event.ts,
|
|
2629
|
-
};
|
|
2630
|
-
case 'freshBootsReasoning':
|
|
2631
|
-
return {
|
|
2632
|
-
type: 'tellask_carryover_result_evt',
|
|
2633
|
-
course,
|
|
2634
|
-
originCourse: event.originCourse,
|
|
2635
|
-
responderId: event.responderId,
|
|
2636
|
-
callName: event.callName,
|
|
2637
|
-
tellaskContent: event.tellaskContent,
|
|
2638
|
-
status: event.status,
|
|
2639
|
-
response: event.response,
|
|
2640
|
-
content: event.content,
|
|
2641
|
-
agentId: event.agentId,
|
|
2642
|
-
callId: event.callId,
|
|
2643
|
-
originMemberId: event.originMemberId,
|
|
2644
|
-
calleeDialogId: event.calleeDialogId,
|
|
2645
|
-
calleeCourse: event.calleeCourse,
|
|
2646
|
-
calleeGenseq: event.calleeGenseq,
|
|
2647
|
-
dialog: {
|
|
2648
|
-
selfId: dialog.id.selfId,
|
|
2649
|
-
rootId: dialog.id.rootId,
|
|
2650
|
-
},
|
|
2651
|
-
timestamp: event.ts,
|
|
2652
|
-
};
|
|
2653
|
-
}
|
|
2654
|
-
})();
|
|
2655
|
-
if (ws.readyState === 1) {
|
|
2656
|
-
ws.send(JSON.stringify(carryoverEvent));
|
|
2657
|
-
}
|
|
2658
|
-
break;
|
|
2659
|
-
}
|
|
2660
|
-
case 'subdialog_created_record':
|
|
2661
|
-
case 'reminders_reconciled_record':
|
|
2662
|
-
case 'questions4human_reconciled_record':
|
|
2663
|
-
case 'pending_subdialogs_reconciled_record':
|
|
2664
|
-
case 'subdialog_registry_reconciled_record':
|
|
2665
|
-
case 'subdialog_responses_reconciled_record':
|
|
2666
|
-
break;
|
|
2667
|
-
case 'tellask_response_record': {
|
|
2668
|
-
// Handle tellask response events (separate bubble for tellask sideline replies)
|
|
2669
|
-
const mentionList = (() => {
|
|
2670
|
-
switch (event.callName) {
|
|
2671
|
-
case 'tellask':
|
|
2672
|
-
case 'tellaskSessionless':
|
|
2673
|
-
return event.mentionList;
|
|
2674
|
-
case 'tellaskBack':
|
|
2675
|
-
case 'freshBootsReasoning':
|
|
2676
|
-
return undefined;
|
|
2799
|
+
const tellaskCarryoverEvent = event.callName === 'tellask'
|
|
2800
|
+
? {
|
|
2801
|
+
...base,
|
|
2802
|
+
callName: event.callName,
|
|
2803
|
+
sessionSlug: event.sessionSlug,
|
|
2804
|
+
mentionList: event.mentionList,
|
|
2677
2805
|
}
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
? event.sessionSlug.trim()
|
|
2684
|
-
: undefined;
|
|
2685
|
-
if (!sessionSlug) {
|
|
2686
|
-
throw new Error(`Replay tellask_response_record invariant violation: missing sessionSlug for tellask ` +
|
|
2687
|
-
`(rootId=${dialog.id.rootId}, selfId=${dialog.id.selfId}, course=${course}, callId=${event.callId})`);
|
|
2688
|
-
}
|
|
2689
|
-
return {
|
|
2690
|
-
type: 'tellask_response_evt',
|
|
2691
|
-
responderId: event.responderId,
|
|
2692
|
-
callName: event.callName,
|
|
2693
|
-
sessionSlug,
|
|
2694
|
-
calleeDialogId: event.calleeDialogId,
|
|
2695
|
-
calleeCourse: event.calleeCourse,
|
|
2696
|
-
calleeGenseq: event.calleeGenseq,
|
|
2697
|
-
mentionList,
|
|
2698
|
-
tellaskContent: event.tellaskContent,
|
|
2699
|
-
status: event.status,
|
|
2700
|
-
response: event.response,
|
|
2701
|
-
agentId: event.agentId,
|
|
2702
|
-
callId: event.callId,
|
|
2703
|
-
originMemberId: event.originMemberId,
|
|
2704
|
-
course,
|
|
2705
|
-
calling_genseq: event.calling_genseq,
|
|
2706
|
-
dialog: {
|
|
2707
|
-
selfId: dialog.id.selfId,
|
|
2708
|
-
rootId: dialog.id.rootId,
|
|
2709
|
-
},
|
|
2710
|
-
timestamp: event.ts,
|
|
2711
|
-
};
|
|
2806
|
+
: event.callName === 'tellaskSessionless'
|
|
2807
|
+
? {
|
|
2808
|
+
...base,
|
|
2809
|
+
callName: event.callName,
|
|
2810
|
+
mentionList: event.mentionList,
|
|
2712
2811
|
}
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
callName: event.callName,
|
|
2718
|
-
calleeDialogId: event.calleeDialogId,
|
|
2719
|
-
calleeCourse: event.calleeCourse,
|
|
2720
|
-
calleeGenseq: event.calleeGenseq,
|
|
2721
|
-
mentionList,
|
|
2722
|
-
tellaskContent: event.tellaskContent,
|
|
2723
|
-
status: event.status,
|
|
2724
|
-
response: event.response,
|
|
2725
|
-
agentId: event.agentId,
|
|
2726
|
-
callId: event.callId,
|
|
2727
|
-
originMemberId: event.originMemberId,
|
|
2728
|
-
course,
|
|
2729
|
-
calling_genseq: event.calling_genseq,
|
|
2730
|
-
dialog: {
|
|
2731
|
-
selfId: dialog.id.selfId,
|
|
2732
|
-
rootId: dialog.id.rootId,
|
|
2733
|
-
},
|
|
2734
|
-
timestamp: event.ts,
|
|
2735
|
-
};
|
|
2736
|
-
case 'tellaskBack':
|
|
2737
|
-
case 'freshBootsReasoning':
|
|
2738
|
-
return {
|
|
2739
|
-
type: 'tellask_response_evt',
|
|
2740
|
-
responderId: event.responderId,
|
|
2741
|
-
callName: event.callName,
|
|
2742
|
-
calleeDialogId: event.calleeDialogId,
|
|
2743
|
-
calleeCourse: event.calleeCourse,
|
|
2744
|
-
calleeGenseq: event.calleeGenseq,
|
|
2745
|
-
tellaskContent: event.tellaskContent,
|
|
2746
|
-
status: event.status,
|
|
2747
|
-
response: event.response,
|
|
2748
|
-
agentId: event.agentId,
|
|
2749
|
-
callId: event.callId,
|
|
2750
|
-
originMemberId: event.originMemberId,
|
|
2751
|
-
course,
|
|
2752
|
-
calling_genseq: event.calling_genseq,
|
|
2753
|
-
dialog: {
|
|
2754
|
-
selfId: dialog.id.selfId,
|
|
2755
|
-
rootId: dialog.id.rootId,
|
|
2756
|
-
},
|
|
2757
|
-
timestamp: event.ts,
|
|
2758
|
-
};
|
|
2759
|
-
}
|
|
2760
|
-
})();
|
|
2812
|
+
: {
|
|
2813
|
+
...base,
|
|
2814
|
+
callName: event.callName,
|
|
2815
|
+
};
|
|
2761
2816
|
if (ws.readyState === 1) {
|
|
2762
|
-
ws.send(JSON.stringify(
|
|
2817
|
+
ws.send(JSON.stringify(tellaskCarryoverEvent));
|
|
2763
2818
|
}
|
|
2764
2819
|
break;
|
|
2765
2820
|
}
|
|
@@ -2791,71 +2846,6 @@ exports.DiskFileDialogStore = DiskFileDialogStore;
|
|
|
2791
2846
|
* Utility class for managing dialog persistence
|
|
2792
2847
|
*/
|
|
2793
2848
|
class DialogPersistence {
|
|
2794
|
-
static async repairInterruptedFunctionCallsOnRestore(args) {
|
|
2795
|
-
const repaired = [];
|
|
2796
|
-
const unresolvedById = new Map();
|
|
2797
|
-
for (const event of args.events) {
|
|
2798
|
-
if (event.type === 'func_call_record') {
|
|
2799
|
-
unresolvedById.set(event.id, event);
|
|
2800
|
-
repaired.push(event);
|
|
2801
|
-
continue;
|
|
2802
|
-
}
|
|
2803
|
-
if (event.type === 'func_result_record') {
|
|
2804
|
-
if (!unresolvedById.has(event.id)) {
|
|
2805
|
-
const repairCall = {
|
|
2806
|
-
ts: event.ts,
|
|
2807
|
-
type: 'func_call_record',
|
|
2808
|
-
genseq: event.genseq,
|
|
2809
|
-
id: event.id,
|
|
2810
|
-
name: event.name,
|
|
2811
|
-
arguments: {},
|
|
2812
|
-
};
|
|
2813
|
-
log_1.log.error('Recovered orphaned persisted func_result_record by synthesizing missing func_call_record during dialog restore', new Error('dialog_restore_recovered_orphaned_func_result'), {
|
|
2814
|
-
rootId: args.dialogId.rootId,
|
|
2815
|
-
selfId: args.dialogId.selfId,
|
|
2816
|
-
course: args.course,
|
|
2817
|
-
genseq: event.genseq,
|
|
2818
|
-
callId: event.id,
|
|
2819
|
-
toolName: event.name,
|
|
2820
|
-
});
|
|
2821
|
-
repaired.push(repairCall);
|
|
2822
|
-
}
|
|
2823
|
-
else {
|
|
2824
|
-
unresolvedById.delete(event.id);
|
|
2825
|
-
}
|
|
2826
|
-
repaired.push(event);
|
|
2827
|
-
continue;
|
|
2828
|
-
}
|
|
2829
|
-
repaired.push(event);
|
|
2830
|
-
}
|
|
2831
|
-
if (args.status !== 'running') {
|
|
2832
|
-
return repaired;
|
|
2833
|
-
}
|
|
2834
|
-
if (unresolvedById.size === 0) {
|
|
2835
|
-
return repaired;
|
|
2836
|
-
}
|
|
2837
|
-
for (const call of unresolvedById.values()) {
|
|
2838
|
-
const repairRecord = {
|
|
2839
|
-
ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
2840
|
-
type: 'func_result_record',
|
|
2841
|
-
id: call.id,
|
|
2842
|
-
name: call.name,
|
|
2843
|
-
content: formatCrashRecoveredFuncResultContent(call.name),
|
|
2844
|
-
genseq: call.genseq,
|
|
2845
|
-
};
|
|
2846
|
-
log_1.log.error('Recovered unresolved persisted func_call_record after unexpected process exit', new Error('dialog_restore_recovered_func_call'), {
|
|
2847
|
-
rootId: args.dialogId.rootId,
|
|
2848
|
-
selfId: args.dialogId.selfId,
|
|
2849
|
-
course: args.course,
|
|
2850
|
-
genseq: call.genseq,
|
|
2851
|
-
callId: call.id,
|
|
2852
|
-
toolName: call.name,
|
|
2853
|
-
});
|
|
2854
|
-
await this.appendEvent(args.dialogId, args.course, repairRecord, args.status);
|
|
2855
|
-
repaired.push(repairRecord);
|
|
2856
|
-
}
|
|
2857
|
-
return repaired;
|
|
2858
|
-
}
|
|
2859
2849
|
static getLatestWriteBackMutex(key) {
|
|
2860
2850
|
const existing = this.latestWriteBackMutexes.get(key);
|
|
2861
2851
|
if (existing)
|
|
@@ -2911,7 +2901,6 @@ class DialogPersistence {
|
|
|
2911
2901
|
static cloneQuestions4Human(questions) {
|
|
2912
2902
|
return questions.map((question) => ({
|
|
2913
2903
|
...question,
|
|
2914
|
-
remainingCallIds: question.remainingCallIds ? [...question.remainingCallIds] : undefined,
|
|
2915
2904
|
callSiteRef: { ...question.callSiteRef },
|
|
2916
2905
|
}));
|
|
2917
2906
|
}
|
|
@@ -3294,10 +3283,13 @@ class DialogPersistence {
|
|
|
3294
3283
|
/**
|
|
3295
3284
|
* Append event to course JSONL file (append-only pattern)
|
|
3296
3285
|
*/
|
|
3297
|
-
static async
|
|
3286
|
+
static async appendEvents(dialogId, course, events, status = 'running') {
|
|
3298
3287
|
const appendMutexKey = this.getCourseAppendMutexKey(dialogId, course, status);
|
|
3299
3288
|
const release = await this.getCourseAppendMutex(appendMutexKey).acquire();
|
|
3300
3289
|
try {
|
|
3290
|
+
if (events.length === 0) {
|
|
3291
|
+
return;
|
|
3292
|
+
}
|
|
3301
3293
|
const dialogPath = this.getDialogEventsPath(dialogId, status);
|
|
3302
3294
|
const courseFilename = this.getCourseFilename(course);
|
|
3303
3295
|
const courseFilePath = path.join(dialogPath, courseFilename);
|
|
@@ -3306,8 +3298,8 @@ class DialogPersistence {
|
|
|
3306
3298
|
// Serialize appends per dialog+course file. Concurrent `appendFile` calls can interleave and
|
|
3307
3299
|
// corrupt JSONL lines (e.g. tool results appended in parallel), which later manifests as
|
|
3308
3300
|
// `Unterminated string in JSON ...` during resume.
|
|
3309
|
-
const
|
|
3310
|
-
await fs.promises.appendFile(courseFilePath,
|
|
3301
|
+
const serialized = events.map((event) => JSON.stringify(event)).join('\n') + '\n';
|
|
3302
|
+
await fs.promises.appendFile(courseFilePath, serialized, 'utf-8');
|
|
3311
3303
|
// Update latest.yaml with new lastModified timestamp
|
|
3312
3304
|
await this.mutateDialogLatest(dialogId, () => ({
|
|
3313
3305
|
kind: 'patch',
|
|
@@ -3318,13 +3310,16 @@ class DialogPersistence {
|
|
|
3318
3310
|
}), status);
|
|
3319
3311
|
}
|
|
3320
3312
|
catch (error) {
|
|
3321
|
-
log_1.log.error(`Failed to append
|
|
3313
|
+
log_1.log.error(`Failed to append events to dialog ${dialogId} course ${course}:`, error);
|
|
3322
3314
|
throw error;
|
|
3323
3315
|
}
|
|
3324
3316
|
finally {
|
|
3325
3317
|
release();
|
|
3326
3318
|
}
|
|
3327
3319
|
}
|
|
3320
|
+
static async appendEvent(dialogId, course, event, status = 'running') {
|
|
3321
|
+
await this.appendEvents(dialogId, course, [event], status);
|
|
3322
|
+
}
|
|
3328
3323
|
static async persistRuntimeGuide(dialog, content, genseq) {
|
|
3329
3324
|
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
3330
3325
|
const ev = {
|
|
@@ -3741,29 +3736,26 @@ class DialogPersistence {
|
|
|
3741
3736
|
}
|
|
3742
3737
|
static async appendQuestion4HumanState(dialogId, question, status = 'running') {
|
|
3743
3738
|
const questionId = question.id;
|
|
3744
|
-
const normalizedCallId =
|
|
3745
|
-
|
|
3746
|
-
:
|
|
3739
|
+
const normalizedCallId = question.callId.trim();
|
|
3740
|
+
if (normalizedCallId === '') {
|
|
3741
|
+
throw new Error(`Q4H append invariant violation: empty callId (dialog=${dialogId.valueOf()} questionId=${questionId})`);
|
|
3742
|
+
}
|
|
3747
3743
|
await this.mutateQuestions4HumanState(dialogId, (previousQuestions) => {
|
|
3748
3744
|
const byId = previousQuestions.find((q) => q.id === questionId);
|
|
3749
3745
|
if (byId) {
|
|
3750
3746
|
throw new Error(`Q4H duplicate question id violation: dialog=${dialogId.valueOf()} status=${status} questionId=${questionId} existingAskedAt=${byId.askedAt} incomingAskedAt=${question.askedAt}`);
|
|
3751
3747
|
}
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
});
|
|
3756
|
-
if (byCallId) {
|
|
3757
|
-
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}`);
|
|
3758
|
-
}
|
|
3748
|
+
const byCallId = previousQuestions.find((q) => q.callId.trim() === normalizedCallId);
|
|
3749
|
+
if (byCallId) {
|
|
3750
|
+
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}`);
|
|
3759
3751
|
}
|
|
3760
3752
|
if (previousQuestions.length > 0) {
|
|
3761
3753
|
const existingIds = previousQuestions.map((q) => q.id).join(',');
|
|
3762
3754
|
const existingCallIds = previousQuestions
|
|
3763
|
-
.map((q) =>
|
|
3755
|
+
.map((q) => q.callId.trim())
|
|
3764
3756
|
.filter((value) => value !== '')
|
|
3765
3757
|
.join(',');
|
|
3766
|
-
throw new Error(`Q4H multi-pending violation: dialog=${dialogId.valueOf()} status=${status} existingCount=${previousQuestions.length} existingQuestionIds=${existingIds} existingCallIds=${existingCallIds} incomingQuestionId=${questionId} incomingCallId=${normalizedCallId
|
|
3758
|
+
throw new Error(`Q4H multi-pending violation: dialog=${dialogId.valueOf()} status=${status} existingCount=${previousQuestions.length} existingQuestionIds=${existingIds} existingCallIds=${existingCallIds} incomingQuestionId=${questionId} incomingCallId=${normalizedCallId}`);
|
|
3767
3759
|
}
|
|
3768
3760
|
return { kind: 'append', question };
|
|
3769
3761
|
}, status);
|
|
@@ -4929,8 +4921,11 @@ class DialogPersistence {
|
|
|
4929
4921
|
}
|
|
4930
4922
|
}
|
|
4931
4923
|
/**
|
|
4932
|
-
* Restore dialog from disk using JSONL events (optimized: only latest course loaded)
|
|
4933
|
-
*
|
|
4924
|
+
* Restore dialog from disk using JSONL events (optimized: only latest course loaded).
|
|
4925
|
+
* Historical-course ask/tellask context that still matters to the current round must already be
|
|
4926
|
+
* represented via latest-course carryover records; older courses themselves are not reloaded into
|
|
4927
|
+
* LLM context during restore. For historical courses, use loadCourseEvents() on-demand for UI
|
|
4928
|
+
* navigation.
|
|
4934
4929
|
*/
|
|
4935
4930
|
static async restoreDialog(dialogId, status = 'running') {
|
|
4936
4931
|
try {
|
|
@@ -4940,16 +4935,11 @@ class DialogPersistence {
|
|
|
4940
4935
|
return null;
|
|
4941
4936
|
}
|
|
4942
4937
|
const reminders = await this.loadReminderState(dialogId, status);
|
|
4943
|
-
// Only load latest course for dialog state restoration
|
|
4938
|
+
// Only load latest course for dialog state restoration. Cross-course business context should
|
|
4939
|
+
// already have been materialized into latest-course carryover records when needed.
|
|
4944
4940
|
const currentCourse = await this.getCurrentCourseNumber(dialogId, status);
|
|
4945
4941
|
const latestEvents = await this.readCourseEvents(dialogId, currentCourse, status);
|
|
4946
|
-
const
|
|
4947
|
-
dialogId,
|
|
4948
|
-
course: currentCourse,
|
|
4949
|
-
status,
|
|
4950
|
-
events: latestEvents,
|
|
4951
|
-
});
|
|
4952
|
-
const reconstructedState = await this.rebuildFromEvents(repairedEvents, metadata, reminders, currentCourse);
|
|
4942
|
+
const reconstructedState = await this.rebuildFromEvents(latestEvents, metadata, reminders, currentCourse);
|
|
4953
4943
|
return reconstructedState;
|
|
4954
4944
|
}
|
|
4955
4945
|
catch (error) {
|
|
@@ -4964,7 +4954,7 @@ class DialogPersistence {
|
|
|
4964
4954
|
return await this.readCourseEvents(dialogId, course, status);
|
|
4965
4955
|
}
|
|
4966
4956
|
/**
|
|
4967
|
-
* Reconstruct dialog state from JSONL events (optimized: only latest course needed)
|
|
4957
|
+
* Reconstruct dialog state from JSONL events (optimized: only latest course needed).
|
|
4968
4958
|
*/
|
|
4969
4959
|
static async rebuildFromEvents(events, metadata, reminders, currentCourse) {
|
|
4970
4960
|
// Events are already in chronological order from JSONL file (append-only pattern)
|
|
@@ -4995,15 +4985,6 @@ class DialogPersistence {
|
|
|
4995
4985
|
});
|
|
4996
4986
|
break;
|
|
4997
4987
|
}
|
|
4998
|
-
case 'ui_only_markdown_record': {
|
|
4999
|
-
messages.push({
|
|
5000
|
-
type: 'ui_only_markdown_msg',
|
|
5001
|
-
role: 'assistant',
|
|
5002
|
-
genseq: event.genseq,
|
|
5003
|
-
content: event.content,
|
|
5004
|
-
});
|
|
5005
|
-
break;
|
|
5006
|
-
}
|
|
5007
4988
|
case 'runtime_guide_record': {
|
|
5008
4989
|
messages.push({
|
|
5009
4990
|
type: 'transient_guide_msg',
|
|
@@ -5013,6 +4994,11 @@ class DialogPersistence {
|
|
|
5013
4994
|
break;
|
|
5014
4995
|
}
|
|
5015
4996
|
case 'human_text_record': {
|
|
4997
|
+
if (typeof event.q4hAnswerCallId === 'string' && event.q4hAnswerCallId.trim() !== '') {
|
|
4998
|
+
// Keep this out of transcript reconstruction: it is only the continuation glue for an
|
|
4999
|
+
// answered askHuman call, not a persisted business-level user prompt fact.
|
|
5000
|
+
break;
|
|
5001
|
+
}
|
|
5016
5002
|
// Convert human text to prompting message
|
|
5017
5003
|
messages.push({
|
|
5018
5004
|
type: 'prompting_msg',
|
|
@@ -5034,18 +5020,18 @@ class DialogPersistence {
|
|
|
5034
5020
|
genseq: event.genseq,
|
|
5035
5021
|
id: event.id,
|
|
5036
5022
|
name: event.name,
|
|
5037
|
-
arguments: event.
|
|
5023
|
+
arguments: event.rawArgumentsText,
|
|
5038
5024
|
});
|
|
5039
5025
|
break;
|
|
5040
5026
|
}
|
|
5041
|
-
case '
|
|
5027
|
+
case 'tellask_call_record': {
|
|
5042
5028
|
messages.push({
|
|
5043
5029
|
type: 'func_call_msg',
|
|
5044
5030
|
role: 'assistant',
|
|
5045
5031
|
genseq: event.genseq,
|
|
5046
5032
|
id: event.id,
|
|
5047
5033
|
name: event.name,
|
|
5048
|
-
arguments:
|
|
5034
|
+
arguments: formatTellaskCallArguments(event),
|
|
5049
5035
|
});
|
|
5050
5036
|
break;
|
|
5051
5037
|
}
|
|
@@ -5053,6 +5039,10 @@ class DialogPersistence {
|
|
|
5053
5039
|
// UI-only timeline event for native web_search tool call visualization.
|
|
5054
5040
|
// Must not be injected into LLM context reconstruction.
|
|
5055
5041
|
break;
|
|
5042
|
+
case 'native_tool_call_record':
|
|
5043
|
+
// UI-only timeline event for OpenAI Responses native tool visualization.
|
|
5044
|
+
// Must not be injected into LLM context reconstruction.
|
|
5045
|
+
break;
|
|
5056
5046
|
case 'func_result_record': {
|
|
5057
5047
|
// Convert function result to ChatMessage
|
|
5058
5048
|
messages.push({
|
|
@@ -5066,69 +5056,68 @@ class DialogPersistence {
|
|
|
5066
5056
|
});
|
|
5067
5057
|
break;
|
|
5068
5058
|
}
|
|
5069
|
-
case '
|
|
5070
|
-
// Convert tellask-call inline result to ChatMessage
|
|
5071
|
-
const mentionList = (() => {
|
|
5072
|
-
switch (event.callName) {
|
|
5073
|
-
case 'tellask':
|
|
5074
|
-
case 'tellaskSessionless':
|
|
5075
|
-
return event.mentionList;
|
|
5076
|
-
case 'tellaskBack':
|
|
5077
|
-
case 'askHuman':
|
|
5078
|
-
case 'freshBootsReasoning':
|
|
5079
|
-
return undefined;
|
|
5080
|
-
}
|
|
5081
|
-
})();
|
|
5059
|
+
case 'tellask_result_record': {
|
|
5082
5060
|
messages.push({
|
|
5083
5061
|
type: 'tellask_result_msg',
|
|
5084
5062
|
role: 'tool',
|
|
5085
|
-
|
|
5086
|
-
mentionList,
|
|
5087
|
-
tellaskContent: event.tellaskContent,
|
|
5088
|
-
status: event.status,
|
|
5063
|
+
genseq: event.genseq,
|
|
5089
5064
|
callId: event.callId,
|
|
5090
|
-
|
|
5091
|
-
});
|
|
5092
|
-
break;
|
|
5093
|
-
}
|
|
5094
|
-
case 'tellask_call_carryover_record':
|
|
5095
|
-
break;
|
|
5096
|
-
case 'tellask_response_record': {
|
|
5097
|
-
// Convert tellask response to ChatMessage (separate bubble)
|
|
5098
|
-
// Note: Tellask responses are stored as separate records but use same message type
|
|
5099
|
-
const mentionList = (() => {
|
|
5100
|
-
switch (event.callName) {
|
|
5101
|
-
case 'tellask':
|
|
5102
|
-
case 'tellaskSessionless':
|
|
5103
|
-
return event.mentionList;
|
|
5104
|
-
case 'tellaskBack':
|
|
5105
|
-
case 'freshBootsReasoning':
|
|
5106
|
-
return undefined;
|
|
5107
|
-
}
|
|
5108
|
-
})();
|
|
5109
|
-
messages.push({
|
|
5110
|
-
type: 'tellask_result_msg',
|
|
5111
|
-
role: 'tool',
|
|
5112
|
-
responderId: event.responderId,
|
|
5113
|
-
mentionList,
|
|
5114
|
-
tellaskContent: event.tellaskContent,
|
|
5065
|
+
callName: event.callName,
|
|
5115
5066
|
status: event.status,
|
|
5116
|
-
|
|
5117
|
-
|
|
5067
|
+
content: event.content,
|
|
5068
|
+
...(event.calling_genseq !== undefined ? { calling_genseq: event.calling_genseq } : {}),
|
|
5069
|
+
call: event.call,
|
|
5070
|
+
responder: event.responder,
|
|
5071
|
+
...(event.route ? { route: event.route } : {}),
|
|
5072
|
+
responderId: event.responder.responderId,
|
|
5073
|
+
...(event.callName === 'tellask' || event.callName === 'tellaskSessionless'
|
|
5074
|
+
? { mentionList: event.call.mentionList }
|
|
5075
|
+
: {}),
|
|
5076
|
+
tellaskContent: event.call.tellaskContent,
|
|
5077
|
+
...(event.callName === 'tellask' ? { sessionSlug: event.call.sessionSlug } : {}),
|
|
5078
|
+
...(event.responder.agentId ? { agentId: event.responder.agentId } : {}),
|
|
5079
|
+
...(event.responder.originMemberId
|
|
5080
|
+
? { originMemberId: event.responder.originMemberId }
|
|
5081
|
+
: {}),
|
|
5082
|
+
...(event.route?.calleeDialogId ? { calleeDialogId: event.route.calleeDialogId } : {}),
|
|
5083
|
+
...(event.route?.calleeCourse !== undefined
|
|
5084
|
+
? { calleeCourse: event.route.calleeCourse }
|
|
5085
|
+
: {}),
|
|
5086
|
+
...(event.route?.calleeGenseq !== undefined
|
|
5087
|
+
? { calleeGenseq: event.route.calleeGenseq }
|
|
5088
|
+
: {}),
|
|
5118
5089
|
});
|
|
5119
5090
|
break;
|
|
5120
5091
|
}
|
|
5121
|
-
case '
|
|
5092
|
+
case 'tellask_carryover_record': {
|
|
5122
5093
|
messages.push({
|
|
5123
|
-
type: '
|
|
5094
|
+
type: 'tellask_carryover_msg',
|
|
5124
5095
|
role: 'user',
|
|
5096
|
+
genseq: event.genseq,
|
|
5125
5097
|
content: event.content,
|
|
5126
5098
|
originCourse: event.originCourse,
|
|
5099
|
+
carryoverCourse: event.carryoverCourse,
|
|
5127
5100
|
responderId: event.responderId,
|
|
5128
5101
|
callName: event.callName,
|
|
5129
5102
|
tellaskContent: event.tellaskContent,
|
|
5130
5103
|
status: event.status,
|
|
5104
|
+
response: event.response,
|
|
5105
|
+
agentId: event.agentId,
|
|
5131
5106
|
callId: event.callId,
|
|
5107
|
+
originMemberId: event.originMemberId,
|
|
5108
|
+
...(event.callName === 'tellask'
|
|
5109
|
+
? {
|
|
5110
|
+
mentionList: event.mentionList,
|
|
5111
|
+
sessionSlug: event.sessionSlug,
|
|
5112
|
+
}
|
|
5113
|
+
: event.callName === 'tellaskSessionless'
|
|
5114
|
+
? {
|
|
5115
|
+
mentionList: event.mentionList,
|
|
5116
|
+
}
|
|
5117
|
+
: {}),
|
|
5118
|
+
...(event.calleeDialogId ? { calleeDialogId: event.calleeDialogId } : {}),
|
|
5119
|
+
...(event.calleeCourse !== undefined ? { calleeCourse: event.calleeCourse } : {}),
|
|
5120
|
+
...(event.calleeGenseq !== undefined ? { calleeGenseq: event.calleeGenseq } : {}),
|
|
5132
5121
|
});
|
|
5133
5122
|
break;
|
|
5134
5123
|
}
|
|
@@ -5149,6 +5138,9 @@ class DialogPersistence {
|
|
|
5149
5138
|
// This record is UI navigation metadata for deep links in callee dialogs.
|
|
5150
5139
|
// It does not contribute to model context or chat transcript reconstruction.
|
|
5151
5140
|
break;
|
|
5141
|
+
case 'ui_only_markdown_record':
|
|
5142
|
+
// UI-only records are replay-only rendering facts. They do not enter dialog messages or ctx.
|
|
5143
|
+
break;
|
|
5152
5144
|
case 'subdialog_created_record':
|
|
5153
5145
|
case 'reminders_reconciled_record':
|
|
5154
5146
|
case 'questions4human_reconciled_record':
|