dominds 1.27.1 → 1.27.3
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 +3 -1
- package/dist/dialog-global-registry.d.ts +11 -1
- package/dist/dialog-global-registry.js +45 -0
- package/dist/dialog.d.ts +13 -3
- package/dist/dialog.js +108 -17
- package/dist/docs/daemon-cmd-runner.md +5 -0
- package/dist/docs/daemon-cmd-runner.zh.md +5 -0
- package/dist/llm/kernel-driver/drive.js +382 -12
- package/dist/llm/kernel-driver/fbr.d.ts +9 -0
- package/dist/llm/kernel-driver/fbr.js +186 -59
- package/dist/llm/kernel-driver/flow.js +58 -56
- package/dist/llm/kernel-driver/reply-guidance.d.ts +3 -0
- package/dist/llm/kernel-driver/reply-guidance.js +15 -31
- package/dist/minds/load.js +1 -0
- package/dist/persistence.js +22 -1
- package/dist/runtime/driver-messages.d.ts +9 -0
- package/dist/runtime/driver-messages.js +61 -5
- package/dist/runtime/shared-reminder-update-impact.d.ts +20 -0
- package/dist/runtime/shared-reminder-update-impact.js +110 -0
- package/dist/server/dominds-runtime-status.js +23 -0
- package/dist/server/static-server.js +20 -5
- package/dist/tool-availability.js +1 -0
- package/dist/tools/builtins.js +2 -0
- package/dist/tools/cmd-runner-protocol.d.ts +6 -0
- package/dist/tools/cmd-runner-protocol.js +57 -2
- package/dist/tools/cmd-runner.js +83 -2
- package/dist/tools/ctrl.d.ts +2 -0
- package/dist/tools/ctrl.js +179 -5
- package/dist/tools/os.js +115 -14
- package/dist/tools/process-kill.js +49 -0
- package/dist/tools/prompts/control/en/errors.md +1 -1
- package/dist/tools/prompts/control/en/index.md +1 -1
- package/dist/tools/prompts/control/en/principles.md +18 -17
- package/dist/tools/prompts/control/en/tools.md +24 -1
- package/dist/tools/prompts/control/zh/errors.md +1 -1
- package/dist/tools/prompts/control/zh/index.md +1 -1
- package/dist/tools/prompts/control/zh/principles.md +17 -16
- package/dist/tools/prompts/control/zh/tools.md +24 -1
- package/dist/tools/prompts/os/en/tools.md +2 -0
- package/dist/tools/prompts/os/zh/tools.md +2 -0
- package/package.json +3 -3
- package/webapp/dist/assets/{main-APO6XREZ.js → main-NXVX2KTO.js} +24 -5
- package/webapp/dist/assets/{main-APO6XREZ.js.map → main-NXVX2KTO.js.map} +3 -3
- package/webapp/dist/index.html +1 -1
package/dist/apps/runtime.js
CHANGED
|
@@ -123,7 +123,9 @@ async function resolveTargetDialog(sourceDlg, target) {
|
|
|
123
123
|
}
|
|
124
124
|
return sideDialog;
|
|
125
125
|
}
|
|
126
|
-
const matches = targetRoot
|
|
126
|
+
const matches = targetRoot
|
|
127
|
+
.getLoadedDialogTreeSnapshot()
|
|
128
|
+
.filter((dialog) => dialog.agentId === target.agentId);
|
|
127
129
|
if (matches.length === 1) {
|
|
128
130
|
return matches[0];
|
|
129
131
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MainDialog } from './dialog';
|
|
1
|
+
import { type Dialog, type MainDialog } from './dialog';
|
|
2
2
|
export type DriveTriggerEvent = Readonly<{
|
|
3
3
|
type: 'drive_trigger_evt';
|
|
4
4
|
action: 'queue_root_drive' | 'clear_root_drive_queue' | 'active_run_cleared';
|
|
@@ -47,6 +47,16 @@ declare class GlobalDialogRegistry {
|
|
|
47
47
|
noteActiveRunBlockedQueuedDrive(rootId: string): void;
|
|
48
48
|
hasPendingActiveRunClearedDrive(rootId: string): boolean;
|
|
49
49
|
isRootDriveQueued(rootId: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* One-shot runtime snapshot for shared-reminder impact routing.
|
|
52
|
+
*
|
|
53
|
+
* This intentionally does not enumerate persisted "all running dialogs". It walks only the roots
|
|
54
|
+
* this runtime has already registered, and includes only dialogs with direct in-memory evidence
|
|
55
|
+
* of current work: locked running main dialogs and the loaded active-callee frontier under each
|
|
56
|
+
* root. Dialogs that merely remain in memory/history but have no current-work signal are not
|
|
57
|
+
* considered parallel work.
|
|
58
|
+
*/
|
|
59
|
+
getLoadedInFlightDialogsForSharedReminderImpact(): Dialog[];
|
|
50
60
|
getLastDriveTrigger(rootId: string): DriveTriggerEvent | undefined;
|
|
51
61
|
consumeQueuedMainDialogs(): MainDialog[];
|
|
52
62
|
get size(): number;
|
|
@@ -218,6 +218,51 @@ class GlobalDialogRegistry {
|
|
|
218
218
|
isRootDriveQueued(rootId) {
|
|
219
219
|
return this.entries.get(rootId)?.driveQueued === true;
|
|
220
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* One-shot runtime snapshot for shared-reminder impact routing.
|
|
223
|
+
*
|
|
224
|
+
* This intentionally does not enumerate persisted "all running dialogs". It walks only the roots
|
|
225
|
+
* this runtime has already registered, and includes only dialogs with direct in-memory evidence
|
|
226
|
+
* of current work: locked running main dialogs and the loaded active-callee frontier under each
|
|
227
|
+
* root. Dialogs that merely remain in memory/history but have no current-work signal are not
|
|
228
|
+
* considered parallel work.
|
|
229
|
+
*/
|
|
230
|
+
getLoadedInFlightDialogsForSharedReminderImpact() {
|
|
231
|
+
const dialogs = [];
|
|
232
|
+
for (const entry of this.entries.values()) {
|
|
233
|
+
const rootDialog = entry.mainDialog;
|
|
234
|
+
const visitedDialogIds = new Set();
|
|
235
|
+
const stack = [];
|
|
236
|
+
if (rootDialog.status === 'running' && rootDialog.isLocked()) {
|
|
237
|
+
dialogs.push(rootDialog);
|
|
238
|
+
visitedDialogIds.add(rootDialog.id.valueOf());
|
|
239
|
+
}
|
|
240
|
+
for (const calleeId of rootDialog.activeCalleeDialogIds) {
|
|
241
|
+
const loadedCallee = rootDialog.lookupDialog(calleeId.selfId);
|
|
242
|
+
if (loadedCallee && loadedCallee.status === 'running') {
|
|
243
|
+
stack.push(loadedCallee);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
while (stack.length > 0) {
|
|
247
|
+
const current = stack.pop();
|
|
248
|
+
if (!current || visitedDialogIds.has(current.id.valueOf())) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
visitedDialogIds.add(current.id.valueOf());
|
|
252
|
+
if (current.status !== 'running') {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
dialogs.push(current);
|
|
256
|
+
for (const calleeId of current.activeCalleeDialogIds) {
|
|
257
|
+
const loadedCallee = rootDialog.lookupDialog(calleeId.selfId);
|
|
258
|
+
if (loadedCallee && loadedCallee.status === 'running') {
|
|
259
|
+
stack.push(loadedCallee);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return dialogs;
|
|
265
|
+
}
|
|
221
266
|
getLastDriveTrigger(rootId) {
|
|
222
267
|
return this.lastDriveTriggerByRootId.get(rootId);
|
|
223
268
|
}
|
package/dist/dialog.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { ContextHealthSnapshot } from '@longrun-ai/kernel/types/context-health';
|
|
16
16
|
import type { DialogEvent, NativeToolCallPayload, ReminderContent, WebSearchCallAction, WebSearchCallSource } from '@longrun-ai/kernel/types/dialog';
|
|
17
|
-
import type { DialogCalleeReplyTarget, DialogQueuedDeferredQ4HAnswerState, DialogQueuedPromptState, DialogQueuedUserGenerationBoundaryState, DialogRunControlSpec, DialogRuntimePrompt, DialogUserPrompt, DriveIntent } from '@longrun-ai/kernel/types/drive-intent';
|
|
17
|
+
import type { DialogCalleeReplyTarget, DialogQueuedDeferredQ4HAnswerState, DialogQueuedPromptState, DialogQueuedUserGenerationBoundaryState, DialogRunControlSpec, DialogRuntimePrompt, DialogRuntimeSideDialogPrompt, DialogUserPrompt, DriveIntent } from '@longrun-ai/kernel/types/drive-intent';
|
|
18
18
|
import type { LanguageCode } from '@longrun-ai/kernel/types/language';
|
|
19
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';
|
|
@@ -130,6 +130,7 @@ export declare function buildSideDialogAskerStack(args: {
|
|
|
130
130
|
askerDialogId: string;
|
|
131
131
|
assignment: AssignmentFromAsker;
|
|
132
132
|
}): DialogAskerStackState;
|
|
133
|
+
export declare function buildSideDialogAssignmentPromptMeta(sideDialog: SideDialog): Pick<DialogRuntimeSideDialogPrompt, 'tellaskReplyDirective' | 'calleeDialogReplyTarget'>;
|
|
133
134
|
/**
|
|
134
135
|
* Abstract base class for all dialog types.
|
|
135
136
|
* Contains common properties and methods shared between MainDialog and SideDialog.
|
|
@@ -274,6 +275,8 @@ export declare abstract class Dialog {
|
|
|
274
275
|
private processReminderCollection;
|
|
275
276
|
private buildVisibleReminderContents;
|
|
276
277
|
private emitFullRemindersUpdate;
|
|
278
|
+
private reportReminderRuntimeFailure;
|
|
279
|
+
private dispatchSharedReminderOwnerUpdateImpacts;
|
|
277
280
|
/**
|
|
278
281
|
* Emits current visible reminders without reconciling tool-owned state or writing persistence.
|
|
279
282
|
* This is for read-only dialog display, especially completed/archived dialogs opened from old tabs.
|
|
@@ -370,6 +373,13 @@ export declare abstract class Dialog {
|
|
|
370
373
|
tellaskReplyDirective: TellaskReplyDirective;
|
|
371
374
|
skipTaskdoc?: boolean;
|
|
372
375
|
}): Promise<DialogQueuedPromptState>;
|
|
376
|
+
queueRuntimeGuidePrompt(options: {
|
|
377
|
+
prompt: string;
|
|
378
|
+
msgId: string;
|
|
379
|
+
grammar: 'markdown';
|
|
380
|
+
userLanguageCode?: LanguageCode;
|
|
381
|
+
skipTaskdoc?: boolean;
|
|
382
|
+
}): Promise<DialogQueuedPromptState>;
|
|
373
383
|
queueRuntimeSideDialogPrompt(options: {
|
|
374
384
|
prompt: string;
|
|
375
385
|
msgId: string;
|
|
@@ -528,9 +538,9 @@ export declare class MainDialog extends Dialog {
|
|
|
528
538
|
*/
|
|
529
539
|
lookupDialog(selfId: string): Dialog | undefined;
|
|
530
540
|
/**
|
|
531
|
-
*
|
|
541
|
+
* Snapshot of dialogs loaded in this root's in-memory dialog tree.
|
|
532
542
|
*/
|
|
533
|
-
|
|
543
|
+
getLoadedDialogTreeSnapshot(): Dialog[];
|
|
534
544
|
/**
|
|
535
545
|
* Remove a dialog from the local registry.
|
|
536
546
|
*/
|
package/dist/dialog.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DialogStore = exports.MainDialog = exports.SideDialog = exports.Dialog = exports.DialogID = exports.InvalidReminderIndexError = void 0;
|
|
4
4
|
exports.scheduleGlobalDialogMutexCleanupForRoot = scheduleGlobalDialogMutexCleanupForRoot;
|
|
5
5
|
exports.buildSideDialogAskerStack = buildSideDialogAskerStack;
|
|
6
|
+
exports.buildSideDialogAssignmentPromptMeta = buildSideDialogAssignmentPromptMeta;
|
|
6
7
|
const id_1 = require("@longrun-ai/kernel/utils/id");
|
|
7
8
|
const time_1 = require("@longrun-ai/kernel/utils/time");
|
|
8
9
|
const util_1 = require("util");
|
|
@@ -571,6 +572,7 @@ class Dialog {
|
|
|
571
572
|
}
|
|
572
573
|
async processReminderCollection(reminders) {
|
|
573
574
|
let changed = false;
|
|
575
|
+
const updatedReminderIds = [];
|
|
574
576
|
const indicesToRemove = [];
|
|
575
577
|
for (let i = 0; i < reminders.length; i++) {
|
|
576
578
|
const reminder = reminders[i];
|
|
@@ -598,26 +600,42 @@ class Dialog {
|
|
|
598
600
|
priority: reminder.priority,
|
|
599
601
|
renderMode: reminder.renderMode,
|
|
600
602
|
});
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
if (
|
|
603
|
+
const reminderChanged = (0, tool_1.computeReminderRenderRevision)(updatedReminder) !==
|
|
604
|
+
(0, tool_1.computeReminderRenderRevision)(reminder);
|
|
605
|
+
if (reminderChanged) {
|
|
604
606
|
reminders[i] = updatedReminder;
|
|
605
607
|
changed = true;
|
|
608
|
+
updatedReminderIds.push(updatedReminder.id);
|
|
606
609
|
}
|
|
607
610
|
break;
|
|
608
611
|
}
|
|
609
612
|
case 'keep':
|
|
610
613
|
break;
|
|
614
|
+
default: {
|
|
615
|
+
const _exhaustive = result.treatment;
|
|
616
|
+
return _exhaustive;
|
|
617
|
+
}
|
|
611
618
|
}
|
|
612
619
|
}
|
|
613
620
|
catch (error) {
|
|
614
|
-
|
|
621
|
+
const detail = `Reminder owner update failed ` +
|
|
622
|
+
`(rootId=${this.id.rootId}, selfId=${this.id.selfId}, course=${this.currentCourse}, ` +
|
|
623
|
+
`reminderId=${reminder.id}, owner=${reminder.owner.name}, taskDocPath=${this.taskDocPath})`;
|
|
624
|
+
await this.reportReminderRuntimeFailure(detail, error, {
|
|
625
|
+
rootId: this.id.rootId,
|
|
626
|
+
selfId: this.id.selfId,
|
|
627
|
+
course: this.currentCourse,
|
|
628
|
+
reminderId: reminder.id,
|
|
629
|
+
ownerName: reminder.owner.name,
|
|
630
|
+
taskDocPath: this.taskDocPath,
|
|
631
|
+
});
|
|
632
|
+
throw error;
|
|
615
633
|
}
|
|
616
634
|
}
|
|
617
635
|
for (let i = indicesToRemove.length - 1; i >= 0; i--) {
|
|
618
636
|
reminders.splice(indicesToRemove[i], 1);
|
|
619
637
|
}
|
|
620
|
-
return changed;
|
|
638
|
+
return { changed, updatedReminderIds };
|
|
621
639
|
}
|
|
622
640
|
buildVisibleReminderContents(taskSharedReminders, runtimeReminders) {
|
|
623
641
|
const visibleReminders = [
|
|
@@ -643,6 +661,32 @@ class Dialog {
|
|
|
643
661
|
};
|
|
644
662
|
(0, evt_registry_1.postDialogEvent)(this, fullRemindersEvt);
|
|
645
663
|
}
|
|
664
|
+
async reportReminderRuntimeFailure(detail, error, context) {
|
|
665
|
+
try {
|
|
666
|
+
await this.streamError(detail);
|
|
667
|
+
}
|
|
668
|
+
catch (streamError) {
|
|
669
|
+
log_1.log.warn('Failed to emit stream_error_evt for reminder runtime failure', streamError, {
|
|
670
|
+
...context,
|
|
671
|
+
streamErrorMessage: streamError instanceof Error ? streamError.message : String(streamError),
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
log_1.log.error(detail, error, {
|
|
675
|
+
...context,
|
|
676
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
async dispatchSharedReminderOwnerUpdateImpacts(reminderIds, scope) {
|
|
680
|
+
const { dispatchSharedReminderUpdateImpact } = await import('./runtime/shared-reminder-update-impact.js');
|
|
681
|
+
for (const reminderId of reminderIds) {
|
|
682
|
+
await dispatchSharedReminderUpdateImpact({
|
|
683
|
+
updater: this,
|
|
684
|
+
reminderId,
|
|
685
|
+
scope,
|
|
686
|
+
language: (0, work_language_1.getWorkLanguage)(),
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
}
|
|
646
690
|
/**
|
|
647
691
|
* Emits current visible reminders without reconciling tool-owned state or writing persistence.
|
|
648
692
|
* This is for read-only dialog display, especially completed/archived dialogs opened from old tabs.
|
|
@@ -674,10 +718,10 @@ class Dialog {
|
|
|
674
718
|
const runtimeTarget = { kind: 'agent', agentId: this.agentId };
|
|
675
719
|
const taskSharedReminders = await (0, shared_reminders_1.loadSharedReminders)(taskSharedTarget);
|
|
676
720
|
const runtimeReminders = await (0, shared_reminders_1.loadSharedReminders)(runtimeTarget);
|
|
677
|
-
const
|
|
678
|
-
const
|
|
679
|
-
const
|
|
680
|
-
if (
|
|
721
|
+
const localResult = await this.processReminderCollection(this.reminders);
|
|
722
|
+
const taskSharedResult = await this.processReminderCollection(taskSharedReminders);
|
|
723
|
+
const runtimeResult = await this.processReminderCollection(runtimeReminders);
|
|
724
|
+
if (localResult.changed || taskSharedResult.changed || runtimeResult.changed) {
|
|
681
725
|
this.touchReminders();
|
|
682
726
|
}
|
|
683
727
|
// Centralized persistence - called when emitting event.
|
|
@@ -686,26 +730,55 @@ class Dialog {
|
|
|
686
730
|
await this.dlgStore.persistReminders(this, this.reminders);
|
|
687
731
|
}
|
|
688
732
|
catch (err) {
|
|
689
|
-
|
|
733
|
+
const detail = `Failed to persist dialog-local reminders ` +
|
|
734
|
+
`(rootId=${this.id.rootId}, selfId=${this.id.selfId}, course=${this.currentCourse})`;
|
|
735
|
+
await this.reportReminderRuntimeFailure(detail, err, {
|
|
736
|
+
rootId: this.id.rootId,
|
|
737
|
+
selfId: this.id.selfId,
|
|
738
|
+
course: this.currentCourse,
|
|
739
|
+
taskDocPath: this.taskDocPath,
|
|
740
|
+
});
|
|
741
|
+
throw err;
|
|
690
742
|
}
|
|
691
743
|
try {
|
|
692
744
|
await (0, shared_reminders_1.replaceSharedReminders)(taskSharedTarget, taskSharedReminders);
|
|
693
745
|
}
|
|
694
746
|
catch (err) {
|
|
695
|
-
|
|
696
|
-
|
|
747
|
+
const detail = `Failed to persist task-scoped reminders ` +
|
|
748
|
+
`(rootId=${this.id.rootId}, selfId=${this.id.selfId}, course=${this.currentCourse}, ` +
|
|
749
|
+
`agentId=${this.agentId}, taskDocPath=${this.taskDocPath})`;
|
|
750
|
+
await this.reportReminderRuntimeFailure(detail, err, {
|
|
751
|
+
rootId: this.id.rootId,
|
|
752
|
+
selfId: this.id.selfId,
|
|
753
|
+
course: this.currentCourse,
|
|
697
754
|
agentId: this.agentId,
|
|
698
755
|
taskDocPath: this.taskDocPath,
|
|
699
756
|
});
|
|
757
|
+
throw err;
|
|
700
758
|
}
|
|
759
|
+
await this.dispatchSharedReminderOwnerUpdateImpacts(taskSharedResult.updatedReminderIds, 'task');
|
|
701
760
|
try {
|
|
702
761
|
await (0, shared_reminders_1.replaceSharedReminders)(runtimeTarget, runtimeReminders);
|
|
703
762
|
}
|
|
704
763
|
catch (err) {
|
|
705
|
-
|
|
706
|
-
|
|
764
|
+
const detail = `Failed to persist agent-scoped reminders ` +
|
|
765
|
+
`(rootId=${this.id.rootId}, selfId=${this.id.selfId}, course=${this.currentCourse}, ` +
|
|
766
|
+
`agentId=${this.agentId})`;
|
|
767
|
+
await this.reportReminderRuntimeFailure(detail, err, {
|
|
768
|
+
rootId: this.id.rootId,
|
|
769
|
+
selfId: this.id.selfId,
|
|
770
|
+
course: this.currentCourse,
|
|
707
771
|
agentId: this.agentId,
|
|
772
|
+
taskDocPath: this.taskDocPath,
|
|
708
773
|
});
|
|
774
|
+
throw err;
|
|
775
|
+
}
|
|
776
|
+
for (const reminderId of runtimeResult.updatedReminderIds) {
|
|
777
|
+
const reminder = runtimeReminders.find((candidate) => candidate.id === reminderId);
|
|
778
|
+
if (!reminder) {
|
|
779
|
+
throw new Error(`Updated shared reminder ${reminderId} disappeared before update impact dispatch`);
|
|
780
|
+
}
|
|
781
|
+
await this.dispatchSharedReminderOwnerUpdateImpacts([reminderId], reminder.scope === 'runtime' ? 'runtime' : 'agent');
|
|
709
782
|
}
|
|
710
783
|
const reminders = this.buildVisibleReminderContents(taskSharedReminders, runtimeReminders);
|
|
711
784
|
this.emitFullRemindersUpdate(reminders);
|
|
@@ -1167,6 +1240,24 @@ class Dialog {
|
|
|
1167
1240
|
});
|
|
1168
1241
|
return created;
|
|
1169
1242
|
}
|
|
1243
|
+
async queueRuntimeGuidePrompt(options) {
|
|
1244
|
+
const common = this.runtimePromptCommon(options);
|
|
1245
|
+
const created = {
|
|
1246
|
+
...common,
|
|
1247
|
+
kind: 'new_course_runtime_guide',
|
|
1248
|
+
skipTaskdoc: options.skipTaskdoc,
|
|
1249
|
+
};
|
|
1250
|
+
this.enqueueQueuedPromptState(created);
|
|
1251
|
+
await this.persistPendingRuntimePrompt({
|
|
1252
|
+
content: created.prompt,
|
|
1253
|
+
msgId: created.msgId,
|
|
1254
|
+
grammar: created.grammar ?? 'markdown',
|
|
1255
|
+
userLanguageCode: created.userLanguageCode,
|
|
1256
|
+
origin: 'runtime',
|
|
1257
|
+
skipTaskdoc: created.skipTaskdoc,
|
|
1258
|
+
});
|
|
1259
|
+
return created;
|
|
1260
|
+
}
|
|
1170
1261
|
async queueRuntimeSideDialogPrompt(options) {
|
|
1171
1262
|
const common = this.runtimePromptCommon(options);
|
|
1172
1263
|
const created = {
|
|
@@ -1859,7 +1950,7 @@ exports.SideDialog = SideDialog;
|
|
|
1859
1950
|
*/
|
|
1860
1951
|
class MainDialog extends Dialog {
|
|
1861
1952
|
_status = 'running';
|
|
1862
|
-
// Tracks
|
|
1953
|
+
// Tracks dialogs loaded into this root's in-memory dialog tree for O(1) lookup
|
|
1863
1954
|
_localRegistry = new Map();
|
|
1864
1955
|
// Tracks Type-B registered sideDialogs by agentId!sessionSlug
|
|
1865
1956
|
_sideDialogRegistry = new Map();
|
|
@@ -1886,9 +1977,9 @@ class MainDialog extends Dialog {
|
|
|
1886
1977
|
return this._localRegistry.get(selfId);
|
|
1887
1978
|
}
|
|
1888
1979
|
/**
|
|
1889
|
-
*
|
|
1980
|
+
* Snapshot of dialogs loaded in this root's in-memory dialog tree.
|
|
1890
1981
|
*/
|
|
1891
|
-
|
|
1982
|
+
getLoadedDialogTreeSnapshot() {
|
|
1892
1983
|
return Array.from(this._localRegistry.values());
|
|
1893
1984
|
}
|
|
1894
1985
|
/**
|
|
@@ -115,6 +115,8 @@ Ownership boundaries are simple:
|
|
|
115
115
|
- `pid: number`
|
|
116
116
|
- `stdout?: boolean`
|
|
117
117
|
- `stderr?: boolean`
|
|
118
|
+
- `wait_for_new_output?: boolean`
|
|
119
|
+
- `timeout_ms?: number`
|
|
118
120
|
|
|
119
121
|
### Semantics
|
|
120
122
|
|
|
@@ -123,6 +125,9 @@ Ownership boundaries are simple:
|
|
|
123
125
|
- output order is always `stdout` first, then `stderr`
|
|
124
126
|
- each stream gets its own heading, content block, and scroll notice
|
|
125
127
|
- unrequested streams are omitted entirely
|
|
128
|
+
- when `wait_for_new_output=true`, the runner waits until at least one requested stream receives output after the request is accepted
|
|
129
|
+
- if `timeout_ms` is provided, the wait is bounded by that many milliseconds, capped at `86400000` (24h), and returns the current snapshot with an explicit timeout notice
|
|
130
|
+
- `timeout_ms` cannot be combined with `wait_for_new_output=false`; that contradictory argument set returns an error
|
|
126
131
|
|
|
127
132
|
### Why this is better
|
|
128
133
|
|
|
@@ -114,6 +114,8 @@ runner 自己作为进程组 leader,daemon 默认继承该 pgid。这样 `stop
|
|
|
114
114
|
- `pid: number`
|
|
115
115
|
- `stdout?: boolean`
|
|
116
116
|
- `stderr?: boolean`
|
|
117
|
+
- `wait_for_new_output?: boolean`
|
|
118
|
+
- `timeout_ms?: number`
|
|
117
119
|
|
|
118
120
|
### 语义
|
|
119
121
|
|
|
@@ -122,6 +124,9 @@ runner 自己作为进程组 leader,daemon 默认继承该 pgid。这样 `stop
|
|
|
122
124
|
- 返回顺序固定为 `stdout` 在前、`stderr` 在后
|
|
123
125
|
- 每个流各自带自己的标题、内容、scroll notice
|
|
124
126
|
- 未请求的流不展示
|
|
127
|
+
- `wait_for_new_output=true` 时,runner 会等到请求的流中至少一个在请求被接受后出现新输出再返回
|
|
128
|
+
- 提供 `timeout_ms` 时,等待最多持续指定毫秒数,上限为 `86400000`(24 小时);超时后返回当前快照,并显式提示等待超时
|
|
129
|
+
- `timeout_ms` 不可与 `wait_for_new_output=false` 同时使用;这种矛盾参数会直接报错
|
|
125
130
|
|
|
126
131
|
### 取舍理由
|
|
127
132
|
|