Files
PaperClipAI/packages/adapter-utils
Priya RamanandPaperclip cf0d2b823a feat(sandbox): add the host duplex bridge broker with nested budgets
Add the host broker for the sandbox duplex channel. The broker reads
request frames from one persistent channel, forwards each request on the
existing API path, and writes one response frame back. It sends heartbeat
frames on an interval to prove liveness.

The broker keeps the forward path unchanged. The caller passes a forward
handler, and the broker calls it for each request. The handler owns the
route allowlist, the token replacement, and the run attribution, so those
rules stay in one place.

The broker runs nested timeout budgets: forward 30 s, response 32 s, and
gateway wait 35 s. Each inner budget is smaller than its outer budget. The
broker asserts this order at construction and rejects a configuration that
breaks it.

Loss is terminal. The broker detects loss through channel exit, a stream
write failure, a protocol failure, a heartbeat write failure, and a close
timeout. On loss the broker stops, records the loss for metrics only, and
dispatches nothing more. It never reconnects and never replays a request.

Wire the existing forward timeout in execution-target.ts to a new option
that defaults to the broker forward budget (30 s), so the current behavior
does not change.

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-20 02:27:58 +00:00
..

@paperclipai/adapter-utils

Shared utilities for Paperclip adapters: process spawning, environment injection, sandbox/SSH transport, workspace sync, and the round-trip helpers that move code between the local execution-workspace cwd and wherever the agent actually runs.

For the adapter-author guide see docs/adapters/creating-an-adapter.md and the in-repo notes at packages/adapters/AUTHORING.md.

No-remote-git contract

The local execution-workspace cwd is the only persistence boundary across runs. No adapter may depend on a git remote for cross-run state.

Adapters that run the agent on a different host should use the SSH round-trip helpers in src/ssh.ts:

  • prepareWorkspaceForSshExecution({ spec, localDir, remoteDir }) — bundles the local cwd (tracked files, dirty edits, untracked additions, and the git history needed to reconstruct it) to remoteDir before the run starts. Runs with no git remote configured.
  • restoreWorkspaceFromSshExecution({ spec, localDir, remoteDir, ... }) — syncs the remote cwd back into localDir after the run, including any new commits the agent created. Also runs with no git remote configured.

prepareRemoteManagedRuntime in src/remote-managed-runtime.ts wraps both calls for adapters that want a per-run remote workspace and an automatic restoreWorkspace() finally hook.

The invariant is pinned by the no-remote-git contract case in src/ssh-fixture.test.ts, which asserts that a remote-only commit propagates to the local worktree through the prepare → restore round-trip with no git remote configured at any point. Do not regress that test.