CodeDocs Vault

01 — Entry Points & Execution Flow

Entry Points

OpenHands has three main entry points, corresponding to different deployment modes.

1. CLI Entry Point (V0 — Legacy)

File: openhands/core/main.py:361-395

if __name__ == '__main__':
    args = parse_arguments()
    config: OpenHandsConfig = setup_config_from_args(args)
    task_str = read_task(args, config.cli_multiline_input)
    initial_user_action = MessageAction(content=task_str)
    sid = generate_sid(config, session_name)
    asyncio.run(
        run_controller(
            config=config,
            initial_user_action=initial_user_action,
            sid=sid,
            fake_user_response_fn=None if args.no_auto_continue else auto_continue_response,
        )
    )

The CLI reads a task from -t, -f, or stdin, wraps it as a MessageAction, and hands it to run_controller() (line 59). In headless mode, the auto_continue_response function (line 322) automatically tells the agent to keep going without waiting for user input.

2. Web Server (V0 — Legacy)

File: openhands/server/__main__.py:16-34

def main():
    uvicorn.run(
        'openhands.server.listen:app',
        host='0.0.0.0',
        port=int(os.environ.get('port') or '3000'),
    )

Starts a Uvicorn ASGI server on port 3000. The FastAPI app is defined in openhands/server/listen.py, which sets up WebSocket endpoints for real-time communication with the React frontend and REST endpoints for session management.

3. V1 Application Server

File: openhands/app_server/v1_router.py:1-20

router = APIRouter(prefix='/api/v1')
router.include_router(event_router.router)
router.include_router(app_conversation_router.router)
router.include_router(sandbox_router.router)
router.include_router(sandbox_spec_router.router)
router.include_router(user_router.router)
router.include_router(webhook_router.router)
router.include_router(web_client_router.router)

The V1 server uses a modular router structure under /api/v1 with dedicated sub-routers for conversations, events, sandboxes, users, and webhooks. The V1 agentic core is powered by the external Software Agent SDK.


Complete Execution Pipeline

The following 10-step flow describes what happens from user input to completion. This applies to both CLI and web server paths (they converge at step 2).

 ┌─────────────────────────────────────────────────────────────────┐
 │                    EXECUTION PIPELINE                           │
 ├─────────────────────────────────────────────────────────────────┤
 │                                                                 │
 │  1. USER INPUT                                                  │
 │     CLI: parse_arguments() → read_task() → MessageAction        │
 │     Web: WebSocket message → MessageAction                      │
 │                         │                                       │
 │  2. INITIALIZATION      ▼                                       │
 │     run_controller() creates:                                   │
 │       • LLMRegistry + ConversationStats                         │
 │       • Agent (via create_agent)                                │
 │       • Runtime (Docker/Remote/Local/K8s/CLI)                   │
 │       • EventStream (from runtime)                              │
 │       • Memory (microagents, repo context)                      │
 │       • AgentController                                         │
 │                         │                                       │
 │  3. EVENT LOOP          ▼                                       │
 │     run_agent_until_done() polls controller state               │
 │     until an end state is reached                               │
 │                         │                                       │
 │  4. AGENT STEP          ▼                                       │
 │     AgentController._step()                                     │
 │       • Check state == RUNNING                                  │
 │       • Check no pending action                                 │
 │       • Run stuck detection                                     │
 │       • Run control flags (iteration/budget limits)             │
 │       • Call agent.step(state)                                  │
 │                         │                                       │
 │  5. LLM CALL            ▼                                       │
 │     CodeActAgent.step():                                        │
 │       • Condense history (via Condenser)                        │
 │       • Build messages (ConversationMemory)                     │
 │       • LLM completion (with tools)                             │
 │       • Parse response → Action(s)                              │
 │                         │                                       │
 │  6. ACTION EXECUTION    ▼                                       │
 │     EventStream dispatches action to Runtime                    │
 │       • Runtime.run() for CmdRunAction                          │
 │       • Runtime.edit() for FileEditAction                       │
 │       • Runtime.browse_interactive() for browser actions        │
 │       • etc.                                                    │
 │                         │                                       │
 │  7. OBSERVATION          ▼                                      │
 │     Runtime produces Observation, added to EventStream          │
 │       • CmdOutputObservation                                    │
 │       • FileReadObservation                                     │
 │       • ErrorObservation                                        │
 │       • BrowserOutputObservation                                │
 │                         │                                       │
 │  8. FEEDBACK LOOP       ▼                                       │
 │     Controller receives observation via on_event()              │
 │     → clears pending action                                     │
 │     → triggers next _step() if agent is RUNNING                 │
 │     → loops back to step 4                                      │
 │                         │                                       │
 │  9. TERMINAL STATES     ▼                                       │
 │     Agent emits AgentFinishAction → FINISHED                    │
 │     Agent emits AgentRejectAction → REJECTED                    │
 │     Error occurs → ERROR                                        │
 │     User stops → STOPPED                                        │
 │     Stuck detection → ERROR (AgentStuckInLoopError)             │
 │                         │                                       │
 │  10. CLEANUP            ▼                                       │
 │      • Save state to FileStore                                  │
 │      • Save trajectory (if configured)                          │
 │      • Close controller, event stream, runtime                  │
 │                                                                 │
 └─────────────────────────────────────────────────────────────────┘

Key source references:


Agent State Machine

The AgentState enum (openhands/core/schema/agent.py:11-58) defines all possible states. Below is the state transition diagram:

                          ┌──────────────┐
                          │   LOADING    │
                          └──────┬───────┘
                                 │ initialization complete
                                 ▼
                   ┌─────────────────────────────┐
        ┌─────────│          RUNNING             │◄────────────────┐
        │         └──┬──────┬──────┬──────┬──────┘                │
        │            │      │      │      │                       │
        │    agent   │  user│  con-│  er- │  stuck                │
        │   finish   │  msg │  firm│  ror │  detect               │
        │            │      │      │      │                       │
        │            ▼      │      ▼      ▼                       │
        │     ┌──────────┐  │ ┌────────┐ ┌────────┐              │
        │     │ FINISHED │  │ │AWAITING│ │ ERROR  │──── resume ──┘
        │     └──────────┘  │ │ USER   │ └────────┘
        │                   │ │CONFIRM │
        │     ┌──────────┐  │ └───┬────┘
        │     │ REJECTED │  │     │ confirmed / rejected
        │     └──────────┘  │     ▼
        │                   │ ┌────────────┐   ┌────────────┐
        │                   │ │  USER      │   │   USER     │
        │                   │ │ CONFIRMED  │   │  REJECTED  │
        │                   │ └─────┬──────┘   └─────┬──────┘
        │                   │       │ re-run action   │ → AWAITING_USER_INPUT
        │                   │       └────────────────►│
        │                   │                         │
        │                   ▼                         │
        │            ┌──────────────┐                 │
        │            │  AWAITING    │◄────────────────┘
        │            │  USER_INPUT  │
        │            └──────┬───────┘
        │                   │ user sends message
        │                   └─────────► RUNNING
        │
        │            ┌──────────┐
        │            │  PAUSED  │ ◄── user pause / loop detection
        │            └──────┬───┘
        │                   │ user resume
        │                   └─────────► RUNNING
        │
        │            ┌──────────┐
        └───────────►│ STOPPED  │ ◄── user stop / ctrl+C
                     └──────────┘

                     ┌──────────────┐
                     │ RATE_LIMITED │ ◄── LLM rate limit (transient)
                     └──────────────┘

State Descriptions

State Value Description
LOADING loading Agent is initializing
RUNNING running Agent is actively processing
AWAITING_USER_INPUT awaiting_user_input Agent asked a question, waiting for user
AWAITING_USER_CONFIRMATION awaiting_user_confirmation Confirmation mode: risky action needs approval
USER_CONFIRMED user_confirmed User approved the pending action
USER_REJECTED user_rejected User rejected the pending action
PAUSED paused Agent paused (user-initiated or loop detection)
STOPPED stopped Agent stopped (terminal)
FINISHED finished Agent completed the task (terminal)
REJECTED rejected Agent rejected the task (terminal)
ERROR error An error occurred (terminal, but can resume)
RATE_LIMITED rate_limited LLM rate limit hit (transient)