@namzu/sdk 33.1.1 → 34.0.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/CHANGELOG.md +27 -0
- package/README.md +22 -16
- package/dist/agents/PipelineAgent.d.ts.map +1 -1
- package/dist/agents/PipelineAgent.js +3 -0
- package/dist/agents/PipelineAgent.js.map +1 -1
- package/dist/agents/ReactiveAgent.d.ts.map +1 -1
- package/dist/agents/ReactiveAgent.js +1 -0
- package/dist/agents/ReactiveAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js +1 -0
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/agents/runAgent.d.ts +2 -0
- package/dist/agents/runAgent.d.ts.map +1 -1
- package/dist/agents/runAgent.js +1 -0
- package/dist/agents/runAgent.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +7 -0
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/plugin/loader.d.ts.map +1 -1
- package/dist/plugin/loader.js +28 -4
- package/dist/plugin/loader.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +10 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/sandbox/provider/local.d.ts +1 -0
- package/dist/sandbox/provider/local.d.ts.map +1 -1
- package/dist/sandbox/provider/local.js +79 -35
- package/dist/sandbox/provider/local.js.map +1 -1
- package/dist/scheduler/local.d.ts +12 -0
- package/dist/scheduler/local.d.ts.map +1 -1
- package/dist/scheduler/local.js +69 -1
- package/dist/scheduler/local.js.map +1 -1
- package/dist/types/agent/base.d.ts +8 -0
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/factory.d.ts +1 -0
- package/dist/types/agent/factory.d.ts.map +1 -1
- package/dist/types/agent/scheduler.d.ts +12 -0
- package/dist/types/agent/scheduler.d.ts.map +1 -1
- package/dist/types/sandbox/index.d.ts +11 -0
- package/dist/types/sandbox/index.d.ts.map +1 -1
- package/dist/types/sandbox/index.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/PipelineAgent.ts +5 -0
- package/src/agents/ReactiveAgent.ts +1 -0
- package/src/agents/SupervisorAgent.ts +1 -0
- package/src/agents/runAgent.ts +3 -0
- package/src/manager/agent/lifecycle.ts +7 -0
- package/src/plugin/loader.ts +28 -4
- package/src/runtime/query/index.ts +10 -0
- package/src/sandbox/provider/local.ts +77 -38
- package/src/scheduler/local.ts +87 -1
- package/src/types/agent/base.ts +9 -0
- package/src/types/agent/factory.ts +1 -0
- package/src/types/agent/scheduler.ts +13 -0
- package/src/types/sandbox/index.ts +12 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/sandbox/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/sandbox/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EACN,6BAA6B,EAC7B,+BAA+B,EAC/B,0BAA0B,GAC1B,MAAM,kCAAkC,CAAA;AAUzC,MAAM,UAAU,mBAAmB,CAAC,MAAqB;IACxD,QAAQ,MAAM,EAAE,CAAC;QAChB,KAAK,UAAU,CAAC;QAChB,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,WAAW;YACf,OAAM;QACP,OAAO,CAAC,CAAC,CAAC;YACT,MAAM,WAAW,GAAU,MAAM,CAAA;YACjC,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAA;QACzD,CAAC;IACF,CAAC;AACF,CAAC;AAQD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAkC;IAClE,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,OAAO;CACP,CAAA;AAmBD,MAAM,CAAC,MAAM,0BAA0B,GAAuC;IAC7E,YAAY;IACZ,SAAS;IACT,SAAS;CACT,CAAA;AAKD,MAAM,UAAU,wBAAwB,CAAC,GAAuB;IAC/D,0EAA0E;IAC1E,wEAAwE;IACxE,iEAAiE;IACjE,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAM;IAC9C,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAA;AACtD,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EACN,6BAA6B,EAC7B,+BAA+B,EAC/B,0BAA0B,GAC1B,MAAM,kCAAkC,CAAA;AAUzC,MAAM,UAAU,mBAAmB,CAAC,MAAqB;IACxD,QAAQ,MAAM,EAAE,CAAC;QAChB,KAAK,UAAU,CAAC;QAChB,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,WAAW;YACf,OAAM;QACP,OAAO,CAAC,CAAC,CAAC;YACT,MAAM,WAAW,GAAU,MAAM,CAAA;YACjC,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAA;QACzD,CAAC;IACF,CAAC;AACF,CAAC;AAQD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAkC;IAClE,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,OAAO;CACP,CAAA;AAmBD,MAAM,CAAC,MAAM,0BAA0B,GAAuC;IAC7E,YAAY;IACZ,SAAS;IACT,SAAS;CACT,CAAA;AAKD,MAAM,UAAU,wBAAwB,CAAC,GAAuB;IAC/D,0EAA0E;IAC1E,wEAAwE;IACxE,iEAAiE;IACjE,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAM;IAC9C,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAA;AACtD,CAAC;AA6aD,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC;IACpE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,+BAA+B,CAAC;IAC7E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC;IAC1E;;;;;;OAMG;IACH,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACnF;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;CAC1E,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -84,6 +84,11 @@ export class PipelineAgent extends AbstractAgent<PipelineAgentConfig, PipelineAg
|
|
|
84
84
|
config: PipelineAgentConfig,
|
|
85
85
|
listener?: RunEventListener,
|
|
86
86
|
): Promise<PipelineAgentResult> {
|
|
87
|
+
if (config.sandbox) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
'PipelineAgent cannot enforce a run-level sandbox around developer-authored step callbacks. Configure confinement inside each step or use a tool-running agent.',
|
|
90
|
+
)
|
|
91
|
+
}
|
|
87
92
|
const startTime = Date.now()
|
|
88
93
|
const runId = this.createRunId()
|
|
89
94
|
this.bindRun(runId, config.logger)
|
|
@@ -128,6 +128,7 @@ export class ReactiveAgent extends AbstractAgent<ReactiveAgentConfig, ReactiveAg
|
|
|
128
128
|
model: config.model,
|
|
129
129
|
tokenBudget: config.tokenBudget,
|
|
130
130
|
timeoutMs: config.timeoutMs,
|
|
131
|
+
...(config.sandbox ? { sandbox: config.sandbox } : {}),
|
|
131
132
|
...(config.streamIdleTimeoutMs !== undefined
|
|
132
133
|
? { streamIdleTimeoutMs: config.streamIdleTimeoutMs }
|
|
133
134
|
: {}),
|
|
@@ -319,6 +319,7 @@ export class SupervisorAgent extends AbstractAgent<SupervisorAgentConfig, Superv
|
|
|
319
319
|
model: config.model,
|
|
320
320
|
tokenBudget: config.tokenBudget,
|
|
321
321
|
timeoutMs: config.timeoutMs,
|
|
322
|
+
...(config.sandbox ? { sandbox: config.sandbox } : {}),
|
|
322
323
|
...(config.streamIdleTimeoutMs !== undefined
|
|
323
324
|
? { streamIdleTimeoutMs: config.streamIdleTimeoutMs }
|
|
324
325
|
: {}),
|
package/src/agents/runAgent.ts
CHANGED
|
@@ -66,6 +66,8 @@ export interface RunAgentOptions extends AgentIdentity {
|
|
|
66
66
|
tools?: ToolRegistryContract
|
|
67
67
|
/** Execute sandbox-aware tools inside this provider's boundary. */
|
|
68
68
|
sandboxProvider?: SandboxProvider
|
|
69
|
+
/** What a supplied sandbox is rooted at and its per-run limits. */
|
|
70
|
+
sandbox?: import('../types/run/config.js').AgentRunConfig['sandbox']
|
|
69
71
|
/** Sandbox teardown wait; defaults to 30 seconds and `0` is unbounded. */
|
|
70
72
|
sandboxTeardownTimeoutMs?: number
|
|
71
73
|
|
|
@@ -266,6 +268,7 @@ export async function runAgent(options: RunAgentOptions): Promise<RunAgentResult
|
|
|
266
268
|
workingDirectory: options.workingDirectory ?? process.cwd(),
|
|
267
269
|
runConfig: {
|
|
268
270
|
model: options.model,
|
|
271
|
+
...(options.sandbox ? { sandbox: options.sandbox } : {}),
|
|
269
272
|
maxIterations: options.maxIterations ?? DEFAULT_MAX_ITERATIONS,
|
|
270
273
|
tokenBudget: options.tokenBudget ?? DEFAULT_TOKEN_BUDGET,
|
|
271
274
|
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
@@ -386,6 +386,12 @@ export class AgentManager {
|
|
|
386
386
|
// key, the same direction it already wins for `model` and `effort`.
|
|
387
387
|
const inheritedEnv = mergeEnv(childConfig.env, options.configOverrides?.env)
|
|
388
388
|
if (inheritedEnv) childConfig.env = inheritedEnv
|
|
389
|
+
// A builder may ignore a newly-added factory option. The requested root
|
|
390
|
+
// policy is an execution boundary, so stamp an explicit child override
|
|
391
|
+
// after the builder rather than silently falling back to ephemeral.
|
|
392
|
+
if (options.configOverrides?.sandbox) {
|
|
393
|
+
childConfig.sandbox = options.configOverrides.sandbox
|
|
394
|
+
}
|
|
389
395
|
} else {
|
|
390
396
|
this.log.warn('No configBuilder, using bare config', {
|
|
391
397
|
[GENAI.AGENT_ID]: options.agentId,
|
|
@@ -408,6 +414,7 @@ export class AgentManager {
|
|
|
408
414
|
thinking: options.configOverrides?.thinking,
|
|
409
415
|
effort: options.configOverrides?.effort,
|
|
410
416
|
env: options.configOverrides?.env,
|
|
417
|
+
sandbox: options.configOverrides?.sandbox,
|
|
411
418
|
sessionId: spawnRecord.childSessionId,
|
|
412
419
|
topicId: context.topicId,
|
|
413
420
|
projectId: context.projectId,
|
package/src/plugin/loader.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { lstat, readFile, readdir } from 'node:fs/promises'
|
|
2
|
-
import { homedir } from 'node:os'
|
|
3
|
-
import { join } from 'node:path'
|
|
1
|
+
import { lstat, readFile, readdir, realpath } from 'node:fs/promises'
|
|
2
|
+
import { homedir, platform } from 'node:os'
|
|
3
|
+
import { join, resolve } from 'node:path'
|
|
4
4
|
import {
|
|
5
5
|
PLUGIN_MANIFEST_FILENAME,
|
|
6
6
|
PROJECT_PLUGIN_DIR,
|
|
@@ -261,9 +261,10 @@ export async function discoverAllPluginDirs(
|
|
|
261
261
|
|
|
262
262
|
const projectRoot = workingDirectory ?? process.cwd()
|
|
263
263
|
const userRoot = homedir()
|
|
264
|
+
const sharedRoot = await samePhysicalDirectory(projectRoot, userRoot)
|
|
264
265
|
|
|
265
266
|
const [project, user] = await Promise.all([
|
|
266
|
-
mayScan('project')
|
|
267
|
+
mayScan('project') && !sharedRoot
|
|
267
268
|
? discoverScopedPlugins(projectRoot, PROJECT_PLUGIN_DIR, 'project', options?.log)
|
|
268
269
|
: Promise.resolve([]),
|
|
269
270
|
mayScan('user')
|
|
@@ -275,7 +276,30 @@ export async function discoverAllPluginDirs(
|
|
|
275
276
|
'namzu.plugin.project_count': project.length,
|
|
276
277
|
'namzu.plugin.user_count': user.length,
|
|
277
278
|
...(scopes ? { 'namzu.plugin.allowed_scopes': scopes } : {}),
|
|
279
|
+
...(sharedRoot ? { 'namzu.plugin.shared_user_project_root': true } : {}),
|
|
278
280
|
})
|
|
279
281
|
|
|
280
282
|
return { project, user }
|
|
281
283
|
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Whether two scope roots name the same directory, including through a
|
|
287
|
+
* symlink. When home is the working directory, `.namzu/plugins` is user state:
|
|
288
|
+
* treating the same bytes as project state would let a project-only trust
|
|
289
|
+
* policy admit user-owned executable code, while scanning both installs it
|
|
290
|
+
* twice. Missing roots fall back to normalized absolute names; discovery will
|
|
291
|
+
* independently report them empty.
|
|
292
|
+
*/
|
|
293
|
+
async function samePhysicalDirectory(left: string, right: string): Promise<boolean> {
|
|
294
|
+
const canonical = async (path: string): Promise<string> => {
|
|
295
|
+
let value: string
|
|
296
|
+
try {
|
|
297
|
+
value = await realpath(path)
|
|
298
|
+
} catch {
|
|
299
|
+
value = resolve(path)
|
|
300
|
+
}
|
|
301
|
+
return platform() === 'win32' ? value.toLocaleLowerCase('en-US') : value
|
|
302
|
+
}
|
|
303
|
+
const [a, b] = await Promise.all([canonical(left), canonical(right)])
|
|
304
|
+
return a === b
|
|
305
|
+
}
|
|
@@ -2396,6 +2396,16 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
|
|
|
2396
2396
|
details: { workspace: 'working-directory' },
|
|
2397
2397
|
})
|
|
2398
2398
|
}
|
|
2399
|
+
if (rootAtCwd && !params.sandboxProvider.workspaceModes?.includes('working-directory')) {
|
|
2400
|
+
throw new NamzuError({
|
|
2401
|
+
code: 'invalid_config',
|
|
2402
|
+
message: `Sandbox provider '${params.sandboxProvider.id}' does not advertise working-directory workspace support. Refusing instead of passing a project path the provider may ignore.`,
|
|
2403
|
+
details: {
|
|
2404
|
+
providerId: params.sandboxProvider.id,
|
|
2405
|
+
workspace: 'working-directory',
|
|
2406
|
+
},
|
|
2407
|
+
})
|
|
2408
|
+
}
|
|
2399
2409
|
const acquisition = await acquireSandbox({
|
|
2400
2410
|
provider: params.sandboxProvider,
|
|
2401
2411
|
config: {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
stat,
|
|
11
11
|
} from 'node:fs/promises'
|
|
12
12
|
import { tmpdir } from 'node:os'
|
|
13
|
-
import { dirname, isAbsolute, join,
|
|
13
|
+
import { dirname, isAbsolute, join, parse, resolve } from 'node:path'
|
|
14
14
|
import { NAMZU } from '../../constants/telemetry/index.js'
|
|
15
15
|
import { SCOPE_ATTRIBUTE } from '../../utils/log/types.js'
|
|
16
16
|
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
// registry needs the same one, and a near-copy would reproduce in the copy
|
|
26
26
|
// every bug the original's comment was written to record.
|
|
27
27
|
import { killTree } from '../../process/kill-tree.js'
|
|
28
|
+
import { resolveWithinReal } from '../../tools/paths.js'
|
|
28
29
|
import type { SandboxId } from '../../types/ids/index.js'
|
|
29
30
|
import type {
|
|
30
31
|
Sandbox,
|
|
@@ -49,19 +50,6 @@ import {
|
|
|
49
50
|
import { assertIsolation, describeIsolation } from '../isolation.js'
|
|
50
51
|
import type { PtyLoader } from '../terminal.js'
|
|
51
52
|
|
|
52
|
-
// ---------------------------------------------------------------------------
|
|
53
|
-
// Path safety
|
|
54
|
-
// ---------------------------------------------------------------------------
|
|
55
|
-
|
|
56
|
-
function assertInsideSandbox(sandboxRoot: string, targetPath: string): string {
|
|
57
|
-
const resolved = resolve(sandboxRoot, targetPath)
|
|
58
|
-
const rel = relative(sandboxRoot, resolved)
|
|
59
|
-
if (rel.startsWith('..') || isAbsolute(rel)) {
|
|
60
|
-
throw new Error(`Path escapes sandbox: ${targetPath}`)
|
|
61
|
-
}
|
|
62
|
-
return resolved
|
|
63
|
-
}
|
|
64
|
-
|
|
65
53
|
// ---------------------------------------------------------------------------
|
|
66
54
|
// Platform detection
|
|
67
55
|
// ---------------------------------------------------------------------------
|
|
@@ -289,7 +277,7 @@ export function buildLimitedSpawn(request: LimitedSpawnRequest): {
|
|
|
289
277
|
case 'macos-seatbelt':
|
|
290
278
|
return {
|
|
291
279
|
spawnCommand: requiredWrapper(request),
|
|
292
|
-
spawnArgs: [
|
|
280
|
+
spawnArgs: [...buildSeatbeltArgs(rootDir), '--', ...inner],
|
|
293
281
|
}
|
|
294
282
|
|
|
295
283
|
case 'basic': {
|
|
@@ -332,10 +320,7 @@ function detectEnvironment(): DetectedEnvironment {
|
|
|
332
320
|
|
|
333
321
|
if (platform === 'darwin') {
|
|
334
322
|
const seatbelt = resolveTrustedWrapper('sandbox-exec')
|
|
335
|
-
if (
|
|
336
|
-
seatbelt !== undefined &&
|
|
337
|
-
probeSandboxSpawn(seatbelt, ['-p', buildSeatbeltProfile(tmpdir())])
|
|
338
|
-
) {
|
|
323
|
+
if (seatbelt !== undefined && probeSandboxSpawn(seatbelt, buildSeatbeltArgs(tmpdir()))) {
|
|
339
324
|
return { environment: 'macos-seatbelt', wrapperCommand: seatbelt }
|
|
340
325
|
}
|
|
341
326
|
}
|
|
@@ -465,9 +450,7 @@ const BWRAP_SYSTEM_PATHS: readonly string[] = [
|
|
|
465
450
|
'/opt',
|
|
466
451
|
]
|
|
467
452
|
|
|
468
|
-
function buildSeatbeltProfile(
|
|
469
|
-
const root = canonicalizePath(sandboxRoot)
|
|
470
|
-
|
|
453
|
+
function buildSeatbeltProfile(): string {
|
|
471
454
|
return [
|
|
472
455
|
'(version 1)',
|
|
473
456
|
'(deny default)',
|
|
@@ -479,8 +462,8 @@ function buildSeatbeltProfile(sandboxRoot: string): string {
|
|
|
479
462
|
'(allow signal (target same-sandbox))',
|
|
480
463
|
|
|
481
464
|
// --- Sandbox workspace — full read/write ---
|
|
482
|
-
|
|
483
|
-
|
|
465
|
+
'(allow file-read* (subpath (param "NAMZU_SANDBOX_ROOT")))',
|
|
466
|
+
'(allow file-write* (subpath (param "NAMZU_SANDBOX_ROOT")))',
|
|
484
467
|
|
|
485
468
|
// --- Root path literal — dyld needs this for path resolution ---
|
|
486
469
|
'(allow file-read* (literal "/"))',
|
|
@@ -547,6 +530,18 @@ function buildSeatbeltProfile(sandboxRoot: string): string {
|
|
|
547
530
|
].join('\n')
|
|
548
531
|
}
|
|
549
532
|
|
|
533
|
+
/**
|
|
534
|
+
* Keep caller-controlled paths out of SBPL source entirely.
|
|
535
|
+
*
|
|
536
|
+
* `sandbox-exec -Dname=value` binds an opaque argv value to `(param "name")`;
|
|
537
|
+
* quotes, newlines, and parentheses in a legal Unix directory name therefore
|
|
538
|
+
* remain path bytes instead of becoming policy syntax. This is the same
|
|
539
|
+
* parameter boundary used by Codex's seatbelt builder.
|
|
540
|
+
*/
|
|
541
|
+
function buildSeatbeltArgs(sandboxRoot: string): string[] {
|
|
542
|
+
return ['-p', buildSeatbeltProfile(), `-DNAMZU_SANDBOX_ROOT=${canonicalizePath(sandboxRoot)}`]
|
|
543
|
+
}
|
|
544
|
+
|
|
550
545
|
// ---------------------------------------------------------------------------
|
|
551
546
|
// Environment building
|
|
552
547
|
// ---------------------------------------------------------------------------
|
|
@@ -610,6 +605,7 @@ class LocalSandbox implements Sandbox {
|
|
|
610
605
|
rootDir: string,
|
|
611
606
|
environment: SandboxEnvironment,
|
|
612
607
|
private readonly wrapperCommand: string | undefined,
|
|
608
|
+
private readonly removeRootOnDestroy: boolean,
|
|
613
609
|
config: SandboxCreateConfig,
|
|
614
610
|
log: Logger,
|
|
615
611
|
) {
|
|
@@ -618,7 +614,10 @@ class LocalSandbox implements Sandbox {
|
|
|
618
614
|
this.environment = environment
|
|
619
615
|
this.config = config
|
|
620
616
|
this._status = 'ready'
|
|
621
|
-
this.log = log.child({
|
|
617
|
+
this.log = log.child({
|
|
618
|
+
[SCOPE_ATTRIBUTE]: 'sandbox/provider/local',
|
|
619
|
+
[NAMZU.SANDBOX_ID]: id,
|
|
620
|
+
})
|
|
622
621
|
|
|
623
622
|
this.log.info('Sandbox created', {
|
|
624
623
|
'namzu.sandbox.root_dir': rootDir,
|
|
@@ -641,7 +640,7 @@ class LocalSandbox implements Sandbox {
|
|
|
641
640
|
const env = buildSafeEnv(this.config.env, opts?.env)
|
|
642
641
|
const timeout = opts?.timeout ?? this.config.timeoutMs ?? SANDBOX_DEFAULT_TIMEOUT_MS
|
|
643
642
|
|
|
644
|
-
const cwd = opts?.cwd ?
|
|
643
|
+
const cwd = opts?.cwd ? await resolveWithinReal(this.rootDir, opts.cwd) : this.rootDir
|
|
645
644
|
|
|
646
645
|
const { spawnCommand, spawnArgs, bwrapInfoFd, bwrapBlockFd } = this.buildSpawnArgs(
|
|
647
646
|
command,
|
|
@@ -690,7 +689,7 @@ class LocalSandbox implements Sandbox {
|
|
|
690
689
|
throw new Error(`Sandbox ${this.id} is destroyed`)
|
|
691
690
|
}
|
|
692
691
|
|
|
693
|
-
const resolved =
|
|
692
|
+
const resolved = await resolveWithinReal(this.rootDir, path)
|
|
694
693
|
await mkdir(dirname(resolved), { recursive: true })
|
|
695
694
|
|
|
696
695
|
// Convention 8: Atomic write (write-tmp-rename)
|
|
@@ -706,7 +705,7 @@ class LocalSandbox implements Sandbox {
|
|
|
706
705
|
throw new Error(`Sandbox ${this.id} is destroyed`)
|
|
707
706
|
}
|
|
708
707
|
|
|
709
|
-
const resolved =
|
|
708
|
+
const resolved = await resolveWithinReal(this.rootDir, path)
|
|
710
709
|
return fsReadFile(resolved)
|
|
711
710
|
}
|
|
712
711
|
|
|
@@ -715,7 +714,7 @@ class LocalSandbox implements Sandbox {
|
|
|
715
714
|
throw new Error(`Sandbox ${this.id} is destroyed`)
|
|
716
715
|
}
|
|
717
716
|
|
|
718
|
-
const resolved =
|
|
717
|
+
const resolved = await resolveWithinReal(this.rootDir, rootPath)
|
|
719
718
|
const root = await stat(resolved).catch(() => null)
|
|
720
719
|
if (!root || !root.isDirectory()) return []
|
|
721
720
|
|
|
@@ -746,7 +745,12 @@ class LocalSandbox implements Sandbox {
|
|
|
746
745
|
}
|
|
747
746
|
|
|
748
747
|
this._status = 'destroyed'
|
|
749
|
-
|
|
748
|
+
// A generated temp root belongs to this allocation. A working-directory
|
|
749
|
+
// root belongs to the caller. Conflating those lifetimes turns normal run
|
|
750
|
+
// teardown into recursive deletion of the project the run just edited.
|
|
751
|
+
if (this.removeRootOnDestroy) {
|
|
752
|
+
await rm(this.rootDir, { recursive: true, force: true })
|
|
753
|
+
}
|
|
750
754
|
|
|
751
755
|
this.log.info('Sandbox destroyed', { 'namzu.sandbox.id': this.id })
|
|
752
756
|
}
|
|
@@ -974,6 +978,7 @@ export interface LocalSandboxProviderOptions {
|
|
|
974
978
|
export class LocalSandboxProvider implements SandboxProvider {
|
|
975
979
|
readonly id = 'local'
|
|
976
980
|
readonly name = 'Local Sandbox'
|
|
981
|
+
readonly workspaceModes = ['ephemeral', 'working-directory'] as const
|
|
977
982
|
readonly environment: SandboxEnvironment
|
|
978
983
|
|
|
979
984
|
private readonly log: Logger
|
|
@@ -1016,25 +1021,59 @@ export class LocalSandboxProvider implements SandboxProvider {
|
|
|
1016
1021
|
async create(config?: SandboxCreateConfig): Promise<Sandbox> {
|
|
1017
1022
|
config?.signal?.throwIfAborted()
|
|
1018
1023
|
const id = generateSandboxId()
|
|
1024
|
+
let rootDir: string
|
|
1025
|
+
let removeRootOnDestroy: boolean
|
|
1019
1026
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1027
|
+
if (config?.workingDirectory !== undefined) {
|
|
1028
|
+
const requested = resolve(config.workingDirectory)
|
|
1029
|
+
let entry: Awaited<ReturnType<typeof stat>>
|
|
1030
|
+
try {
|
|
1031
|
+
entry = await stat(requested)
|
|
1032
|
+
} catch (error) {
|
|
1033
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
1034
|
+
throw new Error(`Sandbox workingDirectory does not exist: ${requested}`, {
|
|
1035
|
+
cause: error,
|
|
1036
|
+
})
|
|
1037
|
+
}
|
|
1038
|
+
throw new Error(`Sandbox workingDirectory could not be inspected: ${requested}`, {
|
|
1039
|
+
cause: error,
|
|
1040
|
+
})
|
|
1041
|
+
}
|
|
1042
|
+
if (!entry.isDirectory()) {
|
|
1043
|
+
throw new Error(`Sandbox workingDirectory is not a directory: ${requested}`)
|
|
1044
|
+
}
|
|
1045
|
+
// The caller owns this tree. The sandbox handle may be per run, but the
|
|
1046
|
+
// workspace survives every handle created for the session.
|
|
1047
|
+
rootDir = canonicalizePath(requested)
|
|
1048
|
+
if (rootDir === parse(rootDir).root) {
|
|
1049
|
+
throw new Error(
|
|
1050
|
+
`Sandbox workingDirectory cannot be a filesystem root: ${rootDir}. Choose a project directory so filesystem confinement has a boundary.`,
|
|
1051
|
+
)
|
|
1052
|
+
}
|
|
1053
|
+
removeRootOnDestroy = false
|
|
1054
|
+
} else {
|
|
1055
|
+
// No workspace was named: this allocation owns a fresh temporary root.
|
|
1056
|
+
const { mkdtemp } = await import('node:fs/promises')
|
|
1057
|
+
const rawDir = await mkdtemp(join(tmpdir(), SANDBOX_TEMP_DIR_PREFIX))
|
|
1058
|
+
rootDir = canonicalizePath(rawDir)
|
|
1059
|
+
removeRootOnDestroy = true
|
|
1060
|
+
}
|
|
1024
1061
|
if (config?.signal?.aborted) {
|
|
1025
|
-
await rm(
|
|
1062
|
+
if (removeRootOnDestroy) await rm(rootDir, { recursive: true, force: true })
|
|
1026
1063
|
throw config.signal.reason
|
|
1027
1064
|
}
|
|
1028
|
-
// Canonicalize — macOS symlinks like /var → /private/var must be resolved
|
|
1029
|
-
const rootDir = canonicalizePath(rawDir)
|
|
1030
1065
|
|
|
1031
|
-
this.log.info('Creating sandbox', {
|
|
1066
|
+
this.log.info('Creating sandbox', {
|
|
1067
|
+
'namzu.sandbox.id': id,
|
|
1068
|
+
'namzu.sandbox.root_dir': rootDir,
|
|
1069
|
+
})
|
|
1032
1070
|
|
|
1033
1071
|
return new LocalSandbox(
|
|
1034
1072
|
id,
|
|
1035
1073
|
rootDir,
|
|
1036
1074
|
this.environment,
|
|
1037
1075
|
this.wrapperCommand,
|
|
1076
|
+
removeRootOnDestroy,
|
|
1038
1077
|
config ?? {},
|
|
1039
1078
|
this.log,
|
|
1040
1079
|
)
|
package/src/scheduler/local.ts
CHANGED
|
@@ -28,6 +28,14 @@ import { type Logger, resolveLogger } from '../utils/logger.js'
|
|
|
28
28
|
*/
|
|
29
29
|
const GATEWAY_TASK_LEDGER_CAP = 1_000
|
|
30
30
|
|
|
31
|
+
interface ObserverDelivery {
|
|
32
|
+
busy: boolean
|
|
33
|
+
readonly queue: Array<{
|
|
34
|
+
readonly event: Parameters<RunEventListener>[0]
|
|
35
|
+
readonly observer: 'scheduler' | 'task'
|
|
36
|
+
}>
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
export class LocalTaskScheduler implements TaskScheduler {
|
|
32
40
|
private agentManager: AgentManagerContract
|
|
33
41
|
private taskContext: AgentTaskContext
|
|
@@ -56,6 +64,15 @@ export class LocalTaskScheduler implements TaskScheduler {
|
|
|
56
64
|
private siblingFailurePolicy: SiblingFailurePolicy = 'continue'
|
|
57
65
|
/** See {@link onTaskProgress}. */
|
|
58
66
|
private readonly progressListeners = new Set<(taskId: TaskId) => void>()
|
|
67
|
+
/**
|
|
68
|
+
* One non-blocking delivery chain per observer.
|
|
69
|
+
*
|
|
70
|
+
* Child streaming never awaits these promises, but a listener still sees
|
|
71
|
+
* its own events in source order. Keeping the chains separate also means a
|
|
72
|
+
* slow exporter cannot hold up a task-specific screen (or another task's
|
|
73
|
+
* screen) that uses a different callback.
|
|
74
|
+
*/
|
|
75
|
+
private readonly observerDeliveries = new WeakMap<RunEventListener, ObserverDelivery>()
|
|
59
76
|
/** Raw, unresolved — kept as the caller handed it so each of the two log
|
|
60
77
|
* sites below resolves it independently via `resolveLogger`, rather than
|
|
61
78
|
* this constructor baking in ONE `.child()` binding both would then share
|
|
@@ -150,7 +167,15 @@ export class LocalTaskScheduler implements TaskScheduler {
|
|
|
150
167
|
// tool's own description tells the model to use — the event loop
|
|
151
168
|
// interleaves and three of the four died. Found by running one.
|
|
152
169
|
(event) => {
|
|
153
|
-
this.
|
|
170
|
+
// A scheduler-wide observer and this task's observer are independent.
|
|
171
|
+
// Either may throw or reject: observation is not authority over the
|
|
172
|
+
// child, and one broken screen/export must neither stop the run nor
|
|
173
|
+
// suppress the other observer. Async listeners are deliberately not
|
|
174
|
+
// awaited, so a slow renderer cannot backpressure model streaming.
|
|
175
|
+
this.deliverEvent(this.listener, event, 'scheduler')
|
|
176
|
+
if (options.onEvent !== this.listener) {
|
|
177
|
+
this.deliverEvent(options.onEvent, event, 'task')
|
|
178
|
+
}
|
|
154
179
|
// No id yet means nothing is waiting on this task: the caller
|
|
155
180
|
// does not hold the handle, so an idle bound cannot be running
|
|
156
181
|
// against it. There is no progress to report to anyone.
|
|
@@ -190,6 +215,67 @@ export class LocalTaskScheduler implements TaskScheduler {
|
|
|
190
215
|
return toHandle(task)
|
|
191
216
|
}
|
|
192
217
|
|
|
218
|
+
private deliverEvent(
|
|
219
|
+
listener: RunEventListener | undefined,
|
|
220
|
+
event: Parameters<RunEventListener>[0],
|
|
221
|
+
observer: 'scheduler' | 'task',
|
|
222
|
+
): void {
|
|
223
|
+
if (!listener) return
|
|
224
|
+
|
|
225
|
+
// Each observer receives its own value graph. RunEvent is readonly at the
|
|
226
|
+
// type boundary, but a JavaScript consumer can still mutate an object it
|
|
227
|
+
// was handed; that must not forge what the next independent observer sees.
|
|
228
|
+
const snapshot = structuredClone(event)
|
|
229
|
+
let delivery = this.observerDeliveries.get(listener)
|
|
230
|
+
if (!delivery) {
|
|
231
|
+
delivery = { busy: false, queue: [] }
|
|
232
|
+
this.observerDeliveries.set(listener, delivery)
|
|
233
|
+
}
|
|
234
|
+
delivery.queue.push({ event: snapshot, observer })
|
|
235
|
+
this.drainObserver(listener, delivery)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private drainObserver(listener: RunEventListener, delivery: ObserverDelivery): void {
|
|
239
|
+
if (delivery.busy) return
|
|
240
|
+
while (delivery.queue.length > 0) {
|
|
241
|
+
const next = delivery.queue.shift()
|
|
242
|
+
if (!next) return
|
|
243
|
+
try {
|
|
244
|
+
const pending = listener(next.event)
|
|
245
|
+
if (!pending) continue
|
|
246
|
+
delivery.busy = true
|
|
247
|
+
void pending.then(
|
|
248
|
+
() => {
|
|
249
|
+
delivery.busy = false
|
|
250
|
+
this.drainObserver(listener, delivery)
|
|
251
|
+
},
|
|
252
|
+
(error) => {
|
|
253
|
+
this.reportObserverFailure(next.event.type, next.observer, error)
|
|
254
|
+
delivery.busy = false
|
|
255
|
+
this.drainObserver(listener, delivery)
|
|
256
|
+
},
|
|
257
|
+
)
|
|
258
|
+
return
|
|
259
|
+
} catch (error) {
|
|
260
|
+
this.reportObserverFailure(next.event.type, next.observer, error)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private reportObserverFailure(
|
|
266
|
+
eventType: Parameters<RunEventListener>[0]['type'],
|
|
267
|
+
observer: 'scheduler' | 'task',
|
|
268
|
+
error: unknown,
|
|
269
|
+
): void {
|
|
270
|
+
resolveLogger(this.log)
|
|
271
|
+
.child({ [SCOPE_ATTRIBUTE]: 'scheduler/local' })
|
|
272
|
+
.warn('Task event observer failed', {
|
|
273
|
+
'namzu.event.type': eventType,
|
|
274
|
+
'namzu.scheduler.observer': observer,
|
|
275
|
+
'exception.message': toErrorMessage(error),
|
|
276
|
+
})
|
|
277
|
+
}
|
|
278
|
+
|
|
193
279
|
/**
|
|
194
280
|
* Decide what a failed child means for the ones still running.
|
|
195
281
|
*
|
package/src/types/agent/base.ts
CHANGED
|
@@ -31,6 +31,15 @@ export interface BaseAgentConfig {
|
|
|
31
31
|
costLimitUsd?: number
|
|
32
32
|
permissionMode?: PermissionMode
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Run-level sandbox limits and workspace ownership.
|
|
36
|
+
*
|
|
37
|
+
* A provider alone only says HOW commands are confined. This field says
|
|
38
|
+
* WHAT it is rooted at; `working-directory` makes sandbox-aware tools act
|
|
39
|
+
* on the run's declared workspace instead of a disposable empty tree.
|
|
40
|
+
*/
|
|
41
|
+
sandbox?: import('../run/config.js').AgentRunConfig['sandbox']
|
|
42
|
+
|
|
34
43
|
/**
|
|
35
44
|
* The tools this run may use, narrowing whatever its registry holds.
|
|
36
45
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TaskId } from '../ids/index.js'
|
|
2
2
|
import type { AgentPersona } from '../persona/index.js'
|
|
3
3
|
import type { CancelCause } from '../run/cancel-cause.js'
|
|
4
|
+
import type { RunEventListener } from '../run/events.js'
|
|
4
5
|
import type { AgentRuntimeContext, BaseAgentConfig, BaseAgentResult } from './base.js'
|
|
5
6
|
import type { AgentTaskState } from './task.js'
|
|
6
7
|
|
|
@@ -27,6 +28,18 @@ export interface TaskHandle {
|
|
|
27
28
|
export type SiblingFailurePolicy = 'continue' | 'cancel-siblings'
|
|
28
29
|
|
|
29
30
|
export interface CreateTaskOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Observe events from this one delegated run when the scheduler can expose
|
|
33
|
+
* them.
|
|
34
|
+
*
|
|
35
|
+
* The built-in local scheduler supports this without replacing its
|
|
36
|
+
* scheduler-wide listener. Delivery is observational and must not
|
|
37
|
+
* backpressure or decide the child run; a remote/custom scheduler may omit
|
|
38
|
+
* it when that transport has no event stream. Callers must therefore settle
|
|
39
|
+
* their task view from the returned {@link TaskHandle} as well.
|
|
40
|
+
*/
|
|
41
|
+
readonly onEvent?: RunEventListener
|
|
42
|
+
|
|
30
43
|
/**
|
|
31
44
|
* Span the spawned run should hang off — normally the executing tool's
|
|
32
45
|
* own span, so the delegation shows up inside the turn that asked for
|
|
@@ -473,6 +473,9 @@ export interface SandboxCreateConfig {
|
|
|
473
473
|
readonly maxProcesses?: number
|
|
474
474
|
}
|
|
475
475
|
|
|
476
|
+
/** Workspace-root contracts a provider can enforce honestly. */
|
|
477
|
+
export type SandboxWorkspaceMode = 'ephemeral' | 'working-directory'
|
|
478
|
+
|
|
476
479
|
/**
|
|
477
480
|
* Tier-specific layout types ({@link ContainerSandboxLayout}, future
|
|
478
481
|
* `MicroVMSandboxLayout`, etc.) are intentionally NOT fields on
|
|
@@ -497,6 +500,15 @@ export interface SandboxProvider {
|
|
|
497
500
|
readonly id: string
|
|
498
501
|
readonly name: string
|
|
499
502
|
readonly environment: SandboxEnvironment
|
|
503
|
+
/**
|
|
504
|
+
* Root modes this provider actually implements.
|
|
505
|
+
*
|
|
506
|
+
* Optional for legacy providers using the ephemeral default. The kernel
|
|
507
|
+
* refuses an explicit `working-directory` request unless that mode is
|
|
508
|
+
* advertised; accepting `workingDirectory` and ignoring it would report a
|
|
509
|
+
* boundary around a project the provider never mounted.
|
|
510
|
+
*/
|
|
511
|
+
readonly workspaceModes?: readonly SandboxWorkspaceMode[]
|
|
500
512
|
create(config?: SandboxCreateConfig): Promise<Sandbox>
|
|
501
513
|
}
|
|
502
514
|
|