@myagentroam/node 0.9.149 → 0.9.151
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.
|
@@ -152,8 +152,6 @@ export class MarAgentHostedConversationRuntime {
|
|
|
152
152
|
await input.onEvent?.(projected);
|
|
153
153
|
}
|
|
154
154
|
const result = await execution.result();
|
|
155
|
-
if (result.status === 'cancelled')
|
|
156
|
-
titleController.abort();
|
|
157
155
|
const generatedTitle = await titleTask;
|
|
158
156
|
if (generatedTitle && !titleController.signal.aborted)
|
|
159
157
|
await agent
|
|
@@ -203,25 +201,31 @@ export class MarAgentHostedConversationRuntime {
|
|
|
203
201
|
cancel: () => {
|
|
204
202
|
if (settled || this.#active.get(input.sessionId)?.handle !== handle)
|
|
205
203
|
return false;
|
|
206
|
-
titleController.abort();
|
|
207
204
|
execution.cancel();
|
|
208
205
|
return true;
|
|
209
206
|
}
|
|
210
207
|
};
|
|
211
|
-
this.#active.set(input.sessionId, {
|
|
208
|
+
this.#active.set(input.sessionId, {
|
|
209
|
+
handle,
|
|
210
|
+
completion,
|
|
211
|
+
cancelTitle: () => titleController.abort()
|
|
212
|
+
});
|
|
212
213
|
return handle;
|
|
213
214
|
}
|
|
214
215
|
async releaseSession(input) {
|
|
215
216
|
const active = this.#active.get(input.sessionId);
|
|
216
217
|
if (active === undefined)
|
|
217
218
|
return;
|
|
219
|
+
active.cancelTitle();
|
|
218
220
|
active.handle.cancel();
|
|
219
221
|
await active.completion.catch(() => undefined);
|
|
220
222
|
}
|
|
221
223
|
async dispose() {
|
|
222
224
|
const active = [...this.#active.values()];
|
|
223
|
-
for (const execution of active)
|
|
225
|
+
for (const execution of active) {
|
|
226
|
+
execution.cancelTitle();
|
|
224
227
|
execution.handle.cancel();
|
|
228
|
+
}
|
|
225
229
|
await Promise.allSettled(active.map((execution) => execution.completion));
|
|
226
230
|
}
|
|
227
231
|
async #readGeneratedTitle(homeDirectory, sessionId) {
|
|
@@ -52,11 +52,15 @@ export class MarAgentManagedRunController {
|
|
|
52
52
|
return this.#disposePromise;
|
|
53
53
|
this.#disposed = true;
|
|
54
54
|
this.#disposePromise = (async () => {
|
|
55
|
-
for (const execution of this.#executions.values())
|
|
55
|
+
for (const execution of this.#executions.values()) {
|
|
56
|
+
execution.cancelTitle();
|
|
56
57
|
execution.cancel();
|
|
58
|
+
}
|
|
57
59
|
await Promise.allSettled([...new Set(this.#runtimeAcquisitions.values())]);
|
|
58
|
-
for (const execution of this.#executions.values())
|
|
60
|
+
for (const execution of this.#executions.values()) {
|
|
61
|
+
execution.cancelTitle();
|
|
59
62
|
execution.cancel();
|
|
63
|
+
}
|
|
60
64
|
await Promise.all([...new Set(this.#sessionRuntimes.values())].map((runtime) => this.#releaseRuntime(runtime)));
|
|
61
65
|
await this.#mcpClients.close();
|
|
62
66
|
await this.#computerUse?.dispose();
|
|
@@ -74,8 +78,11 @@ export class MarAgentManagedRunController {
|
|
|
74
78
|
await this.#computerUse?.releaseSession(sessionId);
|
|
75
79
|
return;
|
|
76
80
|
}
|
|
77
|
-
if (runtime.activeRunId !== undefined)
|
|
78
|
-
this.#executions.get(runtime.activeRunId)
|
|
81
|
+
if (runtime.activeRunId !== undefined) {
|
|
82
|
+
const execution = this.#executions.get(runtime.activeRunId);
|
|
83
|
+
execution?.cancelTitle();
|
|
84
|
+
execution?.cancel();
|
|
85
|
+
}
|
|
79
86
|
await this.#releaseRuntime(runtime);
|
|
80
87
|
await Promise.all([
|
|
81
88
|
this.#computerUse?.releaseSession(sessionId),
|
|
@@ -212,7 +219,7 @@ export class MarAgentManagedRunController {
|
|
|
212
219
|
if (!execution)
|
|
213
220
|
return false;
|
|
214
221
|
execution.cancel();
|
|
215
|
-
this.host.emit(runId, 'run.cancelling', { intent }
|
|
222
|
+
this.host.emit(runId, 'run.cancelling', { intent });
|
|
216
223
|
return true;
|
|
217
224
|
}
|
|
218
225
|
respondUserInput(runId, requestId, answers) {
|
|
@@ -229,6 +236,20 @@ export class MarAgentManagedRunController {
|
|
|
229
236
|
return true;
|
|
230
237
|
}
|
|
231
238
|
async run(input) {
|
|
239
|
+
const controller = new AbortController();
|
|
240
|
+
const titleController = new AbortController();
|
|
241
|
+
let cancelExecution;
|
|
242
|
+
// Own cancellation before any asynchronous preparation, not only after SDK admission.
|
|
243
|
+
this.#executions.set(input.runId, {
|
|
244
|
+
cancel: () => {
|
|
245
|
+
if (controller.signal.aborted)
|
|
246
|
+
return;
|
|
247
|
+
controller.abort();
|
|
248
|
+
titleController.abort();
|
|
249
|
+
cancelExecution?.();
|
|
250
|
+
},
|
|
251
|
+
cancelTitle: () => titleController.abort()
|
|
252
|
+
});
|
|
232
253
|
this.host.active.add(input.runId);
|
|
233
254
|
this.host.adopt({
|
|
234
255
|
runId: input.runId,
|
|
@@ -246,9 +267,10 @@ export class MarAgentManagedRunController {
|
|
|
246
267
|
let executionMcpBinding;
|
|
247
268
|
let computerUseBinding;
|
|
248
269
|
let executionModels = [];
|
|
249
|
-
const titleController = new AbortController();
|
|
250
270
|
let titleTask;
|
|
271
|
+
let cancelledDuringPreparation = false;
|
|
251
272
|
try {
|
|
273
|
+
controller.signal.throwIfAborted();
|
|
252
274
|
const sessionKey = input.externalSessionId ?? input.sessionId;
|
|
253
275
|
// Reserve both identities while opening so a concurrent release can await the same runtime.
|
|
254
276
|
const acquisitionKeys = [...new Set([sessionKey, input.sessionId])];
|
|
@@ -266,6 +288,7 @@ export class MarAgentManagedRunController {
|
|
|
266
288
|
if (this.#runtimeAcquisitions.get(key) === acquisition)
|
|
267
289
|
this.#runtimeAcquisitions.delete(key);
|
|
268
290
|
}
|
|
291
|
+
controller.signal.throwIfAborted();
|
|
269
292
|
if (this.#disposed ||
|
|
270
293
|
this.#sessionReleases.has(sessionKey) ||
|
|
271
294
|
this.#sessionReleases.has(input.sessionId) ||
|
|
@@ -277,6 +300,7 @@ export class MarAgentManagedRunController {
|
|
|
277
300
|
throw new Error('MAR_AGENT_SESSION_RUNTIME_ACTIVE');
|
|
278
301
|
runtime.activeRunId = input.runId;
|
|
279
302
|
await runtime.mcpLease.pool.refreshForExecution();
|
|
303
|
+
controller.signal.throwIfAborted();
|
|
280
304
|
const executionMcpServers = input.mcpServers
|
|
281
305
|
.filter(isExecutionScopedMcp)
|
|
282
306
|
.map((server) => ({ ...server, lifecycle: 'EXECUTION' }));
|
|
@@ -287,6 +311,7 @@ export class MarAgentManagedRunController {
|
|
|
287
311
|
enabled: input.computerUseEnabled === true,
|
|
288
312
|
modelSupportsImages: input.model.inputCapabilities.includes('IMAGE')
|
|
289
313
|
});
|
|
314
|
+
controller.signal.throwIfAborted();
|
|
290
315
|
if (this.#disposed ||
|
|
291
316
|
this.#sessionReleases.has(sessionKey) ||
|
|
292
317
|
this.#sessionReleases.has(input.sessionId) ||
|
|
@@ -302,6 +327,7 @@ export class MarAgentManagedRunController {
|
|
|
302
327
|
authorizationScope: runtime.session.id
|
|
303
328
|
});
|
|
304
329
|
}
|
|
330
|
+
controller.signal.throwIfAborted();
|
|
305
331
|
const userTools = executionMcpLease?.pool.definitions() ?? [];
|
|
306
332
|
const nodeTools = computerUseBinding?.tools ?? [];
|
|
307
333
|
if (userTools.some((tool) => tool.name.startsWith('mcp__computer__')))
|
|
@@ -371,6 +397,7 @@ export class MarAgentManagedRunController {
|
|
|
371
397
|
const metadata = input.mode === 'compact' || !runtime.automaticTitleEnabled
|
|
372
398
|
? undefined
|
|
373
399
|
: await runtime.agent.getSession(session.id).catch(() => undefined);
|
|
400
|
+
controller.signal.throwIfAborted();
|
|
374
401
|
const handle = input.mode === 'plan'
|
|
375
402
|
? session.plan({
|
|
376
403
|
...runInput
|
|
@@ -378,12 +405,7 @@ export class MarAgentManagedRunController {
|
|
|
378
405
|
: input.mode === 'compact'
|
|
379
406
|
? session.compact(runInput)
|
|
380
407
|
: session.run(runInput);
|
|
381
|
-
|
|
382
|
-
cancel: () => {
|
|
383
|
-
titleController.abort();
|
|
384
|
-
handle.cancel();
|
|
385
|
-
}
|
|
386
|
-
});
|
|
408
|
+
cancelExecution = () => handle.cancel();
|
|
387
409
|
this.host.emit(input.runId, 'run.running', {}, 'RUNNING');
|
|
388
410
|
for await (const event of handle) {
|
|
389
411
|
if (event.type === 'execution.started' && metadata?.automaticTitlePending && !titleTask) {
|
|
@@ -398,8 +420,6 @@ export class MarAgentManagedRunController {
|
|
|
398
420
|
this.project(input.runId, event);
|
|
399
421
|
}
|
|
400
422
|
const result = await handle.result();
|
|
401
|
-
if (result.status === 'cancelled')
|
|
402
|
-
titleController.abort();
|
|
403
423
|
const title = await titleTask;
|
|
404
424
|
if (title && !titleController.signal.aborted)
|
|
405
425
|
await runtime.agent
|
|
@@ -427,20 +447,26 @@ export class MarAgentManagedRunController {
|
|
|
427
447
|
}, status);
|
|
428
448
|
}
|
|
429
449
|
catch (error) {
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
450
|
+
if (controller.signal.aborted && cancelExecution === undefined) {
|
|
451
|
+
// Keep the Run owned until preparation and its resources actually settle.
|
|
452
|
+
cancelledDuringPreparation = true;
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
if (runtime !== undefined)
|
|
456
|
+
this.#prepareRuntimeForTerminal(input.runId, runtime);
|
|
457
|
+
const projected = runnerErrorProjection(error, 'MAR_AGENT_RUN_FAILED');
|
|
458
|
+
this.host.emitItem(input.runId, {
|
|
459
|
+
itemId: boundedConversationItemId('mar-agent-error', input.runId),
|
|
460
|
+
kind: 'error',
|
|
461
|
+
status: 'FAILED',
|
|
462
|
+
payload: {
|
|
463
|
+
...projected,
|
|
464
|
+
recoverable: true,
|
|
465
|
+
retryAfterMs: null
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
this.host.emit(input.runId, 'run.failed', projected, 'FAILED');
|
|
469
|
+
}
|
|
444
470
|
}
|
|
445
471
|
finally {
|
|
446
472
|
titleController.abort();
|
|
@@ -449,14 +475,16 @@ export class MarAgentManagedRunController {
|
|
|
449
475
|
delete runtime.automaticTitleTask;
|
|
450
476
|
this.clearInteractions(input.runId);
|
|
451
477
|
this.#normalizers.delete(input.runId);
|
|
452
|
-
this.host.active.delete(input.runId);
|
|
453
|
-
this.#executions.delete(input.runId);
|
|
454
478
|
await closeImageCredentialProviders(executionModels);
|
|
455
479
|
await computerUseBinding?.close().catch(() => undefined);
|
|
456
480
|
runtime?.host.unbindExecutionMcp(executionMcpBinding);
|
|
457
481
|
await executionMcpLease?.release().catch(() => undefined);
|
|
458
482
|
if (runtime !== undefined)
|
|
459
483
|
await this.#finishRuntimeExecution(input.runId, runtime).catch(() => undefined);
|
|
484
|
+
this.host.active.delete(input.runId);
|
|
485
|
+
this.#executions.delete(input.runId);
|
|
486
|
+
if (cancelledDuringPreparation)
|
|
487
|
+
this.host.emit(input.runId, 'run.cancelled', { status: 'CANCELLED' }, 'CANCELLED');
|
|
460
488
|
}
|
|
461
489
|
}
|
|
462
490
|
#prepareRuntimeForTerminal(runId, runtime) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.151",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"npm": "11.12.1",
|
|
35
35
|
"ws": "^8.21.3",
|
|
36
36
|
"zod": "4.4.3",
|
|
37
|
+
"@myagentroam/marctl": "0.9.120",
|
|
38
|
+
"@myagentroam/protocol": "0.9.151",
|
|
37
39
|
"@myagentroam/code-navigation": "0.9.129",
|
|
38
|
-
"@myagentroam/agent": "0.9.
|
|
39
|
-
"@myagentroam/protocol": "0.9.149",
|
|
40
|
-
"@myagentroam/marctl": "0.9.120"
|
|
40
|
+
"@myagentroam/agent": "0.9.151"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/ws": "^8.18.1"
|