stitchkit 0.69.0 → 0.70.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/README.md +4 -4
- package/dist/agent-runtime/coding-tool-contract.d.ts +1 -0
- package/dist/agent-runtime/coding-tool-contract.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-files.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-paths.d.ts +1 -1
- package/dist/agent-runtime/coding-tool-paths.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-shell.d.ts.map +1 -1
- package/dist/agent-runtime/contained-files.d.ts +52 -4
- package/dist/agent-runtime/contained-files.d.ts.map +1 -1
- package/dist/agent-runtime/harness-file-resources.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime-coding-tools.js +202 -145
- package/dist/agent-runtime-harness.js +12 -8
- package/dist/agent-runtime.js +9 -7
- package/dist/application/server-resource.d.ts +1 -0
- package/dist/application/server-resource.d.ts.map +1 -1
- package/dist/application.js +5 -2
- package/dist/cli.js +7 -6
- package/dist/{index-t4dpby6e.js → index-0yphgata.js} +1 -1
- package/dist/index-1z5xxfst.js +397 -0
- package/dist/index-3xnq72rz.js +21 -0
- package/dist/{index-444747ww.js → index-4g196jmf.js} +14 -9
- package/dist/{index-kg9xx84n.js → index-7rey2b8s.js} +1 -1
- package/dist/{index-dk6e56g0.js → index-7wpgrqa8.js} +37 -2
- package/dist/{index-zh459sfj.js → index-aczggrty.js} +1 -1
- package/dist/index-bd17ytae.js +192 -0
- package/dist/{index-q7gdep2c.js → index-da1aqnhb.js} +2 -2
- package/dist/{index-p1be103g.js → index-ktsps64f.js} +4 -2
- package/dist/{index-mbxds404.js → index-mjx0wt4c.js} +8 -6
- package/dist/{index-h8vn1jcr.js → index-qzbg46b6.js} +6 -4
- package/dist/{index-h7ctj1kp.js → index-s8nt8c22.js} +14 -11
- package/dist/{index-d1jsvkyk.js → index-vbf2p6me.js} +1 -1
- package/dist/{index-xxsq3ca1.js → index-vc498pst.js} +1 -1
- package/dist/{index-x18ndp4p.js → index-vj3vvpaa.js} +1 -192
- package/dist/{index-3eqrkqhg.js → index-vy5bjy07.js} +7 -3
- package/dist/{index-6wzr93cg.js → index-w0445741.js} +1 -1
- package/dist/{index-kxxyvkka.js → index-wc80at9n.js} +2 -2
- package/dist/{index-gqdfpv4n.js → index-y3w12g8d.js} +2 -2
- package/dist/node.js +26 -5
- package/dist/observability/index.js +4 -3
- package/dist/remote.js +4 -3
- package/dist/server/bun.d.ts.map +1 -1
- package/dist/server/index.js +20 -10
- package/dist/server/node.d.ts.map +1 -1
- package/dist/server/process-signals.d.ts.map +1 -1
- package/dist/server/shutdown.d.ts +2 -0
- package/dist/server/shutdown.d.ts.map +1 -1
- package/dist/testing.js +6 -5
- package/dist/tool-invoker.js +6 -5
- package/dist/tools/agent-tool-error.d.ts +14 -0
- package/dist/tools/agent-tool-error.d.ts.map +1 -0
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools.js +15 -12
- package/llms-full.txt +73 -22
- package/native/darwin-arm64.node +0 -0
- package/native/darwin-x64.node +0 -0
- package/package.json +3 -1
- package/dist/index-v3dpzpjw.js +0 -92
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
assertContainedFileCurrent,
|
|
3
|
+
assertContainedParentCurrent,
|
|
4
|
+
containedEntryMetadata,
|
|
5
|
+
openContainedFile,
|
|
6
|
+
openContainedParent,
|
|
7
|
+
openContainedParentFile,
|
|
8
|
+
readContainedUtf8Handle,
|
|
9
|
+
scanContainedFiles,
|
|
10
|
+
writeContainedFile
|
|
11
|
+
} from "./index-1z5xxfst.js";
|
|
5
12
|
import {
|
|
6
13
|
defineRuntimeTool
|
|
7
14
|
} from "./index-wwst0td5.js";
|
|
8
15
|
import"./index-22by16v6.js";
|
|
9
16
|
import"./index-cby4ar3v.js";
|
|
17
|
+
import"./index-vj3vvpaa.js";
|
|
18
|
+
import {
|
|
19
|
+
conflict,
|
|
20
|
+
forbidden
|
|
21
|
+
} from "./index-0w9abg87.js";
|
|
10
22
|
import"./index-qyrqwr4c.js";
|
|
23
|
+
import"./index-6k1937bx.js";
|
|
11
24
|
|
|
12
25
|
// src/agent-runtime/coding-tools.ts
|
|
13
26
|
import path3 from "node:path";
|
|
@@ -26,7 +39,8 @@ var AgentCodingToolLimitsSchema = z.object({
|
|
|
26
39
|
maxSearchResults: z.int().positive(),
|
|
27
40
|
maxSearchFiles: z.int().positive(),
|
|
28
41
|
maxSearchDepth: z.int().nonnegative(),
|
|
29
|
-
shellTimeoutMs: z.int().positive()
|
|
42
|
+
shellTimeoutMs: z.int().positive(),
|
|
43
|
+
shellTerminationGraceMs: z.int().positive()
|
|
30
44
|
}).strict();
|
|
31
45
|
var AgentCodingToolAuthorizationSchema = z.discriminatedUnion("operation", [
|
|
32
46
|
z.object({ operation: z.literal("read"), path: z.string().min(1) }).strict(),
|
|
@@ -121,7 +135,8 @@ var DEFAULT_LIMITS = {
|
|
|
121
135
|
maxSearchResults: 100,
|
|
122
136
|
maxSearchFiles: 1e4,
|
|
123
137
|
maxSearchDepth: 32,
|
|
124
|
-
shellTimeoutMs: 30000
|
|
138
|
+
shellTimeoutMs: 30000,
|
|
139
|
+
shellTerminationGraceMs: 250
|
|
125
140
|
};
|
|
126
141
|
function resolveCodingToolLimits(input) {
|
|
127
142
|
return AgentCodingToolLimitsSchema.parse({ ...DEFAULT_LIMITS, ...input });
|
|
@@ -129,11 +144,10 @@ function resolveCodingToolLimits(input) {
|
|
|
129
144
|
|
|
130
145
|
// src/agent-runtime/coding-tool-files.ts
|
|
131
146
|
import { createHash } from "node:crypto";
|
|
132
|
-
import {
|
|
133
|
-
import { open, realpath as realpath2, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
147
|
+
import { realpath as realpath2 } from "node:fs/promises";
|
|
134
148
|
|
|
135
149
|
// src/agent-runtime/coding-tool-paths.ts
|
|
136
|
-
import { lstat, realpath
|
|
150
|
+
import { lstat, realpath } from "node:fs/promises";
|
|
137
151
|
import path from "node:path";
|
|
138
152
|
function within(root, target) {
|
|
139
153
|
const relative = path.relative(root, target);
|
|
@@ -150,53 +164,20 @@ function inputPath(root, requested, maxPathBytes) {
|
|
|
150
164
|
throw new Error("Coding tool path escapes its root");
|
|
151
165
|
return resolved;
|
|
152
166
|
}
|
|
167
|
+
function boundedCodingRelativePath(requested, maxPathBytes) {
|
|
168
|
+
inputPath(path.parse(process.cwd()).root, requested, maxPathBytes);
|
|
169
|
+
return requested;
|
|
170
|
+
}
|
|
153
171
|
async function existingCodingPath(root, requested, maxPathBytes) {
|
|
154
172
|
const resolved = await realpath(inputPath(root, requested, maxPathBytes));
|
|
155
173
|
if (!within(root, resolved))
|
|
156
174
|
throw new Error("Coding tool path resolves outside its root");
|
|
157
175
|
return { absolute: resolved, relative: path.relative(root, resolved) || "." };
|
|
158
176
|
}
|
|
159
|
-
async function writableCodingPath(root, requested, maxPathBytes) {
|
|
160
|
-
const candidate = inputPath(root, requested, maxPathBytes);
|
|
161
|
-
const parent = await realpath(path.dirname(candidate));
|
|
162
|
-
if (!within(root, parent))
|
|
163
|
-
throw new Error("Coding tool parent resolves outside its root");
|
|
164
|
-
const target = path.join(parent, path.basename(candidate));
|
|
165
|
-
const metadata = await lstat(target).catch((error) => {
|
|
166
|
-
if (error.code === "ENOENT")
|
|
167
|
-
return null;
|
|
168
|
-
throw error;
|
|
169
|
-
});
|
|
170
|
-
if (metadata?.isSymbolicLink())
|
|
171
|
-
throw new Error("Coding tools do not write through symlinks");
|
|
172
|
-
return { absolute: target, relative: path.relative(root, target) || "." };
|
|
173
|
-
}
|
|
174
|
-
async function editableCodingPath(root, requested, maxPathBytes) {
|
|
175
|
-
const candidate = inputPath(root, requested, maxPathBytes);
|
|
176
|
-
const metadata = await lstat(candidate);
|
|
177
|
-
if (metadata.isSymbolicLink())
|
|
178
|
-
throw new Error("Coding tools do not edit symlinks");
|
|
179
|
-
const resolved = await realpath(candidate);
|
|
180
|
-
if (!within(root, resolved))
|
|
181
|
-
throw new Error("Coding tool path resolves outside its root");
|
|
182
|
-
return { absolute: resolved, relative: path.relative(root, resolved) || "." };
|
|
183
|
-
}
|
|
184
177
|
async function authorizeCodingTool(config, request) {
|
|
185
178
|
const parsed = AgentCodingToolAuthorizationSchema.parse(request);
|
|
186
179
|
if (!await config.authorize(parsed))
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
async function atomicCodingReplace(target, content, mode) {
|
|
190
|
-
const temporary = path.join(path.dirname(target), `.${path.basename(target)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
191
|
-
try {
|
|
192
|
-
await writeFile(temporary, content, { flag: "wx", ...mode !== undefined && { mode } });
|
|
193
|
-
await rename(temporary, target);
|
|
194
|
-
} catch (error) {
|
|
195
|
-
await unlink(temporary).catch(() => {
|
|
196
|
-
return;
|
|
197
|
-
});
|
|
198
|
-
throw error;
|
|
199
|
-
}
|
|
180
|
+
forbidden("Coding tool permission denied");
|
|
200
181
|
}
|
|
201
182
|
var codingPathLocks = new Map;
|
|
202
183
|
async function withCodingPathLock(target, work) {
|
|
@@ -255,14 +236,15 @@ function createFileCodingTools(config, limits) {
|
|
|
255
236
|
transports: ["AGENT"],
|
|
256
237
|
handler: async ({ input }) => {
|
|
257
238
|
const root = await realpath2(config.root);
|
|
258
|
-
const
|
|
259
|
-
|
|
239
|
+
const relative = boundedCodingRelativePath(input.path, limits.maxPathBytes);
|
|
240
|
+
const handle = await openContainedFile(root, relative);
|
|
260
241
|
const maximum = Math.min(input.maxBytes ?? limits.maxReadBytes, limits.maxReadBytes);
|
|
261
|
-
const handle = await open(target.absolute, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
262
242
|
let selected;
|
|
263
243
|
let size;
|
|
264
244
|
let sha256;
|
|
265
245
|
try {
|
|
246
|
+
await authorizeCodingTool(config, { operation: "read", path: relative });
|
|
247
|
+
await assertContainedFileCurrent(root, relative, handle);
|
|
266
248
|
const metadata = await handle.stat();
|
|
267
249
|
if (!metadata.isFile())
|
|
268
250
|
throw new Error("Coding read path is not a regular file");
|
|
@@ -279,7 +261,7 @@ function createFileCodingTools(config, limits) {
|
|
|
279
261
|
const end = input.offset + selected.byteLength;
|
|
280
262
|
const truncated = end < size;
|
|
281
263
|
return {
|
|
282
|
-
path:
|
|
264
|
+
path: relative,
|
|
283
265
|
text,
|
|
284
266
|
bytes: selected.byteLength,
|
|
285
267
|
sha256,
|
|
@@ -297,23 +279,36 @@ function createFileCodingTools(config, limits) {
|
|
|
297
279
|
transports: ["AGENT"],
|
|
298
280
|
handler: async ({ input }) => {
|
|
299
281
|
const root = await realpath2(config.root);
|
|
300
|
-
const
|
|
282
|
+
const relative = boundedCodingRelativePath(input.path, limits.maxPathBytes);
|
|
301
283
|
const bytes = Buffer.byteLength(input.content);
|
|
302
284
|
if (bytes > limits.maxWriteBytes)
|
|
303
285
|
throw new Error("Coding tool write exceeds maxWriteBytes");
|
|
304
|
-
await
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
await
|
|
313
|
-
|
|
314
|
-
|
|
286
|
+
const parent = await openContainedParent(root, relative);
|
|
287
|
+
try {
|
|
288
|
+
await authorizeCodingTool(config, {
|
|
289
|
+
operation: "write",
|
|
290
|
+
path: relative,
|
|
291
|
+
bytes,
|
|
292
|
+
overwrite: input.overwrite
|
|
293
|
+
});
|
|
294
|
+
await assertContainedParentCurrent(root, relative, parent.handle);
|
|
295
|
+
if (input.overwrite) {
|
|
296
|
+
const current = await containedEntryMetadata(parent);
|
|
297
|
+
if (current?.isSymbolicLink())
|
|
298
|
+
throw new Error("Coding tools do not overwrite symlinks");
|
|
299
|
+
await writeContainedFile({
|
|
300
|
+
parent,
|
|
301
|
+
content: input.content,
|
|
302
|
+
replace: true,
|
|
303
|
+
...current && { mode: current.mode }
|
|
304
|
+
});
|
|
305
|
+
} else {
|
|
306
|
+
await writeContainedFile({ parent, content: input.content, replace: false });
|
|
307
|
+
}
|
|
308
|
+
} finally {
|
|
309
|
+
await parent.handle.close();
|
|
315
310
|
}
|
|
316
|
-
return { path:
|
|
311
|
+
return { path: relative, bytes };
|
|
317
312
|
}
|
|
318
313
|
});
|
|
319
314
|
return [read, write];
|
|
@@ -381,6 +376,10 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
381
376
|
maxDepth: limits.maxSearchDepth,
|
|
382
377
|
maxFiles: limits.maxSearchFiles,
|
|
383
378
|
symlinks: "skip",
|
|
379
|
+
...input.mode === "content" && {
|
|
380
|
+
readMaxBytes: limits.maxReadBytes,
|
|
381
|
+
skipUnreadable: true
|
|
382
|
+
},
|
|
384
383
|
excludeDirectory: (relative) => relative.split(path2.sep).some((segment) => excluded.has(segment))
|
|
385
384
|
});
|
|
386
385
|
const matches = [];
|
|
@@ -390,12 +389,9 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
390
389
|
if (file.relative.includes(input.query))
|
|
391
390
|
matches.push({ path: file.relative });
|
|
392
391
|
} else {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
text = (await readContainedUtf8File(file.absolute, limits.maxReadBytes)).text;
|
|
396
|
-
} catch {
|
|
392
|
+
const text = file.content?.text;
|
|
393
|
+
if (text === undefined)
|
|
397
394
|
continue;
|
|
398
|
-
}
|
|
399
395
|
const lines = text.split(`
|
|
400
396
|
`);
|
|
401
397
|
for (let index = 0;index < lines.length; index += 1) {
|
|
@@ -429,48 +425,61 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
429
425
|
transports: ["AGENT"],
|
|
430
426
|
handler: async ({ input }) => {
|
|
431
427
|
const root = await realpath3(config.root);
|
|
432
|
-
const
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const current = await readContainedUtf8File(target.absolute, limits.maxWriteBytes);
|
|
461
|
-
if (sha256(current.text) !== baseSha256)
|
|
462
|
-
throw new Error("Coding patch base digest became stale before apply");
|
|
463
|
-
await atomicCodingReplace(target.absolute, changed, current.mode);
|
|
428
|
+
const relative = boundedCodingRelativePath(input.path, limits.maxPathBytes);
|
|
429
|
+
const parent = await openContainedParent(root, relative);
|
|
430
|
+
try {
|
|
431
|
+
const initial = await openContainedParentFile(parent);
|
|
432
|
+
const read = await readContainedUtf8Handle(initial, limits.maxWriteBytes).finally(() => initial.close());
|
|
433
|
+
const source = read.text;
|
|
434
|
+
const baseSha256 = sha256(source);
|
|
435
|
+
if (baseSha256 !== input.baseSha256)
|
|
436
|
+
conflict("Coding patch base digest is stale");
|
|
437
|
+
const count = textOccurrences(source, input.oldText);
|
|
438
|
+
if (count === 0)
|
|
439
|
+
throw new Error("Coding patch text was not found");
|
|
440
|
+
if (!input.replaceAll && count !== 1)
|
|
441
|
+
throw new Error("Coding patch text is not unique");
|
|
442
|
+
const replacements = input.replaceAll ? count : 1;
|
|
443
|
+
const changed = input.replaceAll ? source.replaceAll(input.oldText, input.newText) : source.replace(input.oldText, input.newText);
|
|
444
|
+
const bytes = Buffer.byteLength(changed);
|
|
445
|
+
const resultSha256 = sha256(changed);
|
|
446
|
+
if (bytes > limits.maxWriteBytes)
|
|
447
|
+
throw new Error("Coding patch exceeds maxWriteBytes");
|
|
448
|
+
await authorizeCodingTool(config, {
|
|
449
|
+
operation: "patch",
|
|
450
|
+
path: relative,
|
|
451
|
+
baseSha256,
|
|
452
|
+
resultSha256,
|
|
453
|
+
resultBytes: bytes,
|
|
454
|
+
replacements,
|
|
455
|
+
dryRun: input.dryRun
|
|
464
456
|
});
|
|
457
|
+
await assertContainedParentCurrent(root, relative, parent.handle);
|
|
458
|
+
if (!input.dryRun) {
|
|
459
|
+
await withCodingPathLock(`${root}:${relative}`, async () => {
|
|
460
|
+
const currentHandle = await openContainedParentFile(parent);
|
|
461
|
+
const current = await readContainedUtf8Handle(currentHandle, limits.maxWriteBytes).finally(() => currentHandle.close());
|
|
462
|
+
if (sha256(current.text) !== baseSha256)
|
|
463
|
+
conflict("Coding patch base digest became stale before apply");
|
|
464
|
+
await writeContainedFile({
|
|
465
|
+
parent,
|
|
466
|
+
content: changed,
|
|
467
|
+
replace: true,
|
|
468
|
+
mode: current.mode
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
path: relative,
|
|
474
|
+
baseSha256,
|
|
475
|
+
resultSha256,
|
|
476
|
+
replacements,
|
|
477
|
+
bytes,
|
|
478
|
+
applied: !input.dryRun
|
|
479
|
+
};
|
|
480
|
+
} finally {
|
|
481
|
+
await parent.handle.close();
|
|
465
482
|
}
|
|
466
|
-
return {
|
|
467
|
-
path: target.relative,
|
|
468
|
-
baseSha256,
|
|
469
|
-
resultSha256,
|
|
470
|
-
replacements,
|
|
471
|
-
bytes,
|
|
472
|
-
applied: !input.dryRun
|
|
473
|
-
};
|
|
474
483
|
}
|
|
475
484
|
});
|
|
476
485
|
return [search, patch];
|
|
@@ -478,7 +487,7 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
478
487
|
|
|
479
488
|
// src/agent-runtime/coding-tool-shell.ts
|
|
480
489
|
import { spawn } from "node:child_process";
|
|
481
|
-
import { realpath as realpath4, stat
|
|
490
|
+
import { realpath as realpath4, stat } from "node:fs/promises";
|
|
482
491
|
async function runShell(input) {
|
|
483
492
|
const stdoutHeader = Buffer.from(`--- stdout ---
|
|
484
493
|
`);
|
|
@@ -488,11 +497,23 @@ async function runShell(input) {
|
|
|
488
497
|
const artifactPayloadLimit = input.maxArtifactBytes - stdoutHeader.byteLength - stderrHeader.byteLength;
|
|
489
498
|
if (input.artifacts && artifactPayloadLimit < 0)
|
|
490
499
|
throw new Error("maxArtifactBytes is smaller than the shell artifact envelope");
|
|
500
|
+
if (input.signal?.aborted) {
|
|
501
|
+
return ShellOutputSchema.parse({
|
|
502
|
+
executable: input.executableName,
|
|
503
|
+
exitCode: null,
|
|
504
|
+
signal: null,
|
|
505
|
+
stdout: "",
|
|
506
|
+
stderr: "",
|
|
507
|
+
outcome: "cancelled"
|
|
508
|
+
});
|
|
509
|
+
}
|
|
491
510
|
return await new Promise((resolve, reject) => {
|
|
511
|
+
const ownsProcessGroup = process.platform !== "win32";
|
|
492
512
|
const child = spawn(input.executable, input.args, {
|
|
493
513
|
cwd: input.cwd,
|
|
494
514
|
env: input.environment,
|
|
495
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
515
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
516
|
+
detached: ownsProcessGroup
|
|
496
517
|
});
|
|
497
518
|
const stdout = [];
|
|
498
519
|
const stderr = [];
|
|
@@ -502,15 +523,74 @@ async function runShell(input) {
|
|
|
502
523
|
let artifactBytes = 0;
|
|
503
524
|
let outcome = "exited";
|
|
504
525
|
let settled = false;
|
|
526
|
+
let settlementTimer;
|
|
527
|
+
const cancel = () => terminate("cancelled");
|
|
528
|
+
const cleanup = () => {
|
|
529
|
+
clearTimeout(timer);
|
|
530
|
+
if (settlementTimer)
|
|
531
|
+
clearTimeout(settlementTimer);
|
|
532
|
+
input.signal?.removeEventListener("abort", cancel);
|
|
533
|
+
};
|
|
534
|
+
const persistAndResolve = async (exitCode, signal) => {
|
|
535
|
+
if (settled)
|
|
536
|
+
return;
|
|
537
|
+
settled = true;
|
|
538
|
+
cleanup();
|
|
539
|
+
try {
|
|
540
|
+
const hasArtifact = input.artifacts && artifactBytes > input.maxOutputBytes;
|
|
541
|
+
const artifactData = hasArtifact ? Buffer.concat([stdoutHeader, ...artifactStdout, stderrHeader, ...artifactStderr]) : undefined;
|
|
542
|
+
const persisted = hasArtifact ? await input.artifacts?.write({
|
|
543
|
+
mediaType: "text/plain; charset=utf-8",
|
|
544
|
+
data: artifactData ?? new Uint8Array
|
|
545
|
+
}) : undefined;
|
|
546
|
+
resolve(ShellOutputSchema.parse({
|
|
547
|
+
executable: input.executableName,
|
|
548
|
+
exitCode,
|
|
549
|
+
signal,
|
|
550
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
551
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
552
|
+
outcome,
|
|
553
|
+
...persisted && {
|
|
554
|
+
artifact: {
|
|
555
|
+
reference: persisted.reference,
|
|
556
|
+
bytes: artifactData?.byteLength ?? 0,
|
|
557
|
+
truncated: outcome === "output-limit"
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}));
|
|
561
|
+
} catch (error) {
|
|
562
|
+
reject(error);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
const killOwnedProcessGroup = () => {
|
|
566
|
+
if (!ownsProcessGroup || child.pid === undefined)
|
|
567
|
+
return false;
|
|
568
|
+
try {
|
|
569
|
+
process.kill(-child.pid, "SIGKILL");
|
|
570
|
+
return true;
|
|
571
|
+
} catch {
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
const boundStreamSettlement = () => {
|
|
576
|
+
if (settlementTimer)
|
|
577
|
+
return;
|
|
578
|
+
settlementTimer = setTimeout(() => {
|
|
579
|
+
child.stdout.destroy();
|
|
580
|
+
child.stderr.destroy();
|
|
581
|
+
persistAndResolve(child.exitCode, child.signalCode);
|
|
582
|
+
}, input.terminationGraceMs);
|
|
583
|
+
};
|
|
505
584
|
const terminate = (reason) => {
|
|
506
585
|
if (settled || outcome !== "exited")
|
|
507
586
|
return;
|
|
508
587
|
outcome = reason;
|
|
509
|
-
|
|
588
|
+
if (!killOwnedProcessGroup())
|
|
589
|
+
child.kill("SIGKILL");
|
|
590
|
+
boundStreamSettlement();
|
|
510
591
|
};
|
|
511
592
|
const timer = setTimeout(() => terminate("timeout"), input.timeoutMs);
|
|
512
593
|
timer.unref();
|
|
513
|
-
const cancel = () => terminate("cancelled");
|
|
514
594
|
const retain = (target, artifactTarget, chunk) => {
|
|
515
595
|
const remaining = Math.max(0, input.maxOutputBytes - retained);
|
|
516
596
|
if (remaining > 0) {
|
|
@@ -536,42 +616,18 @@ async function runShell(input) {
|
|
|
536
616
|
if (settled)
|
|
537
617
|
return;
|
|
538
618
|
settled = true;
|
|
539
|
-
|
|
540
|
-
input.signal?.removeEventListener("abort", cancel);
|
|
619
|
+
cleanup();
|
|
541
620
|
reject(error);
|
|
542
621
|
});
|
|
543
|
-
child.on("
|
|
544
|
-
if (
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
try {
|
|
550
|
-
const hasArtifact = input.artifacts && artifactBytes > input.maxOutputBytes;
|
|
551
|
-
const artifactData = hasArtifact ? Buffer.concat([stdoutHeader, ...artifactStdout, stderrHeader, ...artifactStderr]) : undefined;
|
|
552
|
-
const persisted = hasArtifact ? await input.artifacts?.write({
|
|
553
|
-
mediaType: "text/plain; charset=utf-8",
|
|
554
|
-
data: artifactData ?? new Uint8Array
|
|
555
|
-
}) : undefined;
|
|
556
|
-
resolve(ShellOutputSchema.parse({
|
|
557
|
-
executable: input.executableName,
|
|
558
|
-
exitCode,
|
|
559
|
-
signal,
|
|
560
|
-
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
561
|
-
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
562
|
-
outcome,
|
|
563
|
-
...persisted && {
|
|
564
|
-
artifact: {
|
|
565
|
-
reference: persisted.reference,
|
|
566
|
-
bytes: artifactData?.byteLength ?? 0,
|
|
567
|
-
truncated: outcome === "output-limit"
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}));
|
|
571
|
-
} catch (error) {
|
|
572
|
-
reject(error);
|
|
622
|
+
child.on("exit", (exitCode, signal) => {
|
|
623
|
+
if (outcome === "exited")
|
|
624
|
+
killOwnedProcessGroup();
|
|
625
|
+
boundStreamSettlement();
|
|
626
|
+
if (child.stdout.destroyed && child.stderr.destroyed) {
|
|
627
|
+
persistAndResolve(exitCode, signal);
|
|
573
628
|
}
|
|
574
629
|
});
|
|
630
|
+
child.on("close", (exitCode, signal) => void persistAndResolve(exitCode, signal));
|
|
575
631
|
input.signal?.addEventListener("abort", cancel, { once: true });
|
|
576
632
|
if (input.signal?.aborted)
|
|
577
633
|
cancel();
|
|
@@ -600,7 +656,7 @@ function createShellCodingTool(config, limits) {
|
|
|
600
656
|
throw new Error("Coding tool executable is not declared");
|
|
601
657
|
const root = await realpath4(config.root);
|
|
602
658
|
const cwd = await existingCodingPath(root, input.cwd, limits.maxPathBytes);
|
|
603
|
-
if (!(await
|
|
659
|
+
if (!(await stat(cwd.absolute)).isDirectory()) {
|
|
604
660
|
throw new Error("Coding tool cwd is not a directory");
|
|
605
661
|
}
|
|
606
662
|
await authorizeCodingTool(config, {
|
|
@@ -617,6 +673,7 @@ function createShellCodingTool(config, limits) {
|
|
|
617
673
|
environment: config.environment ?? {},
|
|
618
674
|
...signal && { signal },
|
|
619
675
|
timeoutMs: limits.shellTimeoutMs,
|
|
676
|
+
terminationGraceMs: limits.shellTerminationGraceMs,
|
|
620
677
|
maxOutputBytes: limits.maxShellOutputBytes,
|
|
621
678
|
maxArtifactBytes: limits.maxArtifactBytes,
|
|
622
679
|
...config.artifacts && { artifacts: config.artifacts }
|
|
@@ -3,28 +3,29 @@ import {
|
|
|
3
3
|
composeAgentPrompt,
|
|
4
4
|
createAgentRuntime,
|
|
5
5
|
createAgentRuntimeEventSink
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-vy5bjy07.js";
|
|
7
7
|
import {
|
|
8
|
-
readContainedUtf8File,
|
|
9
8
|
walkContainedFiles
|
|
10
|
-
} from "./index-
|
|
9
|
+
} from "./index-1z5xxfst.js";
|
|
11
10
|
import {
|
|
12
11
|
AgentModelDescriptorSchema
|
|
13
12
|
} from "./index-tg3m2ec5.js";
|
|
14
13
|
import"./index-es0h4w26.js";
|
|
15
14
|
import"./index-a59da114.js";
|
|
15
|
+
import"./index-3xnq72rz.js";
|
|
16
16
|
import {
|
|
17
17
|
defineRuntimeTool
|
|
18
18
|
} from "./index-wwst0td5.js";
|
|
19
|
-
import"./index-
|
|
20
|
-
import"./index-
|
|
19
|
+
import"./index-qzbg46b6.js";
|
|
20
|
+
import"./index-ktsps64f.js";
|
|
21
21
|
import {
|
|
22
22
|
AgentMessagePartSchema,
|
|
23
23
|
AgentSnapshotSchema
|
|
24
24
|
} from "./index-x1th9s8c.js";
|
|
25
25
|
import"./index-22by16v6.js";
|
|
26
26
|
import"./index-cby4ar3v.js";
|
|
27
|
-
import"./index-
|
|
27
|
+
import"./index-bd17ytae.js";
|
|
28
|
+
import"./index-vj3vvpaa.js";
|
|
28
29
|
import"./index-0w9abg87.js";
|
|
29
30
|
import"./index-qyrqwr4c.js";
|
|
30
31
|
import"./index-6k1937bx.js";
|
|
@@ -202,13 +203,16 @@ function createAgentHarnessFileResources(config) {
|
|
|
202
203
|
const files = await walkContainedFiles({
|
|
203
204
|
root: resolvedRoot,
|
|
204
205
|
maxDepth: limits.maxDepth,
|
|
205
|
-
maxFiles: limits.maxFiles - fileCount
|
|
206
|
+
maxFiles: limits.maxFiles - fileCount,
|
|
207
|
+
readMaxBytes: limits.maxFileBytes
|
|
206
208
|
});
|
|
207
209
|
fileCount += files.length;
|
|
208
210
|
for (const file of files) {
|
|
209
211
|
if (root.kind === "skill" && path.basename(file.absolute) !== "SKILL.md")
|
|
210
212
|
continue;
|
|
211
|
-
const read =
|
|
213
|
+
const read = file.content;
|
|
214
|
+
if (!read)
|
|
215
|
+
throw new Error("Agent harness resource content is unavailable");
|
|
212
216
|
totalBytes += read.bytes;
|
|
213
217
|
if (totalBytes > limits.maxTotalBytes) {
|
|
214
218
|
throw new Error("Agent harness resources exceed maxTotalBytes");
|
package/dist/agent-runtime.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
registerDeferredToolRepair,
|
|
28
28
|
repairedSearchCall,
|
|
29
29
|
selectAgentHistory
|
|
30
|
-
} from "./index-
|
|
30
|
+
} from "./index-vy5bjy07.js";
|
|
31
31
|
import {
|
|
32
32
|
AgentModelCapabilitySchema,
|
|
33
33
|
AgentModelCatalogEntrySchema,
|
|
@@ -82,14 +82,15 @@ import {
|
|
|
82
82
|
import {
|
|
83
83
|
buildToolManifest,
|
|
84
84
|
mountAgent
|
|
85
|
-
} from "./index-
|
|
86
|
-
import"./index-
|
|
85
|
+
} from "./index-s8nt8c22.js";
|
|
86
|
+
import"./index-3xnq72rz.js";
|
|
87
|
+
import"./index-vc498pst.js";
|
|
87
88
|
import {
|
|
88
89
|
defineRuntimeTool
|
|
89
90
|
} from "./index-wwst0td5.js";
|
|
90
|
-
import"./index-
|
|
91
|
-
import"./index-
|
|
92
|
-
import"./index-
|
|
91
|
+
import"./index-7rey2b8s.js";
|
|
92
|
+
import"./index-qzbg46b6.js";
|
|
93
|
+
import"./index-ktsps64f.js";
|
|
93
94
|
import {
|
|
94
95
|
AgentAssistantPlaceholderSchema,
|
|
95
96
|
AgentControlPartSchema,
|
|
@@ -128,7 +129,8 @@ import"./index-cby4ar3v.js";
|
|
|
128
129
|
import {
|
|
129
130
|
childSpan,
|
|
130
131
|
createTraceContext
|
|
131
|
-
} from "./index-
|
|
132
|
+
} from "./index-bd17ytae.js";
|
|
133
|
+
import"./index-vj3vvpaa.js";
|
|
132
134
|
import"./index-0w9abg87.js";
|
|
133
135
|
import {
|
|
134
136
|
executableAgentRuntimeTools
|
|
@@ -14,6 +14,7 @@ export interface ManagedServerResourceConfig<TRuntime> {
|
|
|
14
14
|
readonly dependsOn?: readonly ManagedResourceDependency[];
|
|
15
15
|
readonly required?: boolean;
|
|
16
16
|
readonly retryAfterSeconds?: number;
|
|
17
|
+
readonly realtimeCloseTimeoutMs?: number;
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* A managed resource that owns a managed server.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-resource.d.ts","sourceRoot":"","sources":["../../src/application/server-resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAmC,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC/B,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,2BAA2B,CAAC,QAAQ;IACnD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EACX,mBAAmB,CAAC,QAAQ,CAAC,GAC7B,CAAC,CACC,OAAO,EAAE,sBAAsB,KAC5B,mBAAmB,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"server-resource.d.ts","sourceRoot":"","sources":["../../src/application/server-resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAmC,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC/B,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,2BAA2B,CAAC,QAAQ;IACnD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EACX,mBAAmB,CAAC,QAAQ,CAAC,GAC7B,CAAC,CACC,OAAO,EAAE,sBAAsB,KAC5B,mBAAmB,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB,CAAC,QAAQ,CAAE,SAAQ,eAAe;IACtE,KAAK,CACH,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,CAAC,QAAQ,EAC5C,MAAM,EAAE,2BAA2B,CAAC,QAAQ,CAAC,GAC5C,qBAAqB,CAAC,QAAQ,CAAC,CA2IjC"}
|
package/dist/application.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
ApplicationShutdownBudgetSchema,
|
|
30
30
|
ApplicationShutdownOptionsSchema,
|
|
31
31
|
createApplication
|
|
32
|
-
} from "./index-
|
|
32
|
+
} from "./index-w0445741.js";
|
|
33
33
|
import {
|
|
34
34
|
defineManagedResource,
|
|
35
35
|
managedResourceDependencyId
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
ManagedResourceStateSchema,
|
|
48
48
|
projectApplicationStatus
|
|
49
49
|
} from "./index-8eywc9zv.js";
|
|
50
|
-
import"./index-
|
|
50
|
+
import"./index-7wpgrqa8.js";
|
|
51
51
|
import"./index-0w9abg87.js";
|
|
52
52
|
import {
|
|
53
53
|
isRecord
|
|
@@ -1030,6 +1030,9 @@ function managedServerResource(config) {
|
|
|
1030
1030
|
...gracePeriodMs !== undefined && { gracePeriodMs },
|
|
1031
1031
|
...forceTimeoutMs !== undefined && { forceTimeoutMs },
|
|
1032
1032
|
retryAfterSeconds: grace(config.retryAfterSeconds ?? 5),
|
|
1033
|
+
...config.realtimeCloseTimeoutMs !== undefined && {
|
|
1034
|
+
realtimeCloseTimeoutMs: grace(config.realtimeCloseTimeoutMs)
|
|
1035
|
+
},
|
|
1033
1036
|
signal: context.signal
|
|
1034
1037
|
};
|
|
1035
1038
|
shutdownPromise = isHandle(server) ? server.shutdown(options) : server.then((handle) => handle.shutdown(options));
|
package/dist/cli.js
CHANGED
|
@@ -5,16 +5,17 @@ import {
|
|
|
5
5
|
emitResult,
|
|
6
6
|
parseCliArgs,
|
|
7
7
|
pollUntilDone
|
|
8
|
-
} from "./index-
|
|
9
|
-
import"./index-
|
|
8
|
+
} from "./index-mjx0wt4c.js";
|
|
9
|
+
import"./index-vc498pst.js";
|
|
10
10
|
import"./index-wwst0td5.js";
|
|
11
|
-
import"./index-
|
|
12
|
-
import"./index-
|
|
13
|
-
import"./index-
|
|
11
|
+
import"./index-7rey2b8s.js";
|
|
12
|
+
import"./index-qzbg46b6.js";
|
|
13
|
+
import"./index-ktsps64f.js";
|
|
14
14
|
import"./index-sbdmyz75.js";
|
|
15
15
|
import"./index-22by16v6.js";
|
|
16
16
|
import"./index-cby4ar3v.js";
|
|
17
|
-
import"./index-
|
|
17
|
+
import"./index-bd17ytae.js";
|
|
18
|
+
import"./index-vj3vvpaa.js";
|
|
18
19
|
import"./index-0w9abg87.js";
|
|
19
20
|
import"./index-qyrqwr4c.js";
|
|
20
21
|
import"./index-6k1937bx.js";
|