Session Mode

Session Mode documentation has moved to the main page → #session. The same window updates in place across multiple agent turns via UUID-keyed IPC.

HTTP/SSE & WebSocket

Add --sse <PORT> or --ws <PORT> to a session daemon — any language (Python, Node, Go…) can drive a2native directly over HTTP or WebSocket without wrapping the CLI.

HTTP / SSE
POST http://127.0.0.1:PORT/form

Body: JSON form spec. Response: text/event-streamwaiting event when the form is displayed, then result event when the user submits.

Also: GET /health liveness probe.

WebSocket
ws://127.0.0.1:PORT

Send a form spec as a text frame. Receive {type:"waiting"} immediately, then {type:"result",data:{…}} on submit. One persistent connection handles multiple sequential forms.

Start a daemon with SSE or WebSocket

# Start daemon — SSE on port 8080, no initial form required
a2n --session my-session --sse 8080
# → a2n: SSE  http://127.0.0.1:8080/form  (session: my-session)

# Start daemon — WebSocket on port 8081
a2n --session my-session --ws 8081

# Both can run simultaneously on different ports
a2n --session my-session --sse 8080 --ws 8081

# Close when done
a2n --close my-session

Python — SSE

import requests, json

form_spec = {
    "title": "Choose environment",
    "components": [
        {"id": "env", "type": "radio-group", "label": "Target",
         "options": [{"value": "prod", "label": "Production"},
                    {"value": "stag", "label": "Staging"}]},
        {"id": "go",  "type": "button",     "label": "Deploy", "action": "submit"}
    ]
}

resp = requests.post("http://127.0.0.1:8080/form", json=form_spec, stream=True)
for line in resp.iter_lines():
    if line.startswith(b"data:"):
        result = json.loads(line[5:])
        if result.get("event") == "result":
            break

# result["data"]["values"]  →  {"env": "prod"}

Python — WebSocket

import websocket, json

form_spec = { /* same as above */ }

ws = websocket.create_connection("ws://127.0.0.1:8081")
ws.send(json.dumps(form_spec))

# First message: {"type":"waiting"} — form is now showing
msg = json.loads(ws.recv())
assert msg["type"] == "waiting"

# Second message: {"type":"result","data":{"status":"submitted","values":{...}}}
msg = json.loads(ws.recv())
result = msg["data"]   # → {"status":"submitted","values":{"env":"prod"}}

# Send next form on the same connection — no need to reconnect
ws.send(json.dumps(next_form_spec))

Both endpoints share the same serialised command queue as the CLI session IPC channel — all three (CLI --session, --sse, --ws) can be active simultaneously. Input format auto-detection applies to all three: a2native → A2UI → AG-UI.