How streaming works here
A handler returns a response whose body is aCallbackStream. The emitter calls that callback while it writes the body, so your generator runs after the headers are already on the wire.
src/RequestHandlers/Api/StreamSummaryRequestHandler.php
Presentation\EventStream\Streamer writes one event at a time and flushes:
Call
open() before your first event if you send events yourself rather than through stream().
The wire format
data payload to a single JSON object. Clients parse this with the browser’s EventSource, or with a streaming fetch and an SSE parser when they need to POST.
Handle the write side carefully
Persist before you stream
Persist before you stream
The entity manager is flushed after the response is emitted, which for a stream is after the last byte. If your generator creates records that the client will reference, inject
Doctrine\ORM\EntityManagerInterface and call flush() before or during the stream.Stop when the client leaves
Stop when the client leaves
A user who closes the tab shouldn’t keep a provider call running and a workspace paying for it.
Streamer::open() exits when connection_aborted() reports a dead connection; check it in long loops of your own too.Report errors as events
Report errors as events
Once the headers are sent you can’t change the status code. Catch exceptions inside the generator and emit an
error event with a message the client can show.Charge after the fact
Charge after the fact
Reserve credits before you start, then consume the real cost as usage arrives. See AI models and credits.
Forwarding AI output
When you stream a model’s answer, fold Aikeedo’s stream parts into your own events:JsonSerializable, so passing one straight to sendEvent() produces a payload shaped like {"type": "...", ...}.
Consume the stream in the browser
Deployment notes
X-Accel-Buffering: nodisables nginx buffering; other proxies and CDNs have their own switch.- Check
output_bufferingand any compression module, since gzip on a stream can delay flushes. - Keep
max_execution_timein mind for long generations.