dominds 1.24.3 → 1.24.4
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/apps/runtime.js +0 -3
- package/dist/dialog-display-state.js +4 -2
- package/dist/dialog-global-registry.d.ts +15 -1
- package/dist/dialog-global-registry.js +73 -5
- package/dist/dialog.d.ts +3 -3
- package/dist/dialog.js +4 -2
- package/dist/llm/gen/mock.js +2 -0
- package/dist/llm/kernel-driver/drive.js +74 -16
- package/dist/llm/kernel-driver/flow.js +88 -26
- package/dist/llm/kernel-driver/loop.js +85 -46
- package/dist/llm/kernel-driver/types.d.ts +10 -2
- package/dist/persistence.d.ts +29 -1
- package/dist/persistence.js +153 -0
- package/dist/runtime/driver-messages.d.ts +1 -0
- package/dist/runtime/driver-messages.js +7 -2
- package/dist/server/websocket-handler.d.ts +14 -0
- package/dist/server/websocket-handler.js +42 -3
- package/package.json +4 -4
package/dist/apps/runtime.js
CHANGED
|
@@ -98,9 +98,6 @@ async function resolveTargetDialog(sourceDlg, target) {
|
|
|
98
98
|
matches.push(dialog);
|
|
99
99
|
};
|
|
100
100
|
pushMatch(await ensureDialogLoadedBySelfId(sourceRoot, target.dialogId));
|
|
101
|
-
for (const loadedRoot of dialog_global_registry_1.globalDialogRegistry.getAll()) {
|
|
102
|
-
pushMatch(await ensureDialogLoadedBySelfId(loadedRoot, target.dialogId));
|
|
103
|
-
}
|
|
104
101
|
if (target.dialogId !== sourceRoot.id.rootId) {
|
|
105
102
|
pushMatch(await ensureMainDialogLoaded(target.dialogId));
|
|
106
103
|
}
|
|
@@ -255,10 +255,12 @@ function clearActiveRun(dialogId, options) {
|
|
|
255
255
|
return;
|
|
256
256
|
}
|
|
257
257
|
clearQuarantiningMainDialogIfIdle(dialogId.rootId);
|
|
258
|
-
if (
|
|
258
|
+
if (options?.notifyBackendLoop !== false) {
|
|
259
259
|
dialog_global_registry_1.globalDialogRegistry.notifyActiveRunCleared(dialogId.rootId, {
|
|
260
260
|
source: 'dialog_display_state_active_run_clear',
|
|
261
|
-
reason:
|
|
261
|
+
reason: dialogId.selfId === dialogId.rootId
|
|
262
|
+
? 'root_active_run_cleared'
|
|
263
|
+
: 'sideDialog_active_run_cleared',
|
|
262
264
|
});
|
|
263
265
|
}
|
|
264
266
|
syncRunControlCountsAfterActiveRunChange('clear_active_run', dialogId);
|
|
@@ -16,7 +16,18 @@ export type DriveTriggerMeta = Readonly<{
|
|
|
16
16
|
}>;
|
|
17
17
|
declare class GlobalDialogRegistry {
|
|
18
18
|
private static instance;
|
|
19
|
+
/**
|
|
20
|
+
* Runtime-owned roots keyed by rootId.
|
|
21
|
+
*
|
|
22
|
+
* Do not add an API that enumerates this map for backend driving. A dialog becomes driveable only
|
|
23
|
+
* through an explicit business/runtime wake (`wakeDrive`, result arrival, active-run clear, etc.).
|
|
24
|
+
* Reintroducing "scan every loaded root and see what happens" makes hidden polling loops easy to
|
|
25
|
+
* create and obscures the business event that should own the next action.
|
|
26
|
+
*/
|
|
19
27
|
private readonly entries;
|
|
28
|
+
private readonly queuedRootIds;
|
|
29
|
+
private readonly queuedRootIdSet;
|
|
30
|
+
private queuedRootIdReadIndex;
|
|
20
31
|
private readonly lastDriveTriggerByRootId;
|
|
21
32
|
private readonly driveTriggerPubChan;
|
|
22
33
|
private driveTriggerSubChan;
|
|
@@ -24,6 +35,9 @@ declare class GlobalDialogRegistry {
|
|
|
24
35
|
get(rootId: string): MainDialog | undefined;
|
|
25
36
|
register(mainDialog: MainDialog): void;
|
|
26
37
|
unregister(rootId: string): void;
|
|
38
|
+
private enqueueRoot;
|
|
39
|
+
private compactQueuedRootsIfNeeded;
|
|
40
|
+
private compactSparseQueuedRootsIfNeeded;
|
|
27
41
|
private publishDriveTrigger;
|
|
28
42
|
waitForDriveTrigger(): Promise<DriveTriggerEvent>;
|
|
29
43
|
wakeDrive(rootId: string, meta?: DriveTriggerMeta): void;
|
|
@@ -33,7 +47,7 @@ declare class GlobalDialogRegistry {
|
|
|
33
47
|
hasPendingActiveRunClearedWake(rootId: string): boolean;
|
|
34
48
|
isDriveWakeQueued(rootId: string): boolean;
|
|
35
49
|
getLastDriveTrigger(rootId: string): DriveTriggerEvent | undefined;
|
|
36
|
-
|
|
50
|
+
consumeQueuedMainDialogs(): MainDialog[];
|
|
37
51
|
get size(): number;
|
|
38
52
|
}
|
|
39
53
|
export declare const globalDialogRegistry: GlobalDialogRegistry;
|
|
@@ -8,7 +8,18 @@ const persistence_1 = require("./persistence");
|
|
|
8
8
|
const log = (0, log_1.createLogger)('dialog-global-registry');
|
|
9
9
|
class GlobalDialogRegistry {
|
|
10
10
|
constructor() {
|
|
11
|
+
/**
|
|
12
|
+
* Runtime-owned roots keyed by rootId.
|
|
13
|
+
*
|
|
14
|
+
* Do not add an API that enumerates this map for backend driving. A dialog becomes driveable only
|
|
15
|
+
* through an explicit business/runtime wake (`wakeDrive`, result arrival, active-run clear, etc.).
|
|
16
|
+
* Reintroducing "scan every loaded root and see what happens" makes hidden polling loops easy to
|
|
17
|
+
* create and obscures the business event that should own the next action.
|
|
18
|
+
*/
|
|
11
19
|
this.entries = new Map();
|
|
20
|
+
this.queuedRootIds = [];
|
|
21
|
+
this.queuedRootIdSet = new Set();
|
|
22
|
+
this.queuedRootIdReadIndex = 0;
|
|
12
23
|
this.lastDriveTriggerByRootId = new Map();
|
|
13
24
|
this.driveTriggerPubChan = (0, evt_1.createPubChan)();
|
|
14
25
|
this.driveTriggerSubChan = (0, evt_1.createSubChan)(this.driveTriggerPubChan);
|
|
@@ -60,9 +71,45 @@ class GlobalDialogRegistry {
|
|
|
60
71
|
}
|
|
61
72
|
unregister(rootId) {
|
|
62
73
|
this.entries.delete(rootId);
|
|
74
|
+
this.queuedRootIdSet.delete(rootId);
|
|
63
75
|
this.lastDriveTriggerByRootId.delete(rootId);
|
|
64
76
|
(0, dialog_1.scheduleGlobalDialogMutexCleanupForRoot)(rootId);
|
|
65
77
|
}
|
|
78
|
+
enqueueRoot(rootId) {
|
|
79
|
+
if (this.queuedRootIdSet.has(rootId)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.queuedRootIdSet.add(rootId);
|
|
83
|
+
this.queuedRootIds.push(rootId);
|
|
84
|
+
}
|
|
85
|
+
compactQueuedRootsIfNeeded() {
|
|
86
|
+
if (this.queuedRootIdReadIndex === 0) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (this.queuedRootIdReadIndex < 256 &&
|
|
90
|
+
this.queuedRootIdReadIndex * 2 < this.queuedRootIds.length) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.queuedRootIds.splice(0, this.queuedRootIdReadIndex);
|
|
94
|
+
this.queuedRootIdReadIndex = 0;
|
|
95
|
+
}
|
|
96
|
+
compactSparseQueuedRootsIfNeeded() {
|
|
97
|
+
if (this.queuedRootIds.length < 512) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (this.queuedRootIdSet.size * 2 >= this.queuedRootIds.length - this.queuedRootIdReadIndex) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const compacted = [];
|
|
104
|
+
for (let index = this.queuedRootIdReadIndex; index < this.queuedRootIds.length; index += 1) {
|
|
105
|
+
const rootId = this.queuedRootIds[index];
|
|
106
|
+
if (rootId !== undefined && this.queuedRootIdSet.has(rootId)) {
|
|
107
|
+
compacted.push(rootId);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
this.queuedRootIds.splice(0, this.queuedRootIds.length, ...compacted);
|
|
111
|
+
this.queuedRootIdReadIndex = 0;
|
|
112
|
+
}
|
|
66
113
|
publishDriveTrigger(args) {
|
|
67
114
|
const trigger = {
|
|
68
115
|
type: 'drive_trigger_evt',
|
|
@@ -99,6 +146,7 @@ class GlobalDialogRegistry {
|
|
|
99
146
|
entry.wakeQueued = true;
|
|
100
147
|
// A fresh queueing trigger supersedes any earlier "wake me once active run clears" debt.
|
|
101
148
|
entry.activeRunClearedWakePending = false;
|
|
149
|
+
this.enqueueRoot(rootId);
|
|
102
150
|
}
|
|
103
151
|
this.publishDriveTrigger({
|
|
104
152
|
action: 'wake_drive',
|
|
@@ -119,6 +167,8 @@ class GlobalDialogRegistry {
|
|
|
119
167
|
if (entry) {
|
|
120
168
|
entry.wakeQueued = false;
|
|
121
169
|
entry.activeRunClearedWakePending = false;
|
|
170
|
+
this.queuedRootIdSet.delete(rootId);
|
|
171
|
+
this.compactSparseQueuedRootsIfNeeded();
|
|
122
172
|
}
|
|
123
173
|
this.publishDriveTrigger({
|
|
124
174
|
action: 'clear_drive_wake',
|
|
@@ -138,12 +188,14 @@ class GlobalDialogRegistry {
|
|
|
138
188
|
if (!entry) {
|
|
139
189
|
return;
|
|
140
190
|
}
|
|
141
|
-
if (!entry.activeRunClearedWakePending
|
|
191
|
+
if (!entry.activeRunClearedWakePending) {
|
|
142
192
|
entry.activeRunClearedWakePending = false;
|
|
143
193
|
return;
|
|
144
194
|
}
|
|
145
|
-
const currentWakeQueued = entry
|
|
195
|
+
const currentWakeQueued = entry.wakeQueued;
|
|
146
196
|
entry.activeRunClearedWakePending = false;
|
|
197
|
+
entry.wakeQueued = true;
|
|
198
|
+
this.enqueueRoot(rootId);
|
|
147
199
|
this.publishDriveTrigger({
|
|
148
200
|
action: 'active_run_cleared',
|
|
149
201
|
rootId,
|
|
@@ -155,7 +207,7 @@ class GlobalDialogRegistry {
|
|
|
155
207
|
}
|
|
156
208
|
noteActiveRunBlockedQueuedDrive(rootId) {
|
|
157
209
|
const entry = this.entries.get(rootId);
|
|
158
|
-
if (!entry
|
|
210
|
+
if (!entry) {
|
|
159
211
|
return;
|
|
160
212
|
}
|
|
161
213
|
entry.activeRunClearedWakePending = true;
|
|
@@ -169,8 +221,24 @@ class GlobalDialogRegistry {
|
|
|
169
221
|
getLastDriveTrigger(rootId) {
|
|
170
222
|
return this.lastDriveTriggerByRootId.get(rootId);
|
|
171
223
|
}
|
|
172
|
-
|
|
173
|
-
|
|
224
|
+
consumeQueuedMainDialogs() {
|
|
225
|
+
const queued = [];
|
|
226
|
+
while (this.queuedRootIdReadIndex < this.queuedRootIds.length) {
|
|
227
|
+
const rootId = this.queuedRootIds[this.queuedRootIdReadIndex];
|
|
228
|
+
this.queuedRootIdReadIndex += 1;
|
|
229
|
+
if (rootId === undefined || !this.queuedRootIdSet.has(rootId)) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
this.queuedRootIdSet.delete(rootId);
|
|
233
|
+
const entry = this.entries.get(rootId);
|
|
234
|
+
if (!entry) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
entry.wakeQueued = false;
|
|
238
|
+
queued.push(entry.mainDialog);
|
|
239
|
+
}
|
|
240
|
+
this.compactQueuedRootsIfNeeded();
|
|
241
|
+
return queued;
|
|
174
242
|
}
|
|
175
243
|
get size() {
|
|
176
244
|
return this.entries.size;
|
package/dist/dialog.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type { ContextHealthSnapshot } from '@longrun-ai/kernel/types/context-hea
|
|
|
16
16
|
import type { DialogEvent, NativeToolCallPayload, ReminderContent, WebSearchCallAction, WebSearchCallSource } from '@longrun-ai/kernel/types/dialog';
|
|
17
17
|
import type { DialogCalleeReplyTarget, DialogQueuedDeferredQ4HAnswerState, DialogQueuedPromptState, DialogQueuedUserGenerationBoundaryState, DialogRunControlSpec, DialogRuntimePrompt, DialogUserPrompt, DriveIntent } from '@longrun-ai/kernel/types/drive-intent';
|
|
18
18
|
import type { LanguageCode } from '@longrun-ai/kernel/types/language';
|
|
19
|
-
import type { ActiveCalleesFile, CalleeCourseNumber, CalleeGenerationSeqNumber, CallSiteCourseNo, CallSiteGenseqNo, DialogAskerStackState, DialogLatestFile, DialogMetadataFile, HumanQuestion, ProviderData, ReasoningPayload, TellaskCallRecordName, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
|
|
19
|
+
import type { ActiveCalleesFile, CalleeCourseNumber, CalleeGenerationSeqNumber, CallSiteCourseNo, CallSiteGenseqNo, DialogAskerStackState, DialogLatestFile, DialogMetadataFile, DialogNextStepTrigger, HumanQuestion, ProviderData, ReasoningPayload, TellaskCallRecordName, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
|
|
20
20
|
import { ChatMessage, FuncResultMsg, TellaskCarryoverMsg, TellaskResultMsg } from './llm/client';
|
|
21
21
|
import type { ToolResultImageIngest, UserImageIngest } from './llm/gen';
|
|
22
22
|
import type { JsonValue } from './tool';
|
|
@@ -413,7 +413,7 @@ export declare abstract class Dialog {
|
|
|
413
413
|
calleeCourse?: CalleeCourseNumber;
|
|
414
414
|
calleeGenseq?: CalleeGenerationSeqNumber;
|
|
415
415
|
}): Promise<TellaskResultMsg | TellaskCarryoverMsg>;
|
|
416
|
-
notifyGeneratingStart(msgId?: string): Promise<
|
|
416
|
+
notifyGeneratingStart(msgId?: string): Promise<readonly DialogNextStepTrigger[]>;
|
|
417
417
|
notifyGeneratingFinish(contextHealth?: ContextHealthSnapshot, llmGenModel?: string): Promise<void>;
|
|
418
418
|
streamError(error: string): Promise<void>;
|
|
419
419
|
thinkingStart(): Promise<void>;
|
|
@@ -600,7 +600,7 @@ export declare abstract class DialogStore {
|
|
|
600
600
|
/**
|
|
601
601
|
* Notify start of LLM generation lifecycle (generating_start_evt)
|
|
602
602
|
*/
|
|
603
|
-
notifyGeneratingStart(_dialog: Dialog, _msgId?: string): Promise<
|
|
603
|
+
notifyGeneratingStart(_dialog: Dialog, _msgId?: string): Promise<readonly DialogNextStepTrigger[]>;
|
|
604
604
|
/**
|
|
605
605
|
* Notify end of LLM generation lifecycle (generating_finish_evt)
|
|
606
606
|
*/
|
package/dist/dialog.js
CHANGED
|
@@ -1498,7 +1498,7 @@ class Dialog {
|
|
|
1498
1498
|
// Mark generation as started with the actual genseq
|
|
1499
1499
|
// This ensures sideDialog_final_response_evt waits for both user_text and generating_start_evt
|
|
1500
1500
|
this.markGenerationStarted();
|
|
1501
|
-
|
|
1501
|
+
return this.dlgStore.notifyGeneratingStart(this, msgId);
|
|
1502
1502
|
}
|
|
1503
1503
|
async notifyGeneratingFinish(contextHealth, llmGenModel) {
|
|
1504
1504
|
if (contextHealth) {
|
|
@@ -1958,7 +1958,9 @@ class DialogStore {
|
|
|
1958
1958
|
/**
|
|
1959
1959
|
* Notify start of LLM generation lifecycle (generating_start_evt)
|
|
1960
1960
|
*/
|
|
1961
|
-
async notifyGeneratingStart(_dialog, _msgId) {
|
|
1961
|
+
async notifyGeneratingStart(_dialog, _msgId) {
|
|
1962
|
+
return [];
|
|
1963
|
+
}
|
|
1962
1964
|
/**
|
|
1963
1965
|
* Notify end of LLM generation lifecycle (generating_finish_evt)
|
|
1964
1966
|
*/
|
package/dist/llm/gen/mock.js
CHANGED
|
@@ -67,6 +67,8 @@ const reply_prompt_copy_1 = require("../../runtime/reply-prompt-copy");
|
|
|
67
67
|
const gen_1 = require("../gen");
|
|
68
68
|
const stop_reason_i18n_1 = require("../stop-reason-i18n");
|
|
69
69
|
const RUNTIME_PROMPT_WRAPPER_PREFIXES = [
|
|
70
|
+
'[System notice] Context state: 🔴 critical; user interjection received',
|
|
71
|
+
'【系统提示】 上下文状态:🔴 告急;收到用户插话',
|
|
70
72
|
reply_prompt_copy_1.ACTIVE_REPLY_TOOL_PREFIX_EN,
|
|
71
73
|
reply_prompt_copy_1.ACTIVE_REPLY_TOOL_PREFIX_ZH,
|
|
72
74
|
reply_prompt_copy_1.NO_ACTIVE_REPLY_PREFIX_EN,
|
|
@@ -138,6 +138,40 @@ function buildInterruptedFuncResult(args) {
|
|
|
138
138
|
genseq: args.callGenseq,
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
+
function sameDialogBusinessContinuation(left, right) {
|
|
142
|
+
if (left.kind !== right.kind)
|
|
143
|
+
return false;
|
|
144
|
+
switch (left.kind) {
|
|
145
|
+
case 'none':
|
|
146
|
+
return true;
|
|
147
|
+
case 'inter_dialog_reply': {
|
|
148
|
+
if (right.kind !== 'inter_dialog_reply')
|
|
149
|
+
return false;
|
|
150
|
+
return (sameTellaskReplyDirective(left.tellaskReplyDirective, right.tellaskReplyDirective) &&
|
|
151
|
+
sameDialogCalleeReplyTarget(left.calleeDialogReplyTarget, right.calleeDialogReplyTarget));
|
|
152
|
+
}
|
|
153
|
+
default: {
|
|
154
|
+
const _exhaustive = left;
|
|
155
|
+
throw new Error(`Unhandled business continuation kind: ${String(_exhaustive)}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function sameTellaskReplyDirective(left, right) {
|
|
160
|
+
return (left.expectedReplyCallName === right.expectedReplyCallName &&
|
|
161
|
+
left.targetDialogId === right.targetDialogId &&
|
|
162
|
+
left.targetCallId === right.targetCallId &&
|
|
163
|
+
left.tellaskContent === right.tellaskContent);
|
|
164
|
+
}
|
|
165
|
+
function sameDialogCalleeReplyTarget(left, right) {
|
|
166
|
+
if (left === undefined || right === undefined) {
|
|
167
|
+
return left === right;
|
|
168
|
+
}
|
|
169
|
+
return (left.callerDialogId === right.callerDialogId &&
|
|
170
|
+
left.callType === right.callType &&
|
|
171
|
+
left.callId === right.callId &&
|
|
172
|
+
left.callSiteCourse === right.callSiteCourse &&
|
|
173
|
+
left.callSiteGenseq === right.callSiteGenseq);
|
|
174
|
+
}
|
|
141
175
|
function isFbrSideDialog(dlg) {
|
|
142
176
|
return dlg instanceof dialog_1.SideDialog && dlg.assignmentFromAsker.callName === 'freshBootsReasoning';
|
|
143
177
|
}
|
|
@@ -1171,6 +1205,7 @@ async function upsertImmediateFollowupTrigger(args) {
|
|
|
1171
1205
|
genseq: (0, storage_1.toCallSiteGenseqNo)(genseq),
|
|
1172
1206
|
},
|
|
1173
1207
|
reasons,
|
|
1208
|
+
continuation: args.continuation,
|
|
1174
1209
|
});
|
|
1175
1210
|
}
|
|
1176
1211
|
function shouldImmediatelyFollowUpSuccessfulToolResult(tool) {
|
|
@@ -1753,20 +1788,20 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1753
1788
|
const suppressDiligencePushForDrive = driveOptions?.suppressDiligencePush === true && dlg.disableDiligencePush;
|
|
1754
1789
|
const abortSignal = (0, dialog_display_state_1.getActiveRunSignal)(dlg.id) ?? (0, dialog_display_state_1.createActiveRun)(dlg.id);
|
|
1755
1790
|
let finalDisplayState;
|
|
1756
|
-
let criticalUserInterjectionRuntimeGuide = driveOptions?.criticalUserInterjectionRuntimeGuide;
|
|
1757
1791
|
let lastAssistantSayingContent = null;
|
|
1758
1792
|
let lastAssistantSayingGenseq = null;
|
|
1759
1793
|
let lastAssistantThinkingContent = null;
|
|
1760
1794
|
let lastAssistantThinkingGenseq = null;
|
|
1761
1795
|
let lastFunctionCallGenseq = null;
|
|
1762
1796
|
let lastAssistantReplyTarget;
|
|
1797
|
+
let lastBusinessContinuation = { kind: 'none' };
|
|
1763
1798
|
let fbrConclusion;
|
|
1764
1799
|
let pubRemindersVer = dlg.remindersVer;
|
|
1765
1800
|
let pendingPrompt = humanPrompt;
|
|
1766
1801
|
let resolvingImmediateToolResultForUserPrompt = false;
|
|
1767
1802
|
let resolvingImmediateToolResultUserPromptMsgId;
|
|
1768
|
-
let criticalRemediationAppliedUserPromptMsgId =
|
|
1769
|
-
humanPrompt
|
|
1803
|
+
let criticalRemediationAppliedUserPromptMsgId = humanPrompt?.origin === 'user' &&
|
|
1804
|
+
(0, driver_messages_1.isAgentFacingCriticalUserInterjectionRemediationGuideContent)(humanPrompt.content)
|
|
1770
1805
|
? humanPrompt.msgId
|
|
1771
1806
|
: undefined;
|
|
1772
1807
|
let retryStoppedRecoveryPrompt;
|
|
@@ -1901,8 +1936,10 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1901
1936
|
snapshot,
|
|
1902
1937
|
hadUserPromptThisGen: currentGenerationBelongsToUserPrompt,
|
|
1903
1938
|
hadUserPromptInImmediateToolChain: currentGenerationBelongsToUserToolChain,
|
|
1904
|
-
userPromptCriticalRemediationAlreadyApplied: criticalRemediationAppliedUserPromptMsgId !== undefined &&
|
|
1905
|
-
criticalRemediationAppliedUserPromptMsgId === currentUserPromptMsgId
|
|
1939
|
+
userPromptCriticalRemediationAlreadyApplied: (criticalRemediationAppliedUserPromptMsgId !== undefined &&
|
|
1940
|
+
criticalRemediationAppliedUserPromptMsgId === currentUserPromptMsgId) ||
|
|
1941
|
+
(currentPendingPrompt?.origin === 'user' &&
|
|
1942
|
+
(0, driver_messages_1.isAgentFacingCriticalUserInterjectionRemediationGuideContent)(currentPendingPrompt.content)),
|
|
1906
1943
|
canInjectPromptThisGen: !hasQueuedUpNext,
|
|
1907
1944
|
cautionRemediationCadenceGenerations,
|
|
1908
1945
|
criticalCountdownRemaining,
|
|
@@ -1925,13 +1962,13 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1925
1962
|
skipTaskdocForThisDrive = false;
|
|
1926
1963
|
}
|
|
1927
1964
|
else if (healthDecision.reason === 'critical_user_prompt_remediation') {
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
promptsRemainingAfterThis: (0, context_health_1.consumeCriticalCountdown)(dlg.id.key()),
|
|
1965
|
+
if (currentPendingPrompt === undefined ||
|
|
1966
|
+
!(0, driver_messages_1.isAgentFacingCriticalUserInterjectionRemediationGuideContent)(currentPendingPrompt.content)) {
|
|
1967
|
+
log_1.log.warn('kernel-driver observed unwrapped critical user prompt; critical user interjection wrapping must happen at ingress', undefined, {
|
|
1968
|
+
dialogId: dlg.id.valueOf(),
|
|
1969
|
+
msgId: currentUserPromptMsgId ?? null,
|
|
1934
1970
|
});
|
|
1971
|
+
}
|
|
1935
1972
|
criticalRemediationAppliedUserPromptMsgId = currentUserPromptMsgId;
|
|
1936
1973
|
}
|
|
1937
1974
|
else if (!hasQueuedUpNext) {
|
|
@@ -1964,6 +2001,16 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1964
2001
|
let llmGenModelForGen = model;
|
|
1965
2002
|
const currentPrompt = pendingPrompt;
|
|
1966
2003
|
const currentReplyTarget = currentPrompt?.calleeDialogReplyTarget;
|
|
2004
|
+
let currentBusinessContinuation = driveOptions?.businessContinuation ?? { kind: 'none' };
|
|
2005
|
+
if (currentPrompt?.tellaskReplyDirective !== undefined) {
|
|
2006
|
+
currentBusinessContinuation = {
|
|
2007
|
+
kind: 'inter_dialog_reply',
|
|
2008
|
+
tellaskReplyDirective: currentPrompt.tellaskReplyDirective,
|
|
2009
|
+
...(currentPrompt.calleeDialogReplyTarget === undefined
|
|
2010
|
+
? {}
|
|
2011
|
+
: { calleeDialogReplyTarget: currentPrompt.calleeDialogReplyTarget }),
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
1967
2014
|
const currentFbrState = await loadDialogFbrState(dlg);
|
|
1968
2015
|
let currentRuntimeGuideMsg;
|
|
1969
2016
|
const currentPromptFromFbrState = currentPrompt !== undefined &&
|
|
@@ -1985,12 +2032,20 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1985
2032
|
break;
|
|
1986
2033
|
}
|
|
1987
2034
|
}
|
|
1988
|
-
await dlg.notifyGeneratingStart(currentPrompt?.msgId);
|
|
1989
|
-
|
|
1990
|
-
if (
|
|
1991
|
-
|
|
1992
|
-
|
|
2035
|
+
const acceptedTriggers = await dlg.notifyGeneratingStart(currentPrompt?.msgId);
|
|
2036
|
+
for (const trigger of acceptedTriggers) {
|
|
2037
|
+
if (trigger.kind === 'followup' && trigger.continuation !== undefined) {
|
|
2038
|
+
if (currentBusinessContinuation.kind !== 'none' &&
|
|
2039
|
+
!sameDialogBusinessContinuation(currentBusinessContinuation, trigger.continuation)) {
|
|
2040
|
+
throw new Error(`Business continuation invariant violation: conflicting accepted followup continuations ` +
|
|
2041
|
+
`(dialog=${dlg.id.valueOf()}, course=${String(dlg.activeGenCourseOrUndefined ?? dlg.currentCourse)}, ` +
|
|
2042
|
+
`genseq=${String(dlg.activeGenSeq)}, triggerId=${trigger.triggerId})`);
|
|
2043
|
+
}
|
|
2044
|
+
currentBusinessContinuation = trigger.continuation;
|
|
1993
2045
|
}
|
|
2046
|
+
}
|
|
2047
|
+
lastBusinessContinuation = currentBusinessContinuation;
|
|
2048
|
+
try {
|
|
1994
2049
|
if (currentPrompt) {
|
|
1995
2050
|
if (currentPrompt.skipTaskdoc === true) {
|
|
1996
2051
|
skipTaskdocForThisDrive = true;
|
|
@@ -2682,6 +2737,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2682
2737
|
lastAssistantThinkingGenseq,
|
|
2683
2738
|
lastFunctionCallGenseq,
|
|
2684
2739
|
lastAssistantReplyTarget,
|
|
2740
|
+
lastBusinessContinuation,
|
|
2685
2741
|
};
|
|
2686
2742
|
}
|
|
2687
2743
|
const nextFbrState = (0, fbr_1.advanceFbrState)(persistedFbrState);
|
|
@@ -2871,6 +2927,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2871
2927
|
routed,
|
|
2872
2928
|
invalidFuncCallCount,
|
|
2873
2929
|
streamedFuncCalls,
|
|
2930
|
+
continuation: currentBusinessContinuation,
|
|
2874
2931
|
});
|
|
2875
2932
|
resolvingImmediateToolResultForUserPrompt =
|
|
2876
2933
|
currentGenerationBelongsToUserPrompt ||
|
|
@@ -3023,6 +3080,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
3023
3080
|
lastAssistantThinkingGenseq,
|
|
3024
3081
|
lastFunctionCallGenseq,
|
|
3025
3082
|
lastAssistantReplyTarget,
|
|
3083
|
+
lastBusinessContinuation,
|
|
3026
3084
|
fbrConclusion,
|
|
3027
3085
|
};
|
|
3028
3086
|
}
|
|
@@ -416,6 +416,9 @@ async function clearStaleSideDialogRunControlForFinalResponse(args) {
|
|
|
416
416
|
function hasResultArrivalTrigger(latest) {
|
|
417
417
|
return latest?.nextStep.triggers.some((trigger) => trigger.kind === 'result_arrival') === true;
|
|
418
418
|
}
|
|
419
|
+
function hasFollowupNextAction(latest) {
|
|
420
|
+
return latest?.nextStep.triggers.some((trigger) => trigger.kind === 'followup') === true;
|
|
421
|
+
}
|
|
419
422
|
function hasCallerReviveEntitlement(dialog, driveOptions) {
|
|
420
423
|
const entitlement = driveOptions?.noPromptSideDialogResumeEntitlement;
|
|
421
424
|
if (!entitlement) {
|
|
@@ -527,9 +530,11 @@ async function inspectNoPromptSideDialogDrive(args) {
|
|
|
527
530
|
(0, dialog_drive_work_1.hasRecoverableGenerationBeyondFinalResponse)(latest);
|
|
528
531
|
const resolvedPendingSideDialogReplyEntitlement = hasResolvedPendingSideDialogReplyEntitlement(args.dialog, args.driveOptions);
|
|
529
532
|
const resultArrivalTriggerPresent = hasResultArrivalTrigger(latest);
|
|
533
|
+
const followupNextActionPresent = hasFollowupNextAction(latest);
|
|
530
534
|
const supplyResponseCallerReviveAllowed = hasCallerReviveEntitlement(args.dialog, args.driveOptions) &&
|
|
531
535
|
(!resolvedPendingSideDialogReplyEntitlement || resultArrivalTriggerPresent);
|
|
532
|
-
const backendLoopDurableWorkAllowed = source === 'kernel_driver_backend_loop' &&
|
|
536
|
+
const backendLoopDurableWorkAllowed = source === 'kernel_driver_backend_loop' &&
|
|
537
|
+
(resultArrivalTriggerPresent || followupNextActionPresent);
|
|
533
538
|
const finalResponseResultArrivalReviveAllowed = sideDialogFinalResponseCallId !== undefined &&
|
|
534
539
|
((resolvedPendingSideDialogReplyEntitlement && resultArrivalTriggerPresent) ||
|
|
535
540
|
backendLoopDurableWorkAllowed ||
|
|
@@ -765,8 +770,38 @@ async function executeDriveRound(args) {
|
|
|
765
770
|
let shouldRefreshDisplayStateAfterActiveRunCleared = false;
|
|
766
771
|
let followUp;
|
|
767
772
|
let driveResult;
|
|
768
|
-
let
|
|
769
|
-
|
|
773
|
+
let activeBusinessContinuation = driveOptions?.businessContinuation ?? { kind: 'none' };
|
|
774
|
+
const replyContinuationScope = {
|
|
775
|
+
refresh(continuation) {
|
|
776
|
+
activeBusinessContinuation = continuation;
|
|
777
|
+
},
|
|
778
|
+
directive() {
|
|
779
|
+
switch (activeBusinessContinuation.kind) {
|
|
780
|
+
case 'none':
|
|
781
|
+
return undefined;
|
|
782
|
+
case 'inter_dialog_reply':
|
|
783
|
+
return activeBusinessContinuation.tellaskReplyDirective;
|
|
784
|
+
default: {
|
|
785
|
+
const _exhaustive = activeBusinessContinuation;
|
|
786
|
+
throw new Error(`Unhandled business continuation kind: ${String(_exhaustive)}`);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
target() {
|
|
791
|
+
switch (activeBusinessContinuation.kind) {
|
|
792
|
+
case 'none':
|
|
793
|
+
return undefined;
|
|
794
|
+
case 'inter_dialog_reply':
|
|
795
|
+
return activeBusinessContinuation.calleeDialogReplyTarget;
|
|
796
|
+
default: {
|
|
797
|
+
const _exhaustive = activeBusinessContinuation;
|
|
798
|
+
throw new Error(`Unhandled business continuation kind: ${String(_exhaustive)}`);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
};
|
|
803
|
+
let calleeDialogReplyTarget = replyContinuationScope.target();
|
|
804
|
+
let activeTellaskReplyDirective = replyContinuationScope.directive();
|
|
770
805
|
let activePromptWasReplyToolReminder = false;
|
|
771
806
|
let shouldPauseAfterLocalUserInterjection = false;
|
|
772
807
|
let resumeFromInterjectionPause = false;
|
|
@@ -997,18 +1032,23 @@ async function executeDriveRound(args) {
|
|
|
997
1032
|
cautionRemediationCadenceGenerations = (0, context_health_1.resolveCautionRemediationCadenceGenerations)(providerCfg?.models[model]?.caution_remediation_cadence_generations);
|
|
998
1033
|
}
|
|
999
1034
|
const criticalCountdownRemaining = (0, context_health_1.resolveCriticalCountdownRemaining)(dialog.id.key(), snapshot);
|
|
1035
|
+
const userPromptContentForHealth = humanPrompt?.origin === 'user'
|
|
1036
|
+
? humanPrompt.content
|
|
1037
|
+
: queuedUpNextBeforeHealth?.origin === 'user'
|
|
1038
|
+
? queuedUpNextBeforeHealth.prompt
|
|
1039
|
+
: undefined;
|
|
1000
1040
|
const healthDecision = (0, context_health_1.decideKernelDriverContextHealth)({
|
|
1001
1041
|
dialogKey: dialog.id.key(),
|
|
1002
1042
|
snapshot,
|
|
1003
1043
|
hadUserPromptThisGen: isEffectiveUserPromptForContextHealth(humanPrompt) ||
|
|
1004
1044
|
(humanPrompt === undefined && isQueuedUserPromptForContextHealth(queuedUpNextBeforeHealth)),
|
|
1005
|
-
userPromptCriticalRemediationAlreadyApplied:
|
|
1045
|
+
userPromptCriticalRemediationAlreadyApplied: userPromptContentForHealth !== undefined &&
|
|
1046
|
+
(0, driver_messages_1.isAgentFacingCriticalUserInterjectionRemediationGuideContent)(userPromptContentForHealth),
|
|
1006
1047
|
canInjectPromptThisGen: !hasQueuedUpNext,
|
|
1007
1048
|
cautionRemediationCadenceGenerations,
|
|
1008
1049
|
criticalCountdownRemaining,
|
|
1009
1050
|
});
|
|
1010
1051
|
let healthPrompt;
|
|
1011
|
-
let criticalUserInterjectionRuntimeGuide;
|
|
1012
1052
|
if (healthDecision.kind === 'continue') {
|
|
1013
1053
|
if (healthDecision.reason === 'critical_force_new_course') {
|
|
1014
1054
|
const language = (0, work_language_1.getWorkLanguage)();
|
|
@@ -1021,13 +1061,17 @@ async function executeDriveRound(args) {
|
|
|
1021
1061
|
(0, context_health_1.resetContextHealthRoundState)(dialog.id.key());
|
|
1022
1062
|
}
|
|
1023
1063
|
else if (healthDecision.reason === 'critical_user_prompt_remediation') {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1064
|
+
if (userPromptContentForHealth === undefined ||
|
|
1065
|
+
!(0, driver_messages_1.isAgentFacingCriticalUserInterjectionRemediationGuideContent)(userPromptContentForHealth)) {
|
|
1066
|
+
log_1.log.warn('kernel-driver observed unwrapped critical user prompt; critical user interjection wrapping must happen at ingress', undefined, {
|
|
1067
|
+
dialogId: dialog.id.valueOf(),
|
|
1068
|
+
msgId: humanPrompt?.origin === 'user'
|
|
1069
|
+
? humanPrompt.msgId
|
|
1070
|
+
: queuedUpNextBeforeHealth?.origin === 'user'
|
|
1071
|
+
? queuedUpNextBeforeHealth.msgId
|
|
1072
|
+
: null,
|
|
1030
1073
|
});
|
|
1074
|
+
}
|
|
1031
1075
|
}
|
|
1032
1076
|
else if (!hasQueuedUpNext) {
|
|
1033
1077
|
const language = (0, work_language_1.getWorkLanguage)();
|
|
@@ -1092,7 +1136,17 @@ async function executeDriveRound(args) {
|
|
|
1092
1136
|
throw new Error(`kernel-driver upNext invariant violation: expected queued prompt ${effectivePrompt?.msgId ?? 'unknown'} before drive`);
|
|
1093
1137
|
}
|
|
1094
1138
|
}
|
|
1095
|
-
|
|
1139
|
+
if (effectivePrompt?.tellaskReplyDirective !== undefined) {
|
|
1140
|
+
replyContinuationScope.refresh({
|
|
1141
|
+
kind: 'inter_dialog_reply',
|
|
1142
|
+
tellaskReplyDirective: effectivePrompt.tellaskReplyDirective,
|
|
1143
|
+
...(effectivePrompt.calleeDialogReplyTarget === undefined
|
|
1144
|
+
? {}
|
|
1145
|
+
: { calleeDialogReplyTarget: effectivePrompt.calleeDialogReplyTarget }),
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
calleeDialogReplyTarget =
|
|
1149
|
+
effectivePrompt?.calleeDialogReplyTarget ?? replyContinuationScope.target();
|
|
1096
1150
|
const replyGuidance = await (0, reply_guidance_1.resolvePromptReplyGuidance)({
|
|
1097
1151
|
dlg: dialog,
|
|
1098
1152
|
prompt: effectivePrompt,
|
|
@@ -1110,7 +1164,8 @@ async function executeDriveRound(args) {
|
|
|
1110
1164
|
!replyGuidance.isQ4HAnswerPrompt &&
|
|
1111
1165
|
replyGuidance.suppressInterDialogReplyGuidance &&
|
|
1112
1166
|
replyGuidance.deferredReplyReassertionDirective !== undefined;
|
|
1113
|
-
activeTellaskReplyDirective =
|
|
1167
|
+
activeTellaskReplyDirective =
|
|
1168
|
+
replyGuidance.activeReplyDirective ?? replyContinuationScope.directive();
|
|
1114
1169
|
activePromptWasReplyToolReminder = isReplyToolReminderPrompt(effectivePrompt);
|
|
1115
1170
|
let activePromptCarriesReplyDirective = effectivePrompt?.tellaskReplyDirective !== undefined &&
|
|
1116
1171
|
activeTellaskReplyDirective !== undefined &&
|
|
@@ -1119,19 +1174,10 @@ async function executeDriveRound(args) {
|
|
|
1119
1174
|
if (effectivePrompt && effectivePrompt.userLanguageCode) {
|
|
1120
1175
|
dialog.setLastUserLanguageCode(effectivePrompt.userLanguageCode);
|
|
1121
1176
|
}
|
|
1122
|
-
const coreDriveOptions = criticalUserInterjectionRuntimeGuide === undefined
|
|
1123
|
-
? driveOptions
|
|
1124
|
-
: {
|
|
1125
|
-
...(driveOptions ?? {
|
|
1126
|
-
source: driveSource,
|
|
1127
|
-
reason: 'critical_user_prompt_remediation',
|
|
1128
|
-
}),
|
|
1129
|
-
criticalUserInterjectionRuntimeGuide,
|
|
1130
|
-
};
|
|
1131
1177
|
driveResult = await (0, drive_1.driveDialogStreamCore)(dialog, {
|
|
1132
1178
|
scheduleDrive: args.scheduleDrive,
|
|
1133
1179
|
driveDialog: args.driveDialog,
|
|
1134
|
-
}, effectivePrompt,
|
|
1180
|
+
}, effectivePrompt, driveOptions);
|
|
1135
1181
|
const latestAfterCore = await persistence_1.DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
|
|
1136
1182
|
coreEndedInterrupted = latestAfterCore?.executionMarker?.kind === 'interrupted';
|
|
1137
1183
|
await restoreAcceptedRootDriveWakeAfterDriveFailure({
|
|
@@ -1140,7 +1186,12 @@ async function executeDriveRound(args) {
|
|
|
1140
1186
|
reason: 'core_stopped',
|
|
1141
1187
|
hadRootDriveWakeBeforeCore,
|
|
1142
1188
|
});
|
|
1143
|
-
|
|
1189
|
+
replyContinuationScope.refresh(driveResult.lastBusinessContinuation);
|
|
1190
|
+
calleeDialogReplyTarget =
|
|
1191
|
+
driveResult.lastAssistantReplyTarget ??
|
|
1192
|
+
replyContinuationScope.target() ??
|
|
1193
|
+
calleeDialogReplyTarget;
|
|
1194
|
+
activeTellaskReplyDirective = activeTellaskReplyDirective ?? replyContinuationScope.directive();
|
|
1144
1195
|
interruptedBySignal = (0, dialog_display_state_1.getActiveRunSignal)(dialog.id)?.aborted === true;
|
|
1145
1196
|
if (!interruptedBySignal) {
|
|
1146
1197
|
const queuedFollowUp = dialog.takeUpNext();
|
|
@@ -1224,8 +1275,10 @@ async function executeDriveRound(args) {
|
|
|
1224
1275
|
if (replyDirectiveForAssistantOutput !== undefined &&
|
|
1225
1276
|
replyDirectiveForAssistantOutput.targetCallId !==
|
|
1226
1277
|
activeTellaskReplyDirective?.targetCallId) {
|
|
1227
|
-
//
|
|
1228
|
-
//
|
|
1278
|
+
// Business continuation identity should already come from the accepted next-step
|
|
1279
|
+
// trigger or the current runtime prompt. This branch only handles an explicit
|
|
1280
|
+
// assistant-output reply target surfaced by the core; do not broaden it into
|
|
1281
|
+
// transcript/assignment-anchor reconstruction.
|
|
1229
1282
|
log_1.log.debug('kernel-driver rebound sideDialog reply directive to latest assistant output target', undefined, {
|
|
1230
1283
|
dialogId: dialog.id.valueOf(),
|
|
1231
1284
|
previousTargetCallId: activeTellaskReplyDirective?.targetCallId ?? null,
|
|
@@ -1409,11 +1462,20 @@ async function executeDriveRound(args) {
|
|
|
1409
1462
|
if (followUp.kind === 'runtime_reply_reminder' ||
|
|
1410
1463
|
followUp.kind === 'runtime_sideDialog_reply_reminder') {
|
|
1411
1464
|
await queueReplyReminderFollowUp({ dialog, followUp });
|
|
1465
|
+
const businessContinuation = {
|
|
1466
|
+
kind: 'inter_dialog_reply',
|
|
1467
|
+
tellaskReplyDirective: followUp.tellaskReplyDirective,
|
|
1468
|
+
...(followUp.kind === 'runtime_sideDialog_reply_reminder' &&
|
|
1469
|
+
followUp.calleeDialogReplyTarget !== undefined
|
|
1470
|
+
? { calleeDialogReplyTarget: followUp.calleeDialogReplyTarget }
|
|
1471
|
+
: {}),
|
|
1472
|
+
};
|
|
1412
1473
|
args.scheduleDrive(dialog, {
|
|
1413
1474
|
waitInQue: true,
|
|
1414
1475
|
driveOptions: {
|
|
1415
1476
|
source: 'kernel_driver_follow_up',
|
|
1416
1477
|
reason: 'follow_up_prompt',
|
|
1478
|
+
businessContinuation,
|
|
1417
1479
|
},
|
|
1418
1480
|
});
|
|
1419
1481
|
return driveResult;
|