3M Docs
Streaming

Respostas de chat chegam em partes, por Server-Sent Events.

O erro mais comum é bufferizar a resposta inteira antes de repassar (por exemplo, num proxy que faz await response.text()). Isso anula o streaming e a UI trava até o fim gerar.

SSE[DONE]AbortController
Formato do frame

Cada evento é data: seguido do JSON, uma linha em branco separando frames.

Sentinela de fim

O último frame é sempre data: [DONE] — pare de ler ao vê-lo.

Cancelamento

Use AbortController para interromper a leitura a qualquer momento, sem esperar o servidor terminar.

Consumindo em JavaScript

response.body é um ReadableStream — leia direto, sem bibliotecas extras.

fetch + streaming
1const response = await fetch("https://api.3mm.com.br/v1/chat/completions", {2  method: "POST",3  headers: {4    Authorization: `Bearer ${process.env.THREEM_API_KEY}`,5    "Content-Type": "application/json",6  },7  body: JSON.stringify({8    model: "3m-chat-pro",9    stream: true,10    messages: [{ role: "user", content: "Conte até 5." }],11  }),12});13 14const reader = response.body.getReader();15const decoder = new TextDecoder();16 17for (;;) {18  const { done, value } = await reader.read();19  if (done) break;20  process.stdout.write(decoder.decode(value));21}

Consumindo em Python

httpx.stream lê linha por linha sem carregar a resposta inteira na memória.

httpx.stream
1import httpx, os2 3with httpx.stream(4    "POST",5    "https://api.3mm.com.br/v1/chat/completions",6    headers={"Authorization": f"Bearer {os.environ['THREEM_API_KEY']}"},7    json={"model": "3m-chat-pro", "stream": True,8          "messages": [{"role": "user", "content": "Conte até 5."}]},9) as response:10    for line in response.iter_lines():11        if line.startswith("data:"):12            print(line[5:].strip())
Tratar falhas

Streaming também pode falhar no meio — veja os status e formatos de erro na próxima página.

Ver erros