Add MCP tool profiles for workspace chat flows
Expose stable MCP/server tool profiles so chat hosts can start narrow and widen only when needed. This adds vm-run, workspace-core, and workspace-full across the CLI serve path, Pyro.create_server(), and the package-level create_server() factory while keeping workspace-full as the default. Register profile-specific tool sets from one shared contract mapping, and narrow the workspace-core schemas so secrets, network policy, shells, services, snapshots, and disk tools do not leak into the default persistent chat profile. The full surface remains available unchanged under workspace-full. Refresh the public docs and examples around the profile progression, add a canonical OpenAI Responses workspace-core example, mark the 3.4.0 roadmap milestone done, and verify with uv lock, UV_CACHE_DIR=.uv-cache make check, UV_CACHE_DIR=.uv-cache make dist-check, and a real guest-backed workspace-core smoke for create, file write, exec, diff, export, reset, and delete.
This commit is contained in:
parent
446f7fce04
commit
eecfd7a7d7
23 changed files with 984 additions and 511 deletions
|
|
@ -22,7 +22,7 @@ Networking: tun=yes ip_forward=yes
|
|||
|
||||
```bash
|
||||
$ uvx --from pyro-mcp pyro env list
|
||||
Catalog version: 3.3.0
|
||||
Catalog version: 3.4.0
|
||||
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
|
||||
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
|
||||
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
|
||||
|
|
@ -116,7 +116,7 @@ $ uvx --from pyro-mcp pyro workspace shell open WORKSPACE_ID --secret-env API_TO
|
|||
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID app --secret-env API_TOKEN --ready-file .ready -- sh -lc 'touch .ready && while true; do sleep 60; done'
|
||||
$ uvx --from pyro-mcp pyro workspace create debian:12 --network-policy egress+published-ports
|
||||
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID app --ready-http http://127.0.0.1:8080/ --publish 18080:8080 -- ./start-app
|
||||
$ uvx --from pyro-mcp pyro mcp serve
|
||||
$ uvx --from pyro-mcp pyro mcp serve --profile workspace-core
|
||||
```
|
||||
|
||||
`pyro demo` proves the one-shot create/start/exec/delete VM lifecycle works end to end.
|
||||
|
|
@ -252,7 +252,7 @@ State: started
|
|||
Use `--seed-path` when the workspace should start from a host directory or a local
|
||||
`.tar` / `.tar.gz` / `.tgz` archive instead of an empty `/workspace`. Use
|
||||
`pyro workspace sync push` when you need to import later host-side changes into a started
|
||||
workspace. Sync is non-atomic in `3.3.0`; if it fails partway through, prefer `pyro workspace reset`
|
||||
workspace. Sync is non-atomic in `3.4.0`; if it fails partway through, prefer `pyro workspace reset`
|
||||
to recover from `baseline` or one named snapshot. Use `pyro workspace diff` to compare the current
|
||||
`/workspace` tree to its immutable create-time baseline, `pyro workspace snapshot *` to create
|
||||
named checkpoints, and `pyro workspace export` to copy one changed file or directory back to the
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ uvx --from pyro-mcp pyro env list
|
|||
Expected output:
|
||||
|
||||
```bash
|
||||
Catalog version: 3.3.0
|
||||
Catalog version: 3.4.0
|
||||
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
|
||||
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
|
||||
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
|
||||
|
|
@ -224,7 +224,7 @@ After the CLI path works, you can move on to:
|
|||
- interactive shells: `pyro workspace shell open WORKSPACE_ID`
|
||||
- long-running services: `pyro workspace service start WORKSPACE_ID app --ready-file .ready -- sh -lc 'touch .ready && while true; do sleep 60; done'`
|
||||
- localhost-published ports: `pyro workspace create debian:12 --network-policy egress+published-ports` and `pyro workspace service start WORKSPACE_ID app --ready-http http://127.0.0.1:8080/ --publish 18080:8080 -- ./start-app`
|
||||
- MCP: `pyro mcp serve`
|
||||
- MCP: `pyro mcp serve --profile workspace-core`
|
||||
- Python SDK: `from pyro_mcp import Pyro`
|
||||
- Demos: `pyro demo` or `pyro demo --network`
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ Workspace commands default to the persistent `/workspace` directory inside the g
|
|||
the identifier programmatically, use `--json` and read the `workspace_id` field. Use `--seed-path`
|
||||
when the workspace should start from a host directory or a local `.tar` / `.tar.gz` / `.tgz`
|
||||
archive. Use `pyro workspace sync push` for later host-side changes to a started workspace. Sync
|
||||
is non-atomic in `3.3.0`; if it fails partway through, prefer `pyro workspace reset` to recover
|
||||
is non-atomic in `3.4.0`; if it fails partway through, prefer `pyro workspace reset` to recover
|
||||
from `baseline` or one named snapshot. Use `pyro workspace diff` to compare the current workspace
|
||||
tree to its immutable create-time baseline, `pyro workspace snapshot *` to capture named
|
||||
checkpoints, and `pyro workspace export` to copy one changed file or directory back to the host. Use
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ CLI path in [install.md](install.md) or [first-run.md](first-run.md).
|
|||
|
||||
## Recommended Default
|
||||
|
||||
Use `vm_run` first for one-shot commands, then move to the stable workspace surface when the
|
||||
agent needs to inhabit one sandbox across multiple calls.
|
||||
Use `vm_run` first for one-shot commands, then move to `workspace-core` when the
|
||||
agent needs to inhabit one sandbox across multiple calls. Only promote the chat
|
||||
surface to `workspace-full` when it truly needs shells, services, snapshots,
|
||||
secrets, network policy, or disk tools.
|
||||
|
||||
That keeps the model-facing contract small:
|
||||
|
||||
|
|
@ -17,8 +19,11 @@ That keeps the model-facing contract small:
|
|||
- one ephemeral VM
|
||||
- automatic cleanup
|
||||
|
||||
Move to `workspace_*` when the agent needs repeated commands, shells, services, snapshots, reset,
|
||||
diff, or export in one stable workspace across multiple calls.
|
||||
Profile progression:
|
||||
|
||||
- `vm-run`: one-shot only
|
||||
- `workspace-core`: persistent workspace create/list/update/status/sync/exec/logs/file ops/diff/export/reset/delete
|
||||
- `workspace-full`: the full stable workspace surface, including shells, services, snapshots, secrets, network policy, and disk tools
|
||||
|
||||
## OpenAI Responses API
|
||||
|
||||
|
|
@ -30,20 +35,14 @@ Best when:
|
|||
|
||||
Recommended surface:
|
||||
|
||||
- `vm_run`
|
||||
- `workspace_create(name=..., labels=...)` + `workspace_list` + `workspace_update` when the agent needs to rediscover or retag long-lived workspaces between turns
|
||||
- `workspace_create(seed_path=...)` + `workspace_sync_push` + `workspace_exec` when the agent needs persistent workspace state
|
||||
- `workspace_file_list` / `workspace_file_read` / `workspace_file_write` / `workspace_patch_apply` when the agent needs model-native file inspection and text edits inside one live workspace
|
||||
- `workspace_create(..., secrets=...)` + `workspace_exec(..., secret_env=...)` when the workspace needs private tokens or authenticated setup
|
||||
- `workspace_create(..., network_policy="egress+published-ports")` + `start_service(..., published_ports=[...])` when the host must probe one workspace service
|
||||
- `workspace_diff` + `workspace_export` when the agent needs explicit baseline comparison or host-out file transfer
|
||||
- `stop_workspace(...)` + `list_workspace_disk(...)` / `read_workspace_disk(...)` / `export_workspace_disk(...)` when one stopped guest-backed workspace needs offline inspection or a raw ext4 copy
|
||||
- `start_service` / `list_services` / `status_service` / `logs_service` / `stop_service` when the agent needs long-running processes inside that workspace
|
||||
- `open_shell(..., secret_env=...)` / `read_shell` / `write_shell` when the agent needs an interactive PTY inside that workspace
|
||||
- `vm_run` for one-shot loops
|
||||
- the `workspace-core` tool set for the normal persistent chat loop
|
||||
- the `workspace-full` tool set only when the host explicitly needs advanced workspace capabilities
|
||||
|
||||
Canonical example:
|
||||
|
||||
- [examples/openai_responses_vm_run.py](../examples/openai_responses_vm_run.py)
|
||||
- [examples/openai_responses_workspace_core.py](../examples/openai_responses_workspace_core.py)
|
||||
|
||||
## MCP Clients
|
||||
|
||||
|
|
@ -55,7 +54,13 @@ Best when:
|
|||
|
||||
Recommended entrypoint:
|
||||
|
||||
- `pyro mcp serve`
|
||||
- `pyro mcp serve --profile workspace-core`
|
||||
|
||||
Profile progression:
|
||||
|
||||
- `pyro mcp serve --profile vm-run` for the smallest one-shot surface
|
||||
- `pyro mcp serve --profile workspace-core` for the normal persistent chat loop
|
||||
- `pyro mcp serve --profile workspace-full` only when the model truly needs advanced workspace tools
|
||||
|
||||
Starter config:
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ Behavioral guarantees:
|
|||
- `pyro workspace create --seed-path PATH` seeds `/workspace` from a host directory or a local `.tar` / `.tar.gz` / `.tgz` archive before the workspace is returned.
|
||||
- `pyro workspace create --name NAME --label KEY=VALUE` attaches human-oriented discovery metadata without changing the stable `workspace_id`.
|
||||
- `pyro workspace create --network-policy {off,egress,egress+published-ports}` controls workspace guest networking and whether services may publish localhost ports.
|
||||
- `pyro mcp serve --profile {vm-run,workspace-core,workspace-full}` narrows the model-facing MCP surface without changing runtime behavior.
|
||||
- `pyro workspace create --secret NAME=VALUE` and `--secret-file NAME=PATH` persist guest-only UTF-8 secrets outside `/workspace`.
|
||||
- `pyro workspace list` returns persisted workspaces sorted by most recent `last_activity_at`.
|
||||
- `pyro workspace sync push WORKSPACE_ID SOURCE_PATH [--dest WORKSPACE_PATH]` imports later host-side directory or archive content into a started workspace.
|
||||
|
|
@ -125,8 +126,8 @@ Primary facade:
|
|||
|
||||
Supported public entrypoints:
|
||||
|
||||
- `create_server()`
|
||||
- `Pyro.create_server()`
|
||||
- `create_server(profile="workspace-full")`
|
||||
- `Pyro.create_server(profile="workspace-full")`
|
||||
- `Pyro.list_environments()`
|
||||
- `Pyro.pull_environment(environment)`
|
||||
- `Pyro.inspect_environment(environment)`
|
||||
|
|
@ -176,7 +177,7 @@ Supported public entrypoints:
|
|||
|
||||
Stable public method names:
|
||||
|
||||
- `create_server()`
|
||||
- `create_server(profile="workspace-full")`
|
||||
- `list_environments()`
|
||||
- `pull_environment(environment)`
|
||||
- `inspect_environment(environment)`
|
||||
|
|
@ -265,6 +266,18 @@ Behavioral defaults:
|
|||
|
||||
## MCP Contract
|
||||
|
||||
Stable MCP profiles:
|
||||
|
||||
- `vm-run`: exposes only `vm_run`
|
||||
- `workspace-core`: exposes `vm_run`, `workspace_create`, `workspace_list`, `workspace_update`, `workspace_status`, `workspace_sync_push`, `workspace_exec`, `workspace_logs`, `workspace_file_list`, `workspace_file_read`, `workspace_file_write`, `workspace_patch_apply`, `workspace_diff`, `workspace_export`, `workspace_reset`, and `workspace_delete`
|
||||
- `workspace-full`: exposes the complete stable MCP surface below
|
||||
|
||||
Behavioral defaults:
|
||||
|
||||
- `pyro mcp serve` and `create_server()` default to `workspace-full`.
|
||||
- `workspace-core` narrows `workspace_create` by omitting `network_policy` and `secrets`.
|
||||
- `workspace-core` narrows `workspace_exec` by omitting `secret_env`.
|
||||
|
||||
Primary tool:
|
||||
|
||||
- `vm_run`
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ goal:
|
|||
make the core agent-workspace use cases feel trivial from a chat-driven LLM
|
||||
interface.
|
||||
|
||||
Current baseline is `3.3.0`:
|
||||
Current baseline is `3.4.0`:
|
||||
|
||||
- the stable workspace contract exists across CLI, SDK, and MCP
|
||||
- one-shot `pyro run` still exists as the narrow entrypoint
|
||||
|
|
@ -47,7 +47,7 @@ More concretely, the model should not need to:
|
|||
|
||||
1. [`3.2.0` Model-Native Workspace File Ops](llm-chat-ergonomics/3.2.0-model-native-workspace-file-ops.md) - Done
|
||||
2. [`3.3.0` Workspace Naming And Discovery](llm-chat-ergonomics/3.3.0-workspace-naming-and-discovery.md) - Done
|
||||
3. [`3.4.0` Tool Profiles And Canonical Chat Flows](llm-chat-ergonomics/3.4.0-tool-profiles-and-canonical-chat-flows.md)
|
||||
3. [`3.4.0` Tool Profiles And Canonical Chat Flows](llm-chat-ergonomics/3.4.0-tool-profiles-and-canonical-chat-flows.md) - Done
|
||||
4. [`3.5.0` Chat-Friendly Shell Output](llm-chat-ergonomics/3.5.0-chat-friendly-shell-output.md)
|
||||
5. [`3.6.0` Use-Case Recipes And Smoke Packs](llm-chat-ergonomics/3.6.0-use-case-recipes-and-smoke-packs.md)
|
||||
|
||||
|
|
@ -58,6 +58,9 @@ Completed so far:
|
|||
- `3.3.0` added workspace names, key/value labels, `workspace list`, `workspace update`, and
|
||||
`last_activity_at` tracking so humans and chat-driven agents can rediscover and resume the right
|
||||
workspace without external notes.
|
||||
- `3.4.0` added stable MCP/server tool profiles with `vm-run`, `workspace-core`, and
|
||||
`workspace-full`, plus canonical profile-based OpenAI and MCP examples so chat hosts can start
|
||||
narrow and widen only when needed.
|
||||
|
||||
## Expected Outcome
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# `3.4.0` Tool Profiles And Canonical Chat Flows
|
||||
|
||||
Status: Planned
|
||||
Status: Done
|
||||
|
||||
## Goal
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue