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.
@@ -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: await maybeResolveDeferredReplyReassertionPrompt(dialog),
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 the deferred reply reassertion logic elsewhere.
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 (shouldPauseAfterLocalUserInterjection &&
1826
- effectivePrompt?.origin === 'user' &&
1648
+ if (dialog instanceof dialog_1.SideDialog &&
1649
+ driveResult &&
1827
1650
  !interruptedBySignal &&
1828
- followUp === undefined &&
1829
- driveResult?.lastAssistantSayingContent !== undefined &&
1830
- driveResult.lastAssistantSayingContent !== null &&
1831
- driveResult.lastAssistantSayingContent.trim() !== '') {
1832
- const deferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(dialog.id, dialog.status);
1833
- if (deferredReplyReassertion !== undefined &&
1834
- deferredReplyReassertion.reason === 'user_interjection_with_parked_original_task') {
1835
- const answeredUserInterjection = await confirmAnsweredUserInterjectionCredential({
1836
- dialog,
1837
- credential: driveResult.answeredUserInterjection ??
1838
- (await resolveAnsweredUserInterjectionCredentialForPrompt({
1839
- dialog,
1840
- userPromptMsgId: effectivePrompt?.msgId,
1841
- })),
1842
- userInterjection: deferredReplyReassertion.userInterjection,
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
- if (answeredUserInterjection !== undefined) {
1845
- const language = (0, work_language_1.getWorkLanguage)();
1846
- const prompt = await (0, reply_guidance_1.buildReplyObligationReassertionPrompt)({
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: deferredReplyReassertion.directive,
1681
+ directive: activeTellaskReplyDirective,
1849
1682
  language,
1850
- answeredUserInterjection,
1851
- });
1852
- followUp = {
1853
- kind: 'runtime_reply_reminder',
1854
- prompt,
1855
- msgId: (0, id_1.generateShortId)(),
1856
- grammar: 'markdown',
1857
- origin: 'runtime',
1858
- userLanguageCode: language,
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 { AnswerToHumanItem, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
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.REPLY_REASSERTION_PREFIX_EN,
37
- reply_prompt_copy_1.REPLY_REASSERTION_PREFIX_ZH,
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. It is one leg of the full
208
- // interjection-pause state machine:
209
- // 1. user interjection suppresses the live reply obligation here;
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
- // The business anchor is the deferred reply reassertion. A stale paused execution marker still
217
- // means a repeated interjection should behave as local side conversation, but it is not durable
218
- // drive work and must not force a manual Continue after the answer is visible.
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
  }>;