@myagentroam/node 0.9.179 → 0.10.1
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/NOTICE +7 -0
- package/dist/computer-use-runtime-version.js +1 -1
- package/dist/computer-use-runtime.js +0 -3
- package/dist/connector.js +3 -3
- package/dist/runner/codex-runner.js +1 -1
- package/dist/runner/mar-agent/image-generation.js +23 -6
- package/dist/runner/opencode-runner.js +1 -1
- package/dist/service/code-navigation/ecmascript-path-specifier-resolver.js +0 -4
- package/dist/service/direct-transfer-service.js +25 -6
- package/dist/service/hosted-conversation-node-service.js +0 -12
- package/dist/service/workspace-code-navigation-service.js +0 -4
- package/dist/service/workspace-file-service.js +3 -3
- package/package.json +6 -6
package/NOTICE
CHANGED
|
@@ -2,3 +2,10 @@ MyAgentRoam
|
|
|
2
2
|
Copyright 2026 MyAgentRoam contributors
|
|
3
3
|
|
|
4
4
|
This product includes software developed by the MyAgentRoam project.
|
|
5
|
+
|
|
6
|
+
Enterprise implementation and product composition:
|
|
7
|
+
Copyright 2026 aCHAOS
|
|
8
|
+
Author and licensing contact: aCHAOS (achaosxyz@gmail.com)
|
|
9
|
+
Licensed under MyAgentRoam Enterprise Source-Available License 1.0; see
|
|
10
|
+
ee/LICENSE and LICENSING.md. Independent core and third-party notices remain
|
|
11
|
+
applicable; this attribution does not transfer any contributor's copyright.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const computerUseRuntimeVersion = '0.
|
|
1
|
+
export const computerUseRuntimeVersion = '0.10.1';
|
|
@@ -294,9 +294,6 @@ function safeRuntimePath(root, path) {
|
|
|
294
294
|
throw new ComputerUseRuntimeError('COMPUTER_RUNTIME_MANIFEST_INVALID');
|
|
295
295
|
return target;
|
|
296
296
|
}
|
|
297
|
-
function isMissing(error) {
|
|
298
|
-
return (error instanceof Error && 'code' in error && error.code === 'ENOENT');
|
|
299
|
-
}
|
|
300
297
|
function isAlreadyExists(error) {
|
|
301
298
|
return (error instanceof Error && 'code' in error && error.code === 'EEXIST');
|
|
302
299
|
}
|
package/dist/connector.js
CHANGED
|
@@ -1674,13 +1674,13 @@ export class NodeConnector {
|
|
|
1674
1674
|
this.scheduledSessions.start();
|
|
1675
1675
|
await this.initializeConversationHosting();
|
|
1676
1676
|
this.computerUseEnablement.initialize();
|
|
1677
|
-
this.directTransferService ??= this.createDirectTransferService();
|
|
1677
|
+
this.directTransferService ??= await this.createDirectTransferService();
|
|
1678
1678
|
this.connectionLifecycle.start();
|
|
1679
1679
|
this.controlChannel.connect();
|
|
1680
1680
|
}
|
|
1681
|
-
createDirectTransferService() {
|
|
1681
|
+
async createDirectTransferService() {
|
|
1682
1682
|
try {
|
|
1683
|
-
return
|
|
1683
|
+
return await DirectTransferService.create({
|
|
1684
1684
|
nodeGeneration: () => this.nodeGeneration,
|
|
1685
1685
|
send: (type, payload) => this.send(type, payload),
|
|
1686
1686
|
terminalManager: this.terminalManager,
|
|
@@ -49,7 +49,7 @@ export class CodexRunner extends AbstractRunner {
|
|
|
49
49
|
}).find((profile) => profile.runner === this.name);
|
|
50
50
|
return { ...base, models: this.profileCache?.profile.models ?? [] };
|
|
51
51
|
}
|
|
52
|
-
cachedProfile(capabilities,
|
|
52
|
+
cachedProfile(capabilities, _environment = {}) {
|
|
53
53
|
const base = this.profile(capabilities);
|
|
54
54
|
return this.profileCache === undefined ||
|
|
55
55
|
this.profileCacheVersion !== capabilities.codex.version
|
|
@@ -20,6 +20,7 @@ const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0
|
|
|
20
20
|
const MAX_EDIT_IMAGES = 5;
|
|
21
21
|
const SUPPORTED_EDIT_MIME_TYPES = new Set(['image/png', 'image/jpeg', 'image/webp']);
|
|
22
22
|
const IMAGE_GENERATION_RESPONSE_TIMEOUT_MS = 5 * 60 * 1000;
|
|
23
|
+
const IMAGE_GENERATION_READ_IDLE_TIMEOUT_MS = 5 * 60 * 1000;
|
|
23
24
|
export const codexImageGenToolDefinition = {
|
|
24
25
|
name: 'codex_image_gen',
|
|
25
26
|
agentScope: 'ROOT_ONLY',
|
|
@@ -230,19 +231,34 @@ async function readJsonResponse(response, signal) {
|
|
|
230
231
|
if (response.body === null)
|
|
231
232
|
return {};
|
|
232
233
|
const reader = response.body.getReader();
|
|
234
|
+
const readController = new AbortController();
|
|
235
|
+
const readSignal = AbortSignal.any([signal, readController.signal]);
|
|
233
236
|
const abort = () => {
|
|
234
|
-
void reader.cancel(
|
|
237
|
+
void reader.cancel(readSignal.reason).catch(() => undefined);
|
|
235
238
|
};
|
|
236
|
-
|
|
239
|
+
readSignal.addEventListener('abort', abort, { once: true });
|
|
240
|
+
const onIdle = () => {
|
|
241
|
+
readController.abort(new MarAgentError('MAR_AGENT_IMAGE_GENERATION_READ_TIMEOUT', 'Image response body read timed out waiting for data.', {
|
|
242
|
+
details: {
|
|
243
|
+
reason: 'IMAGE_RESPONSE_READ_TIMEOUT',
|
|
244
|
+
idleTimeoutMs: IMAGE_GENERATION_READ_IDLE_TIMEOUT_MS
|
|
245
|
+
}
|
|
246
|
+
}));
|
|
247
|
+
};
|
|
248
|
+
let readTimeout = setTimeout(onIdle, IMAGE_GENERATION_READ_IDLE_TIMEOUT_MS);
|
|
237
249
|
const chunks = [];
|
|
238
250
|
let bytes = 0;
|
|
239
251
|
try {
|
|
240
|
-
|
|
252
|
+
readSignal.throwIfAborted();
|
|
241
253
|
for (;;) {
|
|
242
|
-
const chunk = await reader.read();
|
|
243
|
-
|
|
254
|
+
const chunk = await waitForImageStep(reader.read(), readSignal);
|
|
255
|
+
readSignal.throwIfAborted();
|
|
244
256
|
if (chunk.done)
|
|
245
257
|
break;
|
|
258
|
+
if (chunk.value.byteLength === 0)
|
|
259
|
+
continue;
|
|
260
|
+
clearTimeout(readTimeout);
|
|
261
|
+
readTimeout = setTimeout(onIdle, IMAGE_GENERATION_READ_IDLE_TIMEOUT_MS);
|
|
246
262
|
bytes += chunk.value.byteLength;
|
|
247
263
|
if (bytes > RESPONSE_MAX_BYTES)
|
|
248
264
|
throw new MarAgentError('MAR_AGENT_TOOL_OUTPUT_LIMIT', 'Image response exceeded the size limit.');
|
|
@@ -254,7 +270,8 @@ async function readJsonResponse(response, signal) {
|
|
|
254
270
|
throw error;
|
|
255
271
|
}
|
|
256
272
|
finally {
|
|
257
|
-
|
|
273
|
+
clearTimeout(readTimeout);
|
|
274
|
+
readSignal.removeEventListener('abort', abort);
|
|
258
275
|
reader.releaseLock();
|
|
259
276
|
}
|
|
260
277
|
try {
|
|
@@ -43,7 +43,7 @@ export class OpenCodeRunner extends AbstractRunner {
|
|
|
43
43
|
}).find((profile) => profile.runner === this.name);
|
|
44
44
|
return { ...base, models: [] };
|
|
45
45
|
}
|
|
46
|
-
cachedProfile(capabilities,
|
|
46
|
+
cachedProfile(capabilities, _environment = {}) {
|
|
47
47
|
const cached = this.profileCache;
|
|
48
48
|
return cached === undefined
|
|
49
49
|
? this.profile(capabilities)
|
|
@@ -70,10 +70,6 @@ function candidates(path) {
|
|
|
70
70
|
? [path]
|
|
71
71
|
: [path, ...extensionlessSourceExtensions.map((extension) => `${path}${extension}`)];
|
|
72
72
|
}
|
|
73
|
-
function sourceFileStem(path) {
|
|
74
|
-
const name = path.slice(path.lastIndexOf('/') + 1);
|
|
75
|
-
return name.replace(/(?:\.d)?\.[^.]+$/u, '');
|
|
76
|
-
}
|
|
77
73
|
function unresolvedSpecifierScore(path, specifier) {
|
|
78
74
|
const normalizedSpecifier = specifier.startsWith('@/') ? specifier.slice(2) : specifier;
|
|
79
75
|
return trailingPathCandidateScore(path, unresolvedCandidates(normalizedSpecifier));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createSocket } from 'node:dgram';
|
|
1
2
|
import { directDataControlFrameSchema, directNodeCommandSchema } from '@myagentroam/protocol';
|
|
2
3
|
import { TerminalDirectService } from './terminal-direct-service.js';
|
|
3
4
|
import { IceUdpMuxListener as NativeIceUdpMuxListener } from 'node-datachannel';
|
|
@@ -21,12 +22,18 @@ export class DirectTransferService {
|
|
|
21
22
|
leaseCheckMs;
|
|
22
23
|
terminalDirect;
|
|
23
24
|
disposed = false;
|
|
24
|
-
|
|
25
|
-
this.options = options;
|
|
26
|
-
this.now = options.now ?? Date.now;
|
|
25
|
+
static async create(options) {
|
|
27
26
|
const range = options.udpPortRange?.() ?? { begin: 49_152, end: 49_215 };
|
|
28
27
|
const createIceUdpMuxListener = options.createIceUdpMuxListener ?? ((port) => new NativeIceUdpMuxListener(port));
|
|
29
|
-
|
|
28
|
+
// Windows can accept an IPv6 mux bind while another IPv4 endpoint owns the port.
|
|
29
|
+
const probe = options.probeUdp4Port ?? (process.platform === 'win32' ? probeUdp4Port : undefined);
|
|
30
|
+
const listener = await bindIceUdpMuxListener(range, createIceUdpMuxListener, probe);
|
|
31
|
+
return new DirectTransferService(options, listener);
|
|
32
|
+
}
|
|
33
|
+
constructor(options, iceUdpMuxListener) {
|
|
34
|
+
this.options = options;
|
|
35
|
+
this.now = options.now ?? Date.now;
|
|
36
|
+
this.iceUdpMuxListener = iceUdpMuxListener;
|
|
30
37
|
const udpPort = this.iceUdpMuxListener.port();
|
|
31
38
|
this.peerConfiguration = {
|
|
32
39
|
iceServers: [],
|
|
@@ -382,7 +389,10 @@ export class DirectTransferService {
|
|
|
382
389
|
const complete = (error) => {
|
|
383
390
|
channel.removeEventListener('bufferedamountlow', available);
|
|
384
391
|
channel.removeEventListener('close', closed);
|
|
385
|
-
error === undefined
|
|
392
|
+
if (error === undefined)
|
|
393
|
+
resolve();
|
|
394
|
+
else
|
|
395
|
+
reject(error);
|
|
386
396
|
};
|
|
387
397
|
const available = () => complete();
|
|
388
398
|
const closed = () => complete(new Error('DIRECT_CHANNEL_CLOSED'));
|
|
@@ -465,10 +475,12 @@ function openFrameSessionId(data) {
|
|
|
465
475
|
return undefined;
|
|
466
476
|
}
|
|
467
477
|
}
|
|
468
|
-
function bindIceUdpMuxListener(range, create) {
|
|
478
|
+
async function bindIceUdpMuxListener(range, create, probe) {
|
|
469
479
|
let lastError;
|
|
470
480
|
for (let port = range.begin; port <= range.end; port += 1) {
|
|
471
481
|
try {
|
|
482
|
+
if (probe !== undefined)
|
|
483
|
+
await probe(port);
|
|
472
484
|
return create(port);
|
|
473
485
|
}
|
|
474
486
|
catch (error) {
|
|
@@ -477,6 +489,13 @@ function bindIceUdpMuxListener(range, create) {
|
|
|
477
489
|
}
|
|
478
490
|
throw new Error('DIRECT_UDP_PORT_UNAVAILABLE', { cause: lastError });
|
|
479
491
|
}
|
|
492
|
+
export function probeUdp4Port(port) {
|
|
493
|
+
const socket = createSocket({ type: 'udp4', reuseAddr: false });
|
|
494
|
+
return new Promise((resolve, reject) => {
|
|
495
|
+
socket.once('error', (error) => socket.close(() => reject(error)));
|
|
496
|
+
socket.bind({ port, address: '0.0.0.0', exclusive: true }, () => socket.close(() => resolve()));
|
|
497
|
+
});
|
|
498
|
+
}
|
|
480
499
|
export function fingerprint(sdp) {
|
|
481
500
|
const match = sdp?.match(/^a=fingerprint:(sha-256 [A-F0-9:]+)\r?$/imu);
|
|
482
501
|
return match?.[1];
|
|
@@ -1798,18 +1798,6 @@ function publishedTemplateEntry(value) {
|
|
|
1798
1798
|
resolvedTarget
|
|
1799
1799
|
};
|
|
1800
1800
|
}
|
|
1801
|
-
function publishedTemplateFiles(value) {
|
|
1802
|
-
if (!Array.isArray(value))
|
|
1803
|
-
throw new Error('CONVERSATION_TEMPLATE_VERSION_CORRUPTED');
|
|
1804
|
-
const paths = new Set();
|
|
1805
|
-
return value.map((candidate) => {
|
|
1806
|
-
const file = publishedTemplateFile(candidate);
|
|
1807
|
-
if (paths.has(file.relativePath))
|
|
1808
|
-
throw new Error('CONVERSATION_TEMPLATE_VERSION_CORRUPTED');
|
|
1809
|
-
paths.add(file.relativePath);
|
|
1810
|
-
return file;
|
|
1811
|
-
});
|
|
1812
|
-
}
|
|
1813
1801
|
function publishedTemplateFile(value, requireKind = false) {
|
|
1814
1802
|
if (!record(value) ||
|
|
1815
1803
|
(requireKind && value.kind !== 'FILE') ||
|
|
@@ -22,10 +22,6 @@ const MAX_TAGS_BYTES = 512 * 1024 * 1024;
|
|
|
22
22
|
const MAX_CANDIDATES = 100;
|
|
23
23
|
const MAX_RESULTS = 20;
|
|
24
24
|
const MAX_REFERENCES = 100;
|
|
25
|
-
const MAX_TAG_LINE_BYTES = 16 * 1024;
|
|
26
|
-
const READ_BLOCK_BYTES = 4096;
|
|
27
|
-
const MAX_TARGET_LINE_SCAN_BYTES = MAX_SOURCE_BYTES;
|
|
28
|
-
const MAX_TARGET_PREVIEW_CHARACTERS = 512;
|
|
29
25
|
/**
|
|
30
26
|
* Builds a demand-driven, standard u-ctags declaration index. It never keeps
|
|
31
27
|
* a complete symbol table, watcher, or idle child process in memory.
|
|
@@ -77,15 +77,15 @@ export class WorkspaceFileService {
|
|
|
77
77
|
: readWorkspaceFileContentRange(workspacePath, path, offset, limit);
|
|
78
78
|
}
|
|
79
79
|
readDirect(workspace, input, workspacePath = workspace.path) {
|
|
80
|
-
const
|
|
80
|
+
const readContent = this.readContent.bind(this);
|
|
81
81
|
return (async function* () {
|
|
82
|
-
const initial = (await
|
|
82
|
+
const initial = (await readContent(workspace, { path: input.path, offset: input.range?.offset ?? 0, limit: 1 }, workspacePath));
|
|
83
83
|
if (initial.size !== input.size || initial.sourceRevision !== input.revision)
|
|
84
84
|
throw new Error('DIRECT_FILE_REVISION_CHANGED');
|
|
85
85
|
let offset = input.range?.offset ?? 0;
|
|
86
86
|
const endOffset = input.range === undefined ? input.size : input.range.offset + input.range.length;
|
|
87
87
|
while (offset < endOffset) {
|
|
88
|
-
const range = (await
|
|
88
|
+
const range = (await readContent(workspace, {
|
|
89
89
|
path: input.path,
|
|
90
90
|
offset,
|
|
91
91
|
limit: Math.min(512 * 1024, endOffset - offset)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"playwright": "1.62.1",
|
|
37
37
|
"ws": "^8.21.3",
|
|
38
38
|
"zod": "4.4.3",
|
|
39
|
-
"@myagentroam/agent": "0.
|
|
40
|
-
"@myagentroam/
|
|
41
|
-
"@myagentroam/marctl": "0.
|
|
42
|
-
"@myagentroam/
|
|
39
|
+
"@myagentroam/agent": "0.10.1",
|
|
40
|
+
"@myagentroam/protocol": "0.10.1",
|
|
41
|
+
"@myagentroam/marctl": "0.10.1",
|
|
42
|
+
"@myagentroam/code-navigation": "0.10.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/ws": "^8.18.1"
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json --noEmit",
|
|
52
52
|
"dev": "tsx watch src/main.ts",
|
|
53
53
|
"start": "node dist/main.js",
|
|
54
|
-
"test:unit": "vitest run --config vitest.config.mts",
|
|
54
|
+
"test:unit": "vitest run --config vitest.config.mts && node --test test/unit/*.test.mjs",
|
|
55
55
|
"test:e2e:real": "vitest run --config vitest.e2e.config.mts"
|
|
56
56
|
}
|
|
57
57
|
}
|