todo-3-websocket-api.md 3.5 KB

Todo 3 WebSocket API and Static UI Plan

Status: done

Result

Implemented by subagent and locally verified.

Commands:

uv run pytest
uv run python -c "from agent_lab.main import app; print(app.title)"

Results:

  • uv run pytest: 8 passed, 1 warning in 0.24s
  • import smoke: Agent Lab

Evaluation note: real LLM configuration already exists through Settings, so Todo 4 should focus on documentation and a minimal manual smoke helper rather than adding another runtime layer.

Goal

Expose the domain runtime through FastAPI WebSocket and serve a usable static debug console.

Scope

This todo covers:

  • FastAPI app factory and HTTP index route.
  • WebSocket endpoint for one debug run per request.
  • OpenAI Chat Completions compatible HTTP client for streaming completions.
  • Assistant message transcript persistence during runtime loops.
  • Static HTML/CSS/JS page without a frontend build chain.
  • Contract tests using FastAPI TestClient and a fake runtime/client where possible.

This todo does not cover:

  • Production auth.
  • Multi-user session storage.
  • Redis/NATS/external queues.
  • Full visual polish.
  • Final README/env docs; those stay in Todo 4.

Files

  • Modify: src/agent_lab/application/runtime.py
  • Create: src/agent_lab/infrastructure/chat_client.py
  • Create: src/agent_lab/settings.py
  • Create: src/agent_lab/main.py
  • Create: src/agent_lab/presentation/web.py
  • Create: src/agent_lab/presentation/static/index.html
  • Create: src/agent_lab/presentation/static/app.js
  • Create: src/agent_lab/presentation/static/styles.css
  • Create: tests/test_websocket_api.py
  • Update: docs/plans/todos.md after evaluation only.

Protocol

Frontend sends one JSON object to /ws/debug:

{
  "user_message": "debug this",
  "system_prompts": ["You are a debugger."],
  "pre_messages": [],
  "chat_agent": {
    "model": "gpt-4.1-mini",
    "temperature": 0.2,
    "max_tokens": 800
  },
  "event_agent": {
    "enabled_tools": ["handoff_note"],
    "max_event_loops": 3
  }
}

Server sends newline-independent JSON WebSocket messages already produced by DebugRuntime.run(), plus an error message on validation/runtime failures.

Steps

  1. Add tests for /health and /ws/debug with a fake runtime or fake chat client.
  2. Update DebugRuntime to aggregate streamed assistant content and append assistant messages to history when a model turn completes.
  3. Implement Settings with pydantic-settings fields:
    • openai_api_key
    • openai_base_url
    • openai_default_model
    • request_timeout_seconds
  4. Implement OpenAICompatibleChatClient using httpx.AsyncClient.stream() against /chat/completions, with stream: true, configured model params, tool definitions, and ChatCompletionStreamParser.
  5. Implement FastAPI app factory and routes:
    • GET /health
    • GET /
    • WebSocket /ws/debug
  6. Implement static page controls:
    • multiple system prompts.
    • pre-message editor.
    • chat input and streamed output.
    • ChatAgent/EventAgent parameter inputs.
    • EventAgent tool toggles.
    • round stats area for tokens, cached tokens, TTFT, and elapsed time.
  7. Run focused tests:

    uv run pytest tests/test_websocket_api.py tests/test_debug_runtime.py
    
  8. Run full tests:

    uv run pytest
    

Verification

Expected result:

  • WebSocket contract test passes without a real LLM key.
  • Existing Todo 2 tests still pass.
  • App imports with uv run python -c "from agent_lab.main import app; print(app.title)".