dominds 1.4.2 → 1.5.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/README.md +24 -0
- package/README.zh.md +24 -0
- package/dist/apps/app-json.js +38 -3
- package/dist/apps/dialog-run-controls.js +4 -0
- package/dist/apps/enabled-apps.js +8 -1
- package/dist/apps/installed-file.js +207 -0
- package/dist/apps/run-app-json.js +6 -6
- package/dist/apps/runtime-port.js +91 -0
- package/dist/apps/runtime.js +316 -68
- package/dist/apps-host/client.js +153 -3
- package/dist/apps-host/host.js +339 -2
- package/dist/apps-host/ipc-types.js +215 -30
- package/dist/cli/install.js +21 -1
- package/dist/dialog-fork.js +609 -0
- package/dist/dialog.js +2 -2
- package/dist/docs/agent-priming.md +38 -0
- package/dist/docs/agent-priming.zh.md +34 -0
- package/dist/docs/app-constitution.md +153 -2
- package/dist/docs/app-constitution.zh.md +153 -2
- package/dist/docs/dialog-persistence.md +31 -0
- package/dist/docs/dialog-persistence.zh.md +31 -0
- package/dist/docs/dialog-system.md +29 -0
- package/dist/docs/dialog-system.zh.md +29 -0
- package/dist/docs/kernel-app-architecture.md +286 -0
- package/dist/docs/kernel-app-architecture.zh.md +285 -0
- package/dist/llm/defaults.yaml +16 -0
- package/dist/llm/driver-entry.js +28 -0
- package/dist/llm/driver-v2/context-health.js +121 -0
- package/dist/llm/driver-v2/context.js +56 -0
- package/dist/llm/driver-v2/core.js +1545 -0
- package/dist/llm/driver-v2/index.js +26 -0
- package/dist/llm/driver-v2/orchestrator.js +158 -0
- package/dist/llm/driver-v2/policy.js +129 -0
- package/dist/llm/driver-v2/restore-dialog-hierarchy.js +73 -0
- package/dist/llm/driver-v2/round.js +366 -0
- package/dist/llm/driver-v2/runtime-utils.js +365 -0
- package/dist/llm/driver-v2/saying-events.js +20 -0
- package/dist/llm/driver-v2/subdialog-txn.js +42 -0
- package/dist/llm/driver-v2/supdialog-response.js +400 -0
- package/dist/llm/driver-v2/tellask-bridge.js +1148 -0
- package/dist/llm/driver-v2/types.js +10 -0
- package/dist/llm/driver-v2-ref-only/context-health.js +121 -0
- package/dist/llm/driver-v2-ref-only/context.js +17 -0
- package/dist/llm/driver-v2-ref-only/core.js +1710 -0
- package/dist/llm/driver-v2-ref-only/index.js +26 -0
- package/dist/llm/driver-v2-ref-only/orchestrator.js +158 -0
- package/dist/llm/driver-v2-ref-only/policy.js +129 -0
- package/dist/llm/driver-v2-ref-only/restore-dialog-hierarchy.js +73 -0
- package/dist/llm/driver-v2-ref-only/round.js +366 -0
- package/dist/llm/driver-v2-ref-only/runtime-utils.js +473 -0
- package/dist/llm/driver-v2-ref-only/saying-events.js +18 -0
- package/dist/llm/driver-v2-ref-only/subdialog-txn.js +42 -0
- package/dist/llm/driver-v2-ref-only/supdialog-response.js +453 -0
- package/dist/llm/driver-v2-ref-only/tellask-bridge.js +1178 -0
- package/dist/llm/driver-v2-ref-only/types.js +10 -0
- package/dist/llm/gen/anthropic.js +68 -15
- package/dist/llm/gen/codex.js +59 -10
- package/dist/llm/gen/openai-compatible.js +38 -9
- package/dist/llm/gen/openai.js +58 -11
- package/dist/llm/gen/tool-output-limit.js +50 -0
- package/dist/llm/kernel-driver/subdialog.js +23 -12
- package/dist/llm/kernel-driver/tellask-special.js +20 -4
- package/dist/minds/load.js +7 -0
- package/dist/persistence.js +216 -30
- package/dist/priming.js +171 -18
- package/dist/server/api-routes.js +82 -0
- package/dist/server/setup-routes.js +15 -0
- package/dist/shared/types/storage.js +77 -0
- package/dist/static/assets/{_basePickBy-B2o4z1Hf.js → _basePickBy-B-A5XrWM.js} +3 -3
- package/dist/static/assets/{_basePickBy-B2o4z1Hf.js.map → _basePickBy-B-A5XrWM.js.map} +1 -1
- package/dist/static/assets/{_baseUniq-CLmcxjdl.js → _baseUniq-BANLb0cu.js} +2 -2
- package/dist/static/assets/{_baseUniq-CLmcxjdl.js.map → _baseUniq-BANLb0cu.js.map} +1 -1
- package/dist/static/assets/{arc-CymD_KN7.js → arc-CYZYnojf.js} +2 -2
- package/dist/static/assets/{arc-CymD_KN7.js.map → arc-CYZYnojf.js.map} +1 -1
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DJQfSJUH.js → architectureDiagram-VXUJARFQ-Cxf4pmYG.js} +7 -7
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DJQfSJUH.js.map → architectureDiagram-VXUJARFQ-Cxf4pmYG.js.map} +1 -1
- package/dist/static/assets/{blockDiagram-VD42YOAC-pHVz60D0.js → blockDiagram-VD42YOAC-wvs0G30c.js} +7 -7
- package/dist/static/assets/{blockDiagram-VD42YOAC-pHVz60D0.js.map → blockDiagram-VD42YOAC-wvs0G30c.js.map} +1 -1
- package/dist/static/assets/{c4Diagram-YG6GDRKO-B0WnCfAT.js → c4Diagram-YG6GDRKO-BKFNexn4.js} +3 -3
- package/dist/static/assets/{c4Diagram-YG6GDRKO-B0WnCfAT.js.map → c4Diagram-YG6GDRKO-BKFNexn4.js.map} +1 -1
- package/dist/static/assets/{channel-CX9BlKil.js → channel-_1qpxJWy.js} +2 -2
- package/dist/static/assets/{channel-CX9BlKil.js.map → channel-_1qpxJWy.js.map} +1 -1
- package/dist/static/assets/{chunk-4BX2VUAB-lXArRj3o.js → chunk-4BX2VUAB-BIdC0phm.js} +2 -2
- package/dist/static/assets/{chunk-4BX2VUAB-lXArRj3o.js.map → chunk-4BX2VUAB-BIdC0phm.js.map} +1 -1
- package/dist/static/assets/{chunk-55IACEB6-CdqwynH9.js → chunk-55IACEB6-BNvGenQ9.js} +2 -2
- package/dist/static/assets/{chunk-55IACEB6-CdqwynH9.js.map → chunk-55IACEB6-BNvGenQ9.js.map} +1 -1
- package/dist/static/assets/{chunk-B4BG7PRW-Y-uXcJst.js → chunk-B4BG7PRW-jmf-1Wv7.js} +5 -5
- package/dist/static/assets/{chunk-B4BG7PRW-Y-uXcJst.js.map → chunk-B4BG7PRW-jmf-1Wv7.js.map} +1 -1
- package/dist/static/assets/{chunk-DI55MBZ5-C5xSbRST.js → chunk-DI55MBZ5-nmEmcikR.js} +4 -4
- package/dist/static/assets/{chunk-DI55MBZ5-C5xSbRST.js.map → chunk-DI55MBZ5-nmEmcikR.js.map} +1 -1
- package/dist/static/assets/{chunk-FMBD7UC4-5uefwCjI.js → chunk-FMBD7UC4-kGysaq_j.js} +2 -2
- package/dist/static/assets/{chunk-FMBD7UC4-5uefwCjI.js.map → chunk-FMBD7UC4-kGysaq_j.js.map} +1 -1
- package/dist/static/assets/{chunk-QN33PNHL-DzWVcvpI.js → chunk-QN33PNHL-8JwMLFIJ.js} +2 -2
- package/dist/static/assets/{chunk-QN33PNHL-DzWVcvpI.js.map → chunk-QN33PNHL-8JwMLFIJ.js.map} +1 -1
- package/dist/static/assets/{chunk-QZHKN3VN-BrrvAZdP.js → chunk-QZHKN3VN-DZleEj00.js} +2 -2
- package/dist/static/assets/{chunk-QZHKN3VN-BrrvAZdP.js.map → chunk-QZHKN3VN-DZleEj00.js.map} +1 -1
- package/dist/static/assets/{chunk-TZMSLE5B-DyKOlPTY.js → chunk-TZMSLE5B-CXxl_uqH.js} +2 -2
- package/dist/static/assets/{chunk-TZMSLE5B-DyKOlPTY.js.map → chunk-TZMSLE5B-CXxl_uqH.js.map} +1 -1
- package/dist/static/assets/{classDiagram-2ON5EDUG-FCrnlCWC.js → classDiagram-2ON5EDUG-C-7R0QB6.js} +6 -6
- package/dist/static/assets/{classDiagram-2ON5EDUG-FCrnlCWC.js.map → classDiagram-2ON5EDUG-C-7R0QB6.js.map} +1 -1
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-FCrnlCWC.js → classDiagram-v2-WZHVMYZB-C-7R0QB6.js} +6 -6
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-FCrnlCWC.js.map → classDiagram-v2-WZHVMYZB-C-7R0QB6.js.map} +1 -1
- package/dist/static/assets/{clone-BlI81KqZ.js → clone-BwOKYSj8.js} +2 -2
- package/dist/static/assets/{clone-BlI81KqZ.js.map → clone-BwOKYSj8.js.map} +1 -1
- package/dist/static/assets/{cose-bilkent-S5V4N54A-yM7S2atz.js → cose-bilkent-S5V4N54A-BCBalM7p.js} +2 -2
- package/dist/static/assets/{cose-bilkent-S5V4N54A-yM7S2atz.js.map → cose-bilkent-S5V4N54A-BCBalM7p.js.map} +1 -1
- package/dist/static/assets/{dagre-6UL2VRFP-BcweuZHt.js → dagre-6UL2VRFP-uV2ekQoj.js} +7 -7
- package/dist/static/assets/{dagre-6UL2VRFP-BcweuZHt.js.map → dagre-6UL2VRFP-uV2ekQoj.js.map} +1 -1
- package/dist/static/assets/{diagram-PSM6KHXK-D4-QwLW1.js → diagram-PSM6KHXK-D-ZMog1-.js} +8 -8
- package/dist/static/assets/{diagram-PSM6KHXK-D4-QwLW1.js.map → diagram-PSM6KHXK-D-ZMog1-.js.map} +1 -1
- package/dist/static/assets/{diagram-QEK2KX5R-BVbuejJn.js → diagram-QEK2KX5R-BThSELUH.js} +7 -7
- package/dist/static/assets/{diagram-QEK2KX5R-BVbuejJn.js.map → diagram-QEK2KX5R-BThSELUH.js.map} +1 -1
- package/dist/static/assets/{diagram-S2PKOQOG-pB6N6Tq_.js → diagram-S2PKOQOG-Di-YN5cd.js} +7 -7
- package/dist/static/assets/{diagram-S2PKOQOG-pB6N6Tq_.js.map → diagram-S2PKOQOG-Di-YN5cd.js.map} +1 -1
- package/dist/static/assets/{erDiagram-Q2GNP2WA-DLKmthuw.js → erDiagram-Q2GNP2WA-lBZ9DITn.js} +5 -5
- package/dist/static/assets/{erDiagram-Q2GNP2WA-DLKmthuw.js.map → erDiagram-Q2GNP2WA-lBZ9DITn.js.map} +1 -1
- package/dist/static/assets/{flowDiagram-NV44I4VS-BsBhWukh.js → flowDiagram-NV44I4VS-C_60PNQR.js} +6 -6
- package/dist/static/assets/{flowDiagram-NV44I4VS-BsBhWukh.js.map → flowDiagram-NV44I4VS-C_60PNQR.js.map} +1 -1
- package/dist/static/assets/{ganttDiagram-JELNMOA3-Debz-J-C.js → ganttDiagram-JELNMOA3-Dvqq-VHJ.js} +3 -3
- package/dist/static/assets/{ganttDiagram-JELNMOA3-Debz-J-C.js.map → ganttDiagram-JELNMOA3-Dvqq-VHJ.js.map} +1 -1
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-BnAPFBGR.js → gitGraphDiagram-V2S2FVAM-BTj8orRe.js} +8 -8
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-BnAPFBGR.js.map → gitGraphDiagram-V2S2FVAM-BTj8orRe.js.map} +1 -1
- package/dist/static/assets/{graph-DbzWiBNK.js → graph-BqCzR2Nl.js} +3 -3
- package/dist/static/assets/{graph-DbzWiBNK.js.map → graph-BqCzR2Nl.js.map} +1 -1
- package/dist/static/assets/{index-B-8J28g7.js → index-DrTqAfFy.js} +386 -201
- package/dist/static/assets/index-DrTqAfFy.js.map +1 -0
- package/dist/static/assets/{infoDiagram-HS3SLOUP-CZ5hWoxV.js → infoDiagram-HS3SLOUP-DlC6wsrv.js} +6 -6
- package/dist/static/assets/{infoDiagram-HS3SLOUP-CZ5hWoxV.js.map → infoDiagram-HS3SLOUP-DlC6wsrv.js.map} +1 -1
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-CKN3oSxk.js → journeyDiagram-XKPGCS4Q-Dg_RgtQX.js} +5 -5
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-CKN3oSxk.js.map → journeyDiagram-XKPGCS4Q-Dg_RgtQX.js.map} +1 -1
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BQCMklfJ.js → kanban-definition-3W4ZIXB7-DuGS3lId.js} +3 -3
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BQCMklfJ.js.map → kanban-definition-3W4ZIXB7-DuGS3lId.js.map} +1 -1
- package/dist/static/assets/{layout-C5B58szc.js → layout-FDz2bstZ.js} +5 -5
- package/dist/static/assets/{layout-C5B58szc.js.map → layout-FDz2bstZ.js.map} +1 -1
- package/dist/static/assets/{linear-_32fut6G.js → linear-CzsdvPGb.js} +2 -2
- package/dist/static/assets/{linear-_32fut6G.js.map → linear-CzsdvPGb.js.map} +1 -1
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-C_goMzjx.js → mindmap-definition-VGOIOE7T-WsAF5UNp.js} +4 -4
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-C_goMzjx.js.map → mindmap-definition-VGOIOE7T-WsAF5UNp.js.map} +1 -1
- package/dist/static/assets/{pieDiagram-ADFJNKIX-BQ2n0cOB.js → pieDiagram-ADFJNKIX-DJpRJ5ei.js} +8 -8
- package/dist/static/assets/{pieDiagram-ADFJNKIX-BQ2n0cOB.js.map → pieDiagram-ADFJNKIX-DJpRJ5ei.js.map} +1 -1
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-BLg7_neg.js → quadrantDiagram-AYHSOK5B-CMyIzTkY.js} +3 -3
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-BLg7_neg.js.map → quadrantDiagram-AYHSOK5B-CMyIzTkY.js.map} +1 -1
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DwkJt0zi.js → requirementDiagram-UZGBJVZJ-D_yqVXGu.js} +4 -4
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DwkJt0zi.js.map → requirementDiagram-UZGBJVZJ-D_yqVXGu.js.map} +1 -1
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DmxmatUB.js → sankeyDiagram-TZEHDZUN-D4-cF724.js} +2 -2
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DmxmatUB.js.map → sankeyDiagram-TZEHDZUN-D4-cF724.js.map} +1 -1
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-KHU_eApU.js → sequenceDiagram-WL72ISMW-B7J3gWYN.js} +4 -4
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-KHU_eApU.js.map → sequenceDiagram-WL72ISMW-B7J3gWYN.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-B3DBCxAL.js → stateDiagram-FKZM4ZOC-DwEYYCcu.js} +9 -9
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-B3DBCxAL.js.map → stateDiagram-FKZM4ZOC-DwEYYCcu.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-C-uIk7gh.js → stateDiagram-v2-4FDKWEC3-D4LOOQV5.js} +5 -5
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-C-uIk7gh.js.map → stateDiagram-v2-4FDKWEC3-D4LOOQV5.js.map} +1 -1
- package/dist/static/assets/{timeline-definition-IT6M3QCI-SysEcQCC.js → timeline-definition-IT6M3QCI-CyG-TJ_A.js} +3 -3
- package/dist/static/assets/{timeline-definition-IT6M3QCI-SysEcQCC.js.map → timeline-definition-IT6M3QCI-CyG-TJ_A.js.map} +1 -1
- package/dist/static/assets/{treemap-GDKQZRPO-d0AbKEc4.js → treemap-GDKQZRPO-yY4GiKmU.js} +5 -5
- package/dist/static/assets/{treemap-GDKQZRPO-d0AbKEc4.js.map → treemap-GDKQZRPO-yY4GiKmU.js.map} +1 -1
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-CmSQMxUh.js → xychartDiagram-PRI3JC2R-5TYN_q15.js} +3 -3
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-CmSQMxUh.js.map → xychartDiagram-PRI3JC2R-5TYN_q15.js.map} +1 -1
- package/dist/static/index.html +1 -1
- package/dist/team.js +33 -4
- package/dist/tools/app-reminders.js +280 -0
- package/dist/tools/prompts/memory/en/errors.md +155 -0
- package/dist/tools/prompts/memory/en/index.md +47 -0
- package/dist/tools/prompts/memory/en/principles.md +79 -0
- package/dist/tools/prompts/memory/en/scenarios.md +174 -0
- package/dist/tools/prompts/memory/en/tools.md +154 -0
- package/dist/tools/prompts/memory/zh/errors.md +155 -0
- package/dist/tools/prompts/memory/zh/index.md +47 -0
- package/dist/tools/prompts/memory/zh/principles.md +79 -0
- package/dist/tools/prompts/memory/zh/scenarios.md +174 -0
- package/dist/tools/prompts/memory/zh/tools.md +154 -0
- package/dist/tools/ripgrep.js +197 -63
- package/package.json +2 -2
- package/dist/static/assets/index-B-8J28g7.js.map +0 -1
|
@@ -0,0 +1,1178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isTellaskSpecialFunctionName = isTellaskSpecialFunctionName;
|
|
4
|
+
exports.classifyTellaskSpecialFunctionCalls = classifyTellaskSpecialFunctionCalls;
|
|
5
|
+
exports.executeTellaskSpecialCalls = executeTellaskSpecialCalls;
|
|
6
|
+
const util_1 = require("util");
|
|
7
|
+
const dialog_1 = require("../../dialog");
|
|
8
|
+
const evt_registry_1 = require("../../evt-registry");
|
|
9
|
+
const log_1 = require("../../log");
|
|
10
|
+
const persistence_1 = require("../../persistence");
|
|
11
|
+
const driver_messages_1 = require("../../shared/i18n/driver-messages");
|
|
12
|
+
const runtime_language_1 = require("../../shared/runtime-language");
|
|
13
|
+
const fbr_1 = require("../../shared/utils/fbr");
|
|
14
|
+
const id_1 = require("../../shared/utils/id");
|
|
15
|
+
const inter_dialog_format_1 = require("../../shared/utils/inter-dialog-format");
|
|
16
|
+
const time_1 = require("../../shared/utils/time");
|
|
17
|
+
const team_1 = require("../../team");
|
|
18
|
+
const pending_tellask_reminder_1 = require("../../tools/pending-tellask-reminder");
|
|
19
|
+
const subdialog_txn_1 = require("./subdialog-txn");
|
|
20
|
+
const TELLASK_SPECIAL_FUNCTION_NAMES = [
|
|
21
|
+
'tellaskBack',
|
|
22
|
+
'tellask',
|
|
23
|
+
'tellaskSessionless',
|
|
24
|
+
'askHuman',
|
|
25
|
+
'freshBootsReasoning',
|
|
26
|
+
];
|
|
27
|
+
function isTellaskSpecialFunctionName(name) {
|
|
28
|
+
return TELLASK_SPECIAL_FUNCTION_NAMES.includes(name);
|
|
29
|
+
}
|
|
30
|
+
function isRecord(value) {
|
|
31
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
32
|
+
}
|
|
33
|
+
function parseFuncCallArgsObject(call) {
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(call.arguments || '{}');
|
|
36
|
+
if (!isRecord(parsed)) {
|
|
37
|
+
return { ok: false, error: 'arguments must be a JSON object' };
|
|
38
|
+
}
|
|
39
|
+
return { ok: true, value: parsed };
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
return {
|
|
43
|
+
ok: false,
|
|
44
|
+
error: `arguments must be valid JSON: ${err instanceof Error ? err.message : String(err)}`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function readRequiredStringField(obj, field) {
|
|
49
|
+
const value = obj[field];
|
|
50
|
+
if (typeof value !== 'string') {
|
|
51
|
+
return { ok: false, error: `field '${field}' must be a string` };
|
|
52
|
+
}
|
|
53
|
+
const trimmed = value.trim();
|
|
54
|
+
if (trimmed === '') {
|
|
55
|
+
return { ok: false, error: `field '${field}' must not be empty` };
|
|
56
|
+
}
|
|
57
|
+
return { ok: true, value: trimmed };
|
|
58
|
+
}
|
|
59
|
+
function readOptionalStringField(obj, field) {
|
|
60
|
+
const value = obj[field];
|
|
61
|
+
if (value === undefined) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (typeof value !== 'string') {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const trimmed = value.trim();
|
|
68
|
+
return trimmed === '' ? null : trimmed;
|
|
69
|
+
}
|
|
70
|
+
function readOptionalEffortField(obj, field) {
|
|
71
|
+
const value = obj[field];
|
|
72
|
+
if (value === undefined) {
|
|
73
|
+
return { ok: true, value: undefined };
|
|
74
|
+
}
|
|
75
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || !Number.isInteger(value)) {
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
error: `field '${field}' must be an integer in [0, 100] when provided`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (value < 0 || value > 100) {
|
|
82
|
+
return {
|
|
83
|
+
ok: false,
|
|
84
|
+
error: `field '${field}' must be an integer in [0, 100] when provided`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return { ok: true, value };
|
|
88
|
+
}
|
|
89
|
+
function readTargetAgentId(obj) {
|
|
90
|
+
const target = readOptionalStringField(obj, 'targetAgentId') ??
|
|
91
|
+
readOptionalStringField(obj, 'agentId') ??
|
|
92
|
+
readOptionalStringField(obj, 'target');
|
|
93
|
+
if (!target) {
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
error: "missing target agent id (expected 'targetAgentId' or 'agentId')",
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return { ok: true, value: target };
|
|
100
|
+
}
|
|
101
|
+
function normalizeTeammateTargetAgentId(rawTarget) {
|
|
102
|
+
const trimmed = rawTarget.trim();
|
|
103
|
+
const withoutAt = trimmed.startsWith('@') ? trimmed.slice(1).trim() : trimmed;
|
|
104
|
+
if (withoutAt === '') {
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
error: 'targetAgentId must not be empty',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return { ok: true, value: withoutAt };
|
|
111
|
+
}
|
|
112
|
+
function parseTellaskSpecialCall(call) {
|
|
113
|
+
if (!isTellaskSpecialFunctionName(call.name)) {
|
|
114
|
+
return { ok: false, error: `unsupported tellask special function '${call.name}'` };
|
|
115
|
+
}
|
|
116
|
+
const argsResult = parseFuncCallArgsObject(call);
|
|
117
|
+
if (!argsResult.ok) {
|
|
118
|
+
return argsResult;
|
|
119
|
+
}
|
|
120
|
+
const args = argsResult.value;
|
|
121
|
+
const tellaskContent = readRequiredStringField(args, 'tellaskContent');
|
|
122
|
+
if (!tellaskContent.ok) {
|
|
123
|
+
return tellaskContent;
|
|
124
|
+
}
|
|
125
|
+
switch (call.name) {
|
|
126
|
+
case 'tellaskBack': {
|
|
127
|
+
return {
|
|
128
|
+
ok: true,
|
|
129
|
+
value: {
|
|
130
|
+
callId: call.id,
|
|
131
|
+
callName: 'tellaskBack',
|
|
132
|
+
tellaskContent: tellaskContent.value,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
case 'askHuman': {
|
|
137
|
+
return {
|
|
138
|
+
ok: true,
|
|
139
|
+
value: {
|
|
140
|
+
callId: call.id,
|
|
141
|
+
callName: 'askHuman',
|
|
142
|
+
tellaskContent: tellaskContent.value,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
case 'freshBootsReasoning': {
|
|
147
|
+
const effort = readOptionalEffortField(args, 'effort');
|
|
148
|
+
if (!effort.ok) {
|
|
149
|
+
return effort;
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
ok: true,
|
|
153
|
+
value: {
|
|
154
|
+
callId: call.id,
|
|
155
|
+
callName: 'freshBootsReasoning',
|
|
156
|
+
tellaskContent: tellaskContent.value,
|
|
157
|
+
effort: effort.value,
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
case 'tellask': {
|
|
162
|
+
const target = readTargetAgentId(args);
|
|
163
|
+
if (!target.ok) {
|
|
164
|
+
return target;
|
|
165
|
+
}
|
|
166
|
+
const normalizedTarget = normalizeTeammateTargetAgentId(target.value);
|
|
167
|
+
if (!normalizedTarget.ok) {
|
|
168
|
+
return normalizedTarget;
|
|
169
|
+
}
|
|
170
|
+
const sessionSlug = readRequiredStringField(args, 'sessionSlug');
|
|
171
|
+
if (!sessionSlug.ok) {
|
|
172
|
+
return sessionSlug;
|
|
173
|
+
}
|
|
174
|
+
if (!isValidSessionSlug(sessionSlug.value)) {
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
error: "field 'sessionSlug' must match <alpha>[<alnum|_|->]*(.<segment>)*, e.g. 'build-loop' or 'repo.sync'",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
ok: true,
|
|
182
|
+
value: {
|
|
183
|
+
callId: call.id,
|
|
184
|
+
callName: 'tellask',
|
|
185
|
+
targetAgentId: normalizedTarget.value,
|
|
186
|
+
sessionSlug: sessionSlug.value,
|
|
187
|
+
mentionList: [`@${normalizedTarget.value}`],
|
|
188
|
+
tellaskContent: tellaskContent.value,
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
case 'tellaskSessionless': {
|
|
193
|
+
const target = readTargetAgentId(args);
|
|
194
|
+
if (!target.ok) {
|
|
195
|
+
return target;
|
|
196
|
+
}
|
|
197
|
+
const normalizedTarget = normalizeTeammateTargetAgentId(target.value);
|
|
198
|
+
if (!normalizedTarget.ok) {
|
|
199
|
+
return normalizedTarget;
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
ok: true,
|
|
203
|
+
value: {
|
|
204
|
+
callId: call.id,
|
|
205
|
+
callName: 'tellaskSessionless',
|
|
206
|
+
targetAgentId: normalizedTarget.value,
|
|
207
|
+
mentionList: [`@${normalizedTarget.value}`],
|
|
208
|
+
tellaskContent: tellaskContent.value,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function classifyTellaskSpecialFunctionCalls(funcCalls, options) {
|
|
215
|
+
const specialCalls = [];
|
|
216
|
+
const normalCalls = [];
|
|
217
|
+
const parseIssues = [];
|
|
218
|
+
const allowed = options?.allowedSpecials ?? null;
|
|
219
|
+
for (const call of funcCalls) {
|
|
220
|
+
if (!isTellaskSpecialFunctionName(call.name)) {
|
|
221
|
+
normalCalls.push(call);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (allowed && !allowed.has(call.name)) {
|
|
225
|
+
normalCalls.push(call);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const parsed = parseTellaskSpecialCall(call);
|
|
229
|
+
if (!parsed.ok) {
|
|
230
|
+
parseIssues.push({ call, error: parsed.error });
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
specialCalls.push(parsed.value);
|
|
234
|
+
}
|
|
235
|
+
return { specialCalls, normalCalls, parseIssues };
|
|
236
|
+
}
|
|
237
|
+
function showErrorToAi(err) {
|
|
238
|
+
try {
|
|
239
|
+
if (err instanceof Error) {
|
|
240
|
+
return `${err.name}: ${err.message}${err.stack ? `\n${err.stack}` : ''}`;
|
|
241
|
+
}
|
|
242
|
+
if (typeof err === 'string') {
|
|
243
|
+
const s = err.trim();
|
|
244
|
+
return s.length > 500 ? `${s.slice(0, 497)}...` : s;
|
|
245
|
+
}
|
|
246
|
+
return (0, util_1.inspect)(err, { depth: 5, breakLength: 120, compact: false, sorted: true });
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return `Unknown error of type ${typeof err}`;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function ensureCallbacks(callbacks) {
|
|
253
|
+
if (!callbacks) {
|
|
254
|
+
throw new Error('driver-v2 tellask executor requires drive callbacks');
|
|
255
|
+
}
|
|
256
|
+
return callbacks;
|
|
257
|
+
}
|
|
258
|
+
async function syncPendingTellaskReminderBestEffort(dlg, where) {
|
|
259
|
+
try {
|
|
260
|
+
const changed = await (0, pending_tellask_reminder_1.syncPendingTellaskReminderState)(dlg);
|
|
261
|
+
if (!changed)
|
|
262
|
+
return;
|
|
263
|
+
await dlg.processReminderUpdates();
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
log_1.log.warn('Failed to sync pending tellask reminder', undefined, {
|
|
267
|
+
where,
|
|
268
|
+
dialogId: dlg.id.selfId,
|
|
269
|
+
rootId: dlg.id.rootId,
|
|
270
|
+
error: err instanceof Error ? err.message : String(err),
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function isValidSessionSlug(sessionSlug) {
|
|
275
|
+
const segments = sessionSlug.split('.');
|
|
276
|
+
if (segments.length === 0)
|
|
277
|
+
return false;
|
|
278
|
+
return segments.every((segment) => /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(segment));
|
|
279
|
+
}
|
|
280
|
+
function resolveFbrEffort(member) {
|
|
281
|
+
const raw = member?.fbr_effort;
|
|
282
|
+
if (typeof raw !== 'number' || !Number.isFinite(raw))
|
|
283
|
+
return 0;
|
|
284
|
+
if (!Number.isInteger(raw))
|
|
285
|
+
return 0;
|
|
286
|
+
if (raw < 0)
|
|
287
|
+
return 0;
|
|
288
|
+
if (raw > 100)
|
|
289
|
+
return 0;
|
|
290
|
+
return raw;
|
|
291
|
+
}
|
|
292
|
+
async function createSubDialog(callerDialog, targetAgentId, mentionList, tellaskContent, options) {
|
|
293
|
+
return await callerDialog.createSubDialog(targetAgentId, mentionList, tellaskContent, options);
|
|
294
|
+
}
|
|
295
|
+
async function updateSubdialogAssignment(subdialog, assignment) {
|
|
296
|
+
subdialog.assignmentFromSup = assignment;
|
|
297
|
+
await persistence_1.DialogPersistence.updateSubdialogAssignment(subdialog.id, assignment);
|
|
298
|
+
}
|
|
299
|
+
async function lookupLiveRegisteredSubdialog(rootDialog, agentId, sessionSlug) {
|
|
300
|
+
const existing = rootDialog.lookupSubdialog(agentId, sessionSlug);
|
|
301
|
+
if (!existing) {
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
304
|
+
const existingSession = existing.sessionSlug;
|
|
305
|
+
if (!existingSession) {
|
|
306
|
+
throw new Error(`Type B registry invariant violation: lookupSubdialog returned entry without sessionSlug (root=${rootDialog.id.valueOf()} sub=${existing.id.valueOf()})`);
|
|
307
|
+
}
|
|
308
|
+
const latest = await persistence_1.DialogPersistence.loadDialogLatest(existing.id, rootDialog.status);
|
|
309
|
+
const runState = latest?.runState;
|
|
310
|
+
if (!runState || runState.kind !== 'dead') {
|
|
311
|
+
return existing;
|
|
312
|
+
}
|
|
313
|
+
const removed = rootDialog.unregisterSubdialog(existing.agentId, existingSession);
|
|
314
|
+
if (!removed) {
|
|
315
|
+
throw new Error(`Failed to unregister dead registered subdialog: root=${rootDialog.id.valueOf()} sub=${existing.id.valueOf()} session=${existingSession}`);
|
|
316
|
+
}
|
|
317
|
+
await rootDialog.saveSubdialogRegistry();
|
|
318
|
+
log_1.log.debug('Pruned dead registered subdialog from Type B registry', undefined, {
|
|
319
|
+
rootId: rootDialog.id.rootId,
|
|
320
|
+
subdialogId: existing.id.selfId,
|
|
321
|
+
agentId: existing.agentId,
|
|
322
|
+
sessionSlug: existingSession,
|
|
323
|
+
});
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
function extractLastAssistantResponse(messages, defaultMessage) {
|
|
327
|
+
let responseText = '';
|
|
328
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
329
|
+
const msg = messages[i];
|
|
330
|
+
if (msg.type === 'saying_msg' && typeof msg.content === 'string') {
|
|
331
|
+
responseText = msg.content;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
if (msg.type === 'thinking_msg' && typeof msg.content === 'string') {
|
|
335
|
+
responseText = msg.content;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (!responseText) {
|
|
339
|
+
responseText = defaultMessage;
|
|
340
|
+
}
|
|
341
|
+
return responseText;
|
|
342
|
+
}
|
|
343
|
+
async function extractSupdialogResponseForTypeA(supdialog) {
|
|
344
|
+
try {
|
|
345
|
+
return extractLastAssistantResponse(supdialog.msgs, 'Supdialog completed without producing output.');
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
log_1.log.warn('Failed to extract supdialog response for Type A', err);
|
|
349
|
+
return 'Supdialog completed with errors.';
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
async function executeTellaskCall(dlg, agent, mentionList, body, callId, callbacks, options) {
|
|
353
|
+
const toolOutputs = [];
|
|
354
|
+
let suspend = false;
|
|
355
|
+
const subdialogsCreated = [];
|
|
356
|
+
const callName = options.callName;
|
|
357
|
+
const parseResult = options.parseResult;
|
|
358
|
+
const normalizedMentionList = mentionList ?? [];
|
|
359
|
+
const isFreshBootsCall = callName === 'freshBootsReasoning';
|
|
360
|
+
const team = await team_1.Team.load();
|
|
361
|
+
const member = parseResult !== null && parseResult.type !== 'A' ? team.getMember(parseResult.agentId) : null;
|
|
362
|
+
const isQ4H = callName === 'askHuman';
|
|
363
|
+
if (isQ4H) {
|
|
364
|
+
try {
|
|
365
|
+
const normalizedCallId = callId.trim();
|
|
366
|
+
if (normalizedCallId === '') {
|
|
367
|
+
throw new Error(`Q4H call invariant violation: empty callId (rootId=${dlg.id.rootId} selfId=${dlg.id.selfId})`);
|
|
368
|
+
}
|
|
369
|
+
const questionId = `q4h-${dlg.id.rootId}-${dlg.id.selfId}-c${dlg.currentCourse}-${normalizedCallId}`;
|
|
370
|
+
const normalizedRemainingCallIds = Array.from(new Set((options?.q4hRemainingCallIds ?? [])
|
|
371
|
+
.map((value) => value.trim())
|
|
372
|
+
.filter((value) => value !== '' && value !== normalizedCallId)));
|
|
373
|
+
const question = {
|
|
374
|
+
id: questionId,
|
|
375
|
+
tellaskContent: body.trim(),
|
|
376
|
+
askedAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
377
|
+
callId: normalizedCallId,
|
|
378
|
+
remainingCallIds: normalizedRemainingCallIds.length > 0 ? normalizedRemainingCallIds : undefined,
|
|
379
|
+
callSiteRef: {
|
|
380
|
+
course: dlg.currentCourse,
|
|
381
|
+
messageIndex: dlg.msgs.length,
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
await persistence_1.DialogPersistence.appendQuestion4HumanState(dlg.id, question);
|
|
385
|
+
const newQuestionEvent = {
|
|
386
|
+
type: 'new_q4h_asked',
|
|
387
|
+
question: {
|
|
388
|
+
id: question.id,
|
|
389
|
+
selfId: dlg.id.selfId,
|
|
390
|
+
tellaskContent: question.tellaskContent,
|
|
391
|
+
askedAt: question.askedAt,
|
|
392
|
+
callId: question.callId,
|
|
393
|
+
remainingCallIds: question.remainingCallIds,
|
|
394
|
+
callSiteRef: question.callSiteRef,
|
|
395
|
+
rootId: dlg.id.rootId,
|
|
396
|
+
agentId: dlg.agentId,
|
|
397
|
+
taskDocPath: dlg.taskDocPath,
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
(0, evt_registry_1.postDialogEvent)(dlg, newQuestionEvent);
|
|
401
|
+
return { toolOutputs, suspend: true, subdialogsCreated: [] };
|
|
402
|
+
}
|
|
403
|
+
catch (q4hErr) {
|
|
404
|
+
const errMsg = q4hErr instanceof Error ? q4hErr.message : String(q4hErr);
|
|
405
|
+
const streamErr = `Q4H register invariant violation: dialog=${dlg.id.selfId} callId=${callId.trim()} reason=${errMsg}`;
|
|
406
|
+
try {
|
|
407
|
+
await dlg.streamError(streamErr);
|
|
408
|
+
}
|
|
409
|
+
catch (streamErrPost) {
|
|
410
|
+
log_1.log.warn('Q4H: failed to emit stream_error_evt', streamErrPost, {
|
|
411
|
+
dialogId: dlg.id.selfId,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
log_1.log.error('Q4H: Failed to register question', q4hErr, {
|
|
415
|
+
dialogId: dlg.id.selfId,
|
|
416
|
+
callId,
|
|
417
|
+
});
|
|
418
|
+
const msg = (0, driver_messages_1.formatDomindsNoteQ4HRegisterFailed)((0, runtime_language_1.getWorkLanguage)(), { error: errMsg });
|
|
419
|
+
toolOutputs.push({ type: 'environment_msg', role: 'user', content: msg });
|
|
420
|
+
toolOutputs.push({
|
|
421
|
+
type: 'tellask_result_msg',
|
|
422
|
+
role: 'tool',
|
|
423
|
+
responderId: 'dominds',
|
|
424
|
+
mentionList: normalizedMentionList,
|
|
425
|
+
tellaskContent: body,
|
|
426
|
+
status: 'failed',
|
|
427
|
+
callId,
|
|
428
|
+
content: msg,
|
|
429
|
+
});
|
|
430
|
+
await dlg.receiveTeammateCallResult('dominds', callName, mentionList, body, msg, 'failed', callId);
|
|
431
|
+
dlg.clearCurrentCallId();
|
|
432
|
+
return { toolOutputs, suspend: false, subdialogsCreated: [] };
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (parseResult) {
|
|
436
|
+
if (callName === 'tellaskBack' && parseResult.type !== 'A') {
|
|
437
|
+
throw new Error(`tellaskBack invariant violation: expected Type A parseResult (callId=${callId}, got=${parseResult.type})`);
|
|
438
|
+
}
|
|
439
|
+
const subdialogCallName = callName === 'tellaskBack' ? 'freshBootsReasoning' : callName;
|
|
440
|
+
const rawCallingCourse = dlg.activeGenCourseOrUndefined ?? dlg.currentCourse;
|
|
441
|
+
const callingCourse = Number.isFinite(rawCallingCourse) && rawCallingCourse > 0
|
|
442
|
+
? Math.floor(rawCallingCourse)
|
|
443
|
+
: undefined;
|
|
444
|
+
const firstMentionForError = options.targetForError ?? parseResult.agentId;
|
|
445
|
+
if (parseResult.type !== 'A' && member === null) {
|
|
446
|
+
const msg = (0, driver_messages_1.formatDomindsNoteTellaskForTeammatesOnly)((0, runtime_language_1.getWorkLanguage)(), {
|
|
447
|
+
firstMention: firstMentionForError,
|
|
448
|
+
});
|
|
449
|
+
toolOutputs.push({ type: 'environment_msg', role: 'user', content: msg });
|
|
450
|
+
toolOutputs.push({
|
|
451
|
+
type: 'tellask_result_msg',
|
|
452
|
+
role: 'tool',
|
|
453
|
+
responderId: 'dominds',
|
|
454
|
+
mentionList: normalizedMentionList,
|
|
455
|
+
tellaskContent: body,
|
|
456
|
+
status: 'failed',
|
|
457
|
+
callId,
|
|
458
|
+
content: msg,
|
|
459
|
+
});
|
|
460
|
+
await dlg.receiveTeammateCallResult('dominds', callName, mentionList, body, msg, 'failed', callId);
|
|
461
|
+
dlg.clearCurrentCallId();
|
|
462
|
+
return { toolOutputs, suspend: false, subdialogsCreated: [] };
|
|
463
|
+
}
|
|
464
|
+
if (isFreshBootsCall) {
|
|
465
|
+
const memberFbrEffort = resolveFbrEffort(member);
|
|
466
|
+
if (memberFbrEffort < 1) {
|
|
467
|
+
const msg = (0, driver_messages_1.formatDomindsNoteFbrDisabled)((0, runtime_language_1.getWorkLanguage)());
|
|
468
|
+
toolOutputs.push({ type: 'environment_msg', role: 'user', content: msg });
|
|
469
|
+
toolOutputs.push({
|
|
470
|
+
type: 'tellask_result_msg',
|
|
471
|
+
role: 'tool',
|
|
472
|
+
responderId: 'dominds',
|
|
473
|
+
mentionList: normalizedMentionList,
|
|
474
|
+
tellaskContent: body,
|
|
475
|
+
status: 'failed',
|
|
476
|
+
callId,
|
|
477
|
+
content: msg,
|
|
478
|
+
});
|
|
479
|
+
await dlg.receiveTeammateCallResult('dominds', callName, mentionList, body, msg, 'failed', callId);
|
|
480
|
+
dlg.clearCurrentCallId();
|
|
481
|
+
return { toolOutputs, suspend: false, subdialogsCreated: [] };
|
|
482
|
+
}
|
|
483
|
+
const override = options.fbrEffortOverride;
|
|
484
|
+
if (override !== undefined &&
|
|
485
|
+
(!Number.isFinite(override) ||
|
|
486
|
+
!Number.isInteger(override) ||
|
|
487
|
+
override < 0 ||
|
|
488
|
+
override > 100)) {
|
|
489
|
+
throw new Error(`freshBootsReasoning invariant violation: effort override out of range [0,100] (got=${override})`);
|
|
490
|
+
}
|
|
491
|
+
const fbrEffort = override ?? memberFbrEffort;
|
|
492
|
+
if (fbrEffort < 1) {
|
|
493
|
+
const msg = (0, driver_messages_1.formatDomindsNoteFbrDisabled)((0, runtime_language_1.getWorkLanguage)());
|
|
494
|
+
toolOutputs.push({ type: 'environment_msg', role: 'user', content: msg });
|
|
495
|
+
toolOutputs.push({
|
|
496
|
+
type: 'tellask_result_msg',
|
|
497
|
+
role: 'tool',
|
|
498
|
+
responderId: 'dominds',
|
|
499
|
+
mentionList: normalizedMentionList,
|
|
500
|
+
tellaskContent: body,
|
|
501
|
+
status: 'failed',
|
|
502
|
+
callId,
|
|
503
|
+
content: msg,
|
|
504
|
+
});
|
|
505
|
+
await dlg.receiveTeammateCallResult('dominds', callName, mentionList, body, msg, 'failed', callId);
|
|
506
|
+
dlg.clearCurrentCallId();
|
|
507
|
+
return { toolOutputs, suspend: false, subdialogsCreated: [] };
|
|
508
|
+
}
|
|
509
|
+
const callerDialog = dlg;
|
|
510
|
+
const originMemberId = dlg.agentId;
|
|
511
|
+
const workLanguage = (0, runtime_language_1.getWorkLanguage)();
|
|
512
|
+
const collectiveTargets = options?.collectiveTargets ?? [parseResult.agentId];
|
|
513
|
+
if (parseResult.type !== 'C') {
|
|
514
|
+
const msg = (0, driver_messages_1.formatDomindsNoteFbrToollessViolation)((0, runtime_language_1.getWorkLanguage)(), {
|
|
515
|
+
kind: 'internal_error',
|
|
516
|
+
});
|
|
517
|
+
toolOutputs.push({ type: 'environment_msg', role: 'user', content: msg });
|
|
518
|
+
toolOutputs.push({
|
|
519
|
+
type: 'tellask_result_msg',
|
|
520
|
+
role: 'tool',
|
|
521
|
+
responderId: 'dominds',
|
|
522
|
+
mentionList: normalizedMentionList,
|
|
523
|
+
tellaskContent: body,
|
|
524
|
+
status: 'failed',
|
|
525
|
+
callId,
|
|
526
|
+
content: msg,
|
|
527
|
+
});
|
|
528
|
+
await dlg.receiveTeammateCallResult('dominds', callName, mentionList, body, msg, 'failed', callId);
|
|
529
|
+
dlg.clearCurrentCallId();
|
|
530
|
+
return { toolOutputs, suspend: false, subdialogsCreated: [] };
|
|
531
|
+
}
|
|
532
|
+
const buildRoundBody = (iteration, total) => (0, fbr_1.appendDistinctPerspectiveFbrBody)({
|
|
533
|
+
body,
|
|
534
|
+
iteration,
|
|
535
|
+
total,
|
|
536
|
+
language: workLanguage,
|
|
537
|
+
isFinalRound: iteration === total,
|
|
538
|
+
});
|
|
539
|
+
const firstInstanceBody = buildRoundBody(1, fbrEffort);
|
|
540
|
+
const sub = await createSubDialog(dlg, parseResult.agentId, mentionList, firstInstanceBody, {
|
|
541
|
+
callName: subdialogCallName,
|
|
542
|
+
originMemberId,
|
|
543
|
+
callerDialogId: callerDialog.id.selfId,
|
|
544
|
+
callId,
|
|
545
|
+
collectiveTargets,
|
|
546
|
+
});
|
|
547
|
+
subdialogsCreated.push(sub.id);
|
|
548
|
+
for (let i = 1; i <= fbrEffort; i++) {
|
|
549
|
+
const instanceBody = buildRoundBody(i, fbrEffort);
|
|
550
|
+
const isFinalRound = i === fbrEffort;
|
|
551
|
+
const shouldReplyToCaller = isFinalRound;
|
|
552
|
+
if (shouldReplyToCaller) {
|
|
553
|
+
const pendingRecord = {
|
|
554
|
+
subdialogId: sub.id.selfId,
|
|
555
|
+
createdAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
556
|
+
callName: subdialogCallName,
|
|
557
|
+
mentionList,
|
|
558
|
+
tellaskContent: body,
|
|
559
|
+
targetAgentId: parseResult.agentId,
|
|
560
|
+
callId,
|
|
561
|
+
callingCourse,
|
|
562
|
+
callType: 'C',
|
|
563
|
+
};
|
|
564
|
+
await (0, subdialog_txn_1.withSubdialogTxnLock)(dlg.id, async () => {
|
|
565
|
+
await persistence_1.DialogPersistence.appendPendingSubdialog(dlg.id, pendingRecord);
|
|
566
|
+
});
|
|
567
|
+
await syncPendingTellaskReminderBestEffort(dlg, 'driver-v2:executeTellaskCall:FBR-TypeC:appendPending:lastRound');
|
|
568
|
+
}
|
|
569
|
+
const initPrompt = {
|
|
570
|
+
content: (0, inter_dialog_format_1.formatAssignmentFromSupdialog)({
|
|
571
|
+
callName: subdialogCallName,
|
|
572
|
+
fromAgentId: dlg.agentId,
|
|
573
|
+
toAgentId: sub.agentId,
|
|
574
|
+
mentionList,
|
|
575
|
+
tellaskContent: instanceBody,
|
|
576
|
+
language: workLanguage,
|
|
577
|
+
collectiveTargets: [sub.agentId],
|
|
578
|
+
fbrRound: {
|
|
579
|
+
iteration: i,
|
|
580
|
+
total: fbrEffort,
|
|
581
|
+
},
|
|
582
|
+
}),
|
|
583
|
+
msgId: (0, id_1.generateShortId)(),
|
|
584
|
+
grammar: 'markdown',
|
|
585
|
+
...(shouldReplyToCaller
|
|
586
|
+
? {
|
|
587
|
+
subdialogReplyTarget: {
|
|
588
|
+
ownerDialogId: callerDialog.id.selfId,
|
|
589
|
+
callType: 'C',
|
|
590
|
+
callId,
|
|
591
|
+
},
|
|
592
|
+
}
|
|
593
|
+
: {}),
|
|
594
|
+
};
|
|
595
|
+
try {
|
|
596
|
+
await callbacks.driveDialog(sub, { humanPrompt: initPrompt, waitInQue: true });
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
600
|
+
log_1.log.error('FBR Type C serial drive failed', error, {
|
|
601
|
+
rootId: dlg.id.rootId,
|
|
602
|
+
ownerDialogId: callerDialog.id.selfId,
|
|
603
|
+
subdialogId: sub.id.selfId,
|
|
604
|
+
iteration: i,
|
|
605
|
+
total: fbrEffort,
|
|
606
|
+
callName: subdialogCallName,
|
|
607
|
+
callId,
|
|
608
|
+
detail,
|
|
609
|
+
});
|
|
610
|
+
throw new Error(`FBR serial round ${i}/${fbrEffort} failed: ${detail}`);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
// FBR Type-C rounds are driven inline via callbacks.driveDialog(...), and the final round
|
|
614
|
+
// may already have supplied a teammate response back to the caller before we return here.
|
|
615
|
+
// Suspending unconditionally in that case would stop the caller turn and can race with
|
|
616
|
+
// backend-loop queue cleanup (needsDrive gets cleared as "idle"), dropping continuation.
|
|
617
|
+
// Only suspend when there is still a pending response record for this call.
|
|
618
|
+
const hasPendingFbrResponse = await (0, subdialog_txn_1.withSubdialogTxnLock)(dlg.id, async () => {
|
|
619
|
+
const pending = await persistence_1.DialogPersistence.loadPendingSubdialogs(dlg.id, dlg.status);
|
|
620
|
+
return pending.some((record) => record.callId === callId &&
|
|
621
|
+
record.callType === 'C' &&
|
|
622
|
+
record.subdialogId === sub.id.selfId);
|
|
623
|
+
});
|
|
624
|
+
return { toolOutputs, suspend: hasPendingFbrResponse, subdialogsCreated };
|
|
625
|
+
}
|
|
626
|
+
const isDirectSelfCall = !isFreshBootsCall && parseResult.agentId === dlg.agentId;
|
|
627
|
+
if (isDirectSelfCall) {
|
|
628
|
+
const msg = (0, driver_messages_1.formatDomindsNoteDirectSelfCall)((0, runtime_language_1.getWorkLanguage)());
|
|
629
|
+
toolOutputs.push({ type: 'environment_msg', role: 'user', content: msg });
|
|
630
|
+
toolOutputs.push({
|
|
631
|
+
type: 'tellask_result_msg',
|
|
632
|
+
role: 'tool',
|
|
633
|
+
responderId: 'dominds',
|
|
634
|
+
mentionList: normalizedMentionList,
|
|
635
|
+
tellaskContent: body,
|
|
636
|
+
status: 'failed',
|
|
637
|
+
callId,
|
|
638
|
+
content: msg,
|
|
639
|
+
});
|
|
640
|
+
await dlg.receiveTeammateCallResult('dominds', callName, mentionList, body, msg, 'failed', callId);
|
|
641
|
+
dlg.clearCurrentCallId();
|
|
642
|
+
return { toolOutputs, suspend: false, subdialogsCreated: [] };
|
|
643
|
+
}
|
|
644
|
+
if (parseResult.type === 'A') {
|
|
645
|
+
if (dlg instanceof dialog_1.SubDialog) {
|
|
646
|
+
const supdialog = dlg.supdialog;
|
|
647
|
+
dlg.setSuspensionState('suspended');
|
|
648
|
+
try {
|
|
649
|
+
const assignment = dlg.assignmentFromSup;
|
|
650
|
+
const supPrompt = {
|
|
651
|
+
content: (0, inter_dialog_format_1.formatSupdialogCallPrompt)({
|
|
652
|
+
fromAgentId: dlg.agentId,
|
|
653
|
+
toAgentId: supdialog.agentId,
|
|
654
|
+
subdialogRequest: {
|
|
655
|
+
callName,
|
|
656
|
+
mentionList,
|
|
657
|
+
tellaskContent: body,
|
|
658
|
+
},
|
|
659
|
+
supdialogAssignment: {
|
|
660
|
+
callName: assignment.callName,
|
|
661
|
+
mentionList: assignment.mentionList,
|
|
662
|
+
tellaskContent: assignment.tellaskContent,
|
|
663
|
+
},
|
|
664
|
+
language: (0, runtime_language_1.getWorkLanguage)(),
|
|
665
|
+
}),
|
|
666
|
+
msgId: (0, id_1.generateShortId)(),
|
|
667
|
+
grammar: 'markdown',
|
|
668
|
+
};
|
|
669
|
+
await callbacks.driveDialog(supdialog, { humanPrompt: supPrompt, waitInQue: true });
|
|
670
|
+
const responseText = await extractSupdialogResponseForTypeA(supdialog);
|
|
671
|
+
const responseContent = (0, inter_dialog_format_1.formatTeammateResponseContent)({
|
|
672
|
+
callName,
|
|
673
|
+
responderId: parseResult.agentId,
|
|
674
|
+
requesterId: dlg.agentId,
|
|
675
|
+
mentionList,
|
|
676
|
+
tellaskContent: body,
|
|
677
|
+
responseBody: responseText,
|
|
678
|
+
status: 'completed',
|
|
679
|
+
language: (0, runtime_language_1.getWorkLanguage)(),
|
|
680
|
+
});
|
|
681
|
+
dlg.setSuspensionState('resumed');
|
|
682
|
+
toolOutputs.push({
|
|
683
|
+
type: 'tellask_result_msg',
|
|
684
|
+
role: 'tool',
|
|
685
|
+
responderId: parseResult.agentId,
|
|
686
|
+
mentionList,
|
|
687
|
+
tellaskContent: body,
|
|
688
|
+
status: 'completed',
|
|
689
|
+
callId,
|
|
690
|
+
content: responseContent,
|
|
691
|
+
});
|
|
692
|
+
await dlg.receiveTeammateResponse(parseResult.agentId, callName, mentionList, body, 'completed', supdialog.id, {
|
|
693
|
+
response: responseContent,
|
|
694
|
+
agentId: parseResult.agentId,
|
|
695
|
+
callId,
|
|
696
|
+
originMemberId: dlg.agentId,
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
catch (err) {
|
|
700
|
+
log_1.log.warn('Type A supdialog processing error:', err);
|
|
701
|
+
dlg.setSuspensionState('resumed');
|
|
702
|
+
const errorText = `❌ **Error processing request to @${parseResult.agentId}:**\n\n${showErrorToAi(err)}`;
|
|
703
|
+
const errorContent = (0, inter_dialog_format_1.formatTeammateResponseContent)({
|
|
704
|
+
callName,
|
|
705
|
+
responderId: parseResult.agentId,
|
|
706
|
+
requesterId: dlg.agentId,
|
|
707
|
+
mentionList,
|
|
708
|
+
tellaskContent: body,
|
|
709
|
+
responseBody: errorText,
|
|
710
|
+
status: 'failed',
|
|
711
|
+
language: (0, runtime_language_1.getWorkLanguage)(),
|
|
712
|
+
});
|
|
713
|
+
toolOutputs.push({
|
|
714
|
+
type: 'tellask_result_msg',
|
|
715
|
+
role: 'tool',
|
|
716
|
+
responderId: parseResult.agentId,
|
|
717
|
+
mentionList,
|
|
718
|
+
tellaskContent: body,
|
|
719
|
+
status: 'failed',
|
|
720
|
+
callId,
|
|
721
|
+
content: errorContent,
|
|
722
|
+
});
|
|
723
|
+
await dlg.receiveTeammateResponse(parseResult.agentId, callName, mentionList, body, 'failed', supdialog.id, {
|
|
724
|
+
response: errorContent,
|
|
725
|
+
agentId: parseResult.agentId,
|
|
726
|
+
callId,
|
|
727
|
+
originMemberId: dlg.agentId,
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
log_1.log.warn('Type A call on dialog without supdialog, falling back to Type C', undefined, {
|
|
733
|
+
dialogId: dlg.id.selfId,
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
else if (parseResult.type === 'B') {
|
|
738
|
+
const callerDialog = dlg;
|
|
739
|
+
let rootDialog;
|
|
740
|
+
if (dlg instanceof dialog_1.RootDialog) {
|
|
741
|
+
rootDialog = dlg;
|
|
742
|
+
}
|
|
743
|
+
else if (dlg instanceof dialog_1.SubDialog) {
|
|
744
|
+
rootDialog = dlg.rootDialog;
|
|
745
|
+
}
|
|
746
|
+
if (!rootDialog) {
|
|
747
|
+
log_1.log.warn('Type B call without root dialog, falling back to Type C', undefined, {
|
|
748
|
+
dialogId: dlg.id.selfId,
|
|
749
|
+
});
|
|
750
|
+
try {
|
|
751
|
+
const sub = await createSubDialog(dlg, parseResult.agentId, mentionList, body, {
|
|
752
|
+
callName: subdialogCallName,
|
|
753
|
+
originMemberId: dlg.agentId,
|
|
754
|
+
callerDialogId: callerDialog.id.selfId,
|
|
755
|
+
callId,
|
|
756
|
+
sessionSlug: parseResult.sessionSlug,
|
|
757
|
+
collectiveTargets: options?.collectiveTargets ?? [parseResult.agentId],
|
|
758
|
+
});
|
|
759
|
+
const pendingRecord = {
|
|
760
|
+
subdialogId: sub.id.selfId,
|
|
761
|
+
createdAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
762
|
+
callName: subdialogCallName,
|
|
763
|
+
mentionList,
|
|
764
|
+
tellaskContent: body,
|
|
765
|
+
targetAgentId: parseResult.agentId,
|
|
766
|
+
callId,
|
|
767
|
+
callingCourse,
|
|
768
|
+
callType: 'C',
|
|
769
|
+
sessionSlug: parseResult.sessionSlug,
|
|
770
|
+
};
|
|
771
|
+
await (0, subdialog_txn_1.withSubdialogTxnLock)(dlg.id, async () => {
|
|
772
|
+
await persistence_1.DialogPersistence.appendPendingSubdialog(dlg.id, pendingRecord);
|
|
773
|
+
});
|
|
774
|
+
await syncPendingTellaskReminderBestEffort(dlg, 'driver-v2:executeTellaskCall:TypeB-fallback:appendPending');
|
|
775
|
+
const initPrompt = {
|
|
776
|
+
content: (0, inter_dialog_format_1.formatAssignmentFromSupdialog)({
|
|
777
|
+
callName: subdialogCallName,
|
|
778
|
+
fromAgentId: dlg.agentId,
|
|
779
|
+
toAgentId: sub.agentId,
|
|
780
|
+
mentionList,
|
|
781
|
+
tellaskContent: body,
|
|
782
|
+
language: (0, runtime_language_1.getWorkLanguage)(),
|
|
783
|
+
collectiveTargets: options?.collectiveTargets ?? [sub.agentId],
|
|
784
|
+
}),
|
|
785
|
+
msgId: (0, id_1.generateShortId)(),
|
|
786
|
+
grammar: 'markdown',
|
|
787
|
+
subdialogReplyTarget: {
|
|
788
|
+
ownerDialogId: callerDialog.id.selfId,
|
|
789
|
+
callType: 'C',
|
|
790
|
+
callId,
|
|
791
|
+
},
|
|
792
|
+
};
|
|
793
|
+
callbacks.scheduleDrive(sub, { humanPrompt: initPrompt, waitInQue: true });
|
|
794
|
+
subdialogsCreated.push(sub.id);
|
|
795
|
+
suspend = true;
|
|
796
|
+
}
|
|
797
|
+
catch (err) {
|
|
798
|
+
log_1.log.warn('Type B fallback subdialog creation error:', err);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
else {
|
|
802
|
+
const originMemberId = dlg.agentId;
|
|
803
|
+
const assignment = {
|
|
804
|
+
callName: subdialogCallName,
|
|
805
|
+
mentionList,
|
|
806
|
+
tellaskContent: body,
|
|
807
|
+
originMemberId,
|
|
808
|
+
callerDialogId: callerDialog.id.selfId,
|
|
809
|
+
callId,
|
|
810
|
+
collectiveTargets: options?.collectiveTargets ?? [parseResult.agentId],
|
|
811
|
+
};
|
|
812
|
+
const pendingOwner = callerDialog;
|
|
813
|
+
const result = await (0, subdialog_txn_1.withSubdialogTxnLock)(rootDialog.id, async () => {
|
|
814
|
+
const existing = await lookupLiveRegisteredSubdialog(rootDialog, parseResult.agentId, parseResult.sessionSlug);
|
|
815
|
+
if (existing) {
|
|
816
|
+
try {
|
|
817
|
+
await updateSubdialogAssignment(existing, assignment);
|
|
818
|
+
}
|
|
819
|
+
catch (err) {
|
|
820
|
+
log_1.log.warn('Failed to update registered subdialog assignment', err);
|
|
821
|
+
}
|
|
822
|
+
return { kind: 'existing', subdialog: existing };
|
|
823
|
+
}
|
|
824
|
+
const created = await createSubDialog(rootDialog, parseResult.agentId, mentionList, body, {
|
|
825
|
+
callName: subdialogCallName,
|
|
826
|
+
originMemberId,
|
|
827
|
+
callerDialogId: callerDialog.id.selfId,
|
|
828
|
+
callId,
|
|
829
|
+
sessionSlug: parseResult.sessionSlug,
|
|
830
|
+
collectiveTargets: options?.collectiveTargets ?? [parseResult.agentId],
|
|
831
|
+
});
|
|
832
|
+
rootDialog.registerSubdialog(created);
|
|
833
|
+
await rootDialog.saveSubdialogRegistry();
|
|
834
|
+
return { kind: 'created', subdialog: created };
|
|
835
|
+
});
|
|
836
|
+
const pendingRecord = {
|
|
837
|
+
subdialogId: result.subdialog.id.selfId,
|
|
838
|
+
createdAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
839
|
+
callName: subdialogCallName,
|
|
840
|
+
mentionList,
|
|
841
|
+
tellaskContent: body,
|
|
842
|
+
targetAgentId: parseResult.agentId,
|
|
843
|
+
callId,
|
|
844
|
+
callingCourse,
|
|
845
|
+
callType: 'B',
|
|
846
|
+
sessionSlug: parseResult.sessionSlug,
|
|
847
|
+
};
|
|
848
|
+
await (0, subdialog_txn_1.withSubdialogTxnLock)(pendingOwner.id, async () => {
|
|
849
|
+
await persistence_1.DialogPersistence.mutatePendingSubdialogs(pendingOwner.id, (previous) => {
|
|
850
|
+
const next = previous.filter((p) => p.subdialogId !== pendingRecord.subdialogId);
|
|
851
|
+
next.push(pendingRecord);
|
|
852
|
+
return { kind: 'replace', records: next };
|
|
853
|
+
});
|
|
854
|
+
});
|
|
855
|
+
await syncPendingTellaskReminderBestEffort(pendingOwner, 'driver-v2:executeTellaskCall:TypeB:replacePending');
|
|
856
|
+
if (result.kind === 'existing') {
|
|
857
|
+
const resumePrompt = {
|
|
858
|
+
content: (0, inter_dialog_format_1.formatAssignmentFromSupdialog)({
|
|
859
|
+
callName: subdialogCallName,
|
|
860
|
+
fromAgentId: dlg.agentId,
|
|
861
|
+
toAgentId: result.subdialog.agentId,
|
|
862
|
+
mentionList,
|
|
863
|
+
sessionSlug: parseResult.sessionSlug,
|
|
864
|
+
tellaskContent: body,
|
|
865
|
+
language: (0, runtime_language_1.getWorkLanguage)(),
|
|
866
|
+
collectiveTargets: options?.collectiveTargets ?? [result.subdialog.agentId],
|
|
867
|
+
}),
|
|
868
|
+
msgId: (0, id_1.generateShortId)(),
|
|
869
|
+
grammar: 'markdown',
|
|
870
|
+
subdialogReplyTarget: {
|
|
871
|
+
ownerDialogId: pendingOwner.id.selfId,
|
|
872
|
+
callType: 'B',
|
|
873
|
+
callId,
|
|
874
|
+
},
|
|
875
|
+
};
|
|
876
|
+
callbacks.scheduleDrive(result.subdialog, { humanPrompt: resumePrompt, waitInQue: true });
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
const initPrompt = {
|
|
880
|
+
content: (0, inter_dialog_format_1.formatAssignmentFromSupdialog)({
|
|
881
|
+
callName: subdialogCallName,
|
|
882
|
+
fromAgentId: rootDialog.agentId,
|
|
883
|
+
toAgentId: result.subdialog.agentId,
|
|
884
|
+
mentionList,
|
|
885
|
+
sessionSlug: parseResult.sessionSlug,
|
|
886
|
+
tellaskContent: body,
|
|
887
|
+
language: (0, runtime_language_1.getWorkLanguage)(),
|
|
888
|
+
collectiveTargets: options?.collectiveTargets ?? [result.subdialog.agentId],
|
|
889
|
+
}),
|
|
890
|
+
msgId: (0, id_1.generateShortId)(),
|
|
891
|
+
grammar: 'markdown',
|
|
892
|
+
subdialogReplyTarget: {
|
|
893
|
+
ownerDialogId: pendingOwner.id.selfId,
|
|
894
|
+
callType: 'B',
|
|
895
|
+
callId,
|
|
896
|
+
},
|
|
897
|
+
};
|
|
898
|
+
callbacks.scheduleDrive(result.subdialog, { humanPrompt: initPrompt, waitInQue: true });
|
|
899
|
+
}
|
|
900
|
+
subdialogsCreated.push(result.subdialog.id);
|
|
901
|
+
suspend = true;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
if (parseResult.type === 'C') {
|
|
905
|
+
try {
|
|
906
|
+
const sub = await createSubDialog(dlg, parseResult.agentId, mentionList, body, {
|
|
907
|
+
callName: subdialogCallName,
|
|
908
|
+
originMemberId: dlg.agentId,
|
|
909
|
+
callerDialogId: dlg.id.selfId,
|
|
910
|
+
callId,
|
|
911
|
+
collectiveTargets: options?.collectiveTargets ?? [parseResult.agentId],
|
|
912
|
+
});
|
|
913
|
+
const pendingRecord = {
|
|
914
|
+
subdialogId: sub.id.selfId,
|
|
915
|
+
createdAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
916
|
+
callName: subdialogCallName,
|
|
917
|
+
mentionList,
|
|
918
|
+
tellaskContent: body,
|
|
919
|
+
targetAgentId: parseResult.agentId,
|
|
920
|
+
callId,
|
|
921
|
+
callingCourse,
|
|
922
|
+
callType: 'C',
|
|
923
|
+
};
|
|
924
|
+
await (0, subdialog_txn_1.withSubdialogTxnLock)(dlg.id, async () => {
|
|
925
|
+
await persistence_1.DialogPersistence.appendPendingSubdialog(dlg.id, pendingRecord);
|
|
926
|
+
});
|
|
927
|
+
await syncPendingTellaskReminderBestEffort(dlg, 'driver-v2:executeTellaskCall:TypeC:appendPending');
|
|
928
|
+
const initPrompt = {
|
|
929
|
+
content: (0, inter_dialog_format_1.formatAssignmentFromSupdialog)({
|
|
930
|
+
callName,
|
|
931
|
+
fromAgentId: dlg.agentId,
|
|
932
|
+
toAgentId: sub.agentId,
|
|
933
|
+
mentionList,
|
|
934
|
+
tellaskContent: body,
|
|
935
|
+
language: (0, runtime_language_1.getWorkLanguage)(),
|
|
936
|
+
collectiveTargets: options?.collectiveTargets ?? [sub.agentId],
|
|
937
|
+
}),
|
|
938
|
+
msgId: (0, id_1.generateShortId)(),
|
|
939
|
+
grammar: 'markdown',
|
|
940
|
+
subdialogReplyTarget: {
|
|
941
|
+
ownerDialogId: dlg.id.selfId,
|
|
942
|
+
callType: 'C',
|
|
943
|
+
callId,
|
|
944
|
+
},
|
|
945
|
+
};
|
|
946
|
+
callbacks.scheduleDrive(sub, { humanPrompt: initPrompt, waitInQue: true });
|
|
947
|
+
subdialogsCreated.push(sub.id);
|
|
948
|
+
suspend = true;
|
|
949
|
+
}
|
|
950
|
+
catch (err) {
|
|
951
|
+
log_1.log.warn('Subdialog creation error:', err);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
const msg = (0, driver_messages_1.formatDomindsNoteTellaskForTeammatesOnly)((0, runtime_language_1.getWorkLanguage)(), {
|
|
957
|
+
firstMention: options.targetForError ?? 'unknown',
|
|
958
|
+
});
|
|
959
|
+
toolOutputs.push({ type: 'environment_msg', role: 'user', content: msg });
|
|
960
|
+
toolOutputs.push({
|
|
961
|
+
type: 'tellask_result_msg',
|
|
962
|
+
role: 'tool',
|
|
963
|
+
responderId: 'dominds',
|
|
964
|
+
mentionList: normalizedMentionList,
|
|
965
|
+
tellaskContent: body,
|
|
966
|
+
status: 'failed',
|
|
967
|
+
callId,
|
|
968
|
+
content: msg,
|
|
969
|
+
});
|
|
970
|
+
await dlg.receiveTeammateCallResult('dominds', callName, mentionList, body, msg, 'failed', callId);
|
|
971
|
+
dlg.clearCurrentCallId();
|
|
972
|
+
}
|
|
973
|
+
return { toolOutputs, suspend, subdialogsCreated };
|
|
974
|
+
}
|
|
975
|
+
async function emitTellaskSpecialCallEvents(args) {
|
|
976
|
+
await args.dlg.callingStart({
|
|
977
|
+
callName: args.callName,
|
|
978
|
+
callId: args.callId,
|
|
979
|
+
mentionList: args.mentionList,
|
|
980
|
+
sessionSlug: args.sessionSlug,
|
|
981
|
+
tellaskContent: args.tellaskContent,
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
function toExecutableValidTellaskCall(call) {
|
|
985
|
+
switch (call.callName) {
|
|
986
|
+
case 'tellaskBack':
|
|
987
|
+
return {
|
|
988
|
+
callName: call.callName,
|
|
989
|
+
tellaskContent: call.tellaskContent,
|
|
990
|
+
callId: call.callId,
|
|
991
|
+
};
|
|
992
|
+
case 'tellask':
|
|
993
|
+
return {
|
|
994
|
+
callName: call.callName,
|
|
995
|
+
mentionList: [...call.mentionList],
|
|
996
|
+
tellaskContent: call.tellaskContent,
|
|
997
|
+
targetAgentId: call.targetAgentId,
|
|
998
|
+
sessionSlug: call.sessionSlug,
|
|
999
|
+
callId: call.callId,
|
|
1000
|
+
};
|
|
1001
|
+
case 'tellaskSessionless':
|
|
1002
|
+
return {
|
|
1003
|
+
callName: call.callName,
|
|
1004
|
+
mentionList: [...call.mentionList],
|
|
1005
|
+
tellaskContent: call.tellaskContent,
|
|
1006
|
+
targetAgentId: call.targetAgentId,
|
|
1007
|
+
callId: call.callId,
|
|
1008
|
+
};
|
|
1009
|
+
case 'askHuman':
|
|
1010
|
+
return {
|
|
1011
|
+
callName: call.callName,
|
|
1012
|
+
tellaskContent: call.tellaskContent,
|
|
1013
|
+
callId: call.callId,
|
|
1014
|
+
};
|
|
1015
|
+
case 'freshBootsReasoning':
|
|
1016
|
+
return {
|
|
1017
|
+
callName: call.callName,
|
|
1018
|
+
tellaskContent: call.tellaskContent,
|
|
1019
|
+
callId: call.callId,
|
|
1020
|
+
effort: call.effort,
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
function normalizeQ4HCalls(calls, dlg) {
|
|
1025
|
+
const q4hCalls = calls.filter((call) => call.callName === 'askHuman');
|
|
1026
|
+
const nonQ4HCalls = calls
|
|
1027
|
+
.filter((call) => call.callName !== 'askHuman')
|
|
1028
|
+
.map((call) => {
|
|
1029
|
+
switch (call.callName) {
|
|
1030
|
+
case 'tellask':
|
|
1031
|
+
case 'tellaskSessionless':
|
|
1032
|
+
return { ...call, mentionList: [...call.mentionList] };
|
|
1033
|
+
case 'tellaskBack':
|
|
1034
|
+
case 'freshBootsReasoning':
|
|
1035
|
+
return { ...call };
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
if (q4hCalls.length <= 1) {
|
|
1039
|
+
return q4hCalls.length === 1 ? [...nonQ4HCalls, { ...q4hCalls[0] }] : nonQ4HCalls;
|
|
1040
|
+
}
|
|
1041
|
+
const primary = q4hCalls[0];
|
|
1042
|
+
const remainingCallIds = q4hCalls
|
|
1043
|
+
.slice(1)
|
|
1044
|
+
.map((call) => call.callId.trim())
|
|
1045
|
+
.filter((callId) => callId !== '');
|
|
1046
|
+
const language = (0, runtime_language_1.getWorkLanguage)();
|
|
1047
|
+
const intro = language === 'zh'
|
|
1048
|
+
? `我这次有 ${q4hCalls.length} 个问题,想请你一次性回复:`
|
|
1049
|
+
: `I have ${q4hCalls.length} questions this round. Please answer them in one response:`;
|
|
1050
|
+
const mergedBody = [
|
|
1051
|
+
intro,
|
|
1052
|
+
...q4hCalls.map((call, index) => {
|
|
1053
|
+
const body = call.tellaskContent.trim();
|
|
1054
|
+
const normalizedBody = body !== ''
|
|
1055
|
+
? body
|
|
1056
|
+
: language === 'zh'
|
|
1057
|
+
? '请结合当前上下文补充这一项。'
|
|
1058
|
+
: 'Please provide this item based on the current context.';
|
|
1059
|
+
return language === 'zh'
|
|
1060
|
+
? `问题 ${index + 1}:\n${normalizedBody}`
|
|
1061
|
+
: `Question ${index + 1}:\n${normalizedBody}`;
|
|
1062
|
+
}),
|
|
1063
|
+
].join('\n\n');
|
|
1064
|
+
const mergedQ4HCall = {
|
|
1065
|
+
callName: 'askHuman',
|
|
1066
|
+
callId: primary.callId,
|
|
1067
|
+
tellaskContent: mergedBody,
|
|
1068
|
+
q4hRemainingCallIds: remainingCallIds.length > 0 ? remainingCallIds : undefined,
|
|
1069
|
+
};
|
|
1070
|
+
log_1.log.debug('Q4H multi-question normalized into a single prompt', undefined, {
|
|
1071
|
+
rootId: dlg.id.rootId,
|
|
1072
|
+
selfId: dlg.id.selfId,
|
|
1073
|
+
mergedCount: q4hCalls.length,
|
|
1074
|
+
primaryCallId: primary.callId,
|
|
1075
|
+
remainingCallIds,
|
|
1076
|
+
});
|
|
1077
|
+
return [...nonQ4HCalls, mergedQ4HCall];
|
|
1078
|
+
}
|
|
1079
|
+
async function executeValidTellaskCalls(args) {
|
|
1080
|
+
const executionCalls = normalizeQ4HCalls(args.calls, args.dlg);
|
|
1081
|
+
const results = [];
|
|
1082
|
+
for (const call of executionCalls) {
|
|
1083
|
+
const runtimeMentionList = (() => {
|
|
1084
|
+
switch (call.callName) {
|
|
1085
|
+
case 'tellask':
|
|
1086
|
+
case 'tellaskSessionless':
|
|
1087
|
+
return call.mentionList;
|
|
1088
|
+
case 'tellaskBack':
|
|
1089
|
+
case 'askHuman':
|
|
1090
|
+
case 'freshBootsReasoning':
|
|
1091
|
+
return undefined;
|
|
1092
|
+
}
|
|
1093
|
+
})();
|
|
1094
|
+
if (args.emitCallEvents) {
|
|
1095
|
+
const sessionSlug = call.callName === 'tellask' ? call.sessionSlug : undefined;
|
|
1096
|
+
await emitTellaskSpecialCallEvents({
|
|
1097
|
+
dlg: args.dlg,
|
|
1098
|
+
callName: call.callName,
|
|
1099
|
+
mentionList: runtimeMentionList,
|
|
1100
|
+
sessionSlug,
|
|
1101
|
+
tellaskContent: call.tellaskContent,
|
|
1102
|
+
callId: call.callId,
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
let targetForError;
|
|
1106
|
+
let parseResult;
|
|
1107
|
+
switch (call.callName) {
|
|
1108
|
+
case 'tellaskBack': {
|
|
1109
|
+
targetForError = args.dlg instanceof dialog_1.SubDialog ? args.dlg.supdialog.agentId : undefined;
|
|
1110
|
+
parseResult =
|
|
1111
|
+
args.dlg instanceof dialog_1.SubDialog ? { type: 'A', agentId: args.dlg.supdialog.agentId } : null;
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
case 'tellask': {
|
|
1115
|
+
const targetAgentId = call.targetAgentId;
|
|
1116
|
+
if (targetAgentId.trim() === '') {
|
|
1117
|
+
throw new Error(`tellask invariant violation: missing targetAgentId for callId=${call.callId}`);
|
|
1118
|
+
}
|
|
1119
|
+
if (!call.sessionSlug) {
|
|
1120
|
+
throw new Error(`tellask invariant violation: missing sessionSlug for callId=${call.callId}`);
|
|
1121
|
+
}
|
|
1122
|
+
targetForError = targetAgentId;
|
|
1123
|
+
parseResult = { type: 'B', agentId: targetAgentId, sessionSlug: call.sessionSlug };
|
|
1124
|
+
break;
|
|
1125
|
+
}
|
|
1126
|
+
case 'tellaskSessionless': {
|
|
1127
|
+
const targetAgentId = call.targetAgentId;
|
|
1128
|
+
if (targetAgentId.trim() === '') {
|
|
1129
|
+
throw new Error(`tellaskSessionless invariant violation: missing targetAgentId for callId=${call.callId}`);
|
|
1130
|
+
}
|
|
1131
|
+
targetForError = targetAgentId;
|
|
1132
|
+
parseResult = { type: 'C', agentId: targetAgentId };
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
case 'askHuman': {
|
|
1136
|
+
targetForError = undefined;
|
|
1137
|
+
parseResult = null;
|
|
1138
|
+
break;
|
|
1139
|
+
}
|
|
1140
|
+
case 'freshBootsReasoning': {
|
|
1141
|
+
targetForError = args.dlg.agentId;
|
|
1142
|
+
parseResult = { type: 'C', agentId: args.dlg.agentId };
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
const result = await executeTellaskCall(args.dlg, args.agent, runtimeMentionList, call.tellaskContent, call.callId, args.callbacks, {
|
|
1147
|
+
callName: call.callName,
|
|
1148
|
+
parseResult,
|
|
1149
|
+
targetForError,
|
|
1150
|
+
q4hRemainingCallIds: call.q4hRemainingCallIds,
|
|
1151
|
+
fbrEffortOverride: call.callName === 'freshBootsReasoning' ? call.effort : undefined,
|
|
1152
|
+
});
|
|
1153
|
+
results.push(result);
|
|
1154
|
+
}
|
|
1155
|
+
return {
|
|
1156
|
+
suspend: results.some((result) => result.suspend),
|
|
1157
|
+
toolOutputs: results.flatMap((result) => result.toolOutputs),
|
|
1158
|
+
subdialogsCreated: results.flatMap((result) => result.subdialogsCreated),
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
async function executeTellaskSpecialCalls(args) {
|
|
1162
|
+
const callbacks = ensureCallbacks(args.callbacks);
|
|
1163
|
+
if (args.calls.length === 0) {
|
|
1164
|
+
return { suspend: false, toolOutputs: [], subdialogsCreated: [] };
|
|
1165
|
+
}
|
|
1166
|
+
const tellaskResult = await executeValidTellaskCalls({
|
|
1167
|
+
dlg: args.dlg,
|
|
1168
|
+
agent: args.agent,
|
|
1169
|
+
calls: args.calls.map((call) => toExecutableValidTellaskCall(call)),
|
|
1170
|
+
callbacks,
|
|
1171
|
+
emitCallEvents: true,
|
|
1172
|
+
});
|
|
1173
|
+
return {
|
|
1174
|
+
suspend: tellaskResult.suspend,
|
|
1175
|
+
toolOutputs: tellaskResult.toolOutputs,
|
|
1176
|
+
subdialogsCreated: tellaskResult.subdialogsCreated,
|
|
1177
|
+
};
|
|
1178
|
+
}
|