Skip to content

Add Narrative-First V0 to V1 Migration Guide (Alternative to #362)#363

Draft
jpshackelford wants to merge 4 commits intomainfrom
narrative-migration-guide
Draft

Add Narrative-First V0 to V1 Migration Guide (Alternative to #362)#363
jpshackelford wants to merge 4 commits intomainfrom
narrative-migration-guide

Conversation

@jpshackelford
Copy link
Contributor

Summary

This PR provides an alternative approach to the migration guide in #362. The key difference is the narrative-first structure that leads with a step-by-step walkthrough rather than reference tables.

Comparison with PR #362

Aspect PR #362 This PR
Lead section Endpoint mapping tables Step-by-step migration walkthrough
Examples Isolated operations Build on each other in a workflow
Agent Server Explained abstractly Shown in context (Step 5) with full curl example
Reference tables Primary content Secondary, for lookup
Flow Reader assembles pieces Guide walks through complete journey

Structure

1. Overview (brief - architecture change + benefits accordion)

2. Migration Walkthrough (THE NARRATIVE)
   Step 1: Create and Start a Conversation
   Step 2: Track Conversation Startup  
   Step 3: Work with Events and Messages
   Step 4: Manage Sandbox Lifecycle
   Step 5: Access the Agent Server
   Step 6: Handle Files and Workspace

3. Quick Reference: Endpoint Mapping (tables for lookup)

4. Agent Server API Reference

5. Known Gaps and Workarounds

6. Authentication Summary

7. Additional Resources

Key Improvements

  1. Actionable from the start - Users can follow along and migrate step-by-step
  2. Context for each change - "Here's what you did in V0, here's why V1 is different"
  3. Complete examples - Each step builds on previous, showing real workflow
  4. Agent Server fully demonstrated - Step 5 shows getting sandbox → extracting session key → making calls
  5. Reference stays available - Endpoint tables at end for quick lookup

Rationale

Based on feedback that a narrative migration flow is important for users. This approach addresses @enyst's "Typical Migration Flow" suggestion from #12578:

  1. Create/Start conversation
  2. Track startup (poll or stream)
  3. Events/messages operations
  4. Sandbox ops
  5. Agent-server operations

Related

This alternative approach restructures the migration guide to lead with
a step-by-step narrative walkthrough, with reference tables moved to
the end for lookup purposes.

Structure:
1. Overview (brief architecture change + benefits accordion)
2. Migration Walkthrough (6 steps with V0→V1 examples)
   - Step 1: Create and Start a Conversation
   - Step 2: Track Conversation Startup
   - Step 3: Work with Events and Messages
   - Step 4: Manage Sandbox Lifecycle
   - Step 5: Access the Agent Server
   - Step 6: Handle Files and Workspace
3. Quick Reference: Endpoint Mapping (tables)
4. Agent Server API Reference
5. Known Gaps and Workarounds
6. Authentication Summary
7. Additional Resources

Based on feedback from OpenHands/OpenHands#12578.

Co-authored-by: openhands <openhands@all-hands.dev>
- Add link to App Server OpenAPI spec (openapi.json) in Additional Resources
- Add new section explaining how to access Agent Server Swagger docs and OpenAPI spec
- Includes step-by-step instructions for getting Agent Server URL from sandbox

Co-authored-by: openhands <openhands@all-hands.dev>
… REST

- Added note highlighting that V1's REST endpoint on Agent Server is a
  big improvement over V0's WebSocket requirement
- Updated Step 3 examples to show Socket.IO code for V0 vs simple curl for V1
- Corrected V1 endpoint to use Agent Server URL with X-Session-API-Key
- Added 'run: true' option explanation for auto-starting agent loop
- Updated Quick Reference table to reflect WebSocket vs REST difference
- Document V0 trajectory endpoint vs V1 events search API
- Show V1 advantages: filtering, pagination, incremental fetches
- Include Python examples for bulk event fetching and real-time polling
- Add trajectory to Quick Reference endpoint mapping table
- Highlight that V1 events API works without active sandbox
jpshackelford pushed a commit to jpshackelford/oh-utils that referenced this pull request Mar 9, 2026
Based on the official V1 migration guide from OpenHands/docs#363, this update
corrects the design document to reflect the actual V1 API architecture:

Key changes:
- Document two-tier API: App Server (conversations/sandboxes) + Agent Server (runtime)
- Correct authentication: App Server uses Authorization header, Agent Server uses X-Session-API-Key
- Update flow: Must get sandbox info first to obtain Agent Server URL and session key
- Add sandbox lifecycle states (STARTING, RUNNING, PAUSED, ERROR, MISSING)
- Update all endpoint references to use correct APIs
- Fix section numbering and remove duplicate content
- Update implementation plan milestones for new architecture

Reference: OpenHands/docs#363
@enyst
Copy link
Collaborator

enyst commented Mar 19, 2026

@OpenHands Read this PR description and the linked issue so you understand the PR goal. You are free to investigate OpenHands/OpenHands and if you need, clone yourself that repo and the agent-sdk repo. Note that you need to pay attention, V1 routes are in openhands/app_server and its execution path; V0 routes are in openhands/server and their files are typically starting with a comment that says they're legacy V0. Understand all I said.

Then do a /codereview on this PR. Submit your feedback as a review on the PR with gh api.

@openhands-ai
Copy link

openhands-ai bot commented Mar 19, 2026

I'm on it! enyst can track my progress at all-hands.dev

enyst
enyst previously requested changes Mar 19, 2026
Copy link
Collaborator

@enyst enyst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting together the narrative-first flow — the structure lines up well with the migration journey described in OpenHands/OpenHands#12578. I reviewed this against the current V1 app-server routes under openhands/app_server/*, the legacy V0 routes under openhands/server/*, and the current software-agent-sdk agent-server/workspace APIs.

I found a few correctness issues that would make some of the copy/paste examples fail against the current implementations, so I’m requesting changes before merge.

Behavior / correctness

  • Steps 1–3 currently document a few request/response shapes that don’t match the live V1 app-server contract (ids, app_conversation_id, start-task statuses, batch event lookup params).
  • stream-start is described as SSE, but the current implementation streams JSON chunks with application/json.
  • The sandbox example shows exposed_urls as an object map, but the actual model returns a list of named URL objects.
  • The guide currently teaches deprecated agent-server file/git routes and an SDK workspace interface that doesn’t exist in the current software-agent-sdk tree.

I’ve left inline comments with the concrete spots to update.

Response:
```json
{
"id": "start-task-uuid",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema shown in Steps 1–2 doesn’t match the current AppConversationStartTask contract in openhands/app_server/app_conversation/app_conversation_models.py: the field is app_conversation_id, not conversation_id, and the status enum starts at WORKING / WAITING_FOR_SANDBOX / … / READY, not STARTING. The poll route also takes repeated ids= values on /start-tasks, not id=. Can we update these examples (and the quick-reference rows that repeat them) to match the real payload/params so readers can copy/paste them successfully?

}'
```

This streams server-sent events as the conversation initializes and begins processing. You'll receive status updates and can show progress to users immediately.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/api/v1/app-conversations/stream-start isn’t emitting SSE frames today. _stream_app_conversation_start() in app_conversation_router.py yields a streamed JSON array with media_type='application/json'. Calling this “server-sent events” will mislead anyone wiring up EventSource/SSE parsing. Please describe it as a streaming JSON response (or change the client guidance to whatever parsing logic is actually required).

-H "Authorization: Bearer YOUR_API_KEY"

# Batch get specific events by ID
curl "https://app.all-hands.dev/api/v1/conversation/{id}/events?event_id=evt1&event_id=evt2" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Batch event lookup on GET /api/v1/conversation/{conversation_id}/events binds repeated id= query params, not event_id=. As written, this example won’t match the router signature in openhands/app_server/event/event_router.py. Please switch this to ?id=evt1&id=evt2 (and update any reference-table rows that repeat the same parameter name).

"id": "sandbox-abc123",
"status": "RUNNING",
"session_api_key": "session-key-xyz",
"exposed_urls": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SandboxInfo response shape here is off: exposed_urls is a list of {name, url, port} objects, not an object keyed by AGENT_SERVER / VSCODE. Consumers following this example won’t be able to parse the response they actually get back. Please show the real array shape and call out that callers need to find the entry whose name == "AGENT_SERVER".


```bash
# Execute a bash command
curl -X POST "https://sandbox-abc123.runtime.all-hands.dev/api/bash/execute_bash_command" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples are teaching the path-style agent-server file routes (/api/file/download/{path}, /api/file/upload/{path}), but current software-agent-sdk agent-server code marks those as deprecated and prefers the query-param forms (/api/file/download?path=..., /api/file/upload?path=...). The same applies to the git path-style routes in the reference section below. Since this is a brand-new V1 migration guide, I think we should document the stable forms here instead of routes already scheduled for removal.


**Alternative: Use the Agent SDK**

The [OpenHands Agent SDK](https://docs.openhands.dev/sdk) provides convenient methods that work with both V0 and V1:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think this SDK example matches the current software-agent-sdk API. Workspace is exported from openhands.sdk, not openhands; it doesn’t accept conversation_id=...; and the current workspace classes don’t expose list_files() / read_file() / write_file() / get_workspace_zip() methods. As written, this sends readers to an SDK workflow that won’t run. Could we either replace this with a real RemoteWorkspace example (host + api_key) using current methods like file_upload, file_download, and execute_command, or drop the SDK workaround entirely?

@openhands-ai

This comment was marked as duplicate.

@enyst enyst dismissed their stale review March 19, 2026 13:43

Today I learned that GPT-5.4 will “request changes” with a simple /codereview prompt. Sorry to mess with a draft PR, I’m happy here with what you see fit either way. Unblocking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

V0 to V1 Migration Guide

3 participants