Skip to content

refactor: simplify web transports with Starlette - #142

Merged
frostming merged 2 commits into
mainfrom
refactor/starlette-web-transports
Sep 11, 2026
Merged

refactor: simplify web transports with Starlette#142
frostming merged 2 commits into
mainfrom
refactor/starlette-web-transports

Conversation

@frostming

@frostming frostming commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

The HTTP and WebSocket servers currently route agent messages through an in-memory transport pair, pump tasks, a connection registry, and WebSocket multiplex queues, while maintaining a hand-written ASGI adapter. This change connects both transports directly to AgentSideConnection and delegates HTTP/ASGI handling to Starlette.

  • Replace ConnectionRegistry/ConnectionState with a connection dictionary and a direct HTTP transport. Keep session routing, bounded SSE buffers, backpressure, keepalives, and cancellation cleanup; use one Future for initialization.
  • Use Starlette requests, responses, streaming, WebSocket handling, and lifespan. Add Starlette to the optional [http] extra; core/stdio imports remain independent of web dependencies.
  • Add create_asgi_app(agent_factory, *, path="/acp"), sharing the configured route between HTTP and WebSocket, including when mounted under a parent application. Method dispatch follows Starlette routing without a separate check in _get.

Experimental API changes: create_asgi_app() returns a Starlette app; AcpServer handlers return Starlette responses. Remove AcpAsgiApp, PostResult, the registry/state helpers, and create_websocket_connection(). Direct WebSocket integrations use handle_websocket(agent_factory, websocket). The default /acp route replaces the previous catch-all route.

session/load now works over HTTP without requiring a sessionId in its response. Correlate the request ID, keep replay and completion on the connection SSE stream, and provision the session stream for continued prompts. Failed loads clean up provisional streams while preserving existing sessions and overlapping loads. Cover empty/null responses, 1100-message histories, repeated loads, retry after failure, and permission callbacks over HTTP and WebSocket. Agent load responses and capability advertisement are preserved.

Related issues

No linked issue.

Testing

  • make test: 256 passed, 1 skipped (optional Gemini test).
  • make check: lockfile consistency, pre-commit/Ruff, ty, and deptry passed.
  • Coverage includes HTTP/WebSocket prompt streaming and reverse permission requests, initialization interruption, backpressure/close, SSE disconnect and reopen, direct/mounted custom paths, rejection of unrelated paths, lifespan cleanup, and concurrent session success/error routing.
  • Checked that core SDK imports work with web dependencies unavailable.

Docs & screenshots

Updated docs/web-transport.md with the simplified architecture, ablation results, API changes, custom paths, and parent/child lifespan mounting example. Updated the HTTP server example. No schema regeneration or screenshots required.

Checklist

  • Conventional Commit title (e.g. feat:, fix:).
  • Tests cover the change or are not required (explain above).
  • Docs/examples updated when behaviour is user-facing.
  • Schema regenerations (make gen-all) are called out if applicable (none).

@frostming
frostming merged commit c1004f8 into main Sep 11, 2026
8 checks passed
@frostming
frostming deleted the refactor/starlette-web-transports branch September 11, 2026 03:38
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.

1 participant