-
Notifications
You must be signed in to change notification settings - Fork 16
docs: add workspace types guide and local_agent_server_mode documentation #414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7591e23
ada6d42
b9db0ea
aaf30a2
bbbb8cd
b2e9a13
de1f9d5
7667853
3eced6e
7cd08c3
e0767d0
0c17284
47de2d0
cbed48d
e9650dc
69da85f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ | |
|
|
||
| > A ready-to-run example is available [here](#ready-to-run-example)! | ||
|
|
||
| The `OpenHandsCloudWorkspace` demonstrates how to use the [OpenHands Cloud](https://app.all-hands.dev) to provision and manage sandboxed environments for agent execution. This provides a seamless experience with automatic sandbox provisioning, monitoring, and secure execution without managing your own infrastructure. | ||
|
|
||
| ## Key Concepts | ||
|
|
||
|
|
@@ -71,7 +71,7 @@ | |
|
|
||
| ```python icon="python" focus={1-3} | ||
| result = workspace.execute_command( | ||
| "echo 'Hello from OpenHands Cloud sandbox!' && pwd" | ||
| ) | ||
| logger.info(f"Command completed: {result.exit_code}, {result.stdout}") | ||
| ``` | ||
|
|
@@ -383,6 +383,121 @@ | |
| uv run python examples/02_remote_agent_server/10_cloud_workspace_share_credentials.py | ||
| ``` | ||
|
|
||
| ## Local Agent Server Mode | ||
|
|
||
| Use `local_agent_server_mode=True` when your SDK script is **already running inside** an OpenHands Cloud sandbox — for example, as part of an automation workflow deployed to the cloud. | ||
|
|
||
| ### When to Use This Mode | ||
|
|
||
| | Scenario | Normal Mode | Local Agent Server Mode | | ||
| |----------|-------------|-------------------------| | ||
| | Script runs on your local machine | ✅ | ❌ | | ||
| | Script runs in CI (GitHub Actions runner) | ✅ | ❌ | | ||
| | Script deployed to run inside Cloud sandbox | ❌ | ✅ | | ||
| | Automation service executes your script | ❌ | ✅ | | ||
|
|
||
| ### How It Differs from Normal Mode | ||
|
|
||
| In **normal mode**, `OpenHandsCloudWorkspace` provisions a new sandbox via the Cloud API: | ||
|
|
||
| <Frame> | ||
| <img src="/sdk/guides/agent-server/images/normal-mode.svg" alt="Normal mode: Your machine communicates with OpenHands Cloud via API" /> | ||
| </Frame> | ||
|
|
||
| In **local agent server mode**, your script is already inside the sandbox and connects to the local agent-server: | ||
|
|
||
| <Frame> | ||
| <img src="/sdk/guides/agent-server/images/local-agent-server-mode-simple.svg" alt="Local agent server mode: Script runs inside Cloud sandbox" /> | ||
| </Frame> | ||
|
|
||
| Key differences: | ||
| - **No sandbox provisioning** — skips create/wait/delete lifecycle | ||
| - **Connects to localhost** — talks to the agent-server already running in the sandbox | ||
| - **Cloud credentials still work** — `get_llm()` and `get_secrets()` call the Cloud API | ||
|
|
||
| ### Configuration | ||
|
|
||
| | Parameter | Type | Default | Description | | ||
| |-----------|------|---------|-------------| | ||
| | `local_agent_server_mode` | `bool` | `False` | Skip sandbox provisioning, connect to localhost | | ||
| | `agent_server_port` | `int` | `60000` | Port of the local agent-server | | ||
|
|
||
| ### Environment Variables | ||
|
|
||
| When running inside a Cloud sandbox, these environment variables are set automatically: | ||
|
|
||
| | Variable | Description | | ||
| |----------|-------------| | ||
| | `SANDBOX_ID` | Sandbox identifier for `get_llm()` / `get_secrets()` | | ||
| | `SESSION_API_KEY` | Session auth key (fallback: `OH_SESSION_API_KEYS_0`) | | ||
| | `AGENT_SERVER_PORT` | Port override (optional) | | ||
jpshackelford marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| | `AUTOMATION_CALLBACK_URL` | URL to POST completion status on exit (optional) | | ||
| | `AUTOMATION_RUN_ID` | ID included in callback payload (optional) | | ||
|
|
||
| ### Example: Automation Script Inside a Cloud Sandbox | ||
|
|
||
| This script is designed to be uploaded and executed inside an OpenHands Cloud sandbox: | ||
|
|
||
| ```python icon="python" | ||
| # my_automation.py — runs INSIDE a Cloud sandbox | ||
| import os | ||
| from openhands.workspace import OpenHandsCloudWorkspace | ||
| from openhands.sdk import Conversation | ||
| from openhands.tools.preset.default import get_default_agent | ||
|
|
||
| with OpenHandsCloudWorkspace( | ||
| local_agent_server_mode=True, | ||
| cloud_api_url="https://app.all-hands.dev", | ||
| cloud_api_key=os.environ["OPENHANDS_API_KEY"], | ||
| ) as workspace: | ||
| # No sandbox created — connects to local agent-server at localhost:60000 | ||
|
|
||
| # Cloud credentials still work | ||
| llm = workspace.get_llm() | ||
| secrets = workspace.get_secrets() | ||
|
|
||
| agent = get_default_agent(llm=llm, cli_mode=True) | ||
| conversation = Conversation(agent=agent, workspace=workspace) | ||
|
|
||
| if secrets: | ||
| conversation.update_secrets(secrets) | ||
jpshackelford marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| conversation.send_message("Perform the automation task") | ||
| conversation.run() | ||
| conversation.close() | ||
|
|
||
| # On exit: completion callback sent automatically (if AUTOMATION_CALLBACK_URL is set) | ||
| ``` | ||
|
|
||
| ### Orchestration Pattern | ||
|
|
||
| To deploy an automation script that uses local agent server mode: | ||
|
|
||
| 1. **Create a sandbox** using normal mode (from your local machine or CI): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟢 Acceptable: The orchestration pattern steps are logically correct, but the presentation suggests step 2's code runs outside the context manager. Readers might wonder: "Can I call Actual answer: Yes, if Not blocking, but consider adding a code comment in step 2: # Workspace persists due to keep_alive=True
workspace.execute_command("python /workspace/my_automation.py") |
||
| ```python | ||
| with OpenHandsCloudWorkspace( | ||
| cloud_api_url="https://app.all-hands.dev", | ||
| cloud_api_key=api_key, | ||
| keep_alive=True, # Don't delete after setup | ||
| ) as workspace: | ||
| workspace.file_upload("my_automation.py", "/workspace/my_automation.py") | ||
| ``` | ||
|
|
||
| 2. **Execute the script** inside the sandbox: | ||
| ```python | ||
| workspace.execute_command("python /workspace/my_automation.py") | ||
| ``` | ||
|
|
||
| 3. The script uses `local_agent_server_mode=True` to connect to the local agent-server | ||
|
|
||
| 4. **Receive callback** when the script completes (optional) | ||
|
|
||
| This pattern enables fire-and-forget automation where your orchestrator doesn't need to maintain a connection for the entire agent session. | ||
|
|
||
| <Note> | ||
| Local agent server mode is primarily used by the OpenHands automation service. For most SDK users, normal mode with `get_llm()` and `get_secrets()` provides a simpler experience. | ||
| </Note> | ||
|
|
||
| ## Next Steps | ||
|
|
||
| - **[API-based Sandbox](/sdk/guides/agent-server/api-sandbox)** - Connect to Runtime API service | ||
|
Comment on lines
+386
to
503
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Technical Verification: I cloned software-agent-sdk PR #2490 and verified: ✅ This section is ~120 lines to explain "connect to localhost instead of provisioning a sandbox," which feels verbose. But previous reviewers flagged this and accepted it as serving a purpose (explaining the automation orchestration pattern). No new issues found beyond what was already discussed. |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟢 Acceptable: This fixes a broken stylesheet reference (link tag had
rel="stylesheet"but nohref). The stylesheet wasn't loading before. Good catch.