stitchkit 0.69.0 → 0.70.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 +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 -0
- 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 +29 -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 +197 -137
- package/dist/agent-runtime-harness.js +12 -8
- package/dist/agent-runtime.js +9 -7
- package/dist/cli.js +7 -6
- package/dist/{index-t4dpby6e.js → index-0yphgata.js} +1 -1
- package/dist/{index-444747ww.js → index-38hs3a58.js} +10 -8
- package/dist/index-3xnq72rz.js +21 -0
- package/dist/{index-kg9xx84n.js → index-7rey2b8s.js} +1 -1
- 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-kxxyvkka.js → index-wc80at9n.js} +2 -2
- package/dist/index-xbtcszs7.js +202 -0
- package/dist/{index-gqdfpv4n.js → index-y3w12g8d.js} +2 -2
- package/dist/node.js +5 -4
- package/dist/observability/index.js +4 -3
- package/dist/remote.js +4 -3
- package/dist/server/index.js +11 -9
- package/dist/testing.js +4 -3
- 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 +56 -14
- package/package.json +1 -1
- package/dist/index-v3dpzpjw.js +0 -92
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
assertContainedFileCurrent,
|
|
3
|
+
assertContainedParentCurrent,
|
|
4
|
+
openContainedFile,
|
|
5
|
+
openContainedParent,
|
|
6
|
+
readContainedUtf8Handle,
|
|
3
7
|
scanContainedFiles
|
|
4
|
-
} from "./index-
|
|
8
|
+
} from "./index-xbtcszs7.js";
|
|
5
9
|
import {
|
|
6
10
|
defineRuntimeTool
|
|
7
11
|
} from "./index-wwst0td5.js";
|
|
8
12
|
import"./index-22by16v6.js";
|
|
9
13
|
import"./index-cby4ar3v.js";
|
|
14
|
+
import"./index-vj3vvpaa.js";
|
|
15
|
+
import {
|
|
16
|
+
conflict,
|
|
17
|
+
forbidden
|
|
18
|
+
} from "./index-0w9abg87.js";
|
|
10
19
|
import"./index-qyrqwr4c.js";
|
|
20
|
+
import"./index-6k1937bx.js";
|
|
11
21
|
|
|
12
22
|
// src/agent-runtime/coding-tools.ts
|
|
13
|
-
import
|
|
23
|
+
import path4 from "node:path";
|
|
14
24
|
import { z as z3 } from "zod";
|
|
15
25
|
|
|
16
26
|
// src/agent-runtime/coding-tool-contract.ts
|
|
@@ -26,7 +36,8 @@ var AgentCodingToolLimitsSchema = z.object({
|
|
|
26
36
|
maxSearchResults: z.int().positive(),
|
|
27
37
|
maxSearchFiles: z.int().positive(),
|
|
28
38
|
maxSearchDepth: z.int().nonnegative(),
|
|
29
|
-
shellTimeoutMs: z.int().positive()
|
|
39
|
+
shellTimeoutMs: z.int().positive(),
|
|
40
|
+
shellTerminationGraceMs: z.int().positive()
|
|
30
41
|
}).strict();
|
|
31
42
|
var AgentCodingToolAuthorizationSchema = z.discriminatedUnion("operation", [
|
|
32
43
|
z.object({ operation: z.literal("read"), path: z.string().min(1) }).strict(),
|
|
@@ -121,7 +132,8 @@ var DEFAULT_LIMITS = {
|
|
|
121
132
|
maxSearchResults: 100,
|
|
122
133
|
maxSearchFiles: 1e4,
|
|
123
134
|
maxSearchDepth: 32,
|
|
124
|
-
shellTimeoutMs: 30000
|
|
135
|
+
shellTimeoutMs: 30000,
|
|
136
|
+
shellTerminationGraceMs: 250
|
|
125
137
|
};
|
|
126
138
|
function resolveCodingToolLimits(input) {
|
|
127
139
|
return AgentCodingToolLimitsSchema.parse({ ...DEFAULT_LIMITS, ...input });
|
|
@@ -129,8 +141,8 @@ function resolveCodingToolLimits(input) {
|
|
|
129
141
|
|
|
130
142
|
// src/agent-runtime/coding-tool-files.ts
|
|
131
143
|
import { createHash } from "node:crypto";
|
|
132
|
-
import {
|
|
133
|
-
import
|
|
144
|
+
import { lstat as lstat2, realpath as realpath2, writeFile as writeFile2 } from "node:fs/promises";
|
|
145
|
+
import path2 from "node:path";
|
|
134
146
|
|
|
135
147
|
// src/agent-runtime/coding-tool-paths.ts
|
|
136
148
|
import { lstat, realpath, rename, unlink, writeFile } from "node:fs/promises";
|
|
@@ -150,41 +162,20 @@ function inputPath(root, requested, maxPathBytes) {
|
|
|
150
162
|
throw new Error("Coding tool path escapes its root");
|
|
151
163
|
return resolved;
|
|
152
164
|
}
|
|
165
|
+
function boundedCodingRelativePath(requested, maxPathBytes) {
|
|
166
|
+
inputPath(path.parse(process.cwd()).root, requested, maxPathBytes);
|
|
167
|
+
return requested;
|
|
168
|
+
}
|
|
153
169
|
async function existingCodingPath(root, requested, maxPathBytes) {
|
|
154
170
|
const resolved = await realpath(inputPath(root, requested, maxPathBytes));
|
|
155
171
|
if (!within(root, resolved))
|
|
156
172
|
throw new Error("Coding tool path resolves outside its root");
|
|
157
173
|
return { absolute: resolved, relative: path.relative(root, resolved) || "." };
|
|
158
174
|
}
|
|
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
175
|
async function authorizeCodingTool(config, request) {
|
|
185
176
|
const parsed = AgentCodingToolAuthorizationSchema.parse(request);
|
|
186
177
|
if (!await config.authorize(parsed))
|
|
187
|
-
|
|
178
|
+
forbidden("Coding tool permission denied");
|
|
188
179
|
}
|
|
189
180
|
async function atomicCodingReplace(target, content, mode) {
|
|
190
181
|
const temporary = path.join(path.dirname(target), `.${path.basename(target)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
@@ -255,14 +246,15 @@ function createFileCodingTools(config, limits) {
|
|
|
255
246
|
transports: ["AGENT"],
|
|
256
247
|
handler: async ({ input }) => {
|
|
257
248
|
const root = await realpath2(config.root);
|
|
258
|
-
const
|
|
259
|
-
|
|
249
|
+
const relative = boundedCodingRelativePath(input.path, limits.maxPathBytes);
|
|
250
|
+
const handle = await openContainedFile(root, relative);
|
|
260
251
|
const maximum = Math.min(input.maxBytes ?? limits.maxReadBytes, limits.maxReadBytes);
|
|
261
|
-
const handle = await open(target.absolute, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
262
252
|
let selected;
|
|
263
253
|
let size;
|
|
264
254
|
let sha256;
|
|
265
255
|
try {
|
|
256
|
+
await authorizeCodingTool(config, { operation: "read", path: relative });
|
|
257
|
+
await assertContainedFileCurrent(root, relative, handle);
|
|
266
258
|
const metadata = await handle.stat();
|
|
267
259
|
if (!metadata.isFile())
|
|
268
260
|
throw new Error("Coding read path is not a regular file");
|
|
@@ -279,7 +271,7 @@ function createFileCodingTools(config, limits) {
|
|
|
279
271
|
const end = input.offset + selected.byteLength;
|
|
280
272
|
const truncated = end < size;
|
|
281
273
|
return {
|
|
282
|
-
path:
|
|
274
|
+
path: relative,
|
|
283
275
|
text,
|
|
284
276
|
bytes: selected.byteLength,
|
|
285
277
|
sha256,
|
|
@@ -297,23 +289,32 @@ function createFileCodingTools(config, limits) {
|
|
|
297
289
|
transports: ["AGENT"],
|
|
298
290
|
handler: async ({ input }) => {
|
|
299
291
|
const root = await realpath2(config.root);
|
|
300
|
-
const
|
|
292
|
+
const relative = boundedCodingRelativePath(input.path, limits.maxPathBytes);
|
|
301
293
|
const bytes = Buffer.byteLength(input.content);
|
|
302
294
|
if (bytes > limits.maxWriteBytes)
|
|
303
295
|
throw new Error("Coding tool write exceeds maxWriteBytes");
|
|
304
|
-
await
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
296
|
+
const parent = await openContainedParent(root, relative);
|
|
297
|
+
const target = path2.join(parent.path, parent.basename);
|
|
298
|
+
try {
|
|
299
|
+
await authorizeCodingTool(config, {
|
|
300
|
+
operation: "write",
|
|
301
|
+
path: relative,
|
|
302
|
+
bytes,
|
|
303
|
+
overwrite: input.overwrite
|
|
304
|
+
});
|
|
305
|
+
await assertContainedParentCurrent(root, relative, parent.handle);
|
|
306
|
+
if (input.overwrite) {
|
|
307
|
+
const current = await lstat2(target).catch(() => null);
|
|
308
|
+
if (current?.isSymbolicLink())
|
|
309
|
+
throw new Error("Coding tools do not overwrite symlinks");
|
|
310
|
+
await atomicCodingReplace(target, input.content, current?.mode);
|
|
311
|
+
} else {
|
|
312
|
+
await writeFile2(target, input.content, { flag: "wx" });
|
|
313
|
+
}
|
|
314
|
+
} finally {
|
|
315
|
+
await parent.handle.close();
|
|
315
316
|
}
|
|
316
|
-
return { path:
|
|
317
|
+
return { path: relative, bytes };
|
|
317
318
|
}
|
|
318
319
|
});
|
|
319
320
|
return [read, write];
|
|
@@ -321,8 +322,9 @@ function createFileCodingTools(config, limits) {
|
|
|
321
322
|
|
|
322
323
|
// src/agent-runtime/coding-tool-search-patch.ts
|
|
323
324
|
import { createHash as createHash2 } from "node:crypto";
|
|
324
|
-
import {
|
|
325
|
-
import
|
|
325
|
+
import { constants } from "node:fs";
|
|
326
|
+
import { open, realpath as realpath3 } from "node:fs/promises";
|
|
327
|
+
import path3 from "node:path";
|
|
326
328
|
import { z as z2 } from "zod";
|
|
327
329
|
var DEFAULT_EXCLUDED_DIRECTORIES = [
|
|
328
330
|
".git",
|
|
@@ -381,7 +383,11 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
381
383
|
maxDepth: limits.maxSearchDepth,
|
|
382
384
|
maxFiles: limits.maxSearchFiles,
|
|
383
385
|
symlinks: "skip",
|
|
384
|
-
|
|
386
|
+
...input.mode === "content" && {
|
|
387
|
+
readMaxBytes: limits.maxReadBytes,
|
|
388
|
+
skipUnreadable: true
|
|
389
|
+
},
|
|
390
|
+
excludeDirectory: (relative) => relative.split(path3.sep).some((segment) => excluded.has(segment))
|
|
385
391
|
});
|
|
386
392
|
const matches = [];
|
|
387
393
|
let truncated = false;
|
|
@@ -390,12 +396,9 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
390
396
|
if (file.relative.includes(input.query))
|
|
391
397
|
matches.push({ path: file.relative });
|
|
392
398
|
} else {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
text = (await readContainedUtf8File(file.absolute, limits.maxReadBytes)).text;
|
|
396
|
-
} catch {
|
|
399
|
+
const text = file.content?.text;
|
|
400
|
+
if (text === undefined)
|
|
397
401
|
continue;
|
|
398
|
-
}
|
|
399
402
|
const lines = text.split(`
|
|
400
403
|
`);
|
|
401
404
|
for (let index = 0;index < lines.length; index += 1) {
|
|
@@ -429,48 +432,57 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
429
432
|
transports: ["AGENT"],
|
|
430
433
|
handler: async ({ input }) => {
|
|
431
434
|
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
|
-
|
|
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);
|
|
435
|
+
const relative = boundedCodingRelativePath(input.path, limits.maxPathBytes);
|
|
436
|
+
const parent = await openContainedParent(root, relative);
|
|
437
|
+
try {
|
|
438
|
+
const target = path3.join(parent.path, parent.basename);
|
|
439
|
+
const initial = await open(target, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
440
|
+
const read = await readContainedUtf8Handle(initial, limits.maxWriteBytes).finally(() => initial.close());
|
|
441
|
+
const source = read.text;
|
|
442
|
+
const baseSha256 = sha256(source);
|
|
443
|
+
if (baseSha256 !== input.baseSha256)
|
|
444
|
+
conflict("Coding patch base digest is stale");
|
|
445
|
+
const count = textOccurrences(source, input.oldText);
|
|
446
|
+
if (count === 0)
|
|
447
|
+
throw new Error("Coding patch text was not found");
|
|
448
|
+
if (!input.replaceAll && count !== 1)
|
|
449
|
+
throw new Error("Coding patch text is not unique");
|
|
450
|
+
const replacements = input.replaceAll ? count : 1;
|
|
451
|
+
const changed = input.replaceAll ? source.replaceAll(input.oldText, input.newText) : source.replace(input.oldText, input.newText);
|
|
452
|
+
const bytes = Buffer.byteLength(changed);
|
|
453
|
+
const resultSha256 = sha256(changed);
|
|
454
|
+
if (bytes > limits.maxWriteBytes)
|
|
455
|
+
throw new Error("Coding patch exceeds maxWriteBytes");
|
|
456
|
+
await authorizeCodingTool(config, {
|
|
457
|
+
operation: "patch",
|
|
458
|
+
path: relative,
|
|
459
|
+
baseSha256,
|
|
460
|
+
resultSha256,
|
|
461
|
+
resultBytes: bytes,
|
|
462
|
+
replacements,
|
|
463
|
+
dryRun: input.dryRun
|
|
464
464
|
});
|
|
465
|
+
await assertContainedParentCurrent(root, relative, parent.handle);
|
|
466
|
+
if (!input.dryRun) {
|
|
467
|
+
await withCodingPathLock(`${root}:${relative}`, async () => {
|
|
468
|
+
const currentHandle = await open(target, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
469
|
+
const current = await readContainedUtf8Handle(currentHandle, limits.maxWriteBytes).finally(() => currentHandle.close());
|
|
470
|
+
if (sha256(current.text) !== baseSha256)
|
|
471
|
+
conflict("Coding patch base digest became stale before apply");
|
|
472
|
+
await atomicCodingReplace(target, changed, current.mode);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
return {
|
|
476
|
+
path: relative,
|
|
477
|
+
baseSha256,
|
|
478
|
+
resultSha256,
|
|
479
|
+
replacements,
|
|
480
|
+
bytes,
|
|
481
|
+
applied: !input.dryRun
|
|
482
|
+
};
|
|
483
|
+
} finally {
|
|
484
|
+
await parent.handle.close();
|
|
465
485
|
}
|
|
466
|
-
return {
|
|
467
|
-
path: target.relative,
|
|
468
|
-
baseSha256,
|
|
469
|
-
resultSha256,
|
|
470
|
-
replacements,
|
|
471
|
-
bytes,
|
|
472
|
-
applied: !input.dryRun
|
|
473
|
-
};
|
|
474
486
|
}
|
|
475
487
|
});
|
|
476
488
|
return [search, patch];
|
|
@@ -478,7 +490,7 @@ function createSearchAndPatchCodingTools(config, limits) {
|
|
|
478
490
|
|
|
479
491
|
// src/agent-runtime/coding-tool-shell.ts
|
|
480
492
|
import { spawn } from "node:child_process";
|
|
481
|
-
import { realpath as realpath4, stat
|
|
493
|
+
import { realpath as realpath4, stat } from "node:fs/promises";
|
|
482
494
|
async function runShell(input) {
|
|
483
495
|
const stdoutHeader = Buffer.from(`--- stdout ---
|
|
484
496
|
`);
|
|
@@ -488,11 +500,23 @@ async function runShell(input) {
|
|
|
488
500
|
const artifactPayloadLimit = input.maxArtifactBytes - stdoutHeader.byteLength - stderrHeader.byteLength;
|
|
489
501
|
if (input.artifacts && artifactPayloadLimit < 0)
|
|
490
502
|
throw new Error("maxArtifactBytes is smaller than the shell artifact envelope");
|
|
503
|
+
if (input.signal?.aborted) {
|
|
504
|
+
return ShellOutputSchema.parse({
|
|
505
|
+
executable: input.executableName,
|
|
506
|
+
exitCode: null,
|
|
507
|
+
signal: null,
|
|
508
|
+
stdout: "",
|
|
509
|
+
stderr: "",
|
|
510
|
+
outcome: "cancelled"
|
|
511
|
+
});
|
|
512
|
+
}
|
|
491
513
|
return await new Promise((resolve, reject) => {
|
|
514
|
+
const ownsProcessGroup = process.platform !== "win32";
|
|
492
515
|
const child = spawn(input.executable, input.args, {
|
|
493
516
|
cwd: input.cwd,
|
|
494
517
|
env: input.environment,
|
|
495
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
518
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
519
|
+
detached: ownsProcessGroup
|
|
496
520
|
});
|
|
497
521
|
const stdout = [];
|
|
498
522
|
const stderr = [];
|
|
@@ -502,15 +526,74 @@ async function runShell(input) {
|
|
|
502
526
|
let artifactBytes = 0;
|
|
503
527
|
let outcome = "exited";
|
|
504
528
|
let settled = false;
|
|
529
|
+
let settlementTimer;
|
|
530
|
+
const cancel = () => terminate("cancelled");
|
|
531
|
+
const cleanup = () => {
|
|
532
|
+
clearTimeout(timer);
|
|
533
|
+
if (settlementTimer)
|
|
534
|
+
clearTimeout(settlementTimer);
|
|
535
|
+
input.signal?.removeEventListener("abort", cancel);
|
|
536
|
+
};
|
|
537
|
+
const persistAndResolve = async (exitCode, signal) => {
|
|
538
|
+
if (settled)
|
|
539
|
+
return;
|
|
540
|
+
settled = true;
|
|
541
|
+
cleanup();
|
|
542
|
+
try {
|
|
543
|
+
const hasArtifact = input.artifacts && artifactBytes > input.maxOutputBytes;
|
|
544
|
+
const artifactData = hasArtifact ? Buffer.concat([stdoutHeader, ...artifactStdout, stderrHeader, ...artifactStderr]) : undefined;
|
|
545
|
+
const persisted = hasArtifact ? await input.artifacts?.write({
|
|
546
|
+
mediaType: "text/plain; charset=utf-8",
|
|
547
|
+
data: artifactData ?? new Uint8Array
|
|
548
|
+
}) : undefined;
|
|
549
|
+
resolve(ShellOutputSchema.parse({
|
|
550
|
+
executable: input.executableName,
|
|
551
|
+
exitCode,
|
|
552
|
+
signal,
|
|
553
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
554
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
555
|
+
outcome,
|
|
556
|
+
...persisted && {
|
|
557
|
+
artifact: {
|
|
558
|
+
reference: persisted.reference,
|
|
559
|
+
bytes: artifactData?.byteLength ?? 0,
|
|
560
|
+
truncated: outcome === "output-limit"
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}));
|
|
564
|
+
} catch (error) {
|
|
565
|
+
reject(error);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
const killOwnedProcessGroup = () => {
|
|
569
|
+
if (!ownsProcessGroup || child.pid === undefined)
|
|
570
|
+
return false;
|
|
571
|
+
try {
|
|
572
|
+
process.kill(-child.pid, "SIGKILL");
|
|
573
|
+
return true;
|
|
574
|
+
} catch {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
const boundStreamSettlement = () => {
|
|
579
|
+
if (settlementTimer)
|
|
580
|
+
return;
|
|
581
|
+
settlementTimer = setTimeout(() => {
|
|
582
|
+
child.stdout.destroy();
|
|
583
|
+
child.stderr.destroy();
|
|
584
|
+
persistAndResolve(child.exitCode, child.signalCode);
|
|
585
|
+
}, input.terminationGraceMs);
|
|
586
|
+
};
|
|
505
587
|
const terminate = (reason) => {
|
|
506
588
|
if (settled || outcome !== "exited")
|
|
507
589
|
return;
|
|
508
590
|
outcome = reason;
|
|
509
|
-
|
|
591
|
+
if (!killOwnedProcessGroup())
|
|
592
|
+
child.kill("SIGKILL");
|
|
593
|
+
boundStreamSettlement();
|
|
510
594
|
};
|
|
511
595
|
const timer = setTimeout(() => terminate("timeout"), input.timeoutMs);
|
|
512
596
|
timer.unref();
|
|
513
|
-
const cancel = () => terminate("cancelled");
|
|
514
597
|
const retain = (target, artifactTarget, chunk) => {
|
|
515
598
|
const remaining = Math.max(0, input.maxOutputBytes - retained);
|
|
516
599
|
if (remaining > 0) {
|
|
@@ -536,42 +619,18 @@ async function runShell(input) {
|
|
|
536
619
|
if (settled)
|
|
537
620
|
return;
|
|
538
621
|
settled = true;
|
|
539
|
-
|
|
540
|
-
input.signal?.removeEventListener("abort", cancel);
|
|
622
|
+
cleanup();
|
|
541
623
|
reject(error);
|
|
542
624
|
});
|
|
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);
|
|
625
|
+
child.on("exit", (exitCode, signal) => {
|
|
626
|
+
if (outcome === "exited")
|
|
627
|
+
killOwnedProcessGroup();
|
|
628
|
+
boundStreamSettlement();
|
|
629
|
+
if (child.stdout.destroyed && child.stderr.destroyed) {
|
|
630
|
+
persistAndResolve(exitCode, signal);
|
|
573
631
|
}
|
|
574
632
|
});
|
|
633
|
+
child.on("close", (exitCode, signal) => void persistAndResolve(exitCode, signal));
|
|
575
634
|
input.signal?.addEventListener("abort", cancel, { once: true });
|
|
576
635
|
if (input.signal?.aborted)
|
|
577
636
|
cancel();
|
|
@@ -600,7 +659,7 @@ function createShellCodingTool(config, limits) {
|
|
|
600
659
|
throw new Error("Coding tool executable is not declared");
|
|
601
660
|
const root = await realpath4(config.root);
|
|
602
661
|
const cwd = await existingCodingPath(root, input.cwd, limits.maxPathBytes);
|
|
603
|
-
if (!(await
|
|
662
|
+
if (!(await stat(cwd.absolute)).isDirectory()) {
|
|
604
663
|
throw new Error("Coding tool cwd is not a directory");
|
|
605
664
|
}
|
|
606
665
|
await authorizeCodingTool(config, {
|
|
@@ -617,6 +676,7 @@ function createShellCodingTool(config, limits) {
|
|
|
617
676
|
environment: config.environment ?? {},
|
|
618
677
|
...signal && { signal },
|
|
619
678
|
timeoutMs: limits.shellTimeoutMs,
|
|
679
|
+
terminationGraceMs: limits.shellTerminationGraceMs,
|
|
620
680
|
maxOutputBytes: limits.maxShellOutputBytes,
|
|
621
681
|
maxArtifactBytes: limits.maxArtifactBytes,
|
|
622
682
|
...config.artifacts && { artifacts: config.artifacts }
|
|
@@ -635,10 +695,10 @@ var AGENT_CODING_TOOL_NAMES = {
|
|
|
635
695
|
writeFile: "write_file"
|
|
636
696
|
};
|
|
637
697
|
function createAgentCodingTools(config) {
|
|
638
|
-
if (!
|
|
698
|
+
if (!path4.isAbsolute(config.root))
|
|
639
699
|
throw new Error("Coding tool root must be absolute");
|
|
640
700
|
for (const executable of Object.values(config.executables ?? {})) {
|
|
641
|
-
if (!
|
|
701
|
+
if (!path4.isAbsolute(executable)) {
|
|
642
702
|
throw new Error("Coding tool executables must be absolute paths");
|
|
643
703
|
}
|
|
644
704
|
}
|
|
@@ -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-xbtcszs7.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
|
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";
|