Repository navigation
Conversation
Add client.agents.workspaces (sync and async) with create, list, get and delete for persistent workspaces under /v2/agents/workspaces. Create accepts an optional idempotency_key that is sent as the Idempotency-Key header only when given, so a retried create is safe. A session names its workspace per session, never inside a manifest: workspace_id is a body field on create_from_config and a query parameter on create_from_manifest and start. Add WorkspaceState constants, a runnable example of the create, attach, remove and re-attach flow, and tests for both clients.
…config A workspace is chosen per session and never travels with a manifest, so workspace_id is removed from create_from_manifest and from start, in the sync and async clients. create_from_config keeps workspace_id as a body field and is now the only way to attach a workspace; the docstrings point to it. Replace the query-parameter tests with tests that those two methods accept no workspace_id and send none.
sanpj2292
marked this pull request as ready for review
October 6, 2026 12:12
list takes state to return only workspaces in one state, on both the sync and async clients. A page can hold fewer workspaces than page_size, even none, while next_page_token is set, so callers keep requesting pages until it is empty. The workspace example now lists the available workspaces.
…elete and create docs The API has a sixth workspace state, DELETING, shown while a delete runs, and accepts it as the list state filter. Add WorkspaceState.DELETING and update the docstrings: delete is a 409 while a session holds the workspace or it is attaching or being saved, and create is a 409 for a key whose workspace is being deleted.
The API now calls the workspace size an upper limit on a disk that is billed on use, and names it size_limit_gib in the create body and the workspace answer (digitalocean/cthulhu#182026). create_workspace takes size_limit_gib instead of size_gibibytes, sends it under that name, and the error messages follow. The workspace calls are in this PR and have no release yet, so nothing that is released changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds persistent workspaces to the hand-written agents resources: a separate set of files with its own id that outlives sessions and is attached to one session at a time. Ticket: MARSOHS-1935.
The API is behind a per-team feature flag and is not generally available yet, so calls return
501for teams that are not enrolled.Changes
client.agents.workspaces(sync and async) withcreate,list,getanddeletefor/v2/agents/workspaces.create(size_limit_gib, *, name=None, idempotency_key=None)sends theIdempotency-Keyheader only when a key is given. A new workspace answers201and a replay answers200; both return the workspace.list(*, page_size=None, page_token=None, state=None)lists only workspaces in one state whenstateis given; any other value is a400from the server.createraisesValueErrorfor a non-integer or a size below 1. The upper bound is left to the server, because a team limit can lower it.401ClientAuthenticationError,404ResourceNotFoundError,409ResourceExistsError, and422or501HttpResponseErrorwith the server's message.WorkspaceStateholds the six state constants (includingDELETING). An unknown state stays a plain string.create_from_config(..., workspace_id=None)sends it as a body field, only when set. This is the only way to attach a workspace.create_from_manifestandagents.startaccept noworkspace_id. Their docstrings say to save the manifest as a config and usecreate_from_config.examples/agents/persistent_workspace.pycreates a workspace with an idempotency key, creates a session from a config with it attached, removes the session, waits until the workspace is available, and attaches it to a second session.The agents packages are hand-written and are preserved by
make generate(see thecleantarget in theMakefile), so nothing here is overwritten by regeneration.Testing
make lint-testspasses (black and pylint 10.00).test_workspaces.pyandtest_async_workspaces.py, which cover201and200replay, the header only when given, paging parameters, get and delete,401,404,409,422and501, the session body field, and that the manifest paths accept noworkspace_id.black --check examplesfails on 10 existing example files; they fail the same way onmainand are not part of this PR.Notes
Rename (MARSOHS-2336)
The size is now
size_limit_gib(wassize_gibibytes), to match the API change in digitalocean/cthulhu#182026. Nothing released changes, because the workspace calls are only in this PR. This should merge after the API change is deployed.