Pivot persistent APIs to workspaces

Replace the public persistent-sandbox contract with workspace-first naming across CLI, SDK, MCP, payloads, and on-disk state.

Rename the task surface to workspace equivalents, switch create-time seeding to `seed_path`, and store records under `workspaces/<workspace_id>/workspace.json` without carrying legacy task aliases or migrating old local task state.

Keep `pyro run` and `vm_*` unchanged. Validation covered `uv lock`, focused public-contract/API/CLI/manager tests, `UV_CACHE_DIR=.uv-cache make check`, and `UV_CACHE_DIR=.uv-cache make dist-check`.
This commit is contained in:
Thales Maciel 2026-03-12 01:21:49 -03:00
parent f57454bcb4
commit 48b82d8386
13 changed files with 743 additions and 618 deletions

View file

@ -48,8 +48,8 @@ def test_pyro_create_server_registers_vm_run(tmp_path: Path) -> None:
tool_names = asyncio.run(_run())
assert "vm_run" in tool_names
assert "vm_create" in tool_names
assert "task_create" in tool_names
assert "task_sync_push" in tool_names
assert "workspace_create" in tool_names
assert "workspace_sync_push" in tool_names
def test_pyro_vm_run_tool_executes(tmp_path: Path) -> None:
@ -106,7 +106,7 @@ def test_pyro_create_vm_defaults_sizing_and_host_compat(tmp_path: Path) -> None:
assert created["allow_host_compat"] is True
def test_pyro_task_methods_delegate_to_manager(tmp_path: Path) -> None:
def test_pyro_workspace_methods_delegate_to_manager(tmp_path: Path) -> None:
pyro = Pyro(
manager=VmManager(
backend_name="mock",
@ -119,20 +119,20 @@ def test_pyro_task_methods_delegate_to_manager(tmp_path: Path) -> None:
source_dir.mkdir()
(source_dir / "note.txt").write_text("ok\n", encoding="utf-8")
created = pyro.create_task(
created = pyro.create_workspace(
environment="debian:12-base",
allow_host_compat=True,
source_path=source_dir,
seed_path=source_dir,
)
task_id = str(created["task_id"])
workspace_id = str(created["workspace_id"])
updated_dir = tmp_path / "updated"
updated_dir.mkdir()
(updated_dir / "more.txt").write_text("more\n", encoding="utf-8")
synced = pyro.push_task_sync(task_id, updated_dir, dest="subdir")
executed = pyro.exec_task(task_id, command="cat note.txt")
status = pyro.status_task(task_id)
logs = pyro.logs_task(task_id)
deleted = pyro.delete_task(task_id)
synced = pyro.push_workspace_sync(workspace_id, updated_dir, dest="subdir")
executed = pyro.exec_workspace(workspace_id, command="cat note.txt")
status = pyro.status_workspace(workspace_id)
logs = pyro.logs_workspace(workspace_id)
deleted = pyro.delete_workspace(workspace_id)
assert executed["stdout"] == "ok\n"
assert created["workspace_seed"]["mode"] == "directory"