Durable streaming.
Resume an interrupted stream from the last received event.
Durable streaming lets a client disconnect mid-stream and resume from where it left off. The server buffers events in a Redis stream, keyed by a stream_id advertised at stream start.
Durable streaming lifecycle
- Start a stream —
chat.stream()emits aResponseCreatedevent with astream_id. - Persist the
stream_idandconversation_idimmediately. - If disconnected, call
chat.active_stream(conversation_id)to check if the stream is still live. - Call
chat.resume(stream_id, last_event_id=...)to replay buffered events fromlast_event_idonwards.
chat.resume(stream_id, *, last_event_id=None, ...)
Resumes a previously detached stream by replaying buffered events from last_event_id. Returns an async generator of ChatEvent. Raises MatildaAPIError (404) when the stream buffer has expired.
async for event in client.chat.resume(saved_stream_id, last_event_id=saved_last_event_id):
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)| Field | type | description |
|---|---|---|
| stream_id | str | The stream ID from response.created. |
| last_event_id | str | None | The last Redis stream entry ID received. Omit to replay from the start. |
| access_token | str | None | Override access token. |
| fingerprint | str | None | Device fingerprint. |
| stall_timeout_ms | int | None | SSE stall watchdog timeout. Defaults to 45_000. |
chat.active_stream(conversation_id)
Checks whether a conversation has an active stream.
result = await client.chat.active_stream("conv-123")
# {"stream_id": "abc-123" | None, "status": "active" | "done" | "error" | None}Returns a dict:
# ActiveStreamLookup:
{"stream_id": "abc-123" or None, "status": "active" | "done" | "error" | None}chat.notify_on_completion(stream_id, enabled=True)
Request a push notification when a backgrounded stream completes.
await client.chat.notify_on_completion(stream_id, enabled=True)| Field | type | description |
|---|---|---|
| stream_id | str | The stream to watch. |
| enabled | bool | Enable or disable the notification. Defaults to True. |
Returns a dict (e.g. {"status": ...}).
Full resume example
import asyncio
import os
from matilda_client import MatildaClient
async def main():
async with MatildaClient(token=os.environ["MATILDA_ACCESS_TOKEN"]) as client:
stream_id = None
last_event_id = None
# Start streaming
async for event in client.chat.stream(
input="Write a long essay about Australia.",
conversation_id="conv-123",
):
if event.type == "response.created":
stream_id = event.stream_id
if event.type == "response.cursor":
last_event_id = event.last_event_id
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
# Later — check if the stream is still active, then resume
active = await client.chat.active_stream("conv-123")
if active["status"] == "active" and stream_id:
print("\n--- Resuming ---")
async for event in client.chat.resume(stream_id, last_event_id=last_event_id):
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
asyncio.run(main())