BBramaDocs
Browse documentation

Stream one completion

Goal: receive one generation as server-sent events, in whichever of the three chat formats the caller already speaks.

Status: written against the streaming contract in CORE.md; not re-verified against the newest published release.

Risk: credentialed, provider-facing, and potentially billable. A stream that has committed cannot be cancelled without cost: quota already spent stays spent.

Environment: running Brama over approved HTTPS or authenticated loopback.

Preconditions: BRAMA_URL; dedicated bearer in BRAMA_BEARER; an allowed alias, canonical provider/model route, or selector. Subscription routes additionally need the three agent HMAC headers over the exact raw body, exactly as the buffered path does.

Inputs: synthetic non-sensitive text only.

Artifacts and side effects: one provider generation, ledger counters for the subscription that paid, and process telemetry. No file is written by the gateway.

OpenAI chat completions

umask 077
cat >stream.json <<'JSON'
{"model":"wisent-backend","messages":[{"role":"user","content":"Count from one to five."}],"max_tokens":64,"temperature":0,"stream":true}
JSON

After explicit provider-cost approval:

curl --fail --silent --show-error --no-buffer \
  -H "Authorization: Bearer $BRAMA_BEARER" \
  -H 'Content-Type: application/json' \
  --data-binary @stream.json \
  "$BRAMA_URL/v1/chat/completions"

Expected: Content-Type: text/event-stream, then data: frames whose object is chat.completion.chunk — one carrying delta.role, then delta.content fragments, then a frame with finish_reason, then a frame carrying usage when the provider published a token meter, and finally data: [DONE]. Provider text is intentionally not predicted here.

Anthropic Messages

cat >stream-anthropic.json <<'JSON'
{"model":"claude-code/claude-sonnet-4-6","messages":[{"role":"user","content":"Count from one to five."}],"max_tokens":64,"stream":true}
JSON
curl --fail --silent --show-error --no-buffer \
  -H "Authorization: Bearer $BRAMA_BEARER" \
  -H "x-agent-id: $BRAMA_AGENT_ID" \
  -H "x-agent-timestamp: $BRAMA_AGENT_TIMESTAMP" \
  -H "x-agent-signature: $BRAMA_AGENT_SIGNATURE" \
  -H 'Content-Type: application/json' \
  --data-binary @stream-anthropic.json \
  "$BRAMA_URL/v1/messages"

Expected event order: message_start, content_block_start, one or more content_block_delta, content_block_stop, message_delta carrying stop_reason and output tokens, message_stop. A tool call appears as its own tool_use content block whose arguments arrive as input_json_delta fragments.

The signature covers the exact bytes of stream-anthropic.json; sign the file, do not re-serialize it.

OpenAI Responses

cat >stream-responses.json <<'JSON'
{"model":"codex/gpt-5.3-codex-spark","input":"Count from one to five.","max_output_tokens":64,"stream":true}
JSON
curl --fail --silent --show-error --no-buffer \
  -H "Authorization: Bearer $BRAMA_BEARER" \
  -H "x-agent-id: $BRAMA_AGENT_ID" \
  -H "x-agent-timestamp: $BRAMA_AGENT_TIMESTAMP" \
  -H "x-agent-signature: $BRAMA_AGENT_SIGNATURE" \
  -H 'Content-Type: application/json' \
  --data-binary @stream-responses.json \
  "$BRAMA_URL/v1/responses"

Expected event order: response.created, response.output_item.added, response.content_part.added, response.output_text.delta fragments, response.output_text.done, response.content_part.done, response.output_item.done, response.completed carrying the whole output again with usage.

Failure path

A refusal that happens before the first byte is an ordinary error document with Brama's own contract code and HTTP status: 403 forbidden for an allowlist miss, 429 subscription_unavailable when every bounded credential is spent, 503 credential_unauthorized when the provider refused the grant. Every retry Brama is allowed to make has already happened by then.

A failure after commit ends the stream without its terminal event: no data: [DONE], no message_stop, and response.failed instead of response.completed. That is the signal that the generation is incomplete. Brama does not continue it on another credential, because a second attempt would duplicate both cost and emitted text; starting a new request is the caller's decision.

Kimi streams carry no usage numbers. The provider's coding endpoint publishes no token meter on its event stream, so none is invented: the frames simply have no usage.

Cleanup

rm -f stream.json stream-anthropic.json stream-responses.json
unset BRAMA_BEARER BRAMA_AGENT_ID BRAMA_AGENT_TIMESTAMP BRAMA_AGENT_SIGNATURE

Quota consumed by an approved stream cannot be undone, including for a stream the caller abandoned.

Next

Buffered equivalents are in Use the bearer-scoped HTTP API; choosing from the shared subscription pool as a signed agent is in Use a subscription selector as a signed agent.