@myagentroam/node 0.11.11 → 0.11.13
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/runtime-state.js
CHANGED
|
@@ -44,7 +44,8 @@ export class NodeRuntimeState {
|
|
|
44
44
|
queueVersions = new Map();
|
|
45
45
|
/** Snapshot version of the last FIFO membership or ordering change. */
|
|
46
46
|
queueOrderVersions = new Map();
|
|
47
|
-
|
|
47
|
+
/** Each pause owns its snapshot version so late admissions cannot undo a newer pause. */
|
|
48
|
+
pausedQueues = new Map();
|
|
48
49
|
/** Bounded tombstones reject stale internal start envelopes after terminal cleanup. */
|
|
49
50
|
terminalRunIds = new Map();
|
|
50
51
|
/**
|
|
@@ -243,7 +244,7 @@ export class NodeRuntimeState {
|
|
|
243
244
|
const queueVersion = this.queueVersions.get(id);
|
|
244
245
|
const queueOrderVersion = this.queueOrderVersions.get(id);
|
|
245
246
|
const lease = this.leases.get(id);
|
|
246
|
-
const
|
|
247
|
+
const pauseVersion = this.pausedQueues.get(id);
|
|
247
248
|
this.sessions.delete(id);
|
|
248
249
|
this.sessions.set(nativeSessionId, next);
|
|
249
250
|
if (this.completeHistorySessions.delete(id))
|
|
@@ -284,9 +285,9 @@ export class NodeRuntimeState {
|
|
|
284
285
|
this.leases.delete(id);
|
|
285
286
|
this.leases.set(nativeSessionId, lease);
|
|
286
287
|
}
|
|
287
|
-
if (
|
|
288
|
+
if (pauseVersion !== undefined) {
|
|
288
289
|
this.pausedQueues.delete(id);
|
|
289
|
-
this.pausedQueues.
|
|
290
|
+
this.pausedQueues.set(nativeSessionId, pauseVersion);
|
|
290
291
|
}
|
|
291
292
|
for (const [key, submission] of [...this.messageSubmissions]) {
|
|
292
293
|
if (!key.startsWith(`${id}\u0000`))
|
|
@@ -514,17 +515,27 @@ export class NodeRuntimeState {
|
|
|
514
515
|
}
|
|
515
516
|
consumeSteeredQueueItem(itemId, runId) {
|
|
516
517
|
const item = this.requireQueueItem(itemId);
|
|
517
|
-
const
|
|
518
|
+
const activeRun = this.getRun(runId);
|
|
519
|
+
const run = activeRun ?? this.terminalRunIds.get(runId);
|
|
518
520
|
if (!run || run.sessionId !== item.sessionId || !this.receivingQueueItems.has(itemId))
|
|
519
521
|
throw new Error('QUEUE_ITEM_INVALID');
|
|
520
522
|
this.queuedItems.set(item.sessionId, (this.queuedItems.get(item.sessionId) ?? []).filter((id) => id !== itemId));
|
|
521
523
|
this.queueItems.delete(itemId);
|
|
522
524
|
this.bumpQueueVersion(item.sessionId);
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
id: run.id
|
|
526
|
-
|
|
527
|
-
|
|
525
|
+
const key = `${item.sessionId}\u0000${item.clientMessageId}`;
|
|
526
|
+
if (activeRun !== undefined) {
|
|
527
|
+
this.messageSubmissions.set(key, { kind: 'run', id: run.id });
|
|
528
|
+
this.recentUserMessages.set(run.id, item.content);
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
this.messageSubmissions.delete(key);
|
|
532
|
+
this.rememberTerminalMessageSubmission(key, run.id);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
rememberTerminalMessageSubmission(key, runId) {
|
|
536
|
+
this.terminalMessageSubmissions.set(key, runId);
|
|
537
|
+
if (this.terminalMessageSubmissions.size > 1_024)
|
|
538
|
+
this.terminalMessageSubmissions.delete(this.terminalMessageSubmissions.keys().next().value);
|
|
528
539
|
}
|
|
529
540
|
claimNextQueueItem(sessionId, content) {
|
|
530
541
|
if (this.pausedQueues.has(sessionId))
|
|
@@ -586,8 +597,11 @@ export class NodeRuntimeState {
|
|
|
586
597
|
return { run: created.run, turn };
|
|
587
598
|
}
|
|
588
599
|
pauseSessionQueue(sessionId) {
|
|
589
|
-
this.pausedQueues.add(sessionId);
|
|
590
600
|
this.bumpQueueVersion(sessionId, false);
|
|
601
|
+
this.pausedQueues.set(sessionId, this.queueVersions.get(sessionId));
|
|
602
|
+
}
|
|
603
|
+
sessionQueuePauseVersion(sessionId) {
|
|
604
|
+
return this.pausedQueues.get(sessionId);
|
|
591
605
|
}
|
|
592
606
|
resumeSessionQueue(sessionId) {
|
|
593
607
|
if (!this.pausedQueues.delete(sessionId))
|
|
@@ -1076,9 +1090,7 @@ export class NodeRuntimeState {
|
|
|
1076
1090
|
for (const [key, candidate] of this.messageSubmissions)
|
|
1077
1091
|
if (candidate.kind === 'run' && candidate.id === runId) {
|
|
1078
1092
|
this.messageSubmissions.delete(key);
|
|
1079
|
-
this.
|
|
1080
|
-
if (this.terminalMessageSubmissions.size > 1_024)
|
|
1081
|
-
this.terminalMessageSubmissions.delete(this.terminalMessageSubmissions.keys().next().value);
|
|
1093
|
+
this.rememberTerminalMessageSubmission(key, runId);
|
|
1082
1094
|
}
|
|
1083
1095
|
for (const [approvalId, approval] of this.approvals)
|
|
1084
1096
|
if (approval.runId === runId || executionIds.has(approval.runId))
|
|
@@ -140,9 +140,9 @@ export class ContinuousRunCoordinator {
|
|
|
140
140
|
this.options.runtime.currentExecutionId(active.id) === input.steerTarget.executionId) {
|
|
141
141
|
const attempt = this.tryNativeSteer(input.submissionId, active, input.onNativeAccepted);
|
|
142
142
|
if (attempt)
|
|
143
|
-
return attempt.then((accepted) => accepted
|
|
143
|
+
return attempt.task.then((accepted) => accepted
|
|
144
144
|
? 'ACCEPTED'
|
|
145
|
-
: this.suspended || this.options.stopped()
|
|
145
|
+
: !this.nativeSteerPauseCurrent(attempt) || this.suspended || this.options.stopped()
|
|
146
146
|
? 'QUEUED'
|
|
147
147
|
: this.settleFallback(input));
|
|
148
148
|
}
|
|
@@ -164,6 +164,8 @@ export class ContinuousRunCoordinator {
|
|
|
164
164
|
(input.steerTarget.executionId === undefined ||
|
|
165
165
|
this.options.runtime.currentExecutionId(active.id) === input.steerTarget.executionId);
|
|
166
166
|
const intent = input.steerTarget !== undefined && !steering ? 'SEND' : input.intent;
|
|
167
|
+
if (active?.status === 'CANCELLING' && intent !== 'REPLACE_CURRENT')
|
|
168
|
+
return 'QUEUED';
|
|
167
169
|
if (steering)
|
|
168
170
|
this.prepareSteering(input.submissionId);
|
|
169
171
|
const executionEnded = active !== undefined &&
|
|
@@ -255,9 +257,9 @@ export class ContinuousRunCoordinator {
|
|
|
255
257
|
if (active) {
|
|
256
258
|
const attempt = this.tryNativeSteer(itemId, active);
|
|
257
259
|
if (attempt)
|
|
258
|
-
return attempt.then((accepted) => accepted
|
|
260
|
+
return attempt.task.then((accepted) => accepted
|
|
259
261
|
? { run: active, delivery: 'ACCEPTED' }
|
|
260
|
-
: this.suspended || this.options.stopped()
|
|
262
|
+
: !this.nativeSteerPauseCurrent(attempt) || this.suspended || this.options.stopped()
|
|
261
263
|
? { run: active, delivery: 'QUEUED' }
|
|
262
264
|
: this.executeQueueItemFallback(itemId));
|
|
263
265
|
}
|
|
@@ -266,7 +268,7 @@ export class ContinuousRunCoordinator {
|
|
|
266
268
|
tryNativeSteer(itemId, active, onAccepted) {
|
|
267
269
|
const previous = this.steerInFlight.get(itemId);
|
|
268
270
|
if (previous)
|
|
269
|
-
return previous
|
|
271
|
+
return previous;
|
|
270
272
|
if (this.suspended || this.options.stopped() || !this.options.steer || !this.canSteer(active))
|
|
271
273
|
return undefined;
|
|
272
274
|
const executionId = this.options.runtime.currentExecutionId(active.id);
|
|
@@ -275,6 +277,7 @@ export class ContinuousRunCoordinator {
|
|
|
275
277
|
this.prepareSteering(itemId);
|
|
276
278
|
const prepared = this.preparedInputs.get(itemId);
|
|
277
279
|
const item = this.options.runtime.getQueueItem(itemId);
|
|
280
|
+
const pauseVersion = this.options.runtime.sessionQueuePauseVersion(item.sessionId);
|
|
278
281
|
const release = this.options.runtime.reserveQueueItem(itemId);
|
|
279
282
|
let attempt;
|
|
280
283
|
try {
|
|
@@ -292,23 +295,29 @@ export class ContinuousRunCoordinator {
|
|
|
292
295
|
.then(async (result) => {
|
|
293
296
|
if (result.status === 'notAccepted')
|
|
294
297
|
return false;
|
|
298
|
+
const currentPrepared = this.preparedInputs.get(itemId) ?? prepared;
|
|
295
299
|
onAccepted?.();
|
|
296
300
|
this.options.runtime.consumeSteeredQueueItem(itemId, active.id);
|
|
297
301
|
this.immediateQueueItems.delete(itemId);
|
|
298
|
-
this.
|
|
302
|
+
if (this.nativeSteerPauseCurrent(admission))
|
|
303
|
+
this.options.runtime.resumeSessionQueue(admission.sessionId);
|
|
299
304
|
this.options.clearImages(itemId);
|
|
300
|
-
if (
|
|
305
|
+
if (currentPrepared.goal !== undefined && this.goalCurrent(currentPrepared)) {
|
|
301
306
|
const current = this.preparedInputs.get(executionId);
|
|
302
307
|
if (current !== undefined)
|
|
303
|
-
this.preparedInputs.set(executionId, { ...current, goal:
|
|
308
|
+
this.preparedInputs.set(executionId, { ...current, goal: currentPrepared.goal });
|
|
304
309
|
}
|
|
305
310
|
try {
|
|
306
|
-
await this.options.afterExecutionSteered?.({
|
|
311
|
+
await this.options.afterExecutionSteered?.({
|
|
312
|
+
...currentPrepared,
|
|
313
|
+
sessionId: admission.sessionId,
|
|
314
|
+
runId: executionId
|
|
315
|
+
});
|
|
307
316
|
}
|
|
308
317
|
catch (error) {
|
|
309
318
|
nodeLog('queue.native_steer.continuation_failed', {
|
|
310
319
|
level: 'warn',
|
|
311
|
-
sessionId:
|
|
320
|
+
sessionId: admission.sessionId,
|
|
312
321
|
executionId,
|
|
313
322
|
code: safeErrorCode(error, 'NATIVE_STEER_CONTINUATION_FAILED')
|
|
314
323
|
});
|
|
@@ -320,7 +329,7 @@ export class ContinuousRunCoordinator {
|
|
|
320
329
|
if (result.status === 'accepted')
|
|
321
330
|
this.options.emitRun(executionId, 'conversation.item', result.item);
|
|
322
331
|
},
|
|
323
|
-
() => this.publish(
|
|
332
|
+
() => this.publish(admission.sessionId)
|
|
324
333
|
]) {
|
|
325
334
|
try {
|
|
326
335
|
notify();
|
|
@@ -328,7 +337,7 @@ export class ContinuousRunCoordinator {
|
|
|
328
337
|
catch {
|
|
329
338
|
nodeLog('queue.native_steer.notification_failed', {
|
|
330
339
|
level: 'warn',
|
|
331
|
-
sessionId:
|
|
340
|
+
sessionId: admission.sessionId,
|
|
332
341
|
executionId
|
|
333
342
|
});
|
|
334
343
|
}
|
|
@@ -338,10 +347,14 @@ export class ContinuousRunCoordinator {
|
|
|
338
347
|
.finally(() => {
|
|
339
348
|
release();
|
|
340
349
|
this.steerInFlight.delete(itemId);
|
|
341
|
-
this.schedule(
|
|
350
|
+
this.schedule(admission.sessionId);
|
|
342
351
|
});
|
|
343
|
-
|
|
344
|
-
|
|
352
|
+
const admission = { sessionId: item.sessionId, pauseVersion, task };
|
|
353
|
+
this.steerInFlight.set(itemId, admission);
|
|
354
|
+
return admission;
|
|
355
|
+
}
|
|
356
|
+
nativeSteerPauseCurrent(admission) {
|
|
357
|
+
return (this.options.runtime.sessionQueuePauseVersion(admission.sessionId) === admission.pauseVersion);
|
|
345
358
|
}
|
|
346
359
|
async executeQueueItemFallback(itemId) {
|
|
347
360
|
const item = this.requirePreparedItem(itemId);
|
|
@@ -669,6 +682,9 @@ export class ContinuousRunCoordinator {
|
|
|
669
682
|
for (const [id, pending] of this.preparedInputs)
|
|
670
683
|
if (pending.sessionId === previousId)
|
|
671
684
|
this.preparedInputs.set(id, { ...pending, sessionId: nextId, externalSessionId: nextId });
|
|
685
|
+
for (const admission of this.steerInFlight.values())
|
|
686
|
+
if (admission.sessionId === previousId)
|
|
687
|
+
admission.sessionId = nextId;
|
|
672
688
|
const timer = this.scheduledSessions.get(previousId);
|
|
673
689
|
if (timer !== undefined) {
|
|
674
690
|
clearTimeout(timer);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.13",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"playwright": "1.62.1",
|
|
38
38
|
"ws": "^8.21.3",
|
|
39
39
|
"zod": "4.4.3",
|
|
40
|
+
"@myagentroam/agent": "0.11.13",
|
|
40
41
|
"@myagentroam/code-navigation": "0.11.0",
|
|
41
|
-
"@myagentroam/protocol": "0.11.
|
|
42
|
-
"@myagentroam/marctl": "0.11.0"
|
|
43
|
-
"@myagentroam/agent": "0.11.11"
|
|
42
|
+
"@myagentroam/protocol": "0.11.13",
|
|
43
|
+
"@myagentroam/marctl": "0.11.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/ws": "^8.18.1"
|