dominds 1.26.5 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/dialog-system.md +9 -6
- package/dist/docs/dialog-system.zh.md +10 -7
- package/dist/llm/gen/mock.js +10 -3
- package/dist/llm/gen.d.ts +4 -0
- package/dist/llm/kernel-driver/drive.js +164 -97
- package/dist/llm/kernel-driver/flow.js +53 -230
- package/dist/llm/kernel-driver/reminder-context.d.ts +0 -2
- package/dist/llm/kernel-driver/reminder-context.js +0 -4
- package/dist/llm/kernel-driver/reply-guidance.d.ts +1 -8
- package/dist/llm/kernel-driver/reply-guidance.js +8 -27
- package/dist/llm/kernel-driver/sideDialog.js +0 -4
- package/dist/llm/kernel-driver/tellask-special.d.ts +22 -2
- package/dist/llm/kernel-driver/tellask-special.js +122 -4
- package/dist/llm/kernel-driver/types.d.ts +3 -2
- package/dist/minds/system-prompt.js +10 -6
- package/dist/persistence.d.ts +2 -3
- package/dist/persistence.js +26 -76
- package/dist/runtime/driver-messages.d.ts +0 -2
- package/dist/runtime/driver-messages.js +2 -10
- package/dist/runtime/interjection-pause-stop.js +7 -8
- package/dist/runtime/reply-prompt-copy.d.ts +7 -9
- package/dist/runtime/reply-prompt-copy.js +48 -50
- package/dist/server/dominds-self-update.js +46 -4
- package/dist/server/websocket-handler.js +0 -2
- package/package.json +3 -3
- package/webapp/dist/assets/{_basePickBy-zyTFuJGa.js → _basePickBy-B5vClVxA.js} +3 -3
- package/webapp/dist/assets/{_basePickBy-zyTFuJGa.js.map → _basePickBy-B5vClVxA.js.map} +1 -1
- package/webapp/dist/assets/{_baseUniq-nq34n_7W.js → _baseUniq-CFvt8kJS.js} +2 -2
- package/webapp/dist/assets/{_baseUniq-nq34n_7W.js.map → _baseUniq-CFvt8kJS.js.map} +1 -1
- package/webapp/dist/assets/{arc-Bv7_22Od.js → arc-tJQBTeDz.js} +2 -2
- package/webapp/dist/assets/{arc-Bv7_22Od.js.map → arc-tJQBTeDz.js.map} +1 -1
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CQe-mbPP.js → architectureDiagram-2XIMDMQ5-DHh9S187.js} +7 -7
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CQe-mbPP.js.map → architectureDiagram-2XIMDMQ5-DHh9S187.js.map} +1 -1
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-CX4Uu1s4.js → blockDiagram-WCTKOSBZ-BbiZ5Eja.js} +7 -7
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-CX4Uu1s4.js.map → blockDiagram-WCTKOSBZ-BbiZ5Eja.js.map} +1 -1
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-75vPtXd7.js → c4Diagram-IC4MRINW-DzSSDB-G.js} +3 -3
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-75vPtXd7.js.map → c4Diagram-IC4MRINW-DzSSDB-G.js.map} +1 -1
- package/webapp/dist/assets/{channel-lMsMuju8.js → channel-XrOKEkK6.js} +2 -2
- package/webapp/dist/assets/{channel-lMsMuju8.js.map → channel-XrOKEkK6.js.map} +1 -1
- package/webapp/dist/assets/{chunk-4BX2VUAB-I371XlIM.js → chunk-4BX2VUAB-DEe7fLDb.js} +2 -2
- package/webapp/dist/assets/{chunk-4BX2VUAB-I371XlIM.js.map → chunk-4BX2VUAB-DEe7fLDb.js.map} +1 -1
- package/webapp/dist/assets/{chunk-55IACEB6-GMAfwcRQ.js → chunk-55IACEB6-DS9LKRkK.js} +2 -2
- package/webapp/dist/assets/{chunk-55IACEB6-GMAfwcRQ.js.map → chunk-55IACEB6-DS9LKRkK.js.map} +1 -1
- package/webapp/dist/assets/{chunk-FMBD7UC4-X9ms5_sJ.js → chunk-FMBD7UC4-zmHWjnBv.js} +2 -2
- package/webapp/dist/assets/{chunk-FMBD7UC4-X9ms5_sJ.js.map → chunk-FMBD7UC4-zmHWjnBv.js.map} +1 -1
- package/webapp/dist/assets/{chunk-JSJVCQXG-s2a971Od.js → chunk-JSJVCQXG-CHhshmdw.js} +2 -2
- package/webapp/dist/assets/{chunk-JSJVCQXG-s2a971Od.js.map → chunk-JSJVCQXG-CHhshmdw.js.map} +1 -1
- package/webapp/dist/assets/{chunk-KX2RTZJC-CSSBs5H9.js → chunk-KX2RTZJC-BrS-M9-j.js} +2 -2
- package/webapp/dist/assets/{chunk-KX2RTZJC-CSSBs5H9.js.map → chunk-KX2RTZJC-BrS-M9-j.js.map} +1 -1
- package/webapp/dist/assets/{chunk-NQ4KR5QH-B8-jtfW1.js → chunk-NQ4KR5QH-aQEIAgyi.js} +4 -4
- package/webapp/dist/assets/{chunk-NQ4KR5QH-B8-jtfW1.js.map → chunk-NQ4KR5QH-aQEIAgyi.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QZHKN3VN-3ZZehtFv.js → chunk-QZHKN3VN-NZNwDEz0.js} +2 -2
- package/webapp/dist/assets/{chunk-QZHKN3VN-3ZZehtFv.js.map → chunk-QZHKN3VN-NZNwDEz0.js.map} +1 -1
- package/webapp/dist/assets/{chunk-WL4C6EOR-D_AtipPw.js → chunk-WL4C6EOR-BA4Gts3V.js} +6 -6
- package/webapp/dist/assets/{chunk-WL4C6EOR-D_AtipPw.js.map → chunk-WL4C6EOR-BA4Gts3V.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-CTxhuDjN.js → classDiagram-VBA2DB6C-BnW_okvO.js} +7 -7
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-CTxhuDjN.js.map → classDiagram-VBA2DB6C-BnW_okvO.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-CTxhuDjN.js → classDiagram-v2-RAHNMMFH-BnW_okvO.js} +7 -7
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-CTxhuDjN.js.map → classDiagram-v2-RAHNMMFH-BnW_okvO.js.map} +1 -1
- package/webapp/dist/assets/{clone-C9MfpI1S.js → clone-yPnqRTsi.js} +2 -2
- package/webapp/dist/assets/{clone-C9MfpI1S.js.map → clone-yPnqRTsi.js.map} +1 -1
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CCYyTSie.js → cose-bilkent-S5V4N54A-CIVtbB4S.js} +2 -2
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CCYyTSie.js.map → cose-bilkent-S5V4N54A-CIVtbB4S.js.map} +1 -1
- package/webapp/dist/assets/{dagre-KLK3FWXG-DxM19yfA.js → dagre-KLK3FWXG-ChT-W9Qx.js} +7 -7
- package/webapp/dist/assets/{dagre-KLK3FWXG-DxM19yfA.js.map → dagre-KLK3FWXG-ChT-W9Qx.js.map} +1 -1
- package/webapp/dist/assets/{diagram-E7M64L7V-BSc4Txf5.js → diagram-E7M64L7V-BN8EY3l2.js} +8 -8
- package/webapp/dist/assets/{diagram-E7M64L7V-BSc4Txf5.js.map → diagram-E7M64L7V-BN8EY3l2.js.map} +1 -1
- package/webapp/dist/assets/{diagram-IFDJBPK2-Cdj6m54B.js → diagram-IFDJBPK2-Vf6QwbQQ.js} +7 -7
- package/webapp/dist/assets/{diagram-IFDJBPK2-Cdj6m54B.js.map → diagram-IFDJBPK2-Vf6QwbQQ.js.map} +1 -1
- package/webapp/dist/assets/{diagram-P4PSJMXO-BKd75i65.js → diagram-P4PSJMXO-CjMHY4Wx.js} +7 -7
- package/webapp/dist/assets/{diagram-P4PSJMXO-BKd75i65.js.map → diagram-P4PSJMXO-CjMHY4Wx.js.map} +1 -1
- package/webapp/dist/assets/{erDiagram-INFDFZHY-eI9rTfbL.js → erDiagram-INFDFZHY-CdziCsxU.js} +5 -5
- package/webapp/dist/assets/{erDiagram-INFDFZHY-eI9rTfbL.js.map → erDiagram-INFDFZHY-CdziCsxU.js.map} +1 -1
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-BFDDBCeb.js → flowDiagram-PKNHOUZH-BAe40rMw.js} +7 -7
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-BFDDBCeb.js.map → flowDiagram-PKNHOUZH-BAe40rMw.js.map} +1 -1
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-ClhbFgCt.js → ganttDiagram-A5KZAMGK-CXdjtDXe.js} +3 -3
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-ClhbFgCt.js.map → ganttDiagram-A5KZAMGK-CXdjtDXe.js.map} +1 -1
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-DOiQN8_s.js → gitGraphDiagram-K3NZZRJ6-U_Rn0HLE.js} +8 -8
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-DOiQN8_s.js.map → gitGraphDiagram-K3NZZRJ6-U_Rn0HLE.js.map} +1 -1
- package/webapp/dist/assets/{graph-_a0YpojF.js → graph-HwBjKopa.js} +3 -3
- package/webapp/dist/assets/{graph-_a0YpojF.js.map → graph-HwBjKopa.js.map} +1 -1
- package/webapp/dist/assets/{index-Dou-k_rC.js → index-BWHqGclz.js} +34 -34
- package/webapp/dist/assets/{index-Dou-k_rC.js.map → index-BWHqGclz.js.map} +1 -1
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-txkiQJKc.js → infoDiagram-LFFYTUFH-Do9srBC6.js} +6 -6
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-txkiQJKc.js.map → infoDiagram-LFFYTUFH-Do9srBC6.js.map} +1 -1
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-D91OZx5x.js → ishikawaDiagram-PHBUUO56-xCtj-FXJ.js} +2 -2
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-D91OZx5x.js.map → ishikawaDiagram-PHBUUO56-xCtj-FXJ.js.map} +1 -1
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BdmmINf5.js → journeyDiagram-4ABVD52K-B0JWfLyo.js} +5 -5
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BdmmINf5.js.map → journeyDiagram-4ABVD52K-B0JWfLyo.js.map} +1 -1
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-C-S70Yrl.js → kanban-definition-K7BYSVSG-CVcU1Etk.js} +3 -3
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-C-S70Yrl.js.map → kanban-definition-K7BYSVSG-CVcU1Etk.js.map} +1 -1
- package/webapp/dist/assets/{layout-BRJaSqhR.js → layout-aH6Cn20A.js} +5 -5
- package/webapp/dist/assets/{layout-BRJaSqhR.js.map → layout-aH6Cn20A.js.map} +1 -1
- package/webapp/dist/assets/{linear-DyNGMbe9.js → linear-Ck43kzmo.js} +2 -2
- package/webapp/dist/assets/{linear-DyNGMbe9.js.map → linear-Ck43kzmo.js.map} +1 -1
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-sDQWtZwL.js → mindmap-definition-YRQLILUH-6OIwzMyc.js} +4 -4
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-sDQWtZwL.js.map → mindmap-definition-YRQLILUH-6OIwzMyc.js.map} +1 -1
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-CxO-PR0P.js → pieDiagram-SKSYHLDU-B61-NHoC.js} +8 -8
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-CxO-PR0P.js.map → pieDiagram-SKSYHLDU-B61-NHoC.js.map} +1 -1
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-2eCl6G-9.js → quadrantDiagram-337W2JSQ-0eM2SOom.js} +3 -3
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-2eCl6G-9.js.map → quadrantDiagram-337W2JSQ-0eM2SOom.js.map} +1 -1
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-BZP0MViS.js → requirementDiagram-Z7DCOOCP-ChcYQDgM.js} +4 -4
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-BZP0MViS.js.map → requirementDiagram-Z7DCOOCP-ChcYQDgM.js.map} +1 -1
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-BFByQmrg.js → sankeyDiagram-WA2Y5GQK-B9cEGu9g.js} +2 -2
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-BFByQmrg.js.map → sankeyDiagram-WA2Y5GQK-B9cEGu9g.js.map} +1 -1
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-vs-caW9J.js → sequenceDiagram-2WXFIKYE-D1vR0q93.js} +4 -4
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-vs-caW9J.js.map → sequenceDiagram-2WXFIKYE-D1vR0q93.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-B_yOKRoN.js → stateDiagram-RAJIS63D-ylazdvD-.js} +9 -9
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-B_yOKRoN.js.map → stateDiagram-RAJIS63D-ylazdvD-.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-B285fcqL.js → stateDiagram-v2-FVOUBMTO-CxtecSrX.js} +5 -5
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-B285fcqL.js.map → stateDiagram-v2-FVOUBMTO-CxtecSrX.js.map} +1 -1
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-B_yCavMb.js → timeline-definition-YZTLITO2-4rofIQXx.js} +3 -3
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-B_yCavMb.js.map → timeline-definition-YZTLITO2-4rofIQXx.js.map} +1 -1
- package/webapp/dist/assets/{treemap-KZPCXAKY-cErPVx9g.js → treemap-KZPCXAKY-0SBcN6kq.js} +5 -5
- package/webapp/dist/assets/{treemap-KZPCXAKY-cErPVx9g.js.map → treemap-KZPCXAKY-0SBcN6kq.js.map} +1 -1
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-C9qgK3p0.js → vennDiagram-LZ73GAT5-CCqbQjX8.js} +2 -2
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-C9qgK3p0.js.map → vennDiagram-LZ73GAT5-CCqbQjX8.js.map} +1 -1
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-B-gCl1Yj.js → xychartDiagram-JWTSCODW-Yl52k-Si.js} +3 -3
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-B-gCl1Yj.js.map → xychartDiagram-JWTSCODW-Yl52k-Si.js.map} +1 -1
- package/webapp/dist/index.html +1 -1
|
@@ -9,6 +9,7 @@ exports.formatTellaskInvalidCallResult = formatTellaskInvalidCallResult;
|
|
|
9
9
|
exports.formatPendingTellaskFuncResultContent = formatPendingTellaskFuncResultContent;
|
|
10
10
|
exports.formatResolvedTellaskFuncResultContent = formatResolvedTellaskFuncResultContent;
|
|
11
11
|
exports.formatResolvedAskHumanResultContent = formatResolvedAskHumanResultContent;
|
|
12
|
+
exports.recordAnswerToHuman = recordAnswerToHuman;
|
|
12
13
|
exports.executeTellaskCalls = executeTellaskCalls;
|
|
13
14
|
exports.processTellaskFunctionRound = processTellaskFunctionRound;
|
|
14
15
|
const util_1 = require("util");
|
|
@@ -37,6 +38,7 @@ const TELLASK_SPECIAL_FUNCTION_NAMES = [
|
|
|
37
38
|
'replyTellaskSessionless',
|
|
38
39
|
'replyTellaskBack',
|
|
39
40
|
'askHuman',
|
|
41
|
+
'answerHuman',
|
|
40
42
|
'freshBootsReasoning',
|
|
41
43
|
];
|
|
42
44
|
const MULTIPLE_ASKHUMAN_CALLS_ERROR = '不允许一轮多次调用 askHuman,必须单次调用问所有问题。 Do not call askHuman multiple times in one round; ask all questions in a single askHuman call.';
|
|
@@ -47,6 +49,9 @@ function isTellaskCallFunctionName(name) {
|
|
|
47
49
|
function isReplyTellaskCallName(name) {
|
|
48
50
|
return (name === 'replyTellask' || name === 'replyTellaskSessionless' || name === 'replyTellaskBack');
|
|
49
51
|
}
|
|
52
|
+
function usesFuncRequestedSpecialLifecycle(name) {
|
|
53
|
+
return isReplyTellaskCallName(name) || name === 'answerHuman';
|
|
54
|
+
}
|
|
50
55
|
function isRecord(value) {
|
|
51
56
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
52
57
|
}
|
|
@@ -420,6 +425,20 @@ function parseTellaskCall(call) {
|
|
|
420
425
|
},
|
|
421
426
|
};
|
|
422
427
|
}
|
|
428
|
+
case 'answerHuman': {
|
|
429
|
+
const answerContent = readRequiredStringField(args, 'answerContent');
|
|
430
|
+
if (!answerContent.ok) {
|
|
431
|
+
return answerContent;
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
ok: true,
|
|
435
|
+
value: {
|
|
436
|
+
callId: call.id,
|
|
437
|
+
callName: 'answerHuman',
|
|
438
|
+
answerContent: answerContent.value,
|
|
439
|
+
},
|
|
440
|
+
};
|
|
441
|
+
}
|
|
423
442
|
case 'freshBootsReasoning': {
|
|
424
443
|
const tellaskContent = readRequiredStringField(args, 'tellaskContent');
|
|
425
444
|
if (!tellaskContent.ok) {
|
|
@@ -2079,6 +2098,85 @@ async function executeReplyTellaskCall(args) {
|
|
|
2079
2098
|
}
|
|
2080
2099
|
}
|
|
2081
2100
|
}
|
|
2101
|
+
function formatAnswerHumanResultContent(args) {
|
|
2102
|
+
const language = (0, work_language_1.getWorkLanguage)();
|
|
2103
|
+
return language === 'zh'
|
|
2104
|
+
? `已记录给人类的答复。\n\n${args.answerContent}`
|
|
2105
|
+
: `Recorded the answer for the human.\n\n${args.answerContent}`;
|
|
2106
|
+
}
|
|
2107
|
+
async function recordAnswerToHuman(args) {
|
|
2108
|
+
const answer = {
|
|
2109
|
+
id: `a2h-${Buffer.from(args.answerIdSource).toString('base64url')}`,
|
|
2110
|
+
content: args.answerContent,
|
|
2111
|
+
answeredAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
2112
|
+
answerRef: {
|
|
2113
|
+
course: (0, storage_1.toDialogCourseNumber)(args.course),
|
|
2114
|
+
genseq: (0, storage_1.toCallSiteGenseqNo)(args.genseq),
|
|
2115
|
+
},
|
|
2116
|
+
};
|
|
2117
|
+
await persistence_1.DialogPersistence.appendAnswerToHumanState(args.dlg.id, answer, args.dlg.status);
|
|
2118
|
+
const metadata = await persistence_1.DialogPersistence.loadDialogMetadata(args.dlg.id, args.dlg.status);
|
|
2119
|
+
const taskDocPath = metadata?.taskDocPath ?? args.dlg.taskDocPath ?? '';
|
|
2120
|
+
const event = {
|
|
2121
|
+
type: 'new_a2h_answered',
|
|
2122
|
+
answer: {
|
|
2123
|
+
...answer,
|
|
2124
|
+
selfId: args.dlg.id.selfId,
|
|
2125
|
+
rootId: args.dlg.id.rootId,
|
|
2126
|
+
agentId: metadata?.agentId ?? args.dlg.agentId,
|
|
2127
|
+
taskDocPath,
|
|
2128
|
+
},
|
|
2129
|
+
};
|
|
2130
|
+
(0, evt_registry_1.postDialogEvent)(args.dlg, event);
|
|
2131
|
+
await persistence_1.DialogPersistence.mutateDialogLatest(args.dlg.id, (previous) => {
|
|
2132
|
+
const previousPending = previous.pendingUserInterjectionReply;
|
|
2133
|
+
if (previousPending === undefined) {
|
|
2134
|
+
return { kind: 'noop' };
|
|
2135
|
+
}
|
|
2136
|
+
const next = { ...previous };
|
|
2137
|
+
delete next.pendingUserInterjectionReply;
|
|
2138
|
+
return { kind: 'replace', next };
|
|
2139
|
+
}, args.dlg.status);
|
|
2140
|
+
return answer;
|
|
2141
|
+
}
|
|
2142
|
+
async function executeAnswerHumanCall(args) {
|
|
2143
|
+
const genseq = args.dlg.activeGenSeqOrUndefined ?? 1;
|
|
2144
|
+
const course = args.dlg.activeGenCourseOrUndefined ?? args.dlg.currentCourse;
|
|
2145
|
+
const answerContent = args.call.answerContent;
|
|
2146
|
+
const answer = await recordAnswerToHuman({
|
|
2147
|
+
dlg: args.dlg,
|
|
2148
|
+
answerContent,
|
|
2149
|
+
course,
|
|
2150
|
+
genseq,
|
|
2151
|
+
answerIdSource: [
|
|
2152
|
+
args.dlg.id.rootId,
|
|
2153
|
+
args.dlg.id.selfId,
|
|
2154
|
+
`c${String(course)}`,
|
|
2155
|
+
`g${String(genseq)}`,
|
|
2156
|
+
`answerHuman:${args.call.callId}`,
|
|
2157
|
+
args.call.callId,
|
|
2158
|
+
].join('|'),
|
|
2159
|
+
});
|
|
2160
|
+
return {
|
|
2161
|
+
messages: [
|
|
2162
|
+
{
|
|
2163
|
+
type: 'func_result_msg',
|
|
2164
|
+
role: 'tool',
|
|
2165
|
+
genseq,
|
|
2166
|
+
id: args.call.callId,
|
|
2167
|
+
name: args.call.callName,
|
|
2168
|
+
content: formatAnswerHumanResultContent({ answerContent }),
|
|
2169
|
+
},
|
|
2170
|
+
],
|
|
2171
|
+
answering: {
|
|
2172
|
+
callId: args.call.callId,
|
|
2173
|
+
answerContent,
|
|
2174
|
+
course,
|
|
2175
|
+
genseq,
|
|
2176
|
+
answer,
|
|
2177
|
+
},
|
|
2178
|
+
};
|
|
2179
|
+
}
|
|
2082
2180
|
function toExecutableValidTellaskCall(call) {
|
|
2083
2181
|
switch (call.callName) {
|
|
2084
2182
|
case 'tellaskBack':
|
|
@@ -2118,6 +2216,12 @@ function toExecutableValidTellaskCall(call) {
|
|
|
2118
2216
|
tellaskContent: call.tellaskContent,
|
|
2119
2217
|
callId: call.callId,
|
|
2120
2218
|
};
|
|
2219
|
+
case 'answerHuman':
|
|
2220
|
+
return {
|
|
2221
|
+
callName: call.callName,
|
|
2222
|
+
answerContent: call.answerContent,
|
|
2223
|
+
callId: call.callId,
|
|
2224
|
+
};
|
|
2121
2225
|
case 'freshBootsReasoning':
|
|
2122
2226
|
return {
|
|
2123
2227
|
callName: call.callName,
|
|
@@ -2130,6 +2234,7 @@ function toExecutableValidTellaskCall(call) {
|
|
|
2130
2234
|
async function executeValidTellaskCalls(args) {
|
|
2131
2235
|
const results = [];
|
|
2132
2236
|
const successfulReplyCallIds = [];
|
|
2237
|
+
const answerHumanOutputs = [];
|
|
2133
2238
|
const deferredScheduleCalls = [];
|
|
2134
2239
|
const registrationPhaseCallbacks = {
|
|
2135
2240
|
driveDialog: args.callbacks.driveDialog,
|
|
@@ -2148,11 +2253,12 @@ async function executeValidTellaskCalls(args) {
|
|
|
2148
2253
|
case 'replyTellaskSessionless':
|
|
2149
2254
|
case 'replyTellaskBack':
|
|
2150
2255
|
case 'askHuman':
|
|
2256
|
+
case 'answerHuman':
|
|
2151
2257
|
case 'freshBootsReasoning':
|
|
2152
2258
|
return undefined;
|
|
2153
2259
|
}
|
|
2154
2260
|
})();
|
|
2155
|
-
if (!
|
|
2261
|
+
if (!usesFuncRequestedSpecialLifecycle(call.callName)) {
|
|
2156
2262
|
const nonReplyCall = call;
|
|
2157
2263
|
const sessionSlug = nonReplyCall.callName === 'tellask' ? nonReplyCall.sessionSlug : undefined;
|
|
2158
2264
|
await emitTellaskCallEvents({
|
|
@@ -2190,6 +2296,15 @@ async function executeValidTellaskCalls(args) {
|
|
|
2190
2296
|
results.push(replyResult.messages);
|
|
2191
2297
|
continue;
|
|
2192
2298
|
}
|
|
2299
|
+
case 'answerHuman': {
|
|
2300
|
+
const answerResult = await executeAnswerHumanCall({
|
|
2301
|
+
dlg: args.dlg,
|
|
2302
|
+
call,
|
|
2303
|
+
});
|
|
2304
|
+
results.push(answerResult.messages);
|
|
2305
|
+
answerHumanOutputs.push(answerResult.answering);
|
|
2306
|
+
continue;
|
|
2307
|
+
}
|
|
2193
2308
|
case 'tellask': {
|
|
2194
2309
|
const targetAgentId = call.targetAgentId;
|
|
2195
2310
|
if (targetAgentId.trim() === '') {
|
|
@@ -2239,11 +2354,12 @@ async function executeValidTellaskCalls(args) {
|
|
|
2239
2354
|
return {
|
|
2240
2355
|
toolOutputs: results.flatMap((result) => result),
|
|
2241
2356
|
successfulReplyCallIds,
|
|
2357
|
+
answerHumanOutputs,
|
|
2242
2358
|
};
|
|
2243
2359
|
}
|
|
2244
2360
|
async function executeTellaskCalls(args) {
|
|
2245
2361
|
if (args.calls.length === 0) {
|
|
2246
|
-
return { toolOutputs: [], successfulReplyCallIds: [] };
|
|
2362
|
+
return { toolOutputs: [], successfulReplyCallIds: [], answerHumanOutputs: [] };
|
|
2247
2363
|
}
|
|
2248
2364
|
return await executeValidTellaskCalls({
|
|
2249
2365
|
dlg: args.dlg,
|
|
@@ -2316,7 +2432,7 @@ async function processTellaskFunctionRound(args) {
|
|
|
2316
2432
|
if (disposition.kind === 'valid') {
|
|
2317
2433
|
const handled = disposition.handled;
|
|
2318
2434
|
await args.dlg.persistTellaskCall(handled.originalCall.id, handled.call.callName, getRawArgumentsText(handled.originalCall), handled.originalCall.genseq, {
|
|
2319
|
-
deliveryMode:
|
|
2435
|
+
deliveryMode: usesFuncRequestedSpecialLifecycle(handled.call.callName)
|
|
2320
2436
|
? 'func_call_requested'
|
|
2321
2437
|
: 'tellask_call_start',
|
|
2322
2438
|
...(isReplyTellaskCallName(handled.call.callName) &&
|
|
@@ -2415,7 +2531,8 @@ async function processTellaskFunctionRound(args) {
|
|
|
2415
2531
|
tellaskFuncResultByCallId.set(result.id, result);
|
|
2416
2532
|
tellaskFuncResults.push(result);
|
|
2417
2533
|
const originatingCall = specialCallById.get(result.id);
|
|
2418
|
-
if (originatingCall !== undefined &&
|
|
2534
|
+
if (originatingCall !== undefined &&
|
|
2535
|
+
usesFuncRequestedSpecialLifecycle(originatingCall.callName)) {
|
|
2419
2536
|
continue;
|
|
2420
2537
|
}
|
|
2421
2538
|
hasImmediateTellaskOutputs = true;
|
|
@@ -2483,6 +2600,7 @@ async function processTellaskFunctionRound(args) {
|
|
|
2483
2600
|
hasImmediateTellaskOutputs,
|
|
2484
2601
|
immediateTellaskOutputCallIds,
|
|
2485
2602
|
invalidTellaskCallIds: orderedInvalidCalls.map((issue) => issue.originalCall.id),
|
|
2603
|
+
answerHumanOutputs: tellaskExecution.answerHumanOutputs,
|
|
2486
2604
|
shouldStopAfterReplyTool: tellaskExecution.successfulReplyCallIds.length > 0,
|
|
2487
2605
|
shouldStopAfterPendingTellaskWait,
|
|
2488
2606
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DialogDisplayState, DialogInterruptionReason } from '@longrun-ai/kernel/types/display-state';
|
|
2
2
|
import type { DialogDiligencePrompt, DialogPrompt, DialogRunControlSpec, DialogRuntimeGuidePrompt, DialogRuntimePrompt, DialogRuntimeReplyPrompt, DialogRuntimeSideDialogPrompt, DialogUserPrompt } from '@longrun-ai/kernel/types/drive-intent';
|
|
3
|
-
import type {
|
|
3
|
+
import type { CallSiteCourseNo, CallSiteGenseqNo, DialogBusinessContinuation } from '@longrun-ai/kernel/types/storage';
|
|
4
4
|
import type { Dialog, DialogID } from '../../dialog';
|
|
5
5
|
export type KernelDriverRunControl = DialogRunControlSpec;
|
|
6
6
|
export type KernelDriverDriveSource = 'unspecified' | 'ws_user_message' | 'ws_user_answer' | 'ws_diligence_push' | 'ws_resume_dialog' | 'ws_resume_all' | 'kernel_driver_backend_loop' | 'kernel_driver_follow_up' | 'kernel_driver_sideDialog_init' | 'kernel_driver_sideDialog_resume' | 'kernel_driver_fbr_sideDialog_round' | 'kernel_driver_type_a_askerDialog_call' | 'kernel_driver_business_continuation' | 'kernel_driver_idle_reminder_wake';
|
|
@@ -96,10 +96,11 @@ export type KernelDriverCoreResult = {
|
|
|
96
96
|
lastAssistantSayingGenseq: number | null;
|
|
97
97
|
lastAssistantThinkingContent: string | null;
|
|
98
98
|
lastAssistantThinkingGenseq: number | null;
|
|
99
|
+
lastAssistantAnsweringContent: string | null;
|
|
100
|
+
lastAssistantAnsweringGenseq: number | null;
|
|
99
101
|
lastFunctionCallGenseq: number | null;
|
|
100
102
|
lastAssistantReplyTarget?: KernelDriverCalleeReplyTarget;
|
|
101
103
|
lastBusinessContinuation: DialogBusinessContinuation;
|
|
102
|
-
answeredUserInterjection?: AnswerToHumanItem;
|
|
103
104
|
fbrConclusion?: {
|
|
104
105
|
responseText: string;
|
|
105
106
|
responseGenseq: number;
|
|
@@ -212,13 +212,13 @@ function buildTellaskCollaborationProtocol(language, dialogScope) {
|
|
|
212
212
|
const lines = [
|
|
213
213
|
...pickLocalized(language, {
|
|
214
214
|
zh: [
|
|
215
|
-
'- Tellask 统一走函数工具通道:`tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `freshBootsReasoning`。',
|
|
215
|
+
'- Tellask special 统一走函数工具通道:`tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `answerHuman` / `freshBootsReasoning`。',
|
|
216
216
|
'- 对队友诉请默认使用 `tellask` 并复用 `sessionSlug`;仅在确认一次性诉请足够、且后续不需要更新任务安排/提前收口时才使用 `tellaskSessionless`,并需说明理由。',
|
|
217
217
|
'- 并行协调默认允许:不要把智能体队友当成真人同事;祂不会因为你又发一条诉请而被打扰。同一个队友 + 同一个 `sessionSlug` = 接着同一件事说;`tellaskSessionless` 或不同 `sessionSlug` = 另一件独立任务。',
|
|
218
218
|
'- 例外优先级(强制):`tellaskBack` 仅用于回问诉请者,不适用队友长线默认规则,也不携带 `sessionSlug`。',
|
|
219
219
|
],
|
|
220
220
|
en: [
|
|
221
|
-
'- Tellask must use the function-tool channel: `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `freshBootsReasoning`.',
|
|
221
|
+
'- Tellask special calls must use the function-tool channel: `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `answerHuman` / `freshBootsReasoning`.',
|
|
222
222
|
'- For teammate tellasks, default to `tellask` and continue with the same `sessionSlug`; use `tellaskSessionless` only when a one-shot is truly sufficient and later assignment updates / early wrap-up are not needed.',
|
|
223
223
|
'- Parallel coordination is allowed by default: do not treat an agent teammate like a human coworker who can only handle one conversation at a time. Same teammate + same `sessionSlug` = continue the same task; `tellaskSessionless` or a different `sessionSlug` = another independent task.',
|
|
224
224
|
'- Mandatory exception precedence: `tellaskBack` is ask-back-only and outside the teammate-session default; it does not carry `sessionSlug`.',
|
|
@@ -246,7 +246,7 @@ function buildFbrGuidelines(language, dialogScope, contextHealthPromptMode) {
|
|
|
246
246
|
zh: [
|
|
247
247
|
'- FBR 由 `freshBootsReasoning` 触发,不属于普通队友诉请分类;请按本节规则执行。',
|
|
248
248
|
'- FBR 不可调用 `tellaskBack`;其回贴标记由 Dominds 在跨对话传递正文中自动注入。',
|
|
249
|
-
'- FBR 禁止一切 tellask(包括 `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman`)。',
|
|
249
|
+
'- FBR 禁止一切 tellask-special(包括 `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `answerHuman`)。',
|
|
250
250
|
'- 当用户明确要求“做一次 FBR/扪心自问”,对话主理人必须发起 `freshBootsReasoning`。',
|
|
251
251
|
fbrContextHealthRule,
|
|
252
252
|
'- FBR 的标准入口是 `freshBootsReasoning({ tellaskContent, effort? })`;禁止用 `tellask` / `tellaskSessionless` 对自己发起 self-target 诉请来替代。',
|
|
@@ -263,7 +263,7 @@ function buildFbrGuidelines(language, dialogScope, contextHealthPromptMode) {
|
|
|
263
263
|
en: [
|
|
264
264
|
'- FBR is triggered by `freshBootsReasoning`, not by normal teammate tellasks; follow this section’s rules.',
|
|
265
265
|
'- FBR cannot call `tellaskBack`; its reply marker is injected by Dominds into the inter-dialog transfer payload.',
|
|
266
|
-
'- FBR forbids all tellask calls (including `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman`).',
|
|
266
|
+
'- FBR forbids all tellask-special calls (including `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `answerHuman`).',
|
|
267
267
|
'- When the user explicitly requests “do an FBR / fresh boots reasoning”, the Dialog Responder must call `freshBootsReasoning`.',
|
|
268
268
|
fbrContextHealthRule,
|
|
269
269
|
'- The standard FBR entry is `freshBootsReasoning({ tellaskContent, effort? })`; do not emulate FBR via self-targeted `tellask` / `tellaskSessionless`.',
|
|
@@ -287,6 +287,7 @@ function buildTellaskInteractionRules(language) {
|
|
|
287
287
|
'- `tellask`:用于可恢复的长线诉请(必须提供 `targetAgentId` / `sessionSlug` / `tellaskContent`)。',
|
|
288
288
|
'- `tellaskSessionless`:用于一次性诉请(必须提供 `targetAgentId` / `tellaskContent`);它不能接着旧任务改要求,后续再次调用只是另一件独立任务,不会影响旧任务继续执行,也不会打扰同一队友正在执行的其它独立诉请。不要把智能体队友当成需要排队说话的真人同事。',
|
|
289
289
|
'- `askHuman`:用于 Q4H(向人类请求必要澄清/决策/授权/缺失输入)。',
|
|
290
|
+
'- `answerHuman`:用于把当前要给人类看的答复记录为 A2H(answer to human);不要用它向队友回贴。',
|
|
290
291
|
'- `freshBootsReasoning`:用于发起扪心自问(FBR)支线(`tellaskContent` 必填,`effort` 可选)。',
|
|
291
292
|
],
|
|
292
293
|
en: [
|
|
@@ -294,6 +295,7 @@ function buildTellaskInteractionRules(language) {
|
|
|
294
295
|
'- `tellask`: resumable tellask (requires `targetAgentId` / `sessionSlug` / `tellaskContent`).',
|
|
295
296
|
'- `tellaskSessionless`: one-shot tellask (requires `targetAgentId` / `tellaskContent`); it cannot continue an earlier task or change its requirements. Later calls are separate tasks and do not affect earlier work for the same teammate. Do not treat agent teammates like human coworkers who need you to wait in line to talk.',
|
|
296
297
|
'- `askHuman`: Q4H for necessary clarification/decision/authorization/missing input.',
|
|
298
|
+
'- `answerHuman`: record the current human-facing answer as A2H (answer to human); do not use it to reply to teammates.',
|
|
297
299
|
'- `freshBootsReasoning`: starts an FBR Side Dialog (requires `tellaskContent`, optional `effort`).',
|
|
298
300
|
],
|
|
299
301
|
});
|
|
@@ -406,6 +408,7 @@ function buildSystemPrompt(input) {
|
|
|
406
408
|
- 回问诉请:支线对话用 \`tellaskBack\` 回问诉请者以澄清。
|
|
407
409
|
- 扪心自问(FBR):由 \`freshBootsReasoning\` 触发的“无工具”支线推理机制。
|
|
408
410
|
- 向人请示(Q4H):通过 \`askHuman\` 向人类请求必要的澄清/决策/授权/缺失输入。
|
|
411
|
+
- 答复人类(A2H):通过 \`answerHuman\` 记录当前要给人类看的答复。
|
|
409
412
|
- 长线诉请:使用 \`tellask\` + \`sessionSlug\` 的可恢复多轮协作。
|
|
410
413
|
- 一次性诉请:一次性、不可恢复的诉请。
|
|
411
414
|
- 主线对话:承载共享差遣牒并负责整体推进的对话。
|
|
@@ -466,7 +469,7 @@ ${input.toolsetManualIntro}
|
|
|
466
469
|
|
|
467
470
|
## 交互协议
|
|
468
471
|
|
|
469
|
-
### Tellask Special Functions(队友/FBR/Q4H)
|
|
472
|
+
### Tellask Special Functions(队友/FBR/Q4H/A2H)
|
|
470
473
|
${tellaskInteractionRules}
|
|
471
474
|
|
|
472
475
|
### 函数工具(仅原生 function-calling)
|
|
@@ -505,6 +508,7 @@ System notices convey important state changes (e.g., context caution/critical, D
|
|
|
505
508
|
- TellaskBack: a Side Dialog uses \`tellaskBack\` to ask the tellasker for clarification.
|
|
506
509
|
- Fresh Boots Reasoning (FBR): a tool-less Side Dialog reasoning mechanism triggered by \`freshBootsReasoning\`.
|
|
507
510
|
- Q4H (Question for Human): use \`askHuman\` to request necessary clarification/decision/authorization/missing input from a human.
|
|
511
|
+
- A2H (Answer to Human): use \`answerHuman\` to record the current human-facing answer.
|
|
508
512
|
- Tellask Session: resumable multi-turn work using \`tellask\` with \`sessionSlug\`.
|
|
509
513
|
- Fresh Tellask: a one-shot, non-resumable Tellask.
|
|
510
514
|
- Main Dialog: the dialog that owns the shared Taskdoc and overall progress.
|
|
@@ -565,7 +569,7 @@ ${input.toolsetManualIntro}
|
|
|
565
569
|
|
|
566
570
|
## Interaction Protocols
|
|
567
571
|
|
|
568
|
-
### Tellask Special Functions (teammates/FBR/Q4H)
|
|
572
|
+
### Tellask Special Functions (teammates/FBR/Q4H/A2H)
|
|
569
573
|
${tellaskInteractionRules}
|
|
570
574
|
|
|
571
575
|
### Function Tools (native function-calling only)
|
package/dist/persistence.d.ts
CHANGED
|
@@ -157,7 +157,7 @@ export declare class DiskFileDialogStore extends DialogStore {
|
|
|
157
157
|
* Persist a function call to storage
|
|
158
158
|
*/
|
|
159
159
|
persistFunctionCall(dialog: Dialog, id: string, name: string, rawArgumentsText: string, genseq: number, rawId?: string): Promise<void>;
|
|
160
|
-
persistTellaskCall(dialog: Dialog, id: string, name: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack' | 'askHuman' | 'freshBootsReasoning', rawArgumentsText: string, genseq: number, options?: {
|
|
160
|
+
persistTellaskCall(dialog: Dialog, id: string, name: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack' | 'askHuman' | 'answerHuman' | 'freshBootsReasoning', rawArgumentsText: string, genseq: number, options?: {
|
|
161
161
|
deliveryMode?: 'tellask_call_start' | 'func_call_requested';
|
|
162
162
|
replyDirective?: TellaskReplyDirective;
|
|
163
163
|
}): Promise<void>;
|
|
@@ -710,8 +710,6 @@ export declare class DialogPersistence {
|
|
|
710
710
|
static removeNextStepTriggers(dialogId: DialogID, predicate: (trigger: DialogNextStepTrigger) => boolean, status?: DialogStatusKind): Promise<void>;
|
|
711
711
|
static hasPendingNextStepTriggers(dialogId: DialogID, status?: DialogStatusKind): Promise<boolean>;
|
|
712
712
|
static clearPendingRuntimePrompt(dialogId: DialogID, msgId: string, status?: DialogStatusKind): Promise<void>;
|
|
713
|
-
static setDeferredReplyReassertion(dialogId: DialogID, deferredReplyReassertion: DialogLatestFile['deferredReplyReassertion'], status?: DialogStatusKind): Promise<void>;
|
|
714
|
-
static getDeferredReplyReassertion(dialogId: DialogID, status?: DialogStatusKind): Promise<DialogLatestFile['deferredReplyReassertion']>;
|
|
715
713
|
/**
|
|
716
714
|
* Get course filename from course number
|
|
717
715
|
*/
|
|
@@ -752,6 +750,7 @@ export declare class DialogPersistence {
|
|
|
752
750
|
course: number;
|
|
753
751
|
pending: DialogLatestFile['pendingUserInterjectionReply'];
|
|
754
752
|
}): AnswerToHumanItem | undefined;
|
|
753
|
+
private static answerRefSettlesPendingUserInterjection;
|
|
755
754
|
private static normalizeDialogLatestPendingUserInterjectionReply;
|
|
756
755
|
/**
|
|
757
756
|
* Reconstruct dialog state from JSONL events (optimized: only latest course needed).
|
package/dist/persistence.js
CHANGED
|
@@ -1909,6 +1909,7 @@ function isTellaskCallIndexCallName(value) {
|
|
|
1909
1909
|
value === 'replyTellaskSessionless' ||
|
|
1910
1910
|
value === 'replyTellaskBack' ||
|
|
1911
1911
|
value === 'askHuman' ||
|
|
1912
|
+
value === 'answerHuman' ||
|
|
1912
1913
|
value === 'freshBootsReasoning');
|
|
1913
1914
|
}
|
|
1914
1915
|
function parseDialogTellaskCallState(value) {
|
|
@@ -2243,36 +2244,6 @@ function parseDialogLatestFile(value) {
|
|
|
2243
2244
|
})();
|
|
2244
2245
|
if (fbrState === null)
|
|
2245
2246
|
return null;
|
|
2246
|
-
const deferredReplyReassertionRaw = value.deferredReplyReassertion;
|
|
2247
|
-
const deferredReplyReassertion = (() => {
|
|
2248
|
-
if (deferredReplyReassertionRaw === undefined)
|
|
2249
|
-
return undefined;
|
|
2250
|
-
if (!isRecord(deferredReplyReassertionRaw))
|
|
2251
|
-
return null;
|
|
2252
|
-
if (deferredReplyReassertionRaw.reason !== 'user_interjection_with_parked_original_task') {
|
|
2253
|
-
return null;
|
|
2254
|
-
}
|
|
2255
|
-
const directive = parseTellaskReplyDirective(deferredReplyReassertionRaw.directive);
|
|
2256
|
-
if (directive === null)
|
|
2257
|
-
return null;
|
|
2258
|
-
const userInterjection = parseDialogPendingUserInterjectionReply(deferredReplyReassertionRaw.userInterjection);
|
|
2259
|
-
if (userInterjection === null)
|
|
2260
|
-
return null;
|
|
2261
|
-
const resumeGuideSurfacedRaw = deferredReplyReassertionRaw.resumeGuideSurfaced;
|
|
2262
|
-
if (resumeGuideSurfacedRaw !== undefined && typeof resumeGuideSurfacedRaw !== 'boolean') {
|
|
2263
|
-
return null;
|
|
2264
|
-
}
|
|
2265
|
-
return {
|
|
2266
|
-
reason: 'user_interjection_with_parked_original_task',
|
|
2267
|
-
directive,
|
|
2268
|
-
userInterjection,
|
|
2269
|
-
...(resumeGuideSurfacedRaw === undefined
|
|
2270
|
-
? {}
|
|
2271
|
-
: { resumeGuideSurfaced: resumeGuideSurfacedRaw }),
|
|
2272
|
-
};
|
|
2273
|
-
})();
|
|
2274
|
-
if (deferredReplyReassertion === null)
|
|
2275
|
-
return null;
|
|
2276
2247
|
const pendingRuntimePromptRaw = value.pendingRuntimePrompt;
|
|
2277
2248
|
const pendingRuntimePrompt = (() => {
|
|
2278
2249
|
if (pendingRuntimePromptRaw === undefined)
|
|
@@ -2301,7 +2272,6 @@ function parseDialogLatestFile(value) {
|
|
|
2301
2272
|
latestAssignmentAnchor,
|
|
2302
2273
|
sideDialogFinalResponse,
|
|
2303
2274
|
fbrState,
|
|
2304
|
-
deferredReplyReassertion,
|
|
2305
2275
|
pendingUserInterjectionReply,
|
|
2306
2276
|
pendingRuntimePrompt,
|
|
2307
2277
|
disableDiligencePush: value.disableDiligencePush,
|
|
@@ -2456,20 +2426,6 @@ function isAnswerToHumanItem(value) {
|
|
|
2456
2426
|
return false;
|
|
2457
2427
|
if (typeof value.answeredAt !== 'string')
|
|
2458
2428
|
return false;
|
|
2459
|
-
if (!isRecord(value.userInterjection))
|
|
2460
|
-
return false;
|
|
2461
|
-
if (typeof value.userInterjection.msgId !== 'string')
|
|
2462
|
-
return false;
|
|
2463
|
-
if (typeof value.userInterjection.course !== 'number')
|
|
2464
|
-
return false;
|
|
2465
|
-
if (!Number.isInteger(value.userInterjection.course) || value.userInterjection.course <= 0) {
|
|
2466
|
-
return false;
|
|
2467
|
-
}
|
|
2468
|
-
if (typeof value.userInterjection.genseq !== 'number')
|
|
2469
|
-
return false;
|
|
2470
|
-
if (!Number.isInteger(value.userInterjection.genseq) || value.userInterjection.genseq <= 0) {
|
|
2471
|
-
return false;
|
|
2472
|
-
}
|
|
2473
2429
|
if (!isRecord(value.answerRef))
|
|
2474
2430
|
return false;
|
|
2475
2431
|
if (typeof value.answerRef.course !== 'number')
|
|
@@ -2595,6 +2551,7 @@ function isTellaskCallFunctionName(name) {
|
|
|
2595
2551
|
name === 'replyTellaskSessionless' ||
|
|
2596
2552
|
name === 'replyTellaskBack' ||
|
|
2597
2553
|
name === 'askHuman' ||
|
|
2554
|
+
name === 'answerHuman' ||
|
|
2598
2555
|
name === 'freshBootsReasoning');
|
|
2599
2556
|
}
|
|
2600
2557
|
/**
|
|
@@ -3635,10 +3592,6 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
3635
3592
|
targetCallId: payload.targetCallId,
|
|
3636
3593
|
};
|
|
3637
3594
|
await this.appendEvent(dialog, course, record);
|
|
3638
|
-
const deferredReplyReassertion = await DialogPersistence.getDeferredReplyReassertion(dialog.id, dialog.status);
|
|
3639
|
-
if (deferredReplyReassertion?.directive.targetCallId === payload.targetCallId) {
|
|
3640
|
-
await DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
|
|
3641
|
-
}
|
|
3642
3595
|
const activeObligation = await DialogPersistence.loadActiveTellaskReplyObligation(dialog.id, dialog.status);
|
|
3643
3596
|
if (activeObligation?.targetCallId === payload.targetCallId) {
|
|
3644
3597
|
await DialogPersistence.setActiveTellaskReplyObligation(dialog.id, undefined, dialog.status);
|
|
@@ -6583,7 +6536,15 @@ class DialogPersistence {
|
|
|
6583
6536
|
filePath: answersFilePath,
|
|
6584
6537
|
});
|
|
6585
6538
|
}
|
|
6586
|
-
return parsed.answers
|
|
6539
|
+
return parsed.answers.map((answer) => ({
|
|
6540
|
+
id: answer.id,
|
|
6541
|
+
content: answer.content,
|
|
6542
|
+
answeredAt: answer.answeredAt,
|
|
6543
|
+
answerRef: {
|
|
6544
|
+
course: answer.answerRef.course,
|
|
6545
|
+
genseq: answer.answerRef.genseq,
|
|
6546
|
+
},
|
|
6547
|
+
}));
|
|
6587
6548
|
}
|
|
6588
6549
|
catch (error) {
|
|
6589
6550
|
if (getErrorCode(error) === 'ENOENT')
|
|
@@ -6668,9 +6629,6 @@ class DialogPersistence {
|
|
|
6668
6629
|
if (answerId === '') {
|
|
6669
6630
|
throw new Error(`A2H append invariant violation: empty answer id (dialog=${dialogId.valueOf()})`);
|
|
6670
6631
|
}
|
|
6671
|
-
if (answer.content.trim() === '') {
|
|
6672
|
-
throw new Error(`A2H append invariant violation: empty answer content (dialog=${dialogId.valueOf()} answerId=${answer.id})`);
|
|
6673
|
-
}
|
|
6674
6632
|
await this.mutateAnswersToHumanState(dialogId, (previousAnswers) => {
|
|
6675
6633
|
const existing = previousAnswers.find((item) => item.id === answer.id);
|
|
6676
6634
|
if (existing) {
|
|
@@ -9191,23 +9149,6 @@ class DialogPersistence {
|
|
|
9191
9149
|
};
|
|
9192
9150
|
}, status);
|
|
9193
9151
|
}
|
|
9194
|
-
static async setDeferredReplyReassertion(dialogId, deferredReplyReassertion, status = 'running') {
|
|
9195
|
-
await this.mutateDialogLatest(dialogId, (previous) => {
|
|
9196
|
-
if (deferredReplyReassertion !== undefined) {
|
|
9197
|
-
return { kind: 'patch', patch: { deferredReplyReassertion } };
|
|
9198
|
-
}
|
|
9199
|
-
if (previous.deferredReplyReassertion === undefined) {
|
|
9200
|
-
return { kind: 'noop' };
|
|
9201
|
-
}
|
|
9202
|
-
const next = { ...previous };
|
|
9203
|
-
delete next.deferredReplyReassertion;
|
|
9204
|
-
return { kind: 'replace', next };
|
|
9205
|
-
}, status);
|
|
9206
|
-
}
|
|
9207
|
-
static async getDeferredReplyReassertion(dialogId, status = 'running') {
|
|
9208
|
-
const latest = await this.loadDialogLatest(dialogId, status);
|
|
9209
|
-
return latest?.deferredReplyReassertion;
|
|
9210
|
-
}
|
|
9211
9152
|
// === FILE SYSTEM UTILITIES ===
|
|
9212
9153
|
/**
|
|
9213
9154
|
* Get course filename from course number
|
|
@@ -9400,21 +9341,31 @@ class DialogPersistence {
|
|
|
9400
9341
|
id: `a2h-${Buffer.from(answerIdSource).toString('base64url')}`,
|
|
9401
9342
|
content: lastVisibleAnswer.content,
|
|
9402
9343
|
answeredAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
9403
|
-
userInterjection: {
|
|
9404
|
-
msgId: pendingUserInterjectionReply.msgId,
|
|
9405
|
-
course: pendingUserInterjectionReply.course,
|
|
9406
|
-
genseq: pendingUserInterjectionReply.genseq,
|
|
9407
|
-
},
|
|
9408
9344
|
answerRef: {
|
|
9409
9345
|
course: (0, storage_1.toDialogCourseNumber)(args.course),
|
|
9410
9346
|
genseq: (0, storage_1.toCallSiteGenseqNo)(lastVisibleAnswer.genseq),
|
|
9411
9347
|
},
|
|
9412
9348
|
};
|
|
9413
9349
|
}
|
|
9350
|
+
static answerRefSettlesPendingUserInterjection(answerRef, pending) {
|
|
9351
|
+
if (pending === undefined) {
|
|
9352
|
+
return false;
|
|
9353
|
+
}
|
|
9354
|
+
if (answerRef.course > pending.course) {
|
|
9355
|
+
return true;
|
|
9356
|
+
}
|
|
9357
|
+
return answerRef.course === pending.course && answerRef.genseq >= pending.genseq;
|
|
9358
|
+
}
|
|
9414
9359
|
static async normalizeDialogLatestPendingUserInterjectionReply(dialogId, status, latest) {
|
|
9415
9360
|
if (latest.pendingUserInterjectionReply === undefined) {
|
|
9416
9361
|
return latest;
|
|
9417
9362
|
}
|
|
9363
|
+
const existingAnswers = await this.loadAnswersToHumanState(dialogId, status);
|
|
9364
|
+
if (existingAnswers.some((answer) => this.answerRefSettlesPendingUserInterjection(answer.answerRef, latest.pendingUserInterjectionReply))) {
|
|
9365
|
+
const next = { ...latest };
|
|
9366
|
+
delete next.pendingUserInterjectionReply;
|
|
9367
|
+
return next;
|
|
9368
|
+
}
|
|
9418
9369
|
const events = await this.readCourseEvents(dialogId, latest.currentCourse, status);
|
|
9419
9370
|
const normalizedPending = this.resolvePendingUserInterjectionReplyFromCourseEvents(events, latest.currentCourse);
|
|
9420
9371
|
if (normalizedPending === undefined) {
|
|
@@ -9425,7 +9376,6 @@ class DialogPersistence {
|
|
|
9425
9376
|
pending: latest.pendingUserInterjectionReply,
|
|
9426
9377
|
});
|
|
9427
9378
|
if (recoveredAnswer !== undefined) {
|
|
9428
|
-
const existingAnswers = await this.loadAnswersToHumanState(dialogId, status);
|
|
9429
9379
|
if (!existingAnswers.some((item) => item.id === recoveredAnswer.id)) {
|
|
9430
9380
|
await this.appendAnswerToHumanState(dialogId, recoveredAnswer, status);
|
|
9431
9381
|
}
|
|
@@ -41,8 +41,6 @@ export type ReminderContextBusiness = Readonly<{
|
|
|
41
41
|
kind: 'pending_user_interjection';
|
|
42
42
|
}> | Readonly<{
|
|
43
43
|
kind: 'pending_user_interjection_with_active_reply';
|
|
44
|
-
}> | Readonly<{
|
|
45
|
-
kind: 'pending_user_interjection_with_parked_reply';
|
|
46
44
|
}> | Readonly<{
|
|
47
45
|
kind: 'user_followup_after_completed_handoff';
|
|
48
46
|
}>;
|
|
@@ -218,10 +218,6 @@ function formatZhReminderBusinessTail(business) {
|
|
|
218
218
|
// would block a valid user request and recreate the same kind of over-specific guidance
|
|
219
219
|
// bug in the opposite direction.
|
|
220
220
|
return '现在是用户在追问你。前面那件转交任务已经回报完成了,不需要再推进;请按用户这条消息正常交流和处理。';
|
|
221
|
-
case 'pending_user_interjection_with_parked_reply':
|
|
222
|
-
// A real user message interrupted an unfinished handoff. The old handoff is parked,
|
|
223
|
-
// so the model must not rush back to reply closure before the user sees an answer.
|
|
224
|
-
return '当前仍有真实用户插话尚未得到可见回复,且原有回贴任务已暂存;先完成对用户插话的回应,不要抢先切回原来的回贴收口。';
|
|
225
221
|
case 'pending_user_interjection':
|
|
226
222
|
// No special handoff state is competing with the user; the shortest useful instruction
|
|
227
223
|
// is simply to answer the still-unanswered user interjection.
|
|
@@ -263,10 +259,6 @@ function formatEnReminderBusinessTail(business) {
|
|
|
263
259
|
// would block a valid user request and recreate the same kind of over-specific guidance
|
|
264
260
|
// bug in the opposite direction.
|
|
265
261
|
return 'The user is asking you a follow-up now. The earlier handed-off task has already been reported back as complete, so there is nothing more to advance there. Talk with the user normally and handle this current message.';
|
|
266
|
-
case 'pending_user_interjection_with_parked_reply':
|
|
267
|
-
// A real user message interrupted an unfinished handoff. The old handoff is parked,
|
|
268
|
-
// so the model must not rush back to reply closure before the user sees an answer.
|
|
269
|
-
return "There is still a real user interjection without a visible reply, and the earlier handoff is parked; finish answering the user's interjection first, and do not switch back to closing the earlier reply yet.";
|
|
270
262
|
case 'pending_user_interjection':
|
|
271
263
|
// No special handoff state is competing with the user; the shortest useful instruction
|
|
272
264
|
// is simply to answer the still-unanswered user interjection.
|
|
@@ -958,7 +950,7 @@ function formatDomindsNoteFbrToollessViolation(language, args) {
|
|
|
958
950
|
`Dominds 提示:当前是扪心自问(FBR)支线对话(无工具模式)。${detail}`,
|
|
959
951
|
'',
|
|
960
952
|
'- 本对话无任何工具:禁止函数工具调用。',
|
|
961
|
-
'- 本对话禁止任何 tellask-special 函数(包括 `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman`)。',
|
|
953
|
+
'- 本对话禁止任何 tellask-special 函数(包括 `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `answerHuman`)。',
|
|
962
954
|
'- 请只基于诉请正文(以及本支线对话自身的会话历史,如有)进行推理与总结。',
|
|
963
955
|
].join('\n');
|
|
964
956
|
}
|
|
@@ -974,7 +966,7 @@ function formatDomindsNoteFbrToollessViolation(language, args) {
|
|
|
974
966
|
`Dominds note: this is a tool-less FBR Side Dialog (triggered by \`freshBootsReasoning\`). ${detail}`,
|
|
975
967
|
'',
|
|
976
968
|
'- No tools are available: do not emit function tool calls.',
|
|
977
|
-
'- No tellask-special functions are allowed (`tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman`).',
|
|
969
|
+
'- No tellask-special functions are allowed (`tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `answerHuman`).',
|
|
978
970
|
'- Provide pure reasoning and a summary grounded in the tellask body (and this Side Dialog’s own tellaskSession history, if any).',
|
|
979
971
|
].join('\n');
|
|
980
972
|
}
|
|
@@ -5,13 +5,12 @@ exports.isUserInterjectionPauseStopReason = isUserInterjectionPauseStopReason;
|
|
|
5
5
|
const USER_INTERJECTION_PAUSE_STOP_DETAIL = 'user_interjection_pause_resume_original_task';
|
|
6
6
|
// WARNING:
|
|
7
7
|
// This special stop reason is only a UI/run-control projection for legacy paused-interjection
|
|
8
|
-
// state. New answered-interjection flow
|
|
9
|
-
//
|
|
10
|
-
// the same thing as ordinary system-stop failure semantics.
|
|
8
|
+
// state. New answered-interjection flow depends on pending interjection settlement plus ordinary
|
|
9
|
+
// drive rules instead of this stop reason. It is intentionally encoded as `system_stop`, but it
|
|
10
|
+
// does NOT mean the same thing as ordinary system-stop failure semantics.
|
|
11
11
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// its true underlying state without showing this resumption panel.
|
|
12
|
+
// New user interjections should simply complete and the dialog should fall back to its true
|
|
13
|
+
// underlying state without showing this legacy resumption panel.
|
|
15
14
|
//
|
|
16
15
|
// In particular, askHuman answers are NOT "user interjections" for this purpose. A prompt carrying
|
|
17
16
|
// a real `q4hAnswerCallId` belongs to the askHuman reply channel and must never be routed through
|
|
@@ -19,8 +18,8 @@ const USER_INTERJECTION_PAUSE_STOP_DETAIL = 'user_interjection_pause_resume_orig
|
|
|
19
18
|
//
|
|
20
19
|
// Do not change this file in isolation. The complete behavior depends on coordinated logic across:
|
|
21
20
|
// - `reply-guidance.ts` suppressing tellasker reply obligation during interjection chat
|
|
22
|
-
// - `flow.ts` answering locally, then
|
|
23
|
-
// - `dialog-display-state.ts` preserving legacy paused projection until Continue
|
|
21
|
+
// - `flow.ts` answering locally, then using ordinary continuation rules
|
|
22
|
+
// - `dialog-display-state.ts` preserving legacy paused projection until Continue during recovery
|
|
24
23
|
// - `websocket-handler.ts` treating Continue as "resume attempt" rather than immediate success
|
|
25
24
|
//
|
|
26
25
|
// Reading only this stop reason or only `displayState.kind === 'stopped'` gives an incomplete and
|