diff --git a/docs/modules/usage/how-to/websocket-connection.md b/docs/modules/usage/how-to/websocket-connection.md new file mode 100644 index 0000000000..3a61a67270 --- /dev/null +++ b/docs/modules/usage/how-to/websocket-connection.md @@ -0,0 +1,181 @@ +--- +sidebar_position: 9 +--- + +# Connecting to the WebSocket + +This guide explains how to connect to the OpenHands WebSocket API to receive real-time events and send actions to the agent. + +## Overview + +OpenHands uses [Socket.IO](https://socket.io/) for WebSocket communication between the client and server. The WebSocket connection allows you to: + +1. Receive real-time events from the agent +2. Send user actions to the agent +3. Maintain a persistent connection for ongoing conversations + +## Connecting to the WebSocket + +### Connection Parameters + +When connecting to the WebSocket, you need to provide the following query parameters: + +- `conversation_id`: The ID of the conversation you want to join +- `latest_event_id`: The ID of the latest event you've received (use `-1` for a new connection) +- `providers_set`: (Optional) A comma-separated list of provider types + +### Connection Example + +Here's a basic example of connecting to the WebSocket using JavaScript: + +```javascript +import { io } from "socket.io-client"; + +const socket = io("http://localhost:3000", { + transports: ["websocket"], + query: { + conversation_id: "your-conversation-id", + latest_event_id: -1, + providers_set: "github,gitlab" // Optional + } +}); + +socket.on("connect", () => { + console.log("Connected to OpenHands WebSocket"); +}); + +socket.on("oh_event", (event) => { + console.log("Received event:", event); +}); + +socket.on("connect_error", (error) => { + console.error("Connection error:", error); +}); + +socket.on("disconnect", (reason) => { + console.log("Disconnected:", reason); +}); +``` + +## Sending Actions to the Agent + +To send an action to the agent, use the `oh_user_action` event: + +```javascript +// Send a user message to the agent +socket.emit("oh_user_action", { + type: "message", + source: "user", + message: "Hello, can you help me with my project?" +}); +``` + +## Receiving Events from the Agent + +The server emits events using the `oh_event` event type. Here are some common event types you might receive: + +- User messages (`source: "user", type: "message"`) +- Agent messages (`source: "agent", type: "message"`) +- File edits (`action: "edit"`) +- File writes (`action: "write"`) +- Command executions (`action: "run"`) + +Example event handler: + +```javascript +socket.on("oh_event", (event) => { + if (event.source === "agent" && event.type === "message") { + console.log("Agent says:", event.message); + } else if (event.action === "run") { + console.log("Command executed:", event.args.command); + console.log("Result:", event.result); + } +}); +``` + +## Using Websocat for Testing + +[Websocat](https://github.com/vi/websocat) is a command-line tool for interacting with WebSockets. It's useful for testing your WebSocket connection without writing a full client application. + +### Installation + +```bash +# On macOS +brew install websocat + +# On Linux +curl -L https://github.com/vi/websocat/releases/download/v1.11.0/websocat.x86_64-unknown-linux-musl > websocat +chmod +x websocat +sudo mv websocat /usr/local/bin/ +``` + +### Connecting to the WebSocket + +```bash +# Connect to the WebSocket and print all received messages +echo "40{}" | \ +websocat "ws://localhost:3000/socket.io/?EIO=4&transport=websocket&conversation_id=your-conversation-id&latest_event_id=-1" +``` + +### Sending a Message + +```bash +# Send a message to the agent +echo '42["oh_user_action",{"type":"message","source":"user","message":"Hello, agent!"}]' | \ +websocat "ws://localhost:3000/socket.io/?EIO=4&transport=websocket&conversation_id=your-conversation-id&latest_event_id=-1" +``` + +### Complete Example with Websocat + +Here's a complete example of connecting to the WebSocket, sending a message, and receiving events: + +```bash +# Start a persistent connection +websocat -v "ws://localhost:3000/socket.io/?EIO=4&transport=websocket&conversation_id=your-conversation-id&latest_event_id=-1" + +# In another terminal, send a message +echo '42["oh_user_action",{"type":"message","source":"user","message":"Can you help me with my project?"}]' | \ +websocat "ws://localhost:3000/socket.io/?EIO=4&transport=websocket&conversation_id=your-conversation-id&latest_event_id=-1" +``` + +## Event Structure + +Events sent and received through the WebSocket follow a specific structure: + +```typescript +interface OpenHandsEvent { + id: string; // Unique event ID + source: string; // "user" or "agent" + timestamp: string; // ISO timestamp + message?: string; // For message events + type?: string; // Event type (e.g., "message") + action?: string; // Action type (e.g., "run", "edit", "write") + args?: any; // Action arguments + result?: any; // Action result +} +``` + +## Best Practices + +1. **Handle Reconnection**: Implement reconnection logic in your client to handle network interruptions. +2. **Track Event IDs**: Store the latest event ID you've received and use it when reconnecting to avoid duplicate events. +3. **Error Handling**: Implement proper error handling for connection errors and failed actions. +4. **Rate Limiting**: Avoid sending too many actions in a short period to prevent overloading the server. + +## Troubleshooting + +### Connection Issues + +- Verify that the OpenHands server is running and accessible +- Check that you're providing the correct conversation ID +- Ensure your WebSocket URL is correctly formatted + +### Authentication Issues + +- Make sure you have the necessary authentication cookies if required +- Verify that you have permission to access the specified conversation + +### Event Handling Issues + +- Check that you're correctly parsing the event data +- Verify that your event handlers are properly registered \ No newline at end of file diff --git a/docs/sidebars.ts b/docs/sidebars.ts index b4c906b810..4cd006139d 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -267,6 +267,11 @@ const sidebars: SidebarsConfig = { label: 'Evaluation', id: 'usage/how-to/evaluation-harness', }, + { + type: 'doc', + label: 'WebSocket Connection', + id: 'usage/how-to/websocket-connection', + }, ], }, {