@myagentroam/node 0.9.125 → 0.9.126
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/codex-app-server.js +30 -0
- package/dist/runner/codex-runner.js +32 -39
- package/package.json +4 -4
package/dist/codex-app-server.js
CHANGED
|
@@ -139,6 +139,36 @@ export class CodexAppServerClient {
|
|
|
139
139
|
this.lifecycleRevision += 1;
|
|
140
140
|
this.stopManaged();
|
|
141
141
|
}
|
|
142
|
+
async stopAndWait() {
|
|
143
|
+
const child = this.child;
|
|
144
|
+
if (child === undefined) {
|
|
145
|
+
this.stop();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const exited = new Promise((resolve, reject) => {
|
|
149
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
150
|
+
resolve();
|
|
151
|
+
else {
|
|
152
|
+
let forcedTimeout;
|
|
153
|
+
const onExit = () => {
|
|
154
|
+
clearTimeout(timeout);
|
|
155
|
+
if (forcedTimeout !== undefined)
|
|
156
|
+
clearTimeout(forcedTimeout);
|
|
157
|
+
resolve();
|
|
158
|
+
};
|
|
159
|
+
const timeout = setTimeout(() => {
|
|
160
|
+
child.kill('SIGKILL');
|
|
161
|
+
forcedTimeout = setTimeout(() => {
|
|
162
|
+
child.off('exit', onExit);
|
|
163
|
+
reject(new Error('CODEX_APP_SERVER_STOP_TIMEOUT'));
|
|
164
|
+
}, 2_000);
|
|
165
|
+
}, 2_000);
|
|
166
|
+
child.once('exit', onExit);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
this.stop();
|
|
170
|
+
await exited;
|
|
171
|
+
}
|
|
142
172
|
stopManaged() {
|
|
143
173
|
this.transport?.destroy();
|
|
144
174
|
this.transport = undefined;
|
|
@@ -3,7 +3,6 @@ import { AbstractRunner } from './abstract-runner.js';
|
|
|
3
3
|
import { declaredRunnerProfiles } from '../runner-profiles.js';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { resolve } from 'node:path';
|
|
6
|
-
import { createHash } from 'node:crypto';
|
|
7
6
|
import { discoverAllNativeSessions } from '../native-session-history.js';
|
|
8
7
|
import { readCodexNativeContextUsage } from '../native-session-history.js';
|
|
9
8
|
import { codexThreadCwd, deduplicateDirectSessions, extractCodexThreads, isWithinWorkspace, latestNativeActivity } from './codex/conversation-parser.js';
|
|
@@ -20,7 +19,6 @@ export class CodexRunner extends AbstractRunner {
|
|
|
20
19
|
discoveryScope = 'ALL_WORKSPACES';
|
|
21
20
|
execution = new CodexExecutionState();
|
|
22
21
|
fastEnabled = false;
|
|
23
|
-
environmentClients = new Map();
|
|
24
22
|
runClients = new Map();
|
|
25
23
|
notificationListeners = new Set();
|
|
26
24
|
clientNotificationDisposers = new Map();
|
|
@@ -318,13 +316,14 @@ export class CodexRunner extends AbstractRunner {
|
|
|
318
316
|
return this.profileCache;
|
|
319
317
|
}
|
|
320
318
|
async resumeExternal(external, context) {
|
|
319
|
+
const threadId = external.externalSessionId;
|
|
321
320
|
if (external.runner !== this.name ||
|
|
322
321
|
external.nativeControl !== 'EXTERNAL' ||
|
|
323
|
-
|
|
322
|
+
threadId === null ||
|
|
324
323
|
!context.available)
|
|
325
324
|
return { failureCode: 'RUNNER_UNAVAILABLE' };
|
|
326
325
|
try {
|
|
327
|
-
await this.resumeThread(
|
|
326
|
+
await this.withTemporaryClient((client) => client.resumeThread(threadId, external.cwd));
|
|
328
327
|
const projection = context.projectionFor(external);
|
|
329
328
|
if (projection !== undefined) {
|
|
330
329
|
const promoted = context.promote(projection.id);
|
|
@@ -437,7 +436,7 @@ export class CodexRunner extends AbstractRunner {
|
|
|
437
436
|
onNotification(listener) {
|
|
438
437
|
this.notificationListeners.add(listener);
|
|
439
438
|
this.attachNotifications(this.client);
|
|
440
|
-
for (const
|
|
439
|
+
for (const client of this.runClients.values())
|
|
441
440
|
this.attachNotifications(client);
|
|
442
441
|
return () => this.notificationListeners.delete(listener);
|
|
443
442
|
}
|
|
@@ -459,8 +458,7 @@ export class CodexRunner extends AbstractRunner {
|
|
|
459
458
|
if (!isCodexRolloutMissingError(error))
|
|
460
459
|
return false;
|
|
461
460
|
const client = this.clientFor(runId);
|
|
462
|
-
|
|
463
|
-
if (entry !== undefined && [...entry.runIds].some((activeRunId) => activeRunId !== runId))
|
|
461
|
+
if ([...this.runClients].some(([activeRunId, activeClient]) => activeRunId !== runId && activeClient === client))
|
|
464
462
|
return false;
|
|
465
463
|
if ([...this.execution.runs].some(([activeRunId]) => activeRunId !== runId && this.runClients.get(activeRunId) === client))
|
|
466
464
|
return false;
|
|
@@ -469,20 +467,12 @@ export class CodexRunner extends AbstractRunner {
|
|
|
469
467
|
return true;
|
|
470
468
|
}
|
|
471
469
|
prepareEnvironment(environment, runId) {
|
|
472
|
-
|
|
473
|
-
.update(JSON.stringify(Object.entries(environment).sort(([left], [right]) => left.localeCompare(right))))
|
|
474
|
-
.digest('base64url');
|
|
475
|
-
const existing = this.environmentClients.get(fingerprint);
|
|
476
|
-
if (existing !== undefined) {
|
|
477
|
-
existing.runIds.add(runId);
|
|
478
|
-
this.runClients.set(runId, existing.client);
|
|
470
|
+
if (this.runClients.has(runId))
|
|
479
471
|
return;
|
|
480
|
-
}
|
|
481
472
|
const client = this.runClientFactory();
|
|
482
473
|
if (Object.keys(environment).length > 0)
|
|
483
474
|
client.configureEnvironment(environment);
|
|
484
475
|
this.attachNotifications(client);
|
|
485
|
-
this.environmentClients.set(fingerprint, { client, runIds: new Set([runId]) });
|
|
486
476
|
this.runClients.set(runId, client);
|
|
487
477
|
}
|
|
488
478
|
releaseEnvironment(runId) {
|
|
@@ -490,19 +480,10 @@ export class CodexRunner extends AbstractRunner {
|
|
|
490
480
|
if (client === undefined)
|
|
491
481
|
return;
|
|
492
482
|
this.runClients.delete(runId);
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if (entry.runIds.size === 0) {
|
|
498
|
-
this.environmentClients.delete(fingerprint);
|
|
499
|
-
if (client !== this.client) {
|
|
500
|
-
this.detachNotifications(client);
|
|
501
|
-
client.stop();
|
|
502
|
-
client.clearEnvironment();
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
return;
|
|
483
|
+
if (client !== this.client && ![...this.runClients.values()].includes(client)) {
|
|
484
|
+
this.detachNotifications(client);
|
|
485
|
+
client.stop();
|
|
486
|
+
client.clearEnvironment();
|
|
506
487
|
}
|
|
507
488
|
}
|
|
508
489
|
stop() {
|
|
@@ -510,13 +491,12 @@ export class CodexRunner extends AbstractRunner {
|
|
|
510
491
|
for (const profileClient of this.profileClients)
|
|
511
492
|
profileClient.stop();
|
|
512
493
|
this.profileClients.clear();
|
|
513
|
-
for (const
|
|
494
|
+
for (const client of new Set(this.runClients.values()))
|
|
514
495
|
if (client !== this.client) {
|
|
515
496
|
this.detachNotifications(client);
|
|
516
497
|
client.stop();
|
|
517
498
|
client.clearEnvironment();
|
|
518
499
|
}
|
|
519
|
-
this.environmentClients.clear();
|
|
520
500
|
this.runClients.clear();
|
|
521
501
|
this.client.stop();
|
|
522
502
|
if (this.profileCacheTimer !== undefined)
|
|
@@ -530,6 +510,17 @@ export class CodexRunner extends AbstractRunner {
|
|
|
530
510
|
clientFor(runId) {
|
|
531
511
|
return runId === undefined ? this.client : (this.runClients.get(runId) ?? this.client);
|
|
532
512
|
}
|
|
513
|
+
async withTemporaryClient(operation) {
|
|
514
|
+
const client = this.runClientFactory();
|
|
515
|
+
try {
|
|
516
|
+
await client.start();
|
|
517
|
+
return await operation(client);
|
|
518
|
+
}
|
|
519
|
+
finally {
|
|
520
|
+
if (client !== this.client)
|
|
521
|
+
await client.stopAndWait();
|
|
522
|
+
}
|
|
523
|
+
}
|
|
533
524
|
attachNotifications(client) {
|
|
534
525
|
if (this.clientNotificationDisposers.has(client))
|
|
535
526
|
return;
|
|
@@ -558,16 +549,18 @@ export class CodexRunner extends AbstractRunner {
|
|
|
558
549
|
return this.client.forkThread(threadId, cwd, lastTurnId, configuration);
|
|
559
550
|
}
|
|
560
551
|
async forkNative(session, boundary, title) {
|
|
561
|
-
|
|
552
|
+
const threadId = session.externalSessionId;
|
|
553
|
+
if (threadId === null)
|
|
562
554
|
throw new Error('SESSION_REWIND_UNAVAILABLE');
|
|
563
|
-
await this.start();
|
|
564
555
|
const configuration = { model: session.model, effort: session.effort, access: session.access };
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
556
|
+
return this.withTemporaryClient(async (client) => {
|
|
557
|
+
const result = boundary === null
|
|
558
|
+
? await client.startThread(session.cwd, configuration)
|
|
559
|
+
: await client.forkThread(threadId, session.cwd, boundary, configuration);
|
|
560
|
+
const forkedThreadId = extractId(result, 'thread');
|
|
561
|
+
await client.setThreadName(forkedThreadId, title);
|
|
562
|
+
return forkedThreadId;
|
|
563
|
+
});
|
|
571
564
|
}
|
|
572
565
|
resumeThread(threadId, cwd, configuration, runId) {
|
|
573
566
|
return this.clientFor(runId).resumeThread(threadId, cwd, configuration);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.126",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"npm": "11.12.1",
|
|
31
31
|
"ws": "^8.21.3",
|
|
32
32
|
"zod": "4.4.3",
|
|
33
|
-
"@myagentroam/agent": "0.9.
|
|
34
|
-
"@myagentroam/
|
|
35
|
-
"@myagentroam/
|
|
33
|
+
"@myagentroam/agent": "0.9.126",
|
|
34
|
+
"@myagentroam/protocol": "0.9.126",
|
|
35
|
+
"@myagentroam/code-navigation": "0.9.126"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/ws": "^8.18.1"
|