dominds 1.26.6 → 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
|
@@ -9,7 +9,6 @@ const dialog_drive_work_1 = require("../../dialog-drive-work");
|
|
|
9
9
|
const dialog_global_registry_1 = require("../../dialog-global-registry");
|
|
10
10
|
const dialog_interruption_1 = require("../../dialog-interruption");
|
|
11
11
|
const dialog_latest_state_1 = require("../../dialog-latest-state");
|
|
12
|
-
const evt_registry_1 = require("../../evt-registry");
|
|
13
12
|
const log_1 = require("../../log");
|
|
14
13
|
const load_1 = require("../../minds/load");
|
|
15
14
|
const persistence_1 = require("../../persistence");
|
|
@@ -25,79 +24,6 @@ const idle_reminder_wake_1 = require("./idle-reminder-wake");
|
|
|
25
24
|
const reply_guidance_1 = require("./reply-guidance");
|
|
26
25
|
const sideDialog_1 = require("./sideDialog");
|
|
27
26
|
const tellask_special_1 = require("./tellask-special");
|
|
28
|
-
async function confirmAnsweredUserInterjectionCredential(args) {
|
|
29
|
-
const credential = args.credential;
|
|
30
|
-
if (credential === undefined) {
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
|
-
const dialog = args.dialog;
|
|
34
|
-
const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
|
|
35
|
-
const answers = await persistence_1.DialogPersistence.loadAnswersToHumanState(dialog.id, dialog.status);
|
|
36
|
-
const persistedCredential = answers.find((answer) => answer.id === credential.id);
|
|
37
|
-
if (persistedCredential === undefined) {
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
40
|
-
if (persistedCredential.userInterjection.msgId !== credential.userInterjection.msgId ||
|
|
41
|
-
persistedCredential.userInterjection.course !== credential.userInterjection.course ||
|
|
42
|
-
persistedCredential.userInterjection.genseq !== credential.userInterjection.genseq ||
|
|
43
|
-
persistedCredential.answerRef.course !== credential.answerRef.course ||
|
|
44
|
-
persistedCredential.answerRef.genseq !== credential.answerRef.genseq) {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
if (persistedCredential.userInterjection.msgId !== args.userInterjection.msgId ||
|
|
48
|
-
persistedCredential.userInterjection.course !== args.userInterjection.course ||
|
|
49
|
-
persistedCredential.userInterjection.genseq !== args.userInterjection.genseq) {
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
const pending = latest?.pendingUserInterjectionReply;
|
|
53
|
-
if (pending === undefined) {
|
|
54
|
-
return persistedCredential;
|
|
55
|
-
}
|
|
56
|
-
if (pending.msgId !== persistedCredential.userInterjection.msgId ||
|
|
57
|
-
pending.course !== persistedCredential.userInterjection.course ||
|
|
58
|
-
pending.genseq !== persistedCredential.userInterjection.genseq) {
|
|
59
|
-
return undefined;
|
|
60
|
-
}
|
|
61
|
-
await persistence_1.DialogPersistence.mutateDialogLatest(dialog.id, (previous) => {
|
|
62
|
-
const previousPending = previous.pendingUserInterjectionReply;
|
|
63
|
-
if (previousPending === undefined ||
|
|
64
|
-
previousPending.msgId !== persistedCredential.userInterjection.msgId ||
|
|
65
|
-
previousPending.course !== persistedCredential.userInterjection.course ||
|
|
66
|
-
previousPending.genseq !== persistedCredential.userInterjection.genseq) {
|
|
67
|
-
return { kind: 'noop' };
|
|
68
|
-
}
|
|
69
|
-
const next = { ...previous };
|
|
70
|
-
delete next.pendingUserInterjectionReply;
|
|
71
|
-
return { kind: 'replace', next };
|
|
72
|
-
}, dialog.status);
|
|
73
|
-
return persistedCredential;
|
|
74
|
-
}
|
|
75
|
-
async function resolveLatestAnsweredUserInterjectionCredential(dialog, userInterjection) {
|
|
76
|
-
const answers = await persistence_1.DialogPersistence.loadAnswersToHumanState(dialog.id, dialog.status);
|
|
77
|
-
for (let index = answers.length - 1; index >= 0; index -= 1) {
|
|
78
|
-
const answer = answers[index];
|
|
79
|
-
if (answer.userInterjection.msgId === userInterjection.msgId &&
|
|
80
|
-
answer.userInterjection.course === userInterjection.course &&
|
|
81
|
-
answer.userInterjection.genseq === userInterjection.genseq) {
|
|
82
|
-
return answer;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return undefined;
|
|
86
|
-
}
|
|
87
|
-
async function resolveAnsweredUserInterjectionCredentialForPrompt(args) {
|
|
88
|
-
const userPromptMsgId = args.userPromptMsgId;
|
|
89
|
-
if (userPromptMsgId === undefined) {
|
|
90
|
-
return undefined;
|
|
91
|
-
}
|
|
92
|
-
const answers = await persistence_1.DialogPersistence.loadAnswersToHumanState(args.dialog.id, args.dialog.status);
|
|
93
|
-
for (let index = answers.length - 1; index >= 0; index -= 1) {
|
|
94
|
-
const answer = answers[index];
|
|
95
|
-
if (answer.userInterjection.msgId === userPromptMsgId) {
|
|
96
|
-
return answer;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return undefined;
|
|
100
|
-
}
|
|
101
27
|
function buildRuntimeReplyReminderFollowUp(args) {
|
|
102
28
|
const common = {
|
|
103
29
|
prompt: args.prompt,
|
|
@@ -353,6 +279,16 @@ async function buildReplyToolReminderPrompt(args) {
|
|
|
353
279
|
}),
|
|
354
280
|
});
|
|
355
281
|
}
|
|
282
|
+
async function buildAnsweringReplyReminderPrompt(args) {
|
|
283
|
+
return (0, reply_prompt_copy_1.buildAnsweringReplyReminderText)({
|
|
284
|
+
language: args.language,
|
|
285
|
+
directive: args.directive,
|
|
286
|
+
replyTargetAgentId: await (0, reply_guidance_1.resolveReplyTargetAgentId)({
|
|
287
|
+
dlg: args.dlg,
|
|
288
|
+
directive: args.directive,
|
|
289
|
+
}),
|
|
290
|
+
});
|
|
291
|
+
}
|
|
356
292
|
function isPositiveInteger(value) {
|
|
357
293
|
return typeof value === 'number' && Number.isInteger(value) && value > 0;
|
|
358
294
|
}
|
|
@@ -1033,112 +969,6 @@ async function inspectSideDialogBusinessContinuationDrive(args) {
|
|
|
1033
969
|
sideDialogFinalResponseCallId,
|
|
1034
970
|
};
|
|
1035
971
|
}
|
|
1036
|
-
async function maybeResolveDeferredReplyReassertionPrompt(dialog) {
|
|
1037
|
-
const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
|
|
1038
|
-
if (latest?.pendingUserInterjectionReply !== undefined) {
|
|
1039
|
-
return undefined;
|
|
1040
|
-
}
|
|
1041
|
-
const deferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(dialog.id, dialog.status);
|
|
1042
|
-
if (!deferredReplyReassertion) {
|
|
1043
|
-
return undefined;
|
|
1044
|
-
}
|
|
1045
|
-
const activeDirective = await (0, tellask_special_1.loadActiveTellaskReplyDirective)(dialog);
|
|
1046
|
-
if (!activeDirective ||
|
|
1047
|
-
activeDirective.targetCallId !== deferredReplyReassertion.directive.targetCallId) {
|
|
1048
|
-
await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
|
|
1049
|
-
return undefined;
|
|
1050
|
-
}
|
|
1051
|
-
// WARNING:
|
|
1052
|
-
// `resumeGuideSurfaced` means the reply-obligation reassertion has already been materialized as a
|
|
1053
|
-
// runtime guide and injected into both dialog.msgs and persisted course history at blocked
|
|
1054
|
-
// Continue time. Once that has happened, later real resume must not emit a second visible prompt:
|
|
1055
|
-
// normal context replay is now the source of truth for the model-facing reminder.
|
|
1056
|
-
if (deferredReplyReassertion.resumeGuideSurfaced === true) {
|
|
1057
|
-
await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
|
|
1058
|
-
return undefined;
|
|
1059
|
-
}
|
|
1060
|
-
const answeredUserInterjection = await confirmAnsweredUserInterjectionCredential({
|
|
1061
|
-
dialog,
|
|
1062
|
-
credential: await resolveLatestAnsweredUserInterjectionCredential(dialog, deferredReplyReassertion.userInterjection),
|
|
1063
|
-
userInterjection: deferredReplyReassertion.userInterjection,
|
|
1064
|
-
});
|
|
1065
|
-
if (answeredUserInterjection === undefined) {
|
|
1066
|
-
return undefined;
|
|
1067
|
-
}
|
|
1068
|
-
await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
|
|
1069
|
-
const language = (0, work_language_1.getWorkLanguage)();
|
|
1070
|
-
return {
|
|
1071
|
-
content: await (0, reply_guidance_1.buildReplyObligationReassertionPrompt)({
|
|
1072
|
-
dlg: dialog,
|
|
1073
|
-
directive: deferredReplyReassertion.directive,
|
|
1074
|
-
language,
|
|
1075
|
-
answeredUserInterjection,
|
|
1076
|
-
}),
|
|
1077
|
-
msgId: (0, id_1.generateShortId)(),
|
|
1078
|
-
grammar: 'markdown',
|
|
1079
|
-
origin: 'runtime',
|
|
1080
|
-
userLanguageCode: language,
|
|
1081
|
-
tellaskReplyDirective: deferredReplyReassertion.directive,
|
|
1082
|
-
};
|
|
1083
|
-
}
|
|
1084
|
-
async function maybeSurfaceDeferredReplyReassertionGuideForBlockedContinue(dialog) {
|
|
1085
|
-
const deferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(dialog.id, dialog.status);
|
|
1086
|
-
if (!deferredReplyReassertion || deferredReplyReassertion.resumeGuideSurfaced === true) {
|
|
1087
|
-
return;
|
|
1088
|
-
}
|
|
1089
|
-
const activeDirective = await (0, tellask_special_1.loadActiveTellaskReplyDirective)(dialog);
|
|
1090
|
-
if (!activeDirective ||
|
|
1091
|
-
activeDirective.targetCallId !== deferredReplyReassertion.directive.targetCallId) {
|
|
1092
|
-
await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
const language = (0, work_language_1.getWorkLanguage)();
|
|
1096
|
-
const answeredUserInterjection = await confirmAnsweredUserInterjectionCredential({
|
|
1097
|
-
dialog,
|
|
1098
|
-
credential: await resolveLatestAnsweredUserInterjectionCredential(dialog, deferredReplyReassertion.userInterjection),
|
|
1099
|
-
userInterjection: deferredReplyReassertion.userInterjection,
|
|
1100
|
-
});
|
|
1101
|
-
if (answeredUserInterjection === undefined) {
|
|
1102
|
-
return;
|
|
1103
|
-
}
|
|
1104
|
-
const content = await (0, reply_guidance_1.buildReplyObligationReassertionPrompt)({
|
|
1105
|
-
dlg: dialog,
|
|
1106
|
-
directive: deferredReplyReassertion.directive,
|
|
1107
|
-
language,
|
|
1108
|
-
answeredUserInterjection,
|
|
1109
|
-
});
|
|
1110
|
-
// WARNING:
|
|
1111
|
-
// This helper intentionally does three things at once:
|
|
1112
|
-
// 1. append the guide into dialog.msgs so an in-memory later resume sees it naturally;
|
|
1113
|
-
// 2. persist a runtime_guide_record so reload/replay reconstructs the same context;
|
|
1114
|
-
// 3. emit runtime_guide_evt so the user immediately sees the reassertion bubble after Continue.
|
|
1115
|
-
//
|
|
1116
|
-
// Do not "optimize" this into only an event or only a deferred prompt. The whole point is that
|
|
1117
|
-
// once a legacy blocked Continue path surfaces the guide, it becomes a first-class historical
|
|
1118
|
-
// context fact and later real driving should need no special duplicate reassertion path.
|
|
1119
|
-
await surfaceRuntimeGuide(dialog, content);
|
|
1120
|
-
await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, {
|
|
1121
|
-
reason: 'user_interjection_with_parked_original_task',
|
|
1122
|
-
directive: deferredReplyReassertion.directive,
|
|
1123
|
-
userInterjection: deferredReplyReassertion.userInterjection,
|
|
1124
|
-
resumeGuideSurfaced: true,
|
|
1125
|
-
}, dialog.status);
|
|
1126
|
-
}
|
|
1127
|
-
async function surfaceRuntimeGuide(dialog, content) {
|
|
1128
|
-
const genseq = dialog.activeGenSeqOrUndefined ?? 1;
|
|
1129
|
-
await dialog.addChatMessages({
|
|
1130
|
-
type: 'transient_guide_msg',
|
|
1131
|
-
role: 'assistant',
|
|
1132
|
-
content,
|
|
1133
|
-
});
|
|
1134
|
-
await persistence_1.DialogPersistence.persistRuntimeGuide(dialog, content, genseq);
|
|
1135
|
-
(0, evt_registry_1.postDialogEvent)(dialog, {
|
|
1136
|
-
type: 'runtime_guide_evt',
|
|
1137
|
-
course: dialog.currentCourse,
|
|
1138
|
-
genseq,
|
|
1139
|
-
content,
|
|
1140
|
-
});
|
|
1141
|
-
}
|
|
1142
972
|
async function resolveEffectivePrompt(dialog, humanPrompt) {
|
|
1143
973
|
if (humanPrompt) {
|
|
1144
974
|
return { prompt: humanPrompt, fromQueuedPrompt: false, droppedStaleQueuedContinuation: false };
|
|
@@ -1148,7 +978,7 @@ async function resolveEffectivePrompt(dialog, humanPrompt) {
|
|
|
1148
978
|
const queuedPrompt = dialog.peekQueuedPrompt();
|
|
1149
979
|
if (!queuedPrompt) {
|
|
1150
980
|
return {
|
|
1151
|
-
prompt:
|
|
981
|
+
prompt: undefined,
|
|
1152
982
|
fromQueuedPrompt: false,
|
|
1153
983
|
droppedStaleQueuedContinuation,
|
|
1154
984
|
};
|
|
@@ -1523,7 +1353,7 @@ async function executeDriveRound(args) {
|
|
|
1523
1353
|
//
|
|
1524
1354
|
// Do not refactor this branch using only `displayState` or only the previous interrupted
|
|
1525
1355
|
// marker. The correct behavior emerges from combining fresh suspension facts, queued prompt
|
|
1526
|
-
// state, and
|
|
1356
|
+
// state, and ordinary reply-obligation state.
|
|
1527
1357
|
const hasSupplyResponseContinuation = hasSupplyResponseBusinessContinuation(dialog, driveOptions);
|
|
1528
1358
|
const suspension = resumeFromInterjectionPause
|
|
1529
1359
|
? await loadFreshSuspensionStatusFromPersistence(dialog)
|
|
@@ -1536,7 +1366,6 @@ async function executeDriveRound(args) {
|
|
|
1536
1366
|
if (resumeFromInterjectionPause) {
|
|
1537
1367
|
const restoredState = await (0, dialog_display_state_1.computeIdleDisplayState)(dialog);
|
|
1538
1368
|
await (0, dialog_display_state_1.setDialogDisplayState)(dialog.id, restoredState);
|
|
1539
|
-
await maybeSurfaceDeferredReplyReassertionGuideForBlockedContinue(dialog);
|
|
1540
1369
|
log_1.log.debug('kernel-driver continue after interjection pause restored true suspended state from fresh persistence facts', undefined, {
|
|
1541
1370
|
dialogId: dialog.id.valueOf(),
|
|
1542
1371
|
restoredState,
|
|
@@ -1721,19 +1550,13 @@ async function executeDriveRound(args) {
|
|
|
1721
1550
|
dlg: dialog,
|
|
1722
1551
|
prompt: effectivePrompt,
|
|
1723
1552
|
});
|
|
1724
|
-
// Only park into the special interjection resumption-panel state when this user turn has
|
|
1725
|
-
// suppressed a still-pending inter-dialog reply obligation that must be reasserted later.
|
|
1726
|
-
// User interjections without a parked original task should simply finish and fall back to the
|
|
1727
|
-
// dialog's true underlying state, without showing the special resumption panel.
|
|
1728
|
-
//
|
|
1729
1553
|
// Q4H answers are explicitly outside this branch even though they also come from the human.
|
|
1730
1554
|
// They belong to the askHuman reply channel and must continue the suspended askHuman round,
|
|
1731
1555
|
// never be mistaken for ad hoc interjection chat.
|
|
1732
1556
|
shouldPauseAfterLocalUserInterjection =
|
|
1733
1557
|
effectivePrompt?.origin === 'user' &&
|
|
1734
1558
|
!replyGuidance.isQ4HAnswerPrompt &&
|
|
1735
|
-
replyGuidance.suppressInterDialogReplyGuidance
|
|
1736
|
-
replyGuidance.deferredReplyReassertionDirective !== undefined;
|
|
1559
|
+
replyGuidance.suppressInterDialogReplyGuidance;
|
|
1737
1560
|
activeTellaskReplyDirective =
|
|
1738
1561
|
replyGuidance.activeReplyDirective ?? replyContinuationScope.directive();
|
|
1739
1562
|
activePromptWasReplyToolReminder = isReplyToolReminderPrompt(effectivePrompt);
|
|
@@ -1822,50 +1645,50 @@ async function executeDriveRound(args) {
|
|
|
1822
1645
|
}
|
|
1823
1646
|
let tailError;
|
|
1824
1647
|
try {
|
|
1825
|
-
if (
|
|
1826
|
-
|
|
1648
|
+
if (dialog instanceof dialog_1.SideDialog &&
|
|
1649
|
+
driveResult &&
|
|
1827
1650
|
!interruptedBySignal &&
|
|
1828
|
-
|
|
1829
|
-
driveResult
|
|
1830
|
-
driveResult.
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1651
|
+
driveResult.fbrConclusion === undefined &&
|
|
1652
|
+
driveResult.lastAssistantAnsweringContent !== null &&
|
|
1653
|
+
driveResult.lastAssistantAnsweringContent.trim() !== '' &&
|
|
1654
|
+
resolveDirectFallbackResponse({ driveResult, dialog }) === undefined &&
|
|
1655
|
+
followUp === undefined) {
|
|
1656
|
+
const suspension = await dialog.getSuspensionStatus();
|
|
1657
|
+
const backgroundCalleeBlocksImplicitReply = suspension.backgroundCalleeDialogs &&
|
|
1658
|
+
!activePromptWasReplyToolReminder &&
|
|
1659
|
+
!activePromptCarriesReplyDirective;
|
|
1660
|
+
if (!suspension.canDrive || backgroundCalleeBlocksImplicitReply) {
|
|
1661
|
+
log_1.log.debug('kernel-driver skip sideDialog answering reminder while tellaskee is not finalized', undefined, {
|
|
1662
|
+
rootId: dialog.id.rootId,
|
|
1663
|
+
selfId: dialog.id.selfId,
|
|
1664
|
+
waitingQ4H: suspension.q4h,
|
|
1665
|
+
backgroundCalleeDialogs: suspension.backgroundCalleeDialogs,
|
|
1666
|
+
backgroundCalleeBlocksImplicitReply,
|
|
1843
1667
|
});
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1668
|
+
}
|
|
1669
|
+
else if (activeTellaskReplyDirective === undefined) {
|
|
1670
|
+
log_1.log.debug('kernel-driver skip sideDialog answering reminder because no active tellask reply directive is bound to this drive', undefined, {
|
|
1671
|
+
rootId: dialog.id.rootId,
|
|
1672
|
+
selfId: dialog.id.selfId,
|
|
1673
|
+
});
|
|
1674
|
+
}
|
|
1675
|
+
else {
|
|
1676
|
+
const language = (0, work_language_1.getWorkLanguage)();
|
|
1677
|
+
followUp = buildRuntimeReplyReminderFollowUp({
|
|
1678
|
+
directive: activeTellaskReplyDirective,
|
|
1679
|
+
prompt: await buildAnsweringReplyReminderPrompt({
|
|
1847
1680
|
dlg: dialog,
|
|
1848
|
-
directive:
|
|
1681
|
+
directive: activeTellaskReplyDirective,
|
|
1849
1682
|
language,
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
tellaskReplyDirective: deferredReplyReassertion.directive,
|
|
1860
|
-
};
|
|
1861
|
-
await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
|
|
1862
|
-
log_1.log.debug('kernel-driver queued automatic reply-obligation reassertion after user interjection answer', undefined, {
|
|
1863
|
-
dialogId: dialog.id.valueOf(),
|
|
1864
|
-
rootId: dialog.id.rootId,
|
|
1865
|
-
selfId: dialog.id.selfId,
|
|
1866
|
-
targetCallId: deferredReplyReassertion.directive.targetCallId,
|
|
1867
|
-
});
|
|
1868
|
-
}
|
|
1683
|
+
}),
|
|
1684
|
+
language,
|
|
1685
|
+
calleeDialogReplyTarget,
|
|
1686
|
+
});
|
|
1687
|
+
log_1.log.debug('kernel-driver queued sideDialog replyTellask reminder after answering-only output', undefined, {
|
|
1688
|
+
dialogId: dialog.id.valueOf(),
|
|
1689
|
+
targetCallId: activeTellaskReplyDirective.targetCallId,
|
|
1690
|
+
targetCallerDialogId: calleeDialogReplyTarget?.callerDialogId,
|
|
1691
|
+
});
|
|
1869
1692
|
}
|
|
1870
1693
|
}
|
|
1871
1694
|
if (dialog instanceof dialog_1.SideDialog &&
|
|
@@ -11,7 +11,6 @@ export declare function resolveReminderContextBusinessState(args: {
|
|
|
11
11
|
followingMessage: ReminderContextFollowingMessage;
|
|
12
12
|
pendingUserInterjectionReply: boolean;
|
|
13
13
|
hasCompletedHandoffWithoutPendingReply: boolean;
|
|
14
|
-
hasDeferredReplyReassertion: boolean;
|
|
15
14
|
hasActiveReplyObligation: boolean;
|
|
16
15
|
}): ReminderContextBusiness;
|
|
17
16
|
export declare function resolveReminderContextFooterStateFromSignals(args: {
|
|
@@ -21,6 +20,5 @@ export declare function resolveReminderContextFooterStateFromSignals(args: {
|
|
|
21
20
|
contextHealth: ContextHealthSnapshot | undefined;
|
|
22
21
|
pendingUserInterjectionReply: boolean;
|
|
23
22
|
hasCompletedHandoffWithoutPendingReply: boolean;
|
|
24
|
-
hasDeferredReplyReassertion: boolean;
|
|
25
23
|
hasActiveReplyObligation: boolean;
|
|
26
24
|
}): ReminderContextFooterState;
|
|
@@ -49,9 +49,6 @@ function resolveReminderContextBusinessState(args) {
|
|
|
49
49
|
if (args.hasCompletedHandoffWithoutPendingReply) {
|
|
50
50
|
return { kind: 'user_followup_after_completed_handoff' };
|
|
51
51
|
}
|
|
52
|
-
if (args.hasDeferredReplyReassertion) {
|
|
53
|
-
return { kind: 'pending_user_interjection_with_parked_reply' };
|
|
54
|
-
}
|
|
55
52
|
if (args.hasActiveReplyObligation) {
|
|
56
53
|
return { kind: 'pending_user_interjection_with_active_reply' };
|
|
57
54
|
}
|
|
@@ -75,7 +72,6 @@ function resolveReminderContextFooterStateFromSignals(args) {
|
|
|
75
72
|
followingMessage,
|
|
76
73
|
pendingUserInterjectionReply: args.pendingUserInterjectionReply,
|
|
77
74
|
hasCompletedHandoffWithoutPendingReply: args.hasCompletedHandoffWithoutPendingReply,
|
|
78
|
-
hasDeferredReplyReassertion: args.hasDeferredReplyReassertion,
|
|
79
75
|
hasActiveReplyObligation: args.hasActiveReplyObligation,
|
|
80
76
|
}),
|
|
81
77
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
|
|
2
2
|
import { Dialog } from '../../dialog';
|
|
3
3
|
import type { KernelDriverPrompt } from './types';
|
|
4
4
|
export declare function resolveReplyTargetAgentId(args: {
|
|
@@ -11,7 +11,6 @@ export declare function resolvePromptReplyGuidance(args: {
|
|
|
11
11
|
language?: 'zh' | 'en';
|
|
12
12
|
}): Promise<{
|
|
13
13
|
activeReplyDirective: KernelDriverPrompt['tellaskReplyDirective'];
|
|
14
|
-
deferredReplyReassertionDirective: KernelDriverPrompt['tellaskReplyDirective'];
|
|
15
14
|
isQ4HAnswerPrompt: boolean;
|
|
16
15
|
promptContent: string | undefined;
|
|
17
16
|
persistedTellaskReplyDirective: KernelDriverPrompt['tellaskReplyDirective'];
|
|
@@ -21,9 +20,3 @@ export declare function resolvePromptReplyGuidance(args: {
|
|
|
21
20
|
export declare function buildReplyObligationSuppressionGuide(args: {
|
|
22
21
|
language: 'zh' | 'en';
|
|
23
22
|
}): string;
|
|
24
|
-
export declare function buildReplyObligationReassertionPrompt(args: {
|
|
25
|
-
dlg: Dialog;
|
|
26
|
-
directive: NonNullable<KernelDriverPrompt['tellaskReplyDirective']>;
|
|
27
|
-
language: 'zh' | 'en';
|
|
28
|
-
answeredUserInterjection: AnswerToHumanItem;
|
|
29
|
-
}): Promise<string>;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.resolveReplyTargetAgentId = resolveReplyTargetAgentId;
|
|
4
4
|
exports.resolvePromptReplyGuidance = resolvePromptReplyGuidance;
|
|
5
5
|
exports.buildReplyObligationSuppressionGuide = buildReplyObligationSuppressionGuide;
|
|
6
|
-
exports.buildReplyObligationReassertionPrompt = buildReplyObligationReassertionPrompt;
|
|
7
6
|
const dialog_1 = require("../../dialog");
|
|
8
7
|
const dialog_instance_registry_1 = require("../../dialog-instance-registry");
|
|
9
8
|
const persistence_1 = require("../../persistence");
|
|
@@ -33,8 +32,8 @@ function buildPromptContentWithExactReplyToolName(args) {
|
|
|
33
32
|
const reminderPrefixes = [
|
|
34
33
|
reply_prompt_copy_1.REPLY_TOOL_REMINDER_PREFIX_EN,
|
|
35
34
|
reply_prompt_copy_1.REPLY_TOOL_REMINDER_PREFIX_ZH,
|
|
36
|
-
reply_prompt_copy_1.
|
|
37
|
-
reply_prompt_copy_1.
|
|
35
|
+
reply_prompt_copy_1.ANSWERING_REPLY_REMINDER_PREFIX_EN,
|
|
36
|
+
reply_prompt_copy_1.ANSWERING_REPLY_REMINDER_PREFIX_ZH,
|
|
38
37
|
];
|
|
39
38
|
const directive = args.activeReplyDirective;
|
|
40
39
|
if (!directive) {
|
|
@@ -204,18 +203,16 @@ function resolvePromptPersistedReplyDirective(args) {
|
|
|
204
203
|
}
|
|
205
204
|
async function shouldSuppressInterDialogReplyGuidanceForUserInterjection(args) {
|
|
206
205
|
// WARNING:
|
|
207
|
-
// This suppression decision is not a cosmetic prompt tweak.
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
// 2. `flow.ts` answers locally and stores a deferred reply reassertion;
|
|
211
|
-
// 3. after a visible local answer, the driver reasserts the reply obligation automatically.
|
|
206
|
+
// This suppression decision is not a cosmetic prompt tweak. A real user interjection should be
|
|
207
|
+
// answered locally before old reply obligations or pending callee work pull the model back into
|
|
208
|
+
// earlier handoff closure.
|
|
212
209
|
//
|
|
213
210
|
// Do not "simplify" this into a pure display-state check or a pure active-callee check.
|
|
214
211
|
// Proceeding dialogs with a still-active reply obligation are part of the same rule: a fresh
|
|
215
212
|
// user interjection should still suppress the live reply obligation and answer locally first.
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
213
|
+
// A stale paused execution marker still means a repeated interjection should behave as local
|
|
214
|
+
// side conversation, but it is not durable drive work and must not force a manual Continue after
|
|
215
|
+
// the answer is visible.
|
|
219
216
|
const prompt = args.prompt;
|
|
220
217
|
if (!prompt) {
|
|
221
218
|
return false;
|
|
@@ -227,9 +224,6 @@ async function shouldSuppressInterDialogReplyGuidanceForUserInterjection(args) {
|
|
|
227
224
|
return false;
|
|
228
225
|
}
|
|
229
226
|
const latest = await persistence_1.DialogPersistence.loadDialogLatest(args.dlg.id, args.dlg.status);
|
|
230
|
-
if (latest?.deferredReplyReassertion?.reason === 'user_interjection_with_parked_original_task') {
|
|
231
|
-
return true;
|
|
232
|
-
}
|
|
233
227
|
if (latest?.executionMarker?.kind === 'interrupted' &&
|
|
234
228
|
(0, interjection_pause_stop_1.isUserInterjectionPauseStopReason)(latest.executionMarker.reason)) {
|
|
235
229
|
return true;
|
|
@@ -290,9 +284,6 @@ async function resolvePromptReplyGuidance(args) {
|
|
|
290
284
|
});
|
|
291
285
|
return {
|
|
292
286
|
activeReplyDirective,
|
|
293
|
-
deferredReplyReassertionDirective: suppressInterDialogReplyGuidance
|
|
294
|
-
? availableReplyDirective
|
|
295
|
-
: undefined,
|
|
296
287
|
isQ4HAnswerPrompt,
|
|
297
288
|
promptContent,
|
|
298
289
|
persistedTellaskReplyDirective: resolvePromptPersistedReplyDirective({
|
|
@@ -310,13 +301,3 @@ async function resolvePromptReplyGuidance(args) {
|
|
|
310
301
|
function buildReplyObligationSuppressionGuide(args) {
|
|
311
302
|
return (0, reply_prompt_copy_1.buildReplyObligationSuppressionGuideText)(args.language);
|
|
312
303
|
}
|
|
313
|
-
async function buildReplyObligationReassertionPrompt(args) {
|
|
314
|
-
return (0, reply_prompt_copy_1.buildReplyObligationReassertionText)({
|
|
315
|
-
language: args.language,
|
|
316
|
-
directive: args.directive,
|
|
317
|
-
replyTargetAgentId: await resolveReplyTargetAgentId({
|
|
318
|
-
dlg: args.dlg,
|
|
319
|
-
directive: args.directive,
|
|
320
|
-
}),
|
|
321
|
-
});
|
|
322
|
-
}
|
|
@@ -331,10 +331,6 @@ async function supplyResponseToAskerDialog(args) {
|
|
|
331
331
|
};
|
|
332
332
|
await persistence_1.DialogPersistence.appendEvent(sideDialogId, calleeResponseRef.course, replyResolutionRecord, callerDialog.status);
|
|
333
333
|
await persistence_1.DialogPersistence.markReplyDeliveryDelivered(sideDialogId, args.replyResolution.callId, replyResolutionRecord.ts, callerDialog.status);
|
|
334
|
-
const deferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(sideDialogId, callerDialog.status);
|
|
335
|
-
if (deferredReplyReassertion?.directive.targetCallId === resolvedCallId) {
|
|
336
|
-
await persistence_1.DialogPersistence.setDeferredReplyReassertion(sideDialogId, undefined, callerDialog.status);
|
|
337
|
-
}
|
|
338
334
|
const activeReplyObligation = await persistence_1.DialogPersistence.loadActiveTellaskReplyObligation(sideDialogId, callerDialog.status);
|
|
339
335
|
if (activeReplyObligation?.targetCallId === resolvedCallId) {
|
|
340
336
|
await persistence_1.DialogPersistence.setActiveTellaskReplyObligation(sideDialogId, undefined, callerDialog.status);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DialogReplyDeliveryState, type TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
|
|
1
|
+
import { type AnswerToHumanItem, type DialogReplyDeliveryState, type TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
|
|
2
2
|
import { Dialog } from '../../dialog';
|
|
3
3
|
import type { ChatMessage, FuncCallMsg, FuncResultMsg } from '../client';
|
|
4
4
|
import type { KernelDriverDriveCallbacks } from './types';
|
|
@@ -13,7 +13,7 @@ export type TellaskRoutingParseResult = {
|
|
|
13
13
|
type: 'C';
|
|
14
14
|
agentId: string;
|
|
15
15
|
};
|
|
16
|
-
declare const TELLASK_SPECIAL_FUNCTION_NAMES: readonly ["tellaskBack", "tellask", "tellaskSessionless", "replyTellask", "replyTellaskSessionless", "replyTellaskBack", "askHuman", "freshBootsReasoning"];
|
|
16
|
+
declare const TELLASK_SPECIAL_FUNCTION_NAMES: readonly ["tellaskBack", "tellask", "tellaskSessionless", "replyTellask", "replyTellaskSessionless", "replyTellaskBack", "askHuman", "answerHuman", "freshBootsReasoning"];
|
|
17
17
|
export type TellaskCallFunctionName = (typeof TELLASK_SPECIAL_FUNCTION_NAMES)[number];
|
|
18
18
|
export type TellaskCall = Readonly<{
|
|
19
19
|
callId: string;
|
|
@@ -48,6 +48,10 @@ export type TellaskCall = Readonly<{
|
|
|
48
48
|
callId: string;
|
|
49
49
|
callName: 'askHuman';
|
|
50
50
|
tellaskContent: string;
|
|
51
|
+
}> | Readonly<{
|
|
52
|
+
callId: string;
|
|
53
|
+
callName: 'answerHuman';
|
|
54
|
+
answerContent: string;
|
|
51
55
|
}> | Readonly<{
|
|
52
56
|
callId: string;
|
|
53
57
|
callName: 'freshBootsReasoning';
|
|
@@ -103,6 +107,20 @@ export declare function formatResolvedTellaskFuncResultContent(args: {
|
|
|
103
107
|
status: 'pending' | 'completed' | 'failed';
|
|
104
108
|
}): string;
|
|
105
109
|
export declare function formatResolvedAskHumanResultContent(): string;
|
|
110
|
+
export type AnswerHumanStructuredOutput = Readonly<{
|
|
111
|
+
callId: string;
|
|
112
|
+
answerContent: string;
|
|
113
|
+
course: number;
|
|
114
|
+
genseq: number;
|
|
115
|
+
answer: AnswerToHumanItem;
|
|
116
|
+
}>;
|
|
117
|
+
export declare function recordAnswerToHuman(args: {
|
|
118
|
+
dlg: Dialog;
|
|
119
|
+
answerContent: string;
|
|
120
|
+
course: number;
|
|
121
|
+
genseq: number;
|
|
122
|
+
answerIdSource: string;
|
|
123
|
+
}): Promise<AnswerToHumanItem>;
|
|
106
124
|
export declare function executeTellaskCalls(args: {
|
|
107
125
|
dlg: Dialog;
|
|
108
126
|
calls: readonly TellaskCall[];
|
|
@@ -111,6 +129,7 @@ export declare function executeTellaskCalls(args: {
|
|
|
111
129
|
}): Promise<{
|
|
112
130
|
toolOutputs: ChatMessage[];
|
|
113
131
|
successfulReplyCallIds: string[];
|
|
132
|
+
answerHumanOutputs: AnswerHumanStructuredOutput[];
|
|
114
133
|
}>;
|
|
115
134
|
export type TellaskFunctionRoundResult = Readonly<{
|
|
116
135
|
normalCalls: readonly FuncCallMsg[];
|
|
@@ -122,6 +141,7 @@ export type TellaskFunctionRoundResult = Readonly<{
|
|
|
122
141
|
hasImmediateTellaskOutputs: boolean;
|
|
123
142
|
immediateTellaskOutputCallIds: readonly string[];
|
|
124
143
|
invalidTellaskCallIds: readonly string[];
|
|
144
|
+
answerHumanOutputs: readonly AnswerHumanStructuredOutput[];
|
|
125
145
|
shouldStopAfterReplyTool: boolean;
|
|
126
146
|
shouldStopAfterPendingTellaskWait: boolean;
|
|
127
147
|
}>;
|