mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 10:48:12 +02:00
feat(sandbox): stream session output by capability, drop three operator flags (#11557)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Sandboxed agents use provider capabilities to select safe execution paths > - Session output still depends on three operator flags that duplicate capability data > - Duplicate flags can drift from the verified sandbox capability snapshot > - This pull request makes the capability snapshot the only streaming decision and removes the obsolete flags > - The benefit is default streaming with a poll fallback when a capability or stream fails ## Linked Issues or Issue Description **What existing behavior does this improve?** ACP sandbox session-output streaming and sandbox execution configuration. **Subsystem affected** Cross-cutting (multiple of the above): server/, packages/shared/, packages/adapter-utils/, and packages/plugins/. **Current behavior** Session-output streaming requires operator flags in the server and Daytona plugin configuration. Saved configurations can retain a removed key. **Proposed behavior** The verified capability snapshot selects streaming. The Daytona plugin uses persistent sessions by default, keeps bypass commands one-shot, and falls back from the log stream to polling. Removed configuration keys become inert. **Reason and benefit** One capability source prevents configuration drift. The fallback keeps output available when capability resolution or log streaming fails. **Breaking changes** The three operator flags no longer control session-output streaming. Existing saved keys load but have no effect. ## What Changed - Remove `useSessions` and `useLogStream` from the Daytona plugin configuration and manifest. - Remove `streamAgentSessionOutput` from server configuration, shared types, and execution-target plumbing. - Select streaming from `persistentProcessSessions` and `independentControlCommands`. - Keep poll fallback on capability resolution failure and stream failure. - Strip removed keys from strict fake-sandbox and catchall plugin configuration. - Update the sandbox capability documentation and focused tests. ## Verification - `tsc --noEmit` passed in `packages/shared`, `packages/adapter-utils`, `server`, and the Daytona plugin. - Daytona `plugin.test.ts` passed 139 tests. - Server capability, configuration, route, and runtime suites passed 160 tests. - `packages/adapter-utils` `execution-target-sandbox.test.ts` passed 44 tests. - The capability matrix covers stream, poll, and resolution-failure paths. - Removed-key tests cover strict fake-sandbox and catchall plugin schemas. ## Risks - A capability snapshot that lacks either required session capability uses polling. - A log stream failure uses polling and can increase request count. - Existing removed configuration keys no longer change behavior. - The isolated-worktree Daytona Vitest run has a pre-existing missing `packages/adapters/droid-local` reference. CI and standard checkouts use the committed configuration. ## Model Used OpenAI Codex, GPT-5, tool use and code review assistance. The exact runtime context window is managed by the Codex platform. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
e71ce9a9d3
commit
3061ce6901
18 files changed
+400
-238
No files matched your search
@@ -50,6 +50,7 @@ environmentDrivers: [
|
||||
nativeSyncOut: true,
|
||||
persistentProcessSessions: false,
|
||||
independentControlCommands: false,
|
||||
incrementalSessionOutput: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -61,8 +62,9 @@ states:
|
||||
- **Omitted** — the host defers to verified worker discovery. The capability is
|
||||
effective when the worker advertises the required methods and no narrowing
|
||||
removes it. Omission is the correct default for a provider that follows the
|
||||
standard method contract. `reusableLeases` is the one exception: an omitted
|
||||
`reusableLeases` key never grants reusable leases (see the next section).
|
||||
standard method contract. `reusableLeases` and `incrementalSessionOutput` are
|
||||
the two exceptions: an omitted key never grants either capability. Both are
|
||||
opt-in (see the next two sections).
|
||||
- **`false`** — the host narrows the capability to off. The capability is never
|
||||
effective, even when the worker advertises the required methods.
|
||||
- **`true`** — the host still requires the verified prerequisites. A `true`
|
||||
@@ -99,6 +101,25 @@ into `sandboxCapabilities.reusableLeases`.
|
||||
A manifest with legacy `true` and nested `false` therefore resolves to `false`.
|
||||
Prefer the nested `sandboxCapabilities.reusableLeases` in a new manifest.
|
||||
|
||||
## Incremental session output needs an explicit opt-in
|
||||
|
||||
Incremental session output is the second exception to the omission rule. The host
|
||||
selects the session-output streaming path only when the declaration sets
|
||||
`incrementalSessionOutput` to `true`. An omitted key resolves the capability to
|
||||
`false`, so the host keeps the output-file poll path.
|
||||
|
||||
The reason is that this key is a behavioral guarantee, not a worker-method
|
||||
property. A generic one-shot provider can keep persistent process sessions and run
|
||||
independent control commands, yet it never emits incremental stdout and stderr
|
||||
from a live session. The two broad capabilities do not imply incremental output,
|
||||
so the host requires the provider to declare the behavior. A provider that streams
|
||||
incremental session output declares `sandboxCapabilities.incrementalSessionOutput:
|
||||
true`; every other provider omits the key and keeps the poll path.
|
||||
|
||||
The opt-in never removes the prerequisites. The worker must still verify
|
||||
`environmentExecute`, and per-run narrowing still applies. A config-resolution
|
||||
failure narrows the capability to off (see [Failure behavior](#failure-behavior)).
|
||||
|
||||
## The capabilities and their worker-method prerequisites
|
||||
|
||||
| Capability | Required worker methods | Meaning |
|
||||
@@ -108,6 +129,7 @@ Prefer the nested `sandboxCapabilities.reusableLeases` in a new manifest.
|
||||
| `nativeSyncOut` | `environmentSyncOut` | The host transfers files out of the sandbox through the native outbound hook. |
|
||||
| `persistentProcessSessions` | `environmentExecute` | The provider keeps a persistent process session open across commands. |
|
||||
| `independentControlCommands` | `environmentExecute` | The provider runs a one-shot control command beside a long-lived command. |
|
||||
| `incrementalSessionOutput` | `environmentExecute` | The provider streams incremental stdout and stderr from a live session. Opt-in: an omitted key resolves `false`. |
|
||||
|
||||
Reusable leases need all three lifecycle methods. The host resumes a lease with
|
||||
`environmentResumeLease`, ends it with `environmentReleaseLease`, and tears down a
|
||||
@@ -131,18 +153,16 @@ this run cannot use.
|
||||
unable to run native file sync, disables native sync. The host narrows
|
||||
`nativeSyncIn` and `nativeSyncOut` to off and keeps the base64-over-exec
|
||||
fallback.
|
||||
- **`useSessions` provider config.** A session-based provider follows its
|
||||
`useSessions` config value for `persistentProcessSessions`. Sessions default to
|
||||
off. A config that omits the key adds no narrowing.
|
||||
|
||||
## Failure behavior
|
||||
|
||||
The host fails closed on two failure states. It never grants a capability from an
|
||||
unknown state.
|
||||
|
||||
- **Config-resolution failure.** When the host cannot resolve the provider
|
||||
config, it cannot read `useSessions`. It narrows `persistentProcessSessions` to
|
||||
off instead of allowing it through an empty config.
|
||||
- **Config-resolution failure.** A provider whose config the host cannot resolve
|
||||
is untrusted. The host narrows `persistentProcessSessions` and
|
||||
`incrementalSessionOutput` to off instead of allowing either through an empty
|
||||
config.
|
||||
- **Exact-plugin identity failure.** A retained lease pins the exact plugin that
|
||||
acquired it. When that plugin is absent, or when it no longer declares this
|
||||
provider key with the `sandbox_provider` kind, the host cannot establish the
|
||||
|
||||
Reference in new issue
Block a user