@myagentroam/node 0.11.45 → 0.11.47
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/connector.js +4 -4
- package/dist/database.js +7 -5
- package/dist/marctl-guidance.js +2 -2
- package/dist/migrations/v023.js +25 -0
- package/dist/runner/abstract-runner.js +1 -1
- package/dist/runner/claude/managed-run-controller.js +1 -1
- package/dist/runner/claude-code-runner.js +1 -1
- package/dist/runner/codex/managed-run-controller.js +1 -1
- package/dist/runner/codex-runner.js +10 -5
- package/dist/runner/mar-agent/agent-network-extension.js +54 -14
- package/dist/runner/mar-agent/conversation-normalizer.js +43 -3
- package/dist/runner/mar-agent/history-projection.js +1 -1
- package/dist/runner/mar-agent/hosted-conversation-runtime.js +1 -1
- package/dist/runner/mar-agent/managed-run-controller.js +2 -2
- package/dist/runner/mar-agent-runner.js +5 -5
- package/dist/runner/opencode/managed-run-controller.js +2 -2
- package/dist/runner/opencode-runner.js +5 -5
- package/dist/runner-profiles.js +1 -1
- package/dist/runtime-state.js +7 -7
- package/dist/service/agent-network-bindings.js +8 -7
- package/dist/service/agent-network-invoke.js +9 -9
- package/dist/service/agent-network-service.js +12 -7
- package/dist/service/continuous-run-coordinator.js +1 -1
- package/dist/service/external-session-resume-service.js +1 -1
- package/dist/service/goal-continuation-coordinator.js +3 -3
- package/dist/service/native-session-watch-service.js +6 -3
- package/dist/service/planned-restart-handoff.js +24 -5
- package/dist/service/restart-session-restorer.js +2 -2
- package/dist/service/session-recent-activity.js +1 -1
- package/dist/session/native-session-projection-service.js +39 -30
- package/dist/session/session-catalog-service.js +116 -90
- package/dist/session/session-command-service.js +1 -0
- package/dist/session/session-context-service.js +1 -1
- package/dist/session/session-lifecycle-service.js +12 -10
- package/dist/session/session-message-service.js +4 -3
- package/dist/workspace/workspace-session-service.js +1 -1
- package/package.json +4 -4
|
@@ -187,7 +187,7 @@ export class SessionCatalogService {
|
|
|
187
187
|
nativeControl: 'EXTERNAL',
|
|
188
188
|
channelToken: null,
|
|
189
189
|
cwd: workspace.path,
|
|
190
|
-
|
|
190
|
+
modelId: persisted.metadata.modelId,
|
|
191
191
|
effort: persisted.metadata.effort,
|
|
192
192
|
access: persisted.metadata.access,
|
|
193
193
|
customTitle: persisted.metadata.customTitle,
|
|
@@ -283,7 +283,7 @@ export class SessionCatalogService {
|
|
|
283
283
|
cwd,
|
|
284
284
|
nativeControl: 'MAR_MANAGED',
|
|
285
285
|
...(nativeId === null ? {} : { externalSessionId: nativeId }),
|
|
286
|
-
...(source.
|
|
286
|
+
...(source.modelId === null ? {} : { modelId: source.modelId }),
|
|
287
287
|
...(source.effort === null ? {} : { effort: source.effort }),
|
|
288
288
|
...(source.access === null ? {} : { access: source.access }),
|
|
289
289
|
title
|
|
@@ -322,7 +322,7 @@ export class SessionCatalogService {
|
|
|
322
322
|
this.options.invalidateWorkspaceSessions(session.workspaceId);
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
|
-
async removeTree(root) {
|
|
325
|
+
async removeTree(root, cleanup) {
|
|
326
326
|
if (root.externalSessionId === null)
|
|
327
327
|
throw new Error('NATIVE_TRANSCRIPT_UNAVAILABLE');
|
|
328
328
|
const database = this.options.database();
|
|
@@ -340,13 +340,20 @@ export class SessionCatalogService {
|
|
|
340
340
|
const ids = [root.externalSessionId];
|
|
341
341
|
const seen = new Set(ids);
|
|
342
342
|
const parents = new Map();
|
|
343
|
+
const settle = (session, deleted) => {
|
|
344
|
+
if (cleanup === undefined)
|
|
345
|
+
return;
|
|
346
|
+
database.deleteSessionRecord(session.id);
|
|
347
|
+
this.options.forget(session, this.options.nativeIds(session));
|
|
348
|
+
cleanup.settled(session, deleted);
|
|
349
|
+
};
|
|
343
350
|
const releases = [];
|
|
344
351
|
const locked = new Set();
|
|
345
352
|
const lock = (id) => {
|
|
346
353
|
const actual = this.options.runtime.getAgentSession(id)?.id ?? id;
|
|
347
354
|
if (locked.has(actual))
|
|
348
355
|
return;
|
|
349
|
-
releases.push(this.options.runtime.beginSessionHistoryMutation(actual, { allowQueued: true }));
|
|
356
|
+
releases.push(this.options.runtime.beginSessionHistoryMutation(actual, cleanup !== undefined && actual === root.id ? undefined : { allowQueued: true }));
|
|
350
357
|
locked.add(actual);
|
|
351
358
|
};
|
|
352
359
|
try {
|
|
@@ -355,6 +362,9 @@ export class SessionCatalogService {
|
|
|
355
362
|
const parent = ids[index];
|
|
356
363
|
const children = [
|
|
357
364
|
...database.listChildSessionRecords(root.workspaceId, parent).map((record) => record.id),
|
|
365
|
+
...(cleanup?.children.get(parent) ?? [])
|
|
366
|
+
.filter((session) => cleanup?.candidates.has(session.id))
|
|
367
|
+
.map((session) => session.externalSessionId ?? session.id),
|
|
358
368
|
...(liveChildren.get(parent) ?? [])
|
|
359
369
|
];
|
|
360
370
|
for (const child of children) {
|
|
@@ -371,35 +381,64 @@ export class SessionCatalogService {
|
|
|
371
381
|
}
|
|
372
382
|
const sessions = [];
|
|
373
383
|
for (const id of ids) {
|
|
374
|
-
const session =
|
|
384
|
+
const session = cleanup?.candidates.get(id) ??
|
|
385
|
+
this.options.runtime.getAgentSession(id) ??
|
|
375
386
|
(await this.options.projection.resolve(id, true));
|
|
376
387
|
if (session === undefined || session.workspaceId !== root.workspaceId)
|
|
377
388
|
throw new Error('SESSION_NOT_FOUND');
|
|
378
389
|
sessions.push(session);
|
|
379
390
|
}
|
|
380
391
|
// Validate every member before performing any irreversible native deletion.
|
|
381
|
-
for (const session of sessions)
|
|
382
|
-
|
|
383
|
-
|
|
392
|
+
for (const session of sessions) {
|
|
393
|
+
const missing = cleanup !== undefined && session.externalDiscovered === false;
|
|
394
|
+
if (missing && !this.options.runnerAvailable(session.runner))
|
|
395
|
+
throw new Error('NATIVE_TRANSCRIPT_UNAVAILABLE');
|
|
396
|
+
await this.assertRemovable(session, cleanup?.budget, missing);
|
|
397
|
+
}
|
|
398
|
+
if (cleanup !== undefined && this.cleanupRootProtected(root, cleanup.cutoff)) {
|
|
399
|
+
throw new Error('SESSION_WATCHING');
|
|
400
|
+
}
|
|
401
|
+
let batch = [];
|
|
402
|
+
const flushBatch = async () => {
|
|
403
|
+
if (batch.length === 0)
|
|
404
|
+
return;
|
|
405
|
+
cleanup?.budget.check();
|
|
406
|
+
await this.options.runners.require(batch[0].runner).removeNativeMembers(batch);
|
|
407
|
+
for (const session of batch)
|
|
408
|
+
settle(session, true);
|
|
409
|
+
batch = [];
|
|
410
|
+
};
|
|
384
411
|
for (const session of [...sessions].reverse()) {
|
|
412
|
+
if (cleanup !== undefined &&
|
|
413
|
+
(session.externalSessionId === null || session.externalDiscovered === false)) {
|
|
414
|
+
await flushBatch();
|
|
415
|
+
cleanup.budget.check();
|
|
416
|
+
settle(session, true);
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
385
419
|
if (session.externalSessionId === null)
|
|
386
420
|
continue;
|
|
387
421
|
const runner = this.options.runners.require(session.runner);
|
|
388
422
|
if (runner.supportsNativeBatchRemoval?.() === true) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
423
|
+
if (batch.length > 0 && batch[0].runner !== session.runner)
|
|
424
|
+
await flushBatch();
|
|
425
|
+
batch.push(session);
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
// Preserve descendant-first order across batch and non-batch native owners.
|
|
429
|
+
await flushBatch();
|
|
430
|
+
cleanup?.budget.check();
|
|
431
|
+
const deleted = await this.removeNativeHistories(session, this.options.nativeIds(session));
|
|
432
|
+
settle(session, deleted);
|
|
392
433
|
}
|
|
393
|
-
else
|
|
394
|
-
await this.removeNativeHistories(session, this.options.nativeIds(session));
|
|
395
434
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
435
|
+
await flushBatch();
|
|
436
|
+
// Manual deletion preserves all relationships if any native owner fails.
|
|
437
|
+
if (cleanup === undefined) {
|
|
438
|
+
for (const session of sessions.reverse()) {
|
|
439
|
+
this.options.database().deleteSessionRecord(session.id);
|
|
440
|
+
this.options.forget(session, this.options.nativeIds(session));
|
|
441
|
+
}
|
|
403
442
|
}
|
|
404
443
|
}
|
|
405
444
|
finally {
|
|
@@ -443,6 +482,7 @@ export class SessionCatalogService {
|
|
|
443
482
|
let deleted = 0;
|
|
444
483
|
let skipped = 0;
|
|
445
484
|
let failed = 0;
|
|
485
|
+
const outcomes = new Map();
|
|
446
486
|
const deletedByRunner = {};
|
|
447
487
|
let candidateCount;
|
|
448
488
|
let timedOut = false;
|
|
@@ -458,7 +498,14 @@ export class SessionCatalogService {
|
|
|
458
498
|
candidates.set(session.id, session);
|
|
459
499
|
}
|
|
460
500
|
this.mergePersisted(candidates, workspaceId, false);
|
|
461
|
-
const
|
|
501
|
+
const children = new Map();
|
|
502
|
+
for (const candidate of candidates.values()) {
|
|
503
|
+
if (candidate.parentSessionId == null)
|
|
504
|
+
continue;
|
|
505
|
+
const siblings = children.get(candidate.parentSessionId) ?? [];
|
|
506
|
+
siblings.push(candidate);
|
|
507
|
+
children.set(candidate.parentSessionId, siblings);
|
|
508
|
+
}
|
|
462
509
|
candidateCount = candidates.size;
|
|
463
510
|
for (const session of candidates.values()) {
|
|
464
511
|
budget.check();
|
|
@@ -472,14 +519,6 @@ export class SessionCatalogService {
|
|
|
472
519
|
session.lastActivityAt > 0 &&
|
|
473
520
|
session.lastActivityAt >= cutoff) ||
|
|
474
521
|
(session.pinOrder !== null && session.pinOrder !== undefined) ||
|
|
475
|
-
(session.externalSessionId !== null &&
|
|
476
|
-
(this.options.database().listChildSessionRecords(workspaceId, session.externalSessionId)
|
|
477
|
-
.length > 0 ||
|
|
478
|
-
candidateParents.has(session.externalSessionId) ||
|
|
479
|
-
this.options.runtime
|
|
480
|
-
.listAgentSessions()
|
|
481
|
-
.some((child) => child.workspaceId === workspaceId &&
|
|
482
|
-
child.parentSessionId === session.externalSessionId))) ||
|
|
483
522
|
this.options.isWatching(session.id) ||
|
|
484
523
|
this.options.isRecovering?.(session.id) ||
|
|
485
524
|
this.options.runtime.sessionQueue(session.id).itemIds.length > 0 ||
|
|
@@ -487,24 +526,31 @@ export class SessionCatalogService {
|
|
|
487
526
|
.listRunsForSession(session.id)
|
|
488
527
|
.some((run) => !isTerminalRunStatus(run.status)) ||
|
|
489
528
|
this.options.externalActivity(session.id) === 'BUSY') {
|
|
490
|
-
skipped
|
|
529
|
+
outcomes.set(session.id, { session, status: 'skipped' });
|
|
491
530
|
continue;
|
|
492
531
|
}
|
|
493
532
|
try {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
533
|
+
await this.removeTree(session, {
|
|
534
|
+
candidates,
|
|
535
|
+
children,
|
|
536
|
+
cutoff,
|
|
537
|
+
budget,
|
|
538
|
+
settled: (member, wasDeleted) => {
|
|
539
|
+
candidates.delete(member.id);
|
|
540
|
+
outcomes.set(member.id, {
|
|
541
|
+
session: member,
|
|
542
|
+
status: wasDeleted ? 'deleted' : 'skipped'
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
});
|
|
500
546
|
}
|
|
501
547
|
catch (error) {
|
|
502
548
|
if (error instanceof WorkspaceSessionCleanupDeadline)
|
|
503
549
|
throw error;
|
|
504
550
|
if (isCleanupSkip(error))
|
|
505
|
-
skipped
|
|
551
|
+
outcomes.set(session.id, { session, status: 'skipped' });
|
|
506
552
|
else {
|
|
507
|
-
failed
|
|
553
|
+
outcomes.set(session.id, { session, status: 'failed' });
|
|
508
554
|
nodeLog('workspace.session.cleanup.failed', {
|
|
509
555
|
workspaceId,
|
|
510
556
|
sessionId: session.id,
|
|
@@ -514,6 +560,7 @@ export class SessionCatalogService {
|
|
|
514
560
|
}
|
|
515
561
|
}
|
|
516
562
|
}
|
|
563
|
+
budget.check();
|
|
517
564
|
}
|
|
518
565
|
catch (error) {
|
|
519
566
|
if (!(error instanceof WorkspaceSessionCleanupDeadline))
|
|
@@ -525,6 +572,16 @@ export class SessionCatalogService {
|
|
|
525
572
|
finally {
|
|
526
573
|
this.options.invalidateWorkspaceSessions(workspaceId);
|
|
527
574
|
}
|
|
575
|
+
for (const { session, status } of outcomes.values()) {
|
|
576
|
+
if (status === 'deleted') {
|
|
577
|
+
deleted += 1;
|
|
578
|
+
deletedByRunner[session.runner] = (deletedByRunner[session.runner] ?? 0) + 1;
|
|
579
|
+
}
|
|
580
|
+
else if (status === 'skipped')
|
|
581
|
+
skipped += 1;
|
|
582
|
+
else
|
|
583
|
+
failed += 1;
|
|
584
|
+
}
|
|
528
585
|
const result = {
|
|
529
586
|
deleted,
|
|
530
587
|
skipped,
|
|
@@ -535,7 +592,7 @@ export class SessionCatalogService {
|
|
|
535
592
|
timedOut: true,
|
|
536
593
|
...(candidateCount === undefined
|
|
537
594
|
? {}
|
|
538
|
-
: { remaining: candidateCount -
|
|
595
|
+
: { remaining: Math.max(0, candidateCount - outcomes.size) })
|
|
539
596
|
}
|
|
540
597
|
: {})
|
|
541
598
|
};
|
|
@@ -559,15 +616,16 @@ export class SessionCatalogService {
|
|
|
559
616
|
lastActivityAt: latestSessionActivityAt(projected.lastActivityAt, native.lastActivityAt)
|
|
560
617
|
};
|
|
561
618
|
}
|
|
562
|
-
async assertRemovable(session) {
|
|
619
|
+
async assertRemovable(session, budget, missing = false) {
|
|
563
620
|
if (this.options.isRecovering?.(session.id))
|
|
564
621
|
throw new Error('SESSION_RESTART_PENDING');
|
|
565
622
|
if (this.options.runtime
|
|
566
623
|
.listRunsForSession(session.id)
|
|
567
624
|
.some((run) => !isTerminalRunStatus(run.status)))
|
|
568
625
|
throw new Error('SESSION_ACTIVE');
|
|
569
|
-
if (session.externalSessionId !== null && session.nativeControl === 'EXTERNAL') {
|
|
570
|
-
|
|
626
|
+
if (!missing && session.externalSessionId !== null && session.nativeControl === 'EXTERNAL') {
|
|
627
|
+
const refresh = () => this.options.refreshActivity(session);
|
|
628
|
+
await (budget ? budget.read(refresh) : refresh());
|
|
571
629
|
if (this.options.externalActivity(session.id) === 'BUSY')
|
|
572
630
|
throw new Error('SESSION_ACTIVE');
|
|
573
631
|
}
|
|
@@ -592,55 +650,22 @@ export class SessionCatalogService {
|
|
|
592
650
|
}
|
|
593
651
|
return deleted;
|
|
594
652
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
653
|
+
cleanupRootProtected(session, cutoff) {
|
|
654
|
+
// Pin updates and Watch admission do not share the history mutation queue.
|
|
655
|
+
const pinOrder = session.externalSessionId === null
|
|
656
|
+
? undefined
|
|
657
|
+
: this.options
|
|
658
|
+
.database()
|
|
659
|
+
.getNativeSessionMetadata(session.runner, session.externalSessionId, session.workspaceId)?.pinOrder;
|
|
660
|
+
return ((session.externalDiscovered !== false &&
|
|
661
|
+
latestSessionActivityAt(session.lastActivityAt, this.options.runtime.getAgentSession(session.id)?.lastActivityAt ?? 0) >= cutoff) ||
|
|
662
|
+
(pinOrder !== undefined && pinOrder !== null) ||
|
|
663
|
+
this.options.isWatching(session.id) ||
|
|
664
|
+
this.options.isRecovering?.(session.id) === true ||
|
|
665
|
+
this.options.runtime.sessionQueue(session.id).itemIds.length > 0 ||
|
|
666
|
+
this.options.runtime
|
|
604
667
|
.listRunsForSession(session.id)
|
|
605
|
-
.some((run) => !isTerminalRunStatus(run.status)))
|
|
606
|
-
throw new Error('SESSION_ACTIVE');
|
|
607
|
-
if (session.nativeControl === 'EXTERNAL' && !missingCandidate) {
|
|
608
|
-
const refresh = () => this.options.refreshActivity(session);
|
|
609
|
-
await (budget ? budget.read(refresh) : refresh());
|
|
610
|
-
if (this.options.externalActivity(session.id) === 'BUSY')
|
|
611
|
-
throw new Error('SESSION_ACTIVE');
|
|
612
|
-
}
|
|
613
|
-
if (requireCleanupSafety) {
|
|
614
|
-
if (this.options.isWatching(session.id))
|
|
615
|
-
throw new Error('SESSION_WATCHING');
|
|
616
|
-
if (this.options.runtime.sessionQueue(session.id).itemIds.length > 0)
|
|
617
|
-
throw new Error('SESSION_QUEUE_NOT_EMPTY');
|
|
618
|
-
// Pin updates do not share the cleanup mutation queue.
|
|
619
|
-
const pinOrder = this.options
|
|
620
|
-
.database()
|
|
621
|
-
.getNativeSessionMetadata(session.runner, session.externalSessionId, session.workspaceId)?.pinOrder;
|
|
622
|
-
if (pinOrder !== undefined && pinOrder !== null)
|
|
623
|
-
return 'skipped';
|
|
624
|
-
if (this.options.runtime
|
|
625
|
-
.listRunsForSession(session.id)
|
|
626
|
-
.some((run) => !isTerminalRunStatus(run.status)))
|
|
627
|
-
throw new Error('SESSION_ACTIVE');
|
|
628
|
-
}
|
|
629
|
-
budget?.check();
|
|
630
|
-
const nativeIds = this.options.nativeIds(session);
|
|
631
|
-
if (missingCandidate) {
|
|
632
|
-
this.options.database().deleteSessionRecord(session.id);
|
|
633
|
-
this.options.forget(session, nativeIds);
|
|
634
|
-
return 'deleted';
|
|
635
|
-
}
|
|
636
|
-
const deleted = await this.removeNativeHistories(session, nativeIds);
|
|
637
|
-
this.options.database().deleteSessionRecord(session.id);
|
|
638
|
-
this.options.forget(session, nativeIds);
|
|
639
|
-
return deleted ? 'deleted' : 'skipped';
|
|
640
|
-
}
|
|
641
|
-
finally {
|
|
642
|
-
releaseMutation();
|
|
643
|
-
}
|
|
668
|
+
.some((run) => !isTerminalRunStatus(run.status)));
|
|
644
669
|
}
|
|
645
670
|
}
|
|
646
671
|
export function rewindTitle(sourceTitle, existingTitles = []) {
|
|
@@ -674,6 +699,7 @@ function deduplicateNativeSessions(sessions) {
|
|
|
674
699
|
function isCleanupSkip(error) {
|
|
675
700
|
return (error instanceof Error &&
|
|
676
701
|
(error.message === 'SESSION_ACTIVE' ||
|
|
702
|
+
error.message === 'SESSION_RESTART_PENDING' ||
|
|
677
703
|
error.message === 'SESSION_NOT_FOUND' ||
|
|
678
704
|
error.message === 'SESSION_QUEUE_NOT_EMPTY' ||
|
|
679
705
|
error.message === 'SESSION_WATCHING' ||
|
|
@@ -31,6 +31,7 @@ export class SessionCommandService {
|
|
|
31
31
|
}
|
|
32
32
|
async sessionCommand(input) {
|
|
33
33
|
if (typeof input.sessionId !== 'string' ||
|
|
34
|
+
Object.hasOwn(input, 'model') ||
|
|
34
35
|
typeof input.commandId !== 'string' ||
|
|
35
36
|
input.commandId.length === 0 ||
|
|
36
37
|
typeof input.input !== 'string' ||
|
|
@@ -20,7 +20,7 @@ export class SessionContextService {
|
|
|
20
20
|
return { context: null, pending: false };
|
|
21
21
|
}
|
|
22
22
|
const context = {
|
|
23
|
-
model: usage.model ?? session.
|
|
23
|
+
model: usage.model ?? session.modelId,
|
|
24
24
|
usedTokens: usage.usedTokens,
|
|
25
25
|
maxTokens: usage.maxTokens,
|
|
26
26
|
percentage: Math.round((usage.usedTokens / usage.maxTokens) * 1000) / 10
|
|
@@ -120,7 +120,8 @@ export class SessionLifecycleService {
|
|
|
120
120
|
(input.externalSessionId !== undefined && typeof input.externalSessionId !== 'string') ||
|
|
121
121
|
!validSessionTitle(input.title) ||
|
|
122
122
|
!validSessionTitle(input.customTitle) ||
|
|
123
|
-
|
|
123
|
+
Object.hasOwn(input, 'model') ||
|
|
124
|
+
!validSessionOption(input.modelId) ||
|
|
124
125
|
!validSessionEffort(input.effort) ||
|
|
125
126
|
!validSessionOption(input.access))
|
|
126
127
|
throw new Error('SESSION_INVALID');
|
|
@@ -172,7 +173,7 @@ export class SessionLifecycleService {
|
|
|
172
173
|
const fallback = runner.defaultConfiguration(workspace, environment, executionContext);
|
|
173
174
|
const configuration = {
|
|
174
175
|
runner: runner.name,
|
|
175
|
-
|
|
176
|
+
modelId: typeof input.modelId === 'string' ? input.modelId : (saved?.modelId ?? fallback.modelId),
|
|
176
177
|
effort: typeof input.effort === 'string' ? input.effort : (saved?.effort ?? fallback.effort),
|
|
177
178
|
access: typeof input.access === 'string'
|
|
178
179
|
? input.access
|
|
@@ -183,7 +184,7 @@ export class SessionLifecycleService {
|
|
|
183
184
|
if (runner.name === 'mar-agent' && !['auto', 'full-access'].includes(configuration.access))
|
|
184
185
|
throw new Error('SESSION_INVALID');
|
|
185
186
|
if (parentSessionId !== undefined)
|
|
186
|
-
runner.assertChildModel(configuration.
|
|
187
|
+
runner.assertChildModel(configuration.modelId, executionContext);
|
|
187
188
|
const session = this.options.runtime.createAgentSession({
|
|
188
189
|
...(parentSessionId === undefined ? {} : { parentSessionId }),
|
|
189
190
|
workspaceId: input.workspaceId,
|
|
@@ -192,7 +193,7 @@ export class SessionLifecycleService {
|
|
|
192
193
|
...(typeof input.externalSessionId === 'string'
|
|
193
194
|
? { externalSessionId: input.externalSessionId }
|
|
194
195
|
: {}),
|
|
195
|
-
|
|
196
|
+
modelId: configuration.modelId,
|
|
196
197
|
effort: configuration.effort,
|
|
197
198
|
access: configuration.access,
|
|
198
199
|
...(typeof input.title === 'string' ? { title: input.title } : {}),
|
|
@@ -208,8 +209,9 @@ export class SessionLifecycleService {
|
|
|
208
209
|
}
|
|
209
210
|
async updateConfiguration(input) {
|
|
210
211
|
if (typeof input.sessionId !== 'string' ||
|
|
211
|
-
(input.
|
|
212
|
-
|
|
212
|
+
(input.modelId === undefined && input.effort === undefined && input.access === undefined) ||
|
|
213
|
+
Object.hasOwn(input, 'model') ||
|
|
214
|
+
!validSessionOption(input.modelId) ||
|
|
213
215
|
!validSessionEffort(input.effort) ||
|
|
214
216
|
!validSessionOption(input.access))
|
|
215
217
|
throw new Error('SESSION_INVALID');
|
|
@@ -222,13 +224,13 @@ export class SessionLifecycleService {
|
|
|
222
224
|
input.access !== undefined &&
|
|
223
225
|
!['auto', 'full-access'].includes(input.access))
|
|
224
226
|
throw new Error('SESSION_INVALID');
|
|
225
|
-
if (current.parentSessionId != null && typeof input.
|
|
227
|
+
if (current.parentSessionId != null && typeof input.modelId === 'string') {
|
|
226
228
|
const runner = this.options.runners.require(current.runner);
|
|
227
|
-
runner.assertChildModel(input.
|
|
229
|
+
runner.assertChildModel(input.modelId, runner.prepareExecutionContext(input));
|
|
228
230
|
}
|
|
229
231
|
const session = this.options.runtime.updateAgentSessionConfiguration({
|
|
230
232
|
sessionId: current.id,
|
|
231
|
-
...(typeof input.
|
|
233
|
+
...(typeof input.modelId === 'string' ? { modelId: input.modelId } : {}),
|
|
232
234
|
...(typeof input.effort === 'string' ? { effort: input.effort } : {}),
|
|
233
235
|
...(typeof input.access === 'string' ? { access: input.access } : {})
|
|
234
236
|
});
|
|
@@ -237,7 +239,7 @@ export class SessionLifecycleService {
|
|
|
237
239
|
runner: session.runner,
|
|
238
240
|
externalSessionId: session.externalSessionId,
|
|
239
241
|
workspaceId: session.workspaceId,
|
|
240
|
-
|
|
242
|
+
modelId: session.modelId,
|
|
241
243
|
effort: session.effort,
|
|
242
244
|
access: session.access
|
|
243
245
|
});
|
|
@@ -91,7 +91,8 @@ export class SessionMessageService {
|
|
|
91
91
|
}
|
|
92
92
|
async prepareMessage(input) {
|
|
93
93
|
checkSessionAdmission(input);
|
|
94
|
-
if (
|
|
94
|
+
if (Object.hasOwn(input, 'model') ||
|
|
95
|
+
typeof input.sessionId !== 'string' ||
|
|
95
96
|
typeof input.clientMessageId !== 'string' ||
|
|
96
97
|
input.clientMessageId.length === 0 ||
|
|
97
98
|
typeof input.content !== 'string' ||
|
|
@@ -148,7 +149,7 @@ export class SessionMessageService {
|
|
|
148
149
|
if (session.parentSessionId != null)
|
|
149
150
|
this.options.runners
|
|
150
151
|
.require(session.runner)
|
|
151
|
-
.assertChildModel(session.
|
|
152
|
+
.assertChildModel(session.modelId, executionContext);
|
|
152
153
|
const sourceContent = withSessionMessageOrigin(content, input.__marctlOrigin, session.parentSessionId);
|
|
153
154
|
const goalMessage = internalGoal || internalSchedule || internalRestore
|
|
154
155
|
? undefined
|
|
@@ -296,7 +297,7 @@ export class SessionMessageService {
|
|
|
296
297
|
cwd,
|
|
297
298
|
workspacePath,
|
|
298
299
|
externalSessionId: currentSession.externalSessionId,
|
|
299
|
-
|
|
300
|
+
modelId: currentSession.modelId,
|
|
300
301
|
effort: currentSession.effort,
|
|
301
302
|
access: currentSession.access,
|
|
302
303
|
collaborationMode: planActive ? 'plan' : 'default',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.47",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"sharp": "0.35.5",
|
|
39
39
|
"ws": "^8.21.3",
|
|
40
40
|
"zod": "4.4.3",
|
|
41
|
-
"@myagentroam/agent": "0.11.45",
|
|
42
41
|
"@myagentroam/code-navigation": "0.11.1",
|
|
43
|
-
"@myagentroam/marctl": "0.11.
|
|
44
|
-
"@myagentroam/
|
|
42
|
+
"@myagentroam/marctl": "0.11.8",
|
|
43
|
+
"@myagentroam/agent": "0.11.47",
|
|
44
|
+
"@myagentroam/protocol": "0.11.47"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/ws": "^8.18.1"
|