Skip to content

Support a wasm / browser based acp client #527

Closed

Description

@jcarver989

Currently, the acp-utils and wisp crates contain an acp client that's used for the tui client.

But another use case is wanting to connect to an agent running aether server over a websocket, using a browser based acp client.

The latest version of the acp crate (2.2+) now supports a wasm compilation target

At a high level, I think we would want something like:

1.Bump the ACP crate to 2.2.0 or later.
2. Untangle acp-utils from tokio/non-compatible deps for wasm, or create new crate(sl
3. Add a spawner-generic connection layer without Send bounds and pure acp reducer.
4. Add a wasm-bindgen facade
5. Provide a nice high level API for a consumer to connect using aether acp client in a browser via wasm and websocket

Activity

  1. added
    size:LLarge change requiring an implementation plan
    assign-agentApply after an optional size:S/M/L label to assign the issue to Aether
    on Sep 26, 2026
  2. contextbridge-pr-automation commented on Sep 26, 2026

    @contextbridge-pr-automation
    Contributor

    Plan saved to docs/aether/plans/issue-527-plan.md (force-added since plans/ is gitignored) and committed as 81dc5bc3 on aether/issue-527.

    Summary of the plan:

    • Phase 0 — Bump ACP 2.1.0 → 2.2.0: verified via registry sources that 2.2.0's wasm delta is the opt-in wasm_js feature (Web Crypto UUID backend, PR fix(aether-lspd): Race condition with lsp events #308), unstable_tool_call_name is stabilized (must drop that feature flag), and the ConnectTo: Send + 'static bound is retained — so the plan works within it via executor choice rather than a trait fork.
    • Phase 1 — New aether-acp-core crate: moves serde-only wire types (meta, config_option_id, notifications split, AcpEvent, AcpClientError) out of tokio-coupled acp-utils, adds a Spawner trait (TokioSpawner / WasmSpawner) and a spawner-generic connect_acp_client ported onto futures::channel (same primitives ACP core uses internally).
    • Phase 2 — Pure reducer: extracts conversation folding from wisp's TUI-coupled acp_reducer.rs into reduce() → (snapshot, effects) over schema::v2 types.
    • Phase 3 — WebSysTransport: message-based web-sys::WebSocket → Lines adapter (no byte-stream shim possible in browsers), mirroring binary-reject/close/backpressure semantics of websocket.rs.
    • Phase 4 — aether-acp-wasm facade: thin wasm-bindgen WasmAcpClient (connect/session/prompt/cancel/event-subscribe) + packages/aether-acp-wasm TS wrapper reusing the AetherMessage shape; deliberately not extending the Node-only aether-sdk.
    • Phase 5 — Hardening/CI: wasm32-unknown-unknown + wasm-pack test jobs, 409/reconnect semantics, remote.mdx browser docs.

    Pushed to aether/issue-527. See the run.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    assign-agentApply after an optional size:S/M/L label to assign the issue to Aethersize:LLarge change requiring an implementation plan

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions