Serve over HTTP and stream
maiden serve exposes the agent over HTTP. Each request is a conversation turn
on a named thread; the thread is checkpointed after every turn, so restarts
resume cleanly (see Execution model).
maiden serve my-agent --port 8080Request
Section titled “Request”POST a JSON body:
{ "thread": "t1", "message": "echo hello", "stream": false}| Field | Type | Default | Description |
|---|---|---|---|
thread | string | — | The conversation to run on. Reusing it resumes history. |
message | string | — | The user message. |
stream | boolean | false | When true, respond with Server-Sent Events instead of one JSON body. |
JSON response
Section titled “JSON response”With stream off (or omitted), you get a single JSON object once the run
finishes:
curl -s localhost:8080 -d '{"thread":"t1","message":"echo hello"}'{ "answer": "Tool returned: {\"echoed\":\"from-mock\", ...}", "turns": 2, "resumed_from_checkpoint": false, "thread_messages": 4}| Field | Description |
|---|---|
answer | The final answer text. |
turns | Model turns taken this run. |
resumed_from_checkpoint | Whether the thread had prior history on disk. |
thread_messages | Total entries in the thread after this exchange. |
A malformed request returns { "error": "..." }.
Streaming response (SSE)
Section titled “Streaming response (SSE)”Set stream: true to receive events as the run progresses. Use curl -N to
disable buffering:
curl -sN localhost:8080 -d '{"thread":"t1","message":"echo hello","stream":true}'event: tooldata: {"tool":"structured-echo"}
event: tokendata: {"token":"The tool returned "}
event: donedata: {"answer":"The tool returned ...","turns":2,"resumed_from_checkpoint":false,"thread_messages":4}The event types are:
| Event | Data | When |
|---|---|---|
token | { "token": "..." } | A chunk of the answer text as the model produces it. |
tool | { "tool": "name" } | A tool is being invoked this round. |
done | the full JSON response (as above) | The run finished. |
error | { "error": "..." } | The run failed. |
Streaming works with every provider. A backend without native token streaming
still drives the same event path — it emits the final answer as a single token
event before done — so your client code is identical regardless of provider.
Concurrency note
Section titled “Concurrency note”The server, schedules, and channels share one runtime lock, so a streaming request holds the runtime for its duration. maiden is designed for durable, sequential agent work rather than many simultaneous requests — see Execution model.