lazy-gravity 0.10.0 → 0.11.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/bin/commands/doctor.js +45 -7
- package/dist/bot/index.js +191 -22
- package/dist/commands/chatCommandHandler.js +11 -41
- package/dist/events/interactionCreateHandler.js +158 -27
- package/dist/events/messageCreateHandler.js +14 -4
- package/dist/handlers/fileChangeButtonAction.js +12 -24
- package/dist/handlers/genericActionButtonAction.js +16 -18
- package/dist/handlers/planningButtonAction.js +105 -17
- package/dist/handlers/planningModalSubmitAction.js +38 -0
- package/dist/handlers/questionSelectAction.js +8 -7
- package/dist/handlers/questionSkipAction.js +7 -6
- package/dist/platform/discord/wrappers.js +76 -0
- package/dist/services/approvalDetector.js +43 -14
- package/dist/services/artifactService.js +61 -21
- package/dist/services/assistantDomExtractor.js +23 -3
- package/dist/services/cdpBridgeManager.js +35 -2
- package/dist/services/cdpConnectionPool.js +7 -2
- package/dist/services/cdpService.js +113 -8
- package/dist/services/chatSessionService.js +15 -8
- package/dist/services/notificationSender.js +12 -2
- package/dist/services/planningDetector.js +1 -1
- package/dist/services/promptDispatcher.js +21 -1
- package/dist/services/questionDetector.js +128 -76
- package/dist/services/responseMonitor.js +17 -1
- package/dist/utils/fileOpenCache.js +2 -6
- package/dist/utils/questionActionUtils.js +22 -0
- package/package.json +1 -1
|
@@ -11,6 +11,7 @@ function buildConnectionKey(projectName, accountName) {
|
|
|
11
11
|
* Pool that manages independent CdpService instances per workspace/account pair.
|
|
12
12
|
*/
|
|
13
13
|
class CdpConnectionPool {
|
|
14
|
+
lastActiveWorkspace = null;
|
|
14
15
|
connections = new Map();
|
|
15
16
|
workspaceToAccount = new Map();
|
|
16
17
|
approvalDetectors = new Map();
|
|
@@ -40,6 +41,7 @@ class CdpConnectionPool {
|
|
|
40
41
|
const key = buildConnectionKey(projectName, effectiveAccount);
|
|
41
42
|
const existing = this.connections.get(key);
|
|
42
43
|
if (existing && existing.isConnected()) {
|
|
44
|
+
this.lastActiveWorkspace = projectName;
|
|
43
45
|
await existing.discoverAndConnectForWorkspace(workspacePath);
|
|
44
46
|
return existing;
|
|
45
47
|
}
|
|
@@ -50,7 +52,9 @@ class CdpConnectionPool {
|
|
|
50
52
|
const connectPromise = this.createAndConnect(workspacePath, projectName, effectiveAccount);
|
|
51
53
|
this.connectingPromises.set(key, connectPromise);
|
|
52
54
|
try {
|
|
53
|
-
|
|
55
|
+
const result = await connectPromise;
|
|
56
|
+
this.lastActiveWorkspace = projectName;
|
|
57
|
+
return result;
|
|
54
58
|
}
|
|
55
59
|
finally {
|
|
56
60
|
this.connectingPromises.delete(key);
|
|
@@ -59,8 +63,9 @@ class CdpConnectionPool {
|
|
|
59
63
|
}
|
|
60
64
|
getConnected(projectName, accountName = 'default') {
|
|
61
65
|
const effectiveAccount = this.resolveAccountName(projectName, accountName);
|
|
62
|
-
const cdp = this.connections.get(buildConnectionKey(projectName, effectiveAccount));
|
|
66
|
+
const cdp = this.connections.get(buildConnectionKey(projectName, effectiveAccount)) || null;
|
|
63
67
|
if (cdp && cdp.isConnected()) {
|
|
68
|
+
this.lastActiveWorkspace = projectName;
|
|
64
69
|
return cdp;
|
|
65
70
|
}
|
|
66
71
|
return null;
|
|
@@ -102,6 +102,12 @@ const WORKSPACE_STATE_SCRIPT = `(() => {
|
|
|
102
102
|
if (isGenerating) break;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
+
if (!isGenerating && panel) {
|
|
106
|
+
const panelText = (panel.textContent || '').trim();
|
|
107
|
+
if (/Working\.\s*$/i.test(panelText)) {
|
|
108
|
+
isGenerating = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
105
111
|
|
|
106
112
|
if (!panel) {
|
|
107
113
|
return { isGenerating, sessionTitle: '', hasActiveChat: false };
|
|
@@ -462,7 +468,8 @@ class CdpService extends events_1.EventEmitter {
|
|
|
462
468
|
returnByValue: true,
|
|
463
469
|
});
|
|
464
470
|
const liveTitle = String(titleResult?.result?.value || '');
|
|
465
|
-
|
|
471
|
+
const titleParts = liveTitle.split(' - ');
|
|
472
|
+
if (titleParts[0].trim().toLowerCase() === projectName.toLowerCase()) {
|
|
466
473
|
this.currentWorkspaceName = projectName;
|
|
467
474
|
return true;
|
|
468
475
|
}
|
|
@@ -509,7 +516,12 @@ class CdpService extends events_1.EventEmitter {
|
|
|
509
516
|
logger_1.logger.debug(` - title="${p.title}" url=${p.url}`);
|
|
510
517
|
}
|
|
511
518
|
// 1. Title match (fast path)
|
|
512
|
-
const titleMatch = workbenchPages.find((t) =>
|
|
519
|
+
const titleMatch = workbenchPages.find((t) => {
|
|
520
|
+
if (!t.title)
|
|
521
|
+
return false;
|
|
522
|
+
const parts = t.title.split(' - ');
|
|
523
|
+
return parts[0].trim().toLowerCase() === projectName.toLowerCase();
|
|
524
|
+
});
|
|
513
525
|
if (titleMatch) {
|
|
514
526
|
return this.connectToPage(titleMatch, projectName);
|
|
515
527
|
}
|
|
@@ -562,9 +574,8 @@ class CdpService extends events_1.EventEmitter {
|
|
|
562
574
|
returnByValue: true,
|
|
563
575
|
});
|
|
564
576
|
const liveTitle = String(result?.result?.value || '');
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
if (normalizedLiveTitle.includes(normalizedProject)) {
|
|
577
|
+
const liveParts = liveTitle.split(' - ');
|
|
578
|
+
if (liveParts[0].trim().toLowerCase() === projectName.toLowerCase()) {
|
|
568
579
|
this.currentWorkspaceName = projectName;
|
|
569
580
|
logger_1.logger.debug(`[CdpService] Probe success: detected "${projectName}"`);
|
|
570
581
|
return true;
|
|
@@ -761,7 +772,12 @@ class CdpService extends events_1.EventEmitter {
|
|
|
761
772
|
!t.url?.includes('workbench-jetski-agent') &&
|
|
762
773
|
t.url?.includes('workbench'));
|
|
763
774
|
// Title match
|
|
764
|
-
const titleMatch = workbenchPages.find((t) =>
|
|
775
|
+
const titleMatch = workbenchPages.find((t) => {
|
|
776
|
+
if (!t.title)
|
|
777
|
+
return false;
|
|
778
|
+
const parts = t.title.split(' - ');
|
|
779
|
+
return parts[0].trim().toLowerCase() === projectName.toLowerCase();
|
|
780
|
+
});
|
|
765
781
|
if (titleMatch) {
|
|
766
782
|
return this.connectToPage(titleMatch, projectName);
|
|
767
783
|
}
|
|
@@ -1290,9 +1306,15 @@ class CdpService extends events_1.EventEmitter {
|
|
|
1290
1306
|
].some((fragment) => message.includes(fragment));
|
|
1291
1307
|
}
|
|
1292
1308
|
async injectMessageCore(text, imageFilePaths) {
|
|
1293
|
-
|
|
1309
|
+
// Check if chat input is already available
|
|
1310
|
+
let focusResult = await this.waitForChatInputReady(500);
|
|
1294
1311
|
if (!focusResult.ok) {
|
|
1295
|
-
|
|
1312
|
+
// Send Cmd+L / Ctrl+L to guarantee application-level focus on the chat panel (and open it if closed)
|
|
1313
|
+
await this.focusChatPanelViaShortcut();
|
|
1314
|
+
focusResult = await this.waitForChatInputReady();
|
|
1315
|
+
if (!focusResult.ok) {
|
|
1316
|
+
return { ok: false, error: focusResult.error || 'Chat input field not found' };
|
|
1317
|
+
}
|
|
1296
1318
|
}
|
|
1297
1319
|
// Clear any existing text in the input field before injecting.
|
|
1298
1320
|
await this.clearInputField();
|
|
@@ -1391,6 +1413,89 @@ class CdpService extends events_1.EventEmitter {
|
|
|
1391
1413
|
nativeVirtualKeyCode: 13,
|
|
1392
1414
|
});
|
|
1393
1415
|
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Opens the chat panel and waits for the UI to be ready.
|
|
1418
|
+
* Can be called right after the IDE launches to ensure the panel is visible.
|
|
1419
|
+
*/
|
|
1420
|
+
async openChatPanel() {
|
|
1421
|
+
if (!await this.isConnected())
|
|
1422
|
+
return;
|
|
1423
|
+
// Ensure IDE UI is fully loaded before sending shortcut
|
|
1424
|
+
const deadline = Date.now() + 15000;
|
|
1425
|
+
let workbenchReady = false;
|
|
1426
|
+
while (Date.now() < deadline) {
|
|
1427
|
+
try {
|
|
1428
|
+
const res = await this.call('Runtime.evaluate', {
|
|
1429
|
+
expression: '!!document.querySelector(".monaco-workbench")',
|
|
1430
|
+
returnByValue: true
|
|
1431
|
+
});
|
|
1432
|
+
if (res?.result?.value) {
|
|
1433
|
+
workbenchReady = true;
|
|
1434
|
+
break;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
catch {
|
|
1438
|
+
// ignore
|
|
1439
|
+
}
|
|
1440
|
+
await new Promise(r => setTimeout(r, 500));
|
|
1441
|
+
}
|
|
1442
|
+
if (workbenchReady) {
|
|
1443
|
+
// Check if chat panel is already open to avoid toggling it closed
|
|
1444
|
+
const focusResult = await this.waitForChatInputReady(1000);
|
|
1445
|
+
if (!focusResult.ok) {
|
|
1446
|
+
await this.focusChatPanelViaShortcut();
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Send Cmd+L / Ctrl+L to focus the chat panel via shortcut.
|
|
1452
|
+
*/
|
|
1453
|
+
async focusChatPanelViaShortcut() {
|
|
1454
|
+
const modifiers = process.platform === 'darwin' ? 4 : 2; // Meta : Ctrl
|
|
1455
|
+
await this.call('Input.dispatchKeyEvent', {
|
|
1456
|
+
type: 'keyDown',
|
|
1457
|
+
key: 'l',
|
|
1458
|
+
code: 'KeyL',
|
|
1459
|
+
modifiers,
|
|
1460
|
+
windowsVirtualKeyCode: 76,
|
|
1461
|
+
nativeVirtualKeyCode: 76,
|
|
1462
|
+
});
|
|
1463
|
+
await this.call('Input.dispatchKeyEvent', {
|
|
1464
|
+
type: 'keyUp',
|
|
1465
|
+
key: 'l',
|
|
1466
|
+
code: 'KeyL',
|
|
1467
|
+
modifiers,
|
|
1468
|
+
windowsVirtualKeyCode: 76,
|
|
1469
|
+
nativeVirtualKeyCode: 76,
|
|
1470
|
+
});
|
|
1471
|
+
await new Promise(r => setTimeout(r, 100)); // wait for focus to shift
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Send Cmd+W / Ctrl+W to close the active editor.
|
|
1475
|
+
*/
|
|
1476
|
+
async closeActiveEditor() {
|
|
1477
|
+
if (!this.isConnectedFlag || !this.ws) {
|
|
1478
|
+
throw new Error('Not connected to CDP. Call connect() first.');
|
|
1479
|
+
}
|
|
1480
|
+
const modifiers = process.platform === 'darwin' ? 4 : 2; // Meta : Ctrl
|
|
1481
|
+
await this.call('Input.dispatchKeyEvent', {
|
|
1482
|
+
type: 'keyDown',
|
|
1483
|
+
key: 'w',
|
|
1484
|
+
code: 'KeyW',
|
|
1485
|
+
modifiers,
|
|
1486
|
+
windowsVirtualKeyCode: 87,
|
|
1487
|
+
nativeVirtualKeyCode: 87,
|
|
1488
|
+
});
|
|
1489
|
+
await this.call('Input.dispatchKeyEvent', {
|
|
1490
|
+
type: 'keyUp',
|
|
1491
|
+
key: 'w',
|
|
1492
|
+
code: 'KeyW',
|
|
1493
|
+
modifiers,
|
|
1494
|
+
windowsVirtualKeyCode: 87,
|
|
1495
|
+
nativeVirtualKeyCode: 87,
|
|
1496
|
+
});
|
|
1497
|
+
await new Promise(r => setTimeout(r, 100));
|
|
1498
|
+
}
|
|
1394
1499
|
/**
|
|
1395
1500
|
* Detect file input in the UI and attach the specified files.
|
|
1396
1501
|
*/
|
|
@@ -40,7 +40,7 @@ const GET_NEW_CHAT_BUTTON_SCRIPT = `(() => {
|
|
|
40
40
|
* The title element is a div with the text-ellipsis class inside the header.
|
|
41
41
|
*/
|
|
42
42
|
const GET_CHAT_TITLE_SCRIPT = `(() => {
|
|
43
|
-
const panel = document.querySelector('.antigravity-agent-side-panel');
|
|
43
|
+
const panel = document.querySelector('.antigravity-agent-side-panel') || document.body;
|
|
44
44
|
if (!panel) return { title: '', hasActiveChat: false };
|
|
45
45
|
const header = panel.querySelector('div[class*="border-b"]');
|
|
46
46
|
if (!header) return { title: '', hasActiveChat: false };
|
|
@@ -58,7 +58,7 @@ const GET_CHAT_TITLE_SCRIPT = `(() => {
|
|
|
58
58
|
return { title: title || '(Untitled)', hasActiveChat };
|
|
59
59
|
})()`;
|
|
60
60
|
const GET_SESSION_VIEW_STATE_SCRIPT = `(() => {
|
|
61
|
-
const panel = document.querySelector('.antigravity-agent-side-panel');
|
|
61
|
+
const panel = document.querySelector('.antigravity-agent-side-panel') || document.body;
|
|
62
62
|
if (!panel) {
|
|
63
63
|
return {
|
|
64
64
|
panelFound: false,
|
|
@@ -169,7 +169,8 @@ const SCRAPE_PAST_CONVERSATIONS_SCRIPT = `(() => {
|
|
|
169
169
|
// Try the visible QuickInput dialog first, then fall back to the side panel.
|
|
170
170
|
const quickInputPanels = Array.from(document.querySelectorAll('div[class*="bg-quickinput-background"]'));
|
|
171
171
|
const panel = quickInputPanels.find((el) => isVisible(el))
|
|
172
|
-
|| document.querySelector('.antigravity-agent-side-panel')
|
|
172
|
+
|| document.querySelector('.antigravity-agent-side-panel')
|
|
173
|
+
|| document.body;
|
|
173
174
|
if (!panel) return null;
|
|
174
175
|
|
|
175
176
|
const items = [];
|
|
@@ -276,9 +277,11 @@ function buildActivateChatByTitleScript(title) {
|
|
|
276
277
|
for (const node of nodes) {
|
|
277
278
|
const text = normalize(node.textContent || '');
|
|
278
279
|
if (!text) continue;
|
|
280
|
+
|
|
281
|
+
const isShort = wanted.length < 5;
|
|
279
282
|
if (text === wanted) {
|
|
280
283
|
exact.push({ node, textLength: text.length });
|
|
281
|
-
} else if (text.includes(wanted)) {
|
|
284
|
+
} else if (!isShort && text.includes(wanted)) {
|
|
282
285
|
includes.push({ node, textLength: text.length });
|
|
283
286
|
} else if (wordsMatch(text, wantedRaw)) {
|
|
284
287
|
fuzzy.push({ node, textLength: text.length });
|
|
@@ -369,10 +372,12 @@ function buildActivateViaPastConversationsScript(title) {
|
|
|
369
372
|
if (!pattern) continue;
|
|
370
373
|
const p = normalize(pattern);
|
|
371
374
|
const pLoose = normalizeLoose(pattern);
|
|
375
|
+
const isShort = p.length < 5;
|
|
376
|
+
|
|
372
377
|
if (
|
|
373
378
|
text === p ||
|
|
374
|
-
|
|
375
|
-
(
|
|
379
|
+
(pLoose && textLoose === pLoose) ||
|
|
380
|
+
(!isShort && (text.includes(p) || (pLoose && textLoose.includes(pLoose))))
|
|
376
381
|
) {
|
|
377
382
|
matched.push({ el, score: Math.abs(text.length - pattern.length) });
|
|
378
383
|
break;
|
|
@@ -611,7 +616,8 @@ class ChatSessionService {
|
|
|
611
616
|
const isVisible = (el) => !!el && el instanceof HTMLElement && el.offsetParent !== null;
|
|
612
617
|
const quickInputPanels = Array.from(document.querySelectorAll('div[class*="bg-quickinput-background"]'));
|
|
613
618
|
const panel = quickInputPanels.find((el) => isVisible(el))
|
|
614
|
-
|| document.querySelector('.antigravity-agent-side-panel')
|
|
619
|
+
|| document.querySelector('.antigravity-agent-side-panel')
|
|
620
|
+
|| document.body;
|
|
615
621
|
if (!panel) return false;
|
|
616
622
|
const containers = Array.from(
|
|
617
623
|
panel.querySelectorAll('div[class*="overflow-auto"], div[class*="overflow-y-scroll"]')
|
|
@@ -1095,12 +1101,13 @@ class ChatSessionService {
|
|
|
1095
1101
|
/**
|
|
1096
1102
|
* Rename the current chat in the Antigravity UI directly by updating the DOM.
|
|
1097
1103
|
* Note: This is a cosmetic change until Antigravity persists a rename.
|
|
1104
|
+
* IDE syncing for chat renaming is strictly "best-effort".
|
|
1098
1105
|
*/
|
|
1099
1106
|
async renameCurrentChatInUI(cdpService, newTitle) {
|
|
1100
1107
|
try {
|
|
1101
1108
|
const contextId = cdpService.getPrimaryContextId();
|
|
1102
1109
|
const RENAME_SCRIPT = `(() => {
|
|
1103
|
-
const panel = document.querySelector('.antigravity-agent-side-panel');
|
|
1110
|
+
const panel = document.querySelector('.antigravity-agent-side-panel') || document.body;
|
|
1104
1111
|
if (!panel) return { ok: false, error: 'Panel not found' };
|
|
1105
1112
|
const header = panel.querySelector('div[class*="border-b"]');
|
|
1106
1113
|
const titleEl = header?.querySelector('div[class*="text-ellipsis"]');
|
|
@@ -82,7 +82,7 @@ function customId(prefix, projectName, channelId) {
|
|
|
82
82
|
// ---------------------------------------------------------------------------
|
|
83
83
|
/** Build the approval notification message. */
|
|
84
84
|
function buildApprovalNotification(opts) {
|
|
85
|
-
const { title, description, projectName, channelId, toolNames, extraFields, hasAlwaysAllow, alwaysAllowText } = opts;
|
|
85
|
+
const { title, description, projectName, channelId, toolNames, extraFields, hasAlwaysAllow, alwaysAllowText, walkthroughCustomId, taskCustomId } = opts;
|
|
86
86
|
const richContent = (0, richContentBuilder_1.pipe)((0, richContentBuilder_1.createRichContent)(), (rc) => (0, richContentBuilder_1.withTitle)(rc, title), (rc) => (0, richContentBuilder_1.withDescription)(rc, description), (rc) => (0, richContentBuilder_1.withColor)(rc, COLOR_APPROVAL), (rc) => (0, richContentBuilder_1.addField)(rc, 'Project', projectName, true), (rc) => toolNames && toolNames.length > 0
|
|
87
87
|
? (0, richContentBuilder_1.addField)(rc, 'Tools', toolNames.join(', '), true)
|
|
88
88
|
: rc, (rc) => extraFields
|
|
@@ -98,6 +98,16 @@ function buildApprovalNotification(opts) {
|
|
|
98
98
|
const components = [
|
|
99
99
|
buttonRow(...buttons),
|
|
100
100
|
];
|
|
101
|
+
const artifactButtons = [];
|
|
102
|
+
if (walkthroughCustomId) {
|
|
103
|
+
artifactButtons.push(button(walkthroughCustomId, 'Review walkthrough.md', 'success'));
|
|
104
|
+
}
|
|
105
|
+
if (taskCustomId) {
|
|
106
|
+
artifactButtons.push(button(taskCustomId, 'Review task.md', 'primary'));
|
|
107
|
+
}
|
|
108
|
+
if (artifactButtons.length > 0) {
|
|
109
|
+
components.push(buttonRow(...artifactButtons));
|
|
110
|
+
}
|
|
101
111
|
return { richContent, components };
|
|
102
112
|
}
|
|
103
113
|
/** Build the planning mode notification message. */
|
|
@@ -107,8 +117,8 @@ function buildPlanningNotification(opts) {
|
|
|
107
117
|
? extraFields.reduce((acc, f) => (0, richContentBuilder_1.addField)(acc, f.name, f.value, f.inline), rc)
|
|
108
118
|
: rc, (rc) => (0, richContentBuilder_1.withFooter)(rc, 'Planning mode detected'), (rc) => (0, richContentBuilder_1.withTimestamp)(rc));
|
|
109
119
|
const buttons = [];
|
|
110
|
-
const openLabel = opts.openText || 'Open';
|
|
111
120
|
if (opts.hasOpenButton !== false) {
|
|
121
|
+
const openLabel = opts.openText || 'Open Plan';
|
|
112
122
|
buttons.push(button(customId(PLANNING_OPEN_ACTION_PREFIX, projectName, channelId), openLabel, 'primary'));
|
|
113
123
|
}
|
|
114
124
|
const buttonLabel = opts.proceedText || 'Proceed';
|
|
@@ -247,7 +247,7 @@ class PlanningDetector {
|
|
|
247
247
|
* @returns true if click succeeded
|
|
248
248
|
*/
|
|
249
249
|
async clickRejectButton(buttonText) {
|
|
250
|
-
const text = buttonText
|
|
250
|
+
const text = buttonText || this.lastDetectedInfo?.rejectText || 'Reject All';
|
|
251
251
|
return this.clickButton(text);
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PromptDispatcher = void 0;
|
|
4
|
+
const logger_1 = require("../utils/logger");
|
|
4
5
|
/**
|
|
5
6
|
* Dispatcher that calls the existing sendPromptToAntigravity.
|
|
6
7
|
* Unifies dependency injection on the caller side and simplifies event handlers.
|
|
7
8
|
*/
|
|
8
9
|
class PromptDispatcher {
|
|
9
10
|
deps;
|
|
11
|
+
activeMonitors = new Map();
|
|
10
12
|
constructor(deps) {
|
|
11
13
|
this.deps = deps;
|
|
12
14
|
}
|
|
@@ -17,7 +19,25 @@ class PromptDispatcher {
|
|
|
17
19
|
await this._dispatch(req, { ...req.options, resumeOnly: true });
|
|
18
20
|
}
|
|
19
21
|
async _dispatch(req, options) {
|
|
20
|
-
|
|
22
|
+
const channelId = req.message.channelId;
|
|
23
|
+
const existing = this.activeMonitors.get(channelId);
|
|
24
|
+
if (existing) {
|
|
25
|
+
logger_1.logger.info(`[PromptDispatcher] Aborting previous active monitor for channel ${channelId}`);
|
|
26
|
+
await existing.stop().catch((err) => logger_1.logger.error('[PromptDispatcher] Error stopping monitor:', err));
|
|
27
|
+
this.activeMonitors.delete(channelId);
|
|
28
|
+
}
|
|
29
|
+
const wrappedOptions = {
|
|
30
|
+
...(options || {}),
|
|
31
|
+
onMonitorCreated: (monitor) => {
|
|
32
|
+
this.activeMonitors.set(channelId, monitor);
|
|
33
|
+
options?.onMonitorCreated?.(monitor);
|
|
34
|
+
},
|
|
35
|
+
onFullCompletion: () => {
|
|
36
|
+
this.activeMonitors.delete(channelId);
|
|
37
|
+
options?.onFullCompletion?.();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
await this.deps.sendPromptImpl(this.deps.bridge, req.message, req.prompt, req.cdp, this.deps.modeService, this.deps.modelService, req.inboundImages ?? [], wrappedOptions);
|
|
21
41
|
}
|
|
22
42
|
}
|
|
23
43
|
exports.PromptDispatcher = PromptDispatcher;
|