agentbox-sdk 0.1.503 → 0.1.511

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 CHANGED
@@ -115,6 +115,72 @@ for await (const event of run) {
115
115
  const result = await run.finished;
116
116
  ```
117
117
 
118
+ Claude Code can leave work running after its turn ends (`run_in_background`
119
+ shells, `Monitor`, background subagents, scheduled wakeups) and re-prompts
120
+ itself when that work finishes. AgentBox reports it through `background.tasks`
121
+ events — `tasks` is the full live set after each change and `waiting` is `true`
122
+ while the harness has ended its turn and the run stays open only for those
123
+ tasks (or, with an empty set, for the wake-up the CLI queues for a task that
124
+ finished mid-turn) — and settles the run on the follow-up turn's result
125
+ instead of the first one. Once background work has been seen, a turn end
126
+ settles the run only after a 15s grace with no new turn, and a final
127
+ `background.tasks` with `tasks: []` and `waiting: false` precedes the settle.
128
+ `backgroundTaskTimeoutMs` bounds the total time spent waiting across the run:
129
+ default 30 minutes, `0` settles at the first turn end as before, `Infinity`
130
+ waits forever. On expiry the tasks are stopped best-effort and the run
131
+ completes with the last turn's text.
132
+
133
+ Codex has no background mode of its own: its unified exec tool hands control
134
+ back to the model early (`yield_time_ms`) and leaves the process running inside
135
+ the app-server, where nothing wakes the model when it finishes. When a Codex
136
+ turn ends with such a command still running, AgentBox keeps the app-server up
137
+ and reports the command through `background.tasks` (`type: "command"`,
138
+ `description` is the command line). Once every leftover command has finished
139
+ while the model was idle, AgentBox starts a follow-up turn on the same thread
140
+ carrying each command's exit code, duration and the last 4000 characters of
141
+ output, asking the model to verify the outcome and finish without restarting
142
+ the command; that turn is surfaced as a `message.injected` event and the run
143
+ settles on its result (which may in turn leave more commands running). A
144
+ message sent while waiting runs as a normal turn and is checked the same way; a
145
+ command that finishes during a turn is left to the model's own polling and is
146
+ only visible through `tool.call.completed`. A failed follow-up turn fails the
147
+ run like any other turn. When `backgroundTaskTimeoutMs` expires, AgentBox asks
148
+ the app-server to terminate the leftover processes
149
+ (`thread/backgroundTerminals/list` + `terminate`, best effort) and completes
150
+ with the last turn's text; `0` keeps the legacy settle-at-first-turn behaviour.
151
+ Any unified-exec process still running at turn end counts — a dev server or
152
+ watcher the model leaves running on purpose holds the run open until the
153
+ ceiling — so hosts that expect such processes should pass a shorter
154
+ `backgroundTaskTimeoutMs` for Codex. Spawned Codex sub-agents are not tracked:
155
+ the parent must `wait_agent` for them within its turn. A waiting run can still
156
+ be cancelled statelessly: `Agent.attach(...).abort()` interrupts the active turn
157
+ when there is one and otherwise starts a turn only to interrupt it, which the
158
+ originating run observes as an interrupted turn and reports as `run.cancelled`;
159
+ the leftover processes are then terminated.
160
+
161
+ OpenCode has no background shells, monitors, or wake-ups; its only work that
162
+ outlives a turn is `task {background: true}`, which the server accepts only when
163
+ it runs with `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` (or the
164
+ `OPENCODE_EXPERIMENTAL` umbrella) in its environment. With that flag the parent
165
+ session goes idle while the child session runs and OpenCode itself re-prompts
166
+ the parent with the child's result. AgentBox recognises a background child from
167
+ the parent's `task` tool call (`metadata.background`), so nothing depends on the
168
+ caller's env: while such a child is live at the parent's idle the run stays
169
+ open, the children are reported through `background.tasks` (`type:
170
+ "subagent"`, `description` is the task description / child session title),
171
+ `waiting` flips to `false` when the parent resumes, and the run settles on the
172
+ next parent idle with nothing live — its text is the parent's last assistant
173
+ message, never the injected result. Child liveness comes from SSE frames
174
+ reconciled against `GET /session/status` at each parent idle and while waiting,
175
+ and the injected `<task id=… state=…>` result also counts as the child's
176
+ completion, so a lost frame cannot hold the run open. A child that ends without
177
+ waking the parent settles the run after the 15s grace. `backgroundTaskTimeoutMs`
178
+ bounds the total wait as for Claude Code; on expiry, or when the run fails with
179
+ a child still live, the leftover subagents are stopped best-effort via
180
+ `POST /session/:id/abort`. Aborting the run while waiting cancels the children
181
+ through the same endpoint. Without the flag nothing changes: a parent idle is
182
+ the end of the run.
183
+
118
184
  ## Agents
119
185
 
120
186
  Three agent providers are supported. Each wraps a CLI that runs inside the sandbox:
@@ -504,6 +570,81 @@ AGENTBOX_RUN_MATRIX_E2E=1 npm run test:e2e:matrix # provider matrix
504
570
 
505
571
  Live test suites are opt-in because they provision real infrastructure.
506
572
 
573
+ ## Host execution settings
574
+
575
+ Use `configuration: "native"` to run a host harness with its own configuration,
576
+ built-in prompt, credentials, and repository instructions. AgentBox does not
577
+ generate settings, skills, commands, subagents, hooks, plugins, or MCP definitions
578
+ in this mode. It cannot be combined with a sandbox or AgentBox-managed skills,
579
+ MCPs, commands, subagents, or RTK. Omit `systemPrompt` when starting a turn to keep
580
+ the harness's built-in instructions unchanged.
581
+
582
+ ```ts
583
+ const agent = new Agent("codex", {
584
+ cwd: "/absolute/path/to/project",
585
+ configuration: "native",
586
+ approvalMode: "interactive",
587
+ });
588
+ await agent.setup();
589
+ ```
590
+
591
+ Start a turn with `agent.stream({ input })`, consume its async event iterator,
592
+ and answer permission requests with `run.respondToPermission()`. Await
593
+ `run.finished` for the result and call `agent.killServer()` to release the runtime.
594
+
595
+ The default `configuration: "managed"` retains AgentBox-generated configuration
596
+ for host and sandbox execution.
597
+
598
+ `stateDirectory` selects a private, persistent directory for generated agent
599
+ configuration and session state on the host. It must be an absolute path and
600
+ cannot be combined with `sandbox`. Use a different directory for each execution
601
+ environment to prevent unrelated local jobs from overwriting configuration.
602
+ This setting does not copy credentials from the user's account.
603
+
604
+ With native configuration, Codex uses the user's sandbox and approval settings.
605
+ Managed host execution defaults to read-only. An explicit
606
+ `provider: { sandboxMode: "workspace-write" }` enables a host write policy;
607
+ `writableRoots` adds allowed directories and `networkAccess` enables network
608
+ access for that policy (disabled by default). The shared
609
+ `approvalMode: "interactive"` routes permission requests to the caller; it does
610
+ not itself change the native harness's policy. Cloud sandbox defaults are unchanged.
611
+
612
+ Host Claude runs the Anthropic SDK with the SDK-matched CLI by default.
613
+ `provider.binary` explicitly selects another compatible CLI. Sign-in and session
614
+ storage remain CLI-owned. Managed configuration loads generated skills, commands,
615
+ and subagents as a private local plugin. Native configuration loads user, project,
616
+ and local settings instead. Neither mode copies the CLI's credentials. When
617
+ `backgroundTaskTimeoutMs` expires, host Claude stops the leftover background
618
+ tasks through the SDK; in a sandbox the daemon lets the CLI wind down on
619
+ disconnect, bounded by `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=30000`, which
620
+ AgentBox sets in the CLI environment unless `env` already defines it.
621
+
622
+ Each host OpenCode Agent owns an authenticated loopback server on an ephemeral
623
+ port. Managed configuration uses an isolated configuration directory; native
624
+ configuration preserves the user's configuration paths. `killServer()` stops
625
+ only that Agent's process. It never discovers or kills another server by port number.
626
+
627
+ All three providers normalize interactive questions into `permission.requested`
628
+ events with `kind: "question"`. Respond with `decision: "allow"` and an `answers`
629
+ array containing each `questionId` and its selected or custom `values`, or use
630
+ `decision: "deny"` to skip. Invalid answers leave the request pending for correction.
631
+ Question answers cannot modify unrelated tool arguments. Ordinary tool requests
632
+ use the same API without `answers`.
633
+
634
+ Native runtimes own a POSIX process group by default. Termination is bounded and
635
+ escalates to SIGKILL if the process ignores SIGTERM. A supervisor that launches
636
+ each run in its own process group can set `processGroup: "inherited"`; that
637
+ supervisor is then responsible for stopping the complete group before reporting
638
+ that a run has stopped. This option is unavailable for cloud sandboxes.
639
+
640
+ ## Packaging
641
+
642
+ `npm pack` builds the package from maintained TypeScript source before creating
643
+ the archive. Host execution includes the pinned Anthropic SDK and its Zod peer
644
+ as runtime dependencies; consumers do not need package-manager extensions.
645
+ Run `npm run check` before publishing. Provider integration tests use fake local
646
+ CLIs and SDK mocks; live tests remain opt-in.
647
+
507
648
  ## License
508
649
 
509
650
  MIT
@@ -1,5 +1,5 @@
1
- import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, a4 as RawAgentEvent, b as AgentAttachRequest, y as AttachedRun, ab as SetupLayout } from '../types-3VRJIiW0.js';
2
- export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexModelProviderConfig, N as CodexProviderOptions, O as DataContent, P as EmbeddedSkillConfig, Q as FilePart, R as ImagePart, Y as OpenCodeAgentOptions, Z as OpenCodePluginConfig, _ as OpenCodePluginEvent, $ as OpenCodePluginHookConfig, a0 as OpenCodeProviderOptions, a1 as OpenRouterPlugin, a6 as RepoSkillConfig, ad as TextPart, ah as UserContent, ai as UserContentPart } from '../types-3VRJIiW0.js';
1
+ import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, a9 as RawAgentEvent, b as AgentAttachRequest, B as AttachedRun, ag as SetupLayout, am as UserContent } from '../types-B4yy80AJ.js';
2
+ export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as DataContent, T as EmbeddedSkillConfig, U as FilePart, V as ImagePart, a1 as OpenCodeAgentOptions, a2 as OpenCodePluginConfig, a3 as OpenCodePluginEvent, a4 as OpenCodePluginHookConfig, a5 as OpenCodeProviderOptions, a6 as OpenRouterPlugin, ab as RepoSkillConfig, ai as TextPart, an as UserContentPart } from '../types-B4yy80AJ.js';
3
3
  import { S as Sandbox } from '../Sandbox-DcKAU-E3.js';
4
4
  export { AgentProvider } from '../enums.js';
5
5
  import 'e2b';
@@ -93,7 +93,7 @@ declare class Agent<P extends AgentProviderName = AgentProviderName> {
93
93
  * - **Sandbox**: `/tmp/agentbox/<provider>` inside the sandbox.
94
94
  * - **Local host**: `<os.tmpdir()>/agentbox-<provider>` on the host.
95
95
  */
96
- declare function agentboxRoot(provider: AgentProviderName, hasSandbox?: boolean): string;
96
+ declare function agentboxRoot(provider: AgentProviderName, hasSandbox?: boolean, stateDirectory?: string): string;
97
97
  /**
98
98
  * Resolve the on-disk layout (config dirs per provider) for the given
99
99
  * agentbox root. Public so external consumers (e.g. agentbox-driven
@@ -124,4 +124,15 @@ declare function getAgentLayout(rootDir: string): SetupLayout;
124
124
  declare const AGENT_RESERVED_PORTS: Record<AgentProviderName, readonly number[]>;
125
125
  declare function collectAllAgentReservedPorts(): number[];
126
126
 
127
- export { AGENT_RESERVED_PORTS, Agent, AgentAttachRequest, AgentOptions, AgentProviderName, AgentResult, AgentRun, AgentRunConfig, AttachedRun, SetupLayout, agentboxRoot, collectAllAgentReservedPorts, getAgentLayout };
127
+ type HarnessCommand = "plan" | "agent" | "goal";
128
+ interface HarnessCapabilities {
129
+ commands: HarnessCommand[];
130
+ planning: "explicit" | "agent-directed";
131
+ questions: boolean;
132
+ fullAccess: boolean;
133
+ }
134
+ /** Adapter capabilities. Runtime adapters additionally validate commands against the live harness. */
135
+ declare function harnessCapabilities(provider: AgentProviderName): HarnessCapabilities;
136
+ declare function resolveHarnessCommand(provider: AgentProviderName, input: UserContent): Pick<AgentRunConfig, "input" | "mode" | "goal">;
137
+
138
+ export { AGENT_RESERVED_PORTS, Agent, AgentAttachRequest, AgentOptions, AgentProviderName, AgentResult, AgentRun, AgentRunConfig, AttachedRun, type HarnessCapabilities, type HarnessCommand, SetupLayout, UserContent, agentboxRoot, collectAllAgentReservedPorts, getAgentLayout, harnessCapabilities, resolveHarnessCommand };
@@ -1,13 +1,15 @@
1
1
  import {
2
2
  Agent,
3
3
  agentboxRoot,
4
- getAgentLayout
5
- } from "../chunk-34LDITII.js";
4
+ getAgentLayout,
5
+ harnessCapabilities,
6
+ resolveHarnessCommand
7
+ } from "../chunk-G3VEVR6Y.js";
6
8
  import "../chunk-775FIGGL.js";
7
9
  import {
8
10
  AGENT_RESERVED_PORTS,
9
11
  collectAllAgentReservedPorts
10
- } from "../chunk-AVXJMCBC.js";
12
+ } from "../chunk-MTQ2S46C.js";
11
13
  import "../chunk-NSJM57Z4.js";
12
14
  import {
13
15
  AgentProvider
@@ -18,5 +20,7 @@ export {
18
20
  AgentProvider,
19
21
  agentboxRoot,
20
22
  collectAllAgentReservedPorts,
21
- getAgentLayout
23
+ getAgentLayout,
24
+ harnessCapabilities,
25
+ resolveHarnessCommand
22
26
  };
@@ -10,7 +10,7 @@ import {
10
10
  sleep,
11
11
  suppressUnhandledRejection,
12
12
  time
13
- } from "./chunk-AVXJMCBC.js";
13
+ } from "./chunk-MTQ2S46C.js";
14
14
  import {
15
15
  shellQuote,
16
16
  toShellCommand