agent-relay 13.2.0 → 13.4.0
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/README.md +60 -0
- package/dist/cli/agent-relay-mcp.d.ts.map +1 -1
- package/dist/cli/agent-relay-mcp.js +131 -10
- package/dist/cli/agent-relay-mcp.js.map +1 -1
- package/dist/cli/commands/agent.d.ts.map +1 -1
- package/dist/cli/commands/agent.js +24 -19
- package/dist/cli/commands/agent.js.map +1 -1
- package/dist/cli/commands/fleet.d.ts.map +1 -1
- package/dist/cli/commands/fleet.js +183 -39
- package/dist/cli/commands/fleet.js.map +1 -1
- package/dist/cli/commands/integration.d.ts.map +1 -1
- package/dist/cli/commands/integration.js +81 -7
- package/dist/cli/commands/integration.js.map +1 -1
- package/dist/cli/commands/local-agent.d.ts.map +1 -1
- package/dist/cli/commands/local-agent.js +22 -3
- package/dist/cli/commands/local-agent.js.map +1 -1
- package/dist/cli/commands/message.d.ts.map +1 -1
- package/dist/cli/commands/message.js +111 -29
- package/dist/cli/commands/message.js.map +1 -1
- package/dist/cli/lib/agent-registration.d.ts +2 -0
- package/dist/cli/lib/agent-registration.d.ts.map +1 -1
- package/dist/cli/lib/agent-registration.js +2 -2
- package/dist/cli/lib/agent-registration.js.map +1 -1
- package/dist/cli/lib/agent-removal.d.ts +30 -0
- package/dist/cli/lib/agent-removal.d.ts.map +1 -0
- package/dist/cli/lib/agent-removal.js +73 -0
- package/dist/cli/lib/agent-removal.js.map +1 -0
- package/dist/cli/lib/attachments.d.ts +31 -0
- package/dist/cli/lib/attachments.d.ts.map +1 -0
- package/dist/cli/lib/attachments.js +239 -0
- package/dist/cli/lib/attachments.js.map +1 -0
- package/dist/cli/lib/fleet-live-agents.d.ts +17 -0
- package/dist/cli/lib/fleet-live-agents.d.ts.map +1 -1
- package/dist/cli/lib/fleet-live-agents.js +23 -0
- package/dist/cli/lib/fleet-live-agents.js.map +1 -1
- package/dist/cli/lib/sdk-command.d.ts.map +1 -1
- package/dist/cli/lib/sdk-command.js +8 -2
- package/dist/cli/lib/sdk-command.js.map +1 -1
- package/dist/cli/lib/spawn-liveness.d.ts +50 -0
- package/dist/cli/lib/spawn-liveness.d.ts.map +1 -0
- package/dist/cli/lib/spawn-liveness.js +184 -0
- package/dist/cli/lib/spawn-liveness.js.map +1 -0
- package/dist/cli/lib/task-input.d.ts +26 -0
- package/dist/cli/lib/task-input.d.ts.map +1 -0
- package/dist/cli/lib/task-input.js +102 -0
- package/dist/cli/lib/task-input.js.map +1 -0
- package/dist/cli/mcp/messaging-tools.d.ts.map +1 -1
- package/dist/cli/mcp/messaging-tools.js +136 -34
- package/dist/cli/mcp/messaging-tools.js.map +1 -1
- package/dist/cli/mcp/request-replay.d.ts +21 -9
- package/dist/cli/mcp/request-replay.d.ts.map +1 -1
- package/dist/cli/mcp/request-replay.js +58 -9
- package/dist/cli/mcp/request-replay.js.map +1 -1
- package/dist/index.cjs +200 -6
- package/package.json +10 -10
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { lstat, mkdir, open, readFile, realpath, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
/** Largest file sent or saved as a message attachment; recipients' injectors use the same cap. */
|
|
5
|
+
export const MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
|
|
6
|
+
const CONTENT_TYPES = {
|
|
7
|
+
'.png': 'image/png',
|
|
8
|
+
'.jpg': 'image/jpeg',
|
|
9
|
+
'.jpeg': 'image/jpeg',
|
|
10
|
+
'.gif': 'image/gif',
|
|
11
|
+
'.webp': 'image/webp',
|
|
12
|
+
'.svg': 'image/svg+xml',
|
|
13
|
+
'.pdf': 'application/pdf',
|
|
14
|
+
'.txt': 'text/plain',
|
|
15
|
+
'.log': 'text/plain',
|
|
16
|
+
'.md': 'text/markdown',
|
|
17
|
+
'.json': 'application/json',
|
|
18
|
+
'.csv': 'text/csv',
|
|
19
|
+
'.html': 'text/html',
|
|
20
|
+
'.zip': 'application/zip',
|
|
21
|
+
};
|
|
22
|
+
/** The MIME type for a file name's extension, or `application/octet-stream`. */
|
|
23
|
+
export function contentTypeFor(filename) {
|
|
24
|
+
return CONTENT_TYPES[path.extname(filename).toLowerCase()] ?? 'application/octet-stream';
|
|
25
|
+
}
|
|
26
|
+
/** Device names Windows reserves, with or without an extension. */
|
|
27
|
+
const WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i;
|
|
28
|
+
/**
|
|
29
|
+
* A sender-supplied file name reduced to one safe path segment that also
|
|
30
|
+
* saves on Windows: no control characters, no `<>:"|?*`, no leading dot, no
|
|
31
|
+
* trailing dots or spaces, and no reserved device name.
|
|
32
|
+
*/
|
|
33
|
+
export function safeAttachmentFilename(name) {
|
|
34
|
+
const base = path.basename(name.replace(/\\/g, '/'));
|
|
35
|
+
const cleaned = base
|
|
36
|
+
// eslint-disable-next-line no-control-regex
|
|
37
|
+
.replace(/[\u0000-\u001f\u007f]/g, '')
|
|
38
|
+
.replace(/[<>:"|?*]/g, '_')
|
|
39
|
+
// Trim before removing leading dots so names such as ` .env` cannot
|
|
40
|
+
// become hidden only after the whitespace is stripped.
|
|
41
|
+
.replace(/^[. ]+/, '')
|
|
42
|
+
.replace(/[. ]+$/, '');
|
|
43
|
+
if (!cleaned)
|
|
44
|
+
return 'attachment';
|
|
45
|
+
return WINDOWS_RESERVED.test(cleaned) ? `_${cleaned}` : cleaned;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Decode strict base64 (standard alphabet, optional padding, whitespace
|
|
49
|
+
* ignored). `Buffer.from(..., 'base64')` silently skips invalid characters,
|
|
50
|
+
* which would upload different bytes than the caller meant.
|
|
51
|
+
*/
|
|
52
|
+
export function decodeBase64Strict(value, maxBytes = MAX_ATTACHMENT_BYTES) {
|
|
53
|
+
const compact = value.replace(/\s+/g, '');
|
|
54
|
+
// Refuse oversized input by its encoded length, before decoding it.
|
|
55
|
+
if (Math.floor((compact.length * 3) / 4) - 2 > maxBytes) {
|
|
56
|
+
throw new Error(`content_base64 exceeds the ${maxBytes}-byte limit.`);
|
|
57
|
+
}
|
|
58
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(compact) || compact.length % 4 === 1) {
|
|
59
|
+
throw new Error('content_base64 is not valid base64.');
|
|
60
|
+
}
|
|
61
|
+
const data = Buffer.from(compact, 'base64');
|
|
62
|
+
if (data.toString('base64').replace(/=+$/, '') !== compact.replace(/=+$/, '')) {
|
|
63
|
+
throw new Error('content_base64 is not valid base64.');
|
|
64
|
+
}
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
/** Check that a local file can be attached: a non-empty regular file under the size cap. */
|
|
68
|
+
export async function checkAttachment(filePath) {
|
|
69
|
+
const info = await stat(filePath).catch(() => undefined);
|
|
70
|
+
if (!info?.isFile()) {
|
|
71
|
+
throw new Error(`Cannot attach ${filePath}: not a readable file.`);
|
|
72
|
+
}
|
|
73
|
+
if (info.size === 0) {
|
|
74
|
+
throw new Error(`Cannot attach ${filePath}: the file is empty.`);
|
|
75
|
+
}
|
|
76
|
+
if (info.size > MAX_ATTACHMENT_BYTES) {
|
|
77
|
+
throw new Error(`Cannot attach ${filePath}: ${info.size} bytes exceeds the ${MAX_ATTACHMENT_BYTES}-byte limit.`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Read a local file to attach, enforcing the same rules on the bytes actually read. */
|
|
81
|
+
export async function readAttachment(filePath) {
|
|
82
|
+
await checkAttachment(filePath);
|
|
83
|
+
// The file can change between stat and read; check what was read.
|
|
84
|
+
const data = await readFile(filePath);
|
|
85
|
+
if (data.byteLength === 0) {
|
|
86
|
+
throw new Error(`Cannot attach ${filePath}: the file is empty.`);
|
|
87
|
+
}
|
|
88
|
+
if (data.byteLength > MAX_ATTACHMENT_BYTES) {
|
|
89
|
+
throw new Error(`Cannot attach ${filePath}: ${data.byteLength} bytes exceeds the ${MAX_ATTACHMENT_BYTES}-byte limit.`);
|
|
90
|
+
}
|
|
91
|
+
const filename = path.basename(filePath);
|
|
92
|
+
return { filename, contentType: contentTypeFor(filename), data };
|
|
93
|
+
}
|
|
94
|
+
async function ensurePlainDefaultDirectory(fileId) {
|
|
95
|
+
let currentPath = path.resolve('.');
|
|
96
|
+
let currentReal = await realpath(currentPath);
|
|
97
|
+
for (const segment of ['.agent-relay', 'attachments', safeAttachmentFilename(fileId)]) {
|
|
98
|
+
currentPath = path.join(currentPath, segment);
|
|
99
|
+
try {
|
|
100
|
+
await mkdir(currentPath, { mode: 0o700 });
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error.code !== 'EEXIST')
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
const expected = path.join(currentReal, segment);
|
|
107
|
+
if (process.platform !== 'win32') {
|
|
108
|
+
let directory;
|
|
109
|
+
try {
|
|
110
|
+
directory = await open(currentPath, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const code = error.code;
|
|
114
|
+
if (code === 'ELOOP' || code === 'ENOTDIR') {
|
|
115
|
+
throw new Error(`Cannot save attachment ${fileId}: default destination contains a symlink.`, {
|
|
116
|
+
cause: error,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const [opened, visible, pinnedReal] = await Promise.all([
|
|
123
|
+
directory.stat(),
|
|
124
|
+
lstat(currentPath),
|
|
125
|
+
realpath(currentPath),
|
|
126
|
+
]);
|
|
127
|
+
if (pinnedReal !== expected ||
|
|
128
|
+
!opened.isDirectory() ||
|
|
129
|
+
!visible.isDirectory() ||
|
|
130
|
+
visible.isSymbolicLink() ||
|
|
131
|
+
visible.dev !== opened.dev ||
|
|
132
|
+
visible.ino !== opened.ino) {
|
|
133
|
+
throw new Error(`Cannot save attachment ${fileId}: default destination changed while opening.`);
|
|
134
|
+
}
|
|
135
|
+
if ((opened.mode & 0o077) !== 0)
|
|
136
|
+
await directory.chmod(0o700);
|
|
137
|
+
const privateInfo = await directory.stat();
|
|
138
|
+
if ((privateInfo.mode & 0o077) !== 0) {
|
|
139
|
+
throw new Error(`Cannot save attachment ${fileId}: default destination is not private.`);
|
|
140
|
+
}
|
|
141
|
+
currentReal = pinnedReal;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
await directory.close();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const info = await lstat(currentPath).catch(() => undefined);
|
|
149
|
+
if (!info?.isDirectory() || info.isSymbolicLink()) {
|
|
150
|
+
throw new Error(`Cannot save attachment ${fileId}: default destination contains a symlink.`);
|
|
151
|
+
}
|
|
152
|
+
const resolved = await realpath(currentPath);
|
|
153
|
+
if (resolved !== expected) {
|
|
154
|
+
throw new Error(`Cannot save attachment ${fileId}: default destination escaped its root.`);
|
|
155
|
+
}
|
|
156
|
+
currentReal = resolved;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return { path: currentPath, real: currentReal };
|
|
160
|
+
}
|
|
161
|
+
async function writePinnedDefaultFile(directory, expectedDirectoryReal, target, data) {
|
|
162
|
+
// Create the final file before validating the path again, then write only
|
|
163
|
+
// through that open descriptor. A directory or file substitution between
|
|
164
|
+
// validation and byte transfer can no longer redirect the write.
|
|
165
|
+
const noFollow = process.platform === 'win32' ? 0 : constants.O_NOFOLLOW;
|
|
166
|
+
const file = await open(target, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | noFollow, 0o600);
|
|
167
|
+
try {
|
|
168
|
+
const [directoryReal, visible, opened] = await Promise.all([
|
|
169
|
+
realpath(directory),
|
|
170
|
+
lstat(target),
|
|
171
|
+
file.stat(),
|
|
172
|
+
]);
|
|
173
|
+
if (directoryReal !== expectedDirectoryReal ||
|
|
174
|
+
!visible.isFile() ||
|
|
175
|
+
visible.isSymbolicLink() ||
|
|
176
|
+
visible.dev !== opened.dev ||
|
|
177
|
+
visible.ino !== opened.ino) {
|
|
178
|
+
throw new Error('default destination changed while opening the attachment file');
|
|
179
|
+
}
|
|
180
|
+
await file.writeFile(data);
|
|
181
|
+
const [directoryRealAfter, visibleAfter] = await Promise.all([realpath(directory), lstat(target)]);
|
|
182
|
+
if (directoryRealAfter !== expectedDirectoryReal ||
|
|
183
|
+
!visibleAfter.isFile() ||
|
|
184
|
+
visibleAfter.isSymbolicLink() ||
|
|
185
|
+
visibleAfter.dev !== opened.dev ||
|
|
186
|
+
visibleAfter.ino !== opened.ino) {
|
|
187
|
+
throw new Error('default destination changed while saving the attachment file');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
await file.close();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Write a downloaded attachment and return its absolute path. `out` may be a
|
|
196
|
+
* file or an existing directory; by default the file lands in
|
|
197
|
+
* `.agent-relay/attachments/<fileId>/` under the working directory.
|
|
198
|
+
*/
|
|
199
|
+
export async function saveAttachment(fileId, filename, data, out) {
|
|
200
|
+
if (data.byteLength > MAX_ATTACHMENT_BYTES) {
|
|
201
|
+
throw new Error(`Cannot save attachment ${fileId}: ${data.byteLength} bytes exceeds the ${MAX_ATTACHMENT_BYTES}-byte limit.`);
|
|
202
|
+
}
|
|
203
|
+
const name = safeAttachmentFilename(filename);
|
|
204
|
+
let defaultDirectoryReal;
|
|
205
|
+
if (!out) {
|
|
206
|
+
const destination = await ensurePlainDefaultDirectory(fileId);
|
|
207
|
+
out = destination.path;
|
|
208
|
+
defaultDirectoryReal = destination.real;
|
|
209
|
+
}
|
|
210
|
+
const outInfo = await stat(out).catch(() => undefined);
|
|
211
|
+
if (!outInfo?.isDirectory()) {
|
|
212
|
+
// An explicit output file is the caller's choice to overwrite.
|
|
213
|
+
const target = path.resolve(out);
|
|
214
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
215
|
+
await writeFile(target, data);
|
|
216
|
+
return target;
|
|
217
|
+
}
|
|
218
|
+
// In a directory, the sender chose the name: never replace an existing file
|
|
219
|
+
// (or follow a link); pick the first free `name (n).ext` instead.
|
|
220
|
+
const { name: stem, ext } = path.parse(name);
|
|
221
|
+
for (let n = 0; n < 1000; n += 1) {
|
|
222
|
+
const target = path.resolve(out, n === 0 ? name : `${stem} (${n})${ext}`);
|
|
223
|
+
try {
|
|
224
|
+
if (defaultDirectoryReal) {
|
|
225
|
+
await writePinnedDefaultFile(out, defaultDirectoryReal, target, data);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
await writeFile(target, data, { flag: 'wx' });
|
|
229
|
+
}
|
|
230
|
+
return target;
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
if (err.code !== 'EEXIST')
|
|
234
|
+
throw err;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
throw new Error(`Cannot save attachment ${fileId}: no free file name in ${out}.`);
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/cli/lib/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,11 @@ export interface RemoteLiveAgent {
|
|
|
18
18
|
export declare const LIVE_AGENT_CAPABILITY_NAME = "relay:live-agents:v1";
|
|
19
19
|
export interface RemoteLiveAgentRead {
|
|
20
20
|
supported: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether `agents` is the node's whole live set: the capability is present
|
|
23
|
+
* and every entry decoded. Duplicates do not make a roster incomplete.
|
|
24
|
+
*/
|
|
25
|
+
complete: boolean;
|
|
21
26
|
agents: RemoteLiveAgent[];
|
|
22
27
|
warning?: string;
|
|
23
28
|
}
|
|
@@ -39,4 +44,16 @@ export declare function isAvailableFleetNode(node: {
|
|
|
39
44
|
handlersLive?: boolean;
|
|
40
45
|
tags?: unknown;
|
|
41
46
|
}): boolean;
|
|
47
|
+
export declare const MAX_LIVE_HEARTBEAT_AGE_MS = 36000;
|
|
48
|
+
/**
|
|
49
|
+
* Clock skew tolerated before a server-stamped heartbeat in the future stops
|
|
50
|
+
* counting as fresh. Within it the age clamps to zero; beyond it the local
|
|
51
|
+
* clock cannot be trusted to judge the heartbeat at all, and a lagging clock
|
|
52
|
+
* would otherwise make an old snapshot look current.
|
|
53
|
+
*/
|
|
54
|
+
export declare const MAX_HEARTBEAT_CLOCK_SKEW_MS = 5000;
|
|
55
|
+
/** Age of a node's last heartbeat, or null when it cannot be judged. */
|
|
56
|
+
export declare function heartbeatAgeMs(node: {
|
|
57
|
+
lastHeartbeatAt?: string;
|
|
58
|
+
}, now?: number): number | null;
|
|
42
59
|
//# sourceMappingURL=fleet-live-agents.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fleet-live-agents.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/fleet-live-agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"fleet-live-agents.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/fleet-live-agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,mBAAmB,CAiCzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAKV;AAED,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAEjD,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,SAAa,GAAG,MAAM,GAAG,IAAI,CAMlG"}
|
|
@@ -16,6 +16,7 @@ export const LIVE_AGENT_CAPABILITY_NAME = 'relay:live-agents:v1';
|
|
|
16
16
|
export function readRemoteLiveAgents(node) {
|
|
17
17
|
let supported = false;
|
|
18
18
|
let malformed = 0;
|
|
19
|
+
let undecoded = false;
|
|
19
20
|
const names = new Set();
|
|
20
21
|
for (const capability of node.capabilities) {
|
|
21
22
|
if (capability.name !== LIVE_AGENT_CAPABILITY_NAME)
|
|
@@ -24,11 +25,14 @@ export function readRemoteLiveAgents(node) {
|
|
|
24
25
|
const rawNames = capability.metadata?.names;
|
|
25
26
|
if (!Array.isArray(rawNames)) {
|
|
26
27
|
malformed += 1;
|
|
28
|
+
undecoded = true;
|
|
27
29
|
continue;
|
|
28
30
|
}
|
|
29
31
|
for (const rawName of rawNames) {
|
|
30
32
|
if (typeof rawName !== 'string' || !rawName || names.has(rawName)) {
|
|
31
33
|
malformed += 1;
|
|
34
|
+
if (typeof rawName !== 'string' || !rawName)
|
|
35
|
+
undecoded = true;
|
|
32
36
|
continue;
|
|
33
37
|
}
|
|
34
38
|
names.add(rawName);
|
|
@@ -36,6 +40,7 @@ export function readRemoteLiveAgents(node) {
|
|
|
36
40
|
}
|
|
37
41
|
return {
|
|
38
42
|
supported,
|
|
43
|
+
complete: supported && !undecoded,
|
|
39
44
|
agents: Array.from(names, (name) => ({ name })).sort((a, b) => a.name.localeCompare(b.name)),
|
|
40
45
|
...(malformed > 0
|
|
41
46
|
? {
|
|
@@ -60,4 +65,22 @@ export function isAvailableFleetNode(node) {
|
|
|
60
65
|
const isLive = node.live === undefined ? node.status === 'online' : node.live === true;
|
|
61
66
|
return isLive && node.handlersLive !== false && !isDirectPseudoNode;
|
|
62
67
|
}
|
|
68
|
+
export const MAX_LIVE_HEARTBEAT_AGE_MS = 36_000;
|
|
69
|
+
/**
|
|
70
|
+
* Clock skew tolerated before a server-stamped heartbeat in the future stops
|
|
71
|
+
* counting as fresh. Within it the age clamps to zero; beyond it the local
|
|
72
|
+
* clock cannot be trusted to judge the heartbeat at all, and a lagging clock
|
|
73
|
+
* would otherwise make an old snapshot look current.
|
|
74
|
+
*/
|
|
75
|
+
export const MAX_HEARTBEAT_CLOCK_SKEW_MS = 5_000;
|
|
76
|
+
/** Age of a node's last heartbeat, or null when it cannot be judged. */
|
|
77
|
+
export function heartbeatAgeMs(node, now = Date.now()) {
|
|
78
|
+
const timestamp = Date.parse(node.lastHeartbeatAt ?? '');
|
|
79
|
+
if (!Number.isFinite(timestamp))
|
|
80
|
+
return null;
|
|
81
|
+
const age = now - timestamp;
|
|
82
|
+
if (age < -MAX_HEARTBEAT_CLOCK_SKEW_MS)
|
|
83
|
+
return null;
|
|
84
|
+
return Math.max(0, age);
|
|
85
|
+
}
|
|
63
86
|
//# sourceMappingURL=fleet-live-agents.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fleet-live-agents.js","sourceRoot":"","sources":["../../../src/cli/lib/fleet-live-agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,MAAM,CAAC,MAAM,0BAA0B,GAAG,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"fleet-live-agents.js","sourceRoot":"","sources":["../../../src/cli/lib/fleet-live-agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-command.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/sdk-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EACL,UAAU,EAGV,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"sdk-command.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/sdk-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EACL,UAAU,EAGV,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAA0C,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGhG,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;AAEtC,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,KAAK,eAAe,CAAC;IAClE,oBAAoB,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,KAAK,eAAe,CAAC;IACtE,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACzE,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,cAAc,CAUvF;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAqBvD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAMlF;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAEpE;AAED,oFAAoF;AACpF,wBAAsB,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BzF"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { AgentRelay, RelayPlacementError, safeRelayErrorMessage, } from '@agent-relay/sdk';
|
|
2
|
+
import { AgentRemovalPendingError } from './agent-removal.js';
|
|
3
|
+
import { FleetSpawnError } from './spawn-liveness.js';
|
|
2
4
|
import { defaultExit } from './exit.js';
|
|
3
5
|
import { createAgentRelay, createWorkspaceRelay } from './sdk-client.js';
|
|
4
6
|
import { sanitizedSpawnReceipt } from './spawn-lifecycle.js';
|
|
@@ -48,7 +50,7 @@ export async function runSdk(deps, fn) {
|
|
|
48
50
|
}
|
|
49
51
|
catch (err) {
|
|
50
52
|
const message = safeRelayErrorMessage(err);
|
|
51
|
-
if (err instanceof RelayPlacementError) {
|
|
53
|
+
if (err instanceof RelayPlacementError || err instanceof FleetSpawnError) {
|
|
52
54
|
const structured = {
|
|
53
55
|
error: {
|
|
54
56
|
code: err.code,
|
|
@@ -57,6 +59,10 @@ export async function runSdk(deps, fn) {
|
|
|
57
59
|
...(err.node ? { node: err.node } : {}),
|
|
58
60
|
...(err.dispatchState ? { dispatchState: err.dispatchState } : {}),
|
|
59
61
|
...(err.receipt ? { receipt: sanitizedSpawnReceipt(err.receipt) } : {}),
|
|
62
|
+
...(err instanceof FleetSpawnError && err.liveness ? { liveness: err.liveness } : {}),
|
|
63
|
+
...(err instanceof FleetSpawnError && err.diagnostic
|
|
64
|
+
? { diagnostic: safeRelayErrorMessage(new Error(err.diagnostic)) }
|
|
65
|
+
: {}),
|
|
60
66
|
message,
|
|
61
67
|
},
|
|
62
68
|
};
|
|
@@ -65,7 +71,7 @@ export async function runSdk(deps, fn) {
|
|
|
65
71
|
else {
|
|
66
72
|
deps.error(message);
|
|
67
73
|
}
|
|
68
|
-
deps.exit(1);
|
|
74
|
+
deps.exit(err instanceof FleetSpawnError || err instanceof AgentRemovalPendingError ? err.exitCode : 1);
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
//# sourceMappingURL=sdk-command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-command.js","sourceRoot":"","sources":["../../../src/cli/lib/sdk-command.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAc7D,MAAM,UAAU,eAAe,CAAC,YAAqC,EAAE;IACrE,OAAO;QACL,gBAAgB;QAChB,oBAAoB;QACpB,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACjF,GAAG,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACjD,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QACrD,IAAI,EAAE,WAAW;QACjB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO,CACL,OAAO;SACJ,MAAM,CACL,uBAAuB,EACvB,yEAAyE,CAC1E;SACA,MAAM,CAAC,YAAY,EAAE,2BAA2B,CAAC;SACjD,MAAM,CAAC,iBAAiB,EAAE,6CAA6C,CAAC;SACxE,MAAM,CAAC,kBAAkB,EAAE,wDAAwD,CAAC;QACrF,6EAA6E;QAC7E,iFAAiF;QACjF,8EAA8E;QAC9E,yDAAyD;SACxD,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACxE,WAAW,CAAC,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAA6B;IAC9D,OAAO;QACL,YAAY,EAAE,IAAI,CAAC,YAAkC;QACrD,KAAK,EAAE,IAAI,CAAC,KAA2B;QACvC,OAAO,EAAE,IAAI,CAAC,OAA6B;KAC5C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAoB,EAAE,KAAc;IAC5D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAoB,EAAE,EAAuB;IACxE,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,GAAG,YAAY,mBAAmB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"sdk-command.js","sourceRoot":"","sources":["../../../src/cli/lib/sdk-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type RelayNode } from '@agent-relay/sdk';
|
|
2
|
+
export interface SpawnLiveness {
|
|
3
|
+
evidence: 'invocation_terminal' | 'live' | 'live_elsewhere' | 'stale' | 'registered' | 'absent' | 'unknown';
|
|
4
|
+
node?: string;
|
|
5
|
+
heartbeatAgeMs?: number | null;
|
|
6
|
+
readError?: string;
|
|
7
|
+
invocation?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
interface SpawnContext {
|
|
10
|
+
invocationId?: string;
|
|
11
|
+
node?: string;
|
|
12
|
+
dispatchState?: string;
|
|
13
|
+
receipt?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export declare class FleetSpawnError extends Error {
|
|
16
|
+
readonly code: 'spawn_unconfirmed' | 'spawn_name_taken';
|
|
17
|
+
readonly liveness?: SpawnLiveness | undefined;
|
|
18
|
+
readonly diagnostic?: string | undefined;
|
|
19
|
+
readonly state: 'pending' | 'failed';
|
|
20
|
+
readonly exitCode: number;
|
|
21
|
+
readonly invocationId?: string;
|
|
22
|
+
readonly node?: string;
|
|
23
|
+
readonly dispatchState?: string;
|
|
24
|
+
readonly receipt?: Record<string, unknown>;
|
|
25
|
+
constructor(code: 'spawn_unconfirmed' | 'spawn_name_taken', message: string, context: SpawnContext, liveness?: SpawnLiveness | undefined, diagnostic?: string | undefined);
|
|
26
|
+
}
|
|
27
|
+
export declare function mayStillBeRunning(error: unknown): boolean;
|
|
28
|
+
export declare function pendingSpawnError(name: string, context: SpawnContext, liveness: SpawnLiveness, diagnostic?: string): FleetSpawnError;
|
|
29
|
+
export declare function classifySpawnFailure(message: string): 'spawn_name_taken' | undefined;
|
|
30
|
+
export declare function nameTakenSpawnError(name: string, error: Error & SpawnContext): FleetSpawnError;
|
|
31
|
+
/** Reads are bounded and client construction is fallible (agent-token-only callers are supported). */
|
|
32
|
+
export declare function probeSpawnLiveness(options: {
|
|
33
|
+
name: string;
|
|
34
|
+
targetNode?: string;
|
|
35
|
+
getInvocation?: () => Promise<unknown>;
|
|
36
|
+
createClient: () => {
|
|
37
|
+
nodes: {
|
|
38
|
+
get: (name: string) => Promise<RelayNode | null>;
|
|
39
|
+
list: () => Promise<RelayNode[]>;
|
|
40
|
+
};
|
|
41
|
+
agents: {
|
|
42
|
+
get: (name: string) => Promise<unknown>;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
now?: () => number;
|
|
46
|
+
}): Promise<SpawnLiveness>;
|
|
47
|
+
/** Preserve the original request's launch/readiness contract on the final invocation read. */
|
|
48
|
+
export declare function terminalSpawnOutcome(invocation: Record<string, unknown>, context: SpawnContext, requireReady: boolean): Record<string, unknown>;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=spawn-liveness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn-liveness.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/spawn-liveness.ts"],"names":[],"mappings":"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"}
|