App öffnen
Moonborn — Developers

Streaming-Patterns

Server-Sent Events von der Generation-Pipeline und vom Chat-Endpoint — Event-Formen, Reconnect, Abort.

Zwei Endpoints streamen:

  • POST /v1/personas?stream=true — die sechsstufige Generation- Pipeline.
  • POST /v1/chat/sessions/{id}/messages?stream=true — Chat- Antworten.

Beide sprechen Server-Sent Events. Selbes Envelope, andere Event-Typen.

Generation-Events

event: step.started      data: { step: "soul_draft" }
event: step.completed    data: { step: "soul_draft", durationMs, model }
event: pipeline.completed data: { personaId, durationMs }

Die sechs Steps emittieren step.started + step.completed in Reihenfolge; das terminale pipeline.completed trägt die finale Persona-ID.

Chat-Events

event: token       data: { delta: "Erzähl..." }
event: token       data: { delta: " mir mehr" }
event: completed   data: { messageId, driftScore, driftThreshold }

Tokens streamen in Reihenfolge; completed kommt einmal, mit dem Drift-Envelope.

Read-Loop (TypeScript)

const res = await fetch(url, { method: 'POST', headers, body });
const reader = res.body!.getReader();
const decoder = new TextDecoder();
let buf = '';
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buf += decoder.decode(value, { stream: true });
  let idx;
  while ((idx = buf.indexOf('\n\n')) !== -1) {
    const frame = buf.slice(0, idx);
    buf = buf.slice(idx + 2);
    const lines = frame.split('\n');
    const event = lines.find((l) => l.startsWith('event:'))?.slice(6).trim();
    const data = lines.find((l) => l.startsWith('data:'))?.slice(5).trim();
    if (event === 'token') process.stdout.write(JSON.parse(data!).delta);
  }
}

Das SDK macht das für dich — siehe client.chat.streamMessage() und client.personas.createStream().

Abort

Übergib einen AbortController.signal an fetch. Moonborn stoppt die Abrechnung, sobald der Client disconnected.

Reconnect

SSE hat kein eingebautes Resume. Wenn dein Client mid-stream abbricht, läuft die Generation/Antwort serverseitig schon — hole sie via GET /v1/personas/{id} (für Generation) oder GET /v1/chat/sessions/{id}/messages (für Chat) erneut. Retrye den Stream selbst nicht.

Tarif

Jeder Tier.