mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-15 18:56:05 +01:00
Poll asynchronous workspace provider preparation (#20865)
## Thinking Path > - Paperclip starts agent runs through a workspace provider when a project uses remote storage. > - The provider must prepare the workspace before the agent starts. > - One long worker call ties the checkout to its transport. > - Some checkouts take longer than the transport allows. > - This change lets an opted-in provider accept work and report its deadline. > - Core waits for completion through short status calls and stops at the provider deadline. ## Linked Issues or Issue Description **What happened?** A workspace provider can lose its reply when preparation takes longer than a single transport request. This stops run bootstrap before agent execution. **Expected behavior** Core should wait for a provider-confirmed workspace through short requests. The provider's deadline must bound the wait. **Steps to reproduce** Use a workspace provider that takes longer to prepare a checkout than its transport can remain open. Start a run that requires a new checkout. ## What Changed - Add an optional workspace preparation method to the plugin SDK. - Validate pending receipts and keep the original binding checks on completed replies. - Poll only during active preparation. Retry a lost status reply within the advertised deadline. - Preserve the original operation for providers that do not offer asynchronous preparation. - Reject deadline offers that exceed the existing lifecycle lock budget. Honor accepted offers without shortening them. - Checkout verification uses the existing synchronous RPC with a 10-second deadline and a 12-second transport timeout. [Core verification PR #20876](https://github.com/paperclipai/paperclip/pull/20876) ## Verification - All 63 workspace SDK and Core integration tests passed with temporary local PostgreSQL. The tests cover lost status replies, deadline expiry, oversized offers, and synchronous verification with an async-capable worker. - All 58 runner SDK input, evidence, and public type tests passed with the regenerated source pins. The local server typecheck passed. ## Risks - This change activates only when the provider advertises the method. Existing providers keep their current behavior. - Polling uses one-second intervals during active preparation. It stops at completion, failure, or the provider deadline. - No database migration is required. ## Model Used - OpenAI GPT-6 Codex with local code execution and tests. ## 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
e601f9d2fc
commit
5dfbb04b85
11 files changed
+233
-27
No files matched your search
@@ -175,6 +175,8 @@ It does not qualify a deployed plugin, live account, or production WSS proxy.
|
||||
A storage provider can declare `workspaceProvider.workspaceVerificationVersion: 1`.
|
||||
Before creating a fresh workspace for an admitted Retry, Core may send the
|
||||
original task-owned workspace's `prepare` request with `verifyExisting: true`.
|
||||
Core sends verification through `workspaceOperation` with a 10-second
|
||||
deadline and a 12-second RPC timeout.
|
||||
The provider must verify a completed checkout without creating or fetching
|
||||
one and return `prepared` with `created: false`. Core checks prior writer
|
||||
settlement and continues normal preparation on the retained workspace after
|
||||
@@ -261,6 +263,32 @@ Provider upgrades, activation, company re-enablement, and finalization settlemen
|
||||
wake cleanup transactionally. No table, independent timer, or background scan of
|
||||
all remote PR refs is required.
|
||||
|
||||
### Asynchronous workspace preparation
|
||||
|
||||
A provider can implement `onWorkspacePrepare` alongside `onWorkspaceOperation`.
|
||||
Core calls the optional method with `phase: "submit"` and a short submission
|
||||
deadline. A provider that cannot prepare asynchronously returns
|
||||
`{ kind: "unsupported" }` before starting work, so Core can use the original
|
||||
operation. Otherwise the provider returns the completed result or a
|
||||
`{ kind: "pending", deadline }` receipt. The provider sets and enforces that
|
||||
operation deadline. Core holds the workspace lifecycle lock during preparation
|
||||
and rejects offers beyond the previous synchronous RPC budget before polling.
|
||||
It honors accepted deadlines as supplied. Replayed submission must not duplicate
|
||||
an active prepare.
|
||||
|
||||
Core sends `phase: "poll"` with the same operation identity and the deadline
|
||||
from the receipt. The provider returns the same receipt while work is pending
|
||||
and the usual scoped `prepared` result after success. Core rejects late results
|
||||
and stops polling when the deadline expires. Each submission and poll has a
|
||||
short transport bound independent of the operation deadline. A provider can
|
||||
keep reporting pending while it restores recovery snapshots, under the same
|
||||
deadline.
|
||||
|
||||
Each invocation has its own scoped host access. Complete scoped host calls
|
||||
inside the submit or poll that owns them. Detached work can use a remote
|
||||
operation already authorized by that invocation. It cannot reuse the
|
||||
invocation to call host services after the reply.
|
||||
|
||||
### Workspace operation failures
|
||||
|
||||
Core separates a failed `workspaceOperation` call by what it knows about the
|
||||
@@ -274,7 +302,7 @@ outcome:
|
||||
| The provider threw any other error | `Workspace storage provider reported a failure; retry the same workspace` | Unchanged setup failure. |
|
||||
|
||||
To report a reason, throw `PluginWorkspaceOperationError` from
|
||||
`onWorkspaceOperation`, or any error with an own `workspaceFailureReason`
|
||||
`onWorkspaceOperation` or `onWorkspacePrepare`, or any error with an own `workspaceFailureReason`
|
||||
property. The reason must come from `WORKSPACE_OPERATION_FAILURE_REASONS`:
|
||||
|
||||
| Reason | Retrying the same workspace can help |
|
||||
|
||||
Reference in new issue
Block a user