AgentsOutput

Generation and streaming

Stream an agent's answer as a conversation with saved history, or as one-off text.

Get text from your agent as it is written. Use client.chat() for a conversation: Blazing Agents saves the history in a session, and each answer streams in the AI SDK UI message format your frontend can render directly. Use client.completion() for one-off text, such as a summary or a rewrite, where you want no history at all.

Stream one-off text

const result = await client.completion({
  agentId,
  prompt: "Write a two-sentence release note for passkey login.",
});

for await (const delta of result.textStream) {
  process.stdout.write(delta);
}
process.stdout.write("\n");

If you only need the finished text, skip the loop: await result.text in TypeScript, or client.completion(...) in Python, which returns a string.

Choose chat or completion

client.chat()client.completion()
InputOne user message in AI SDK UIMessage shape, or a saved promptPlain text, or a saved prompt
HistoryStarts a session, or continues one when you pass its IDNone
OutputAn AI SDK UI message stream, plus the session IDPlain text deltas
Good forChat interfaces and multi-step conversationsSummaries, rewrites, and other standalone text

Both run the same agent with the same tools, skills, MCP connections, memory, and workspace, and both record usage. To get JSON in a fixed shape instead of text, use structured output.

Relay chat to your frontend

Your backend holds the API key and passes the stream through unchanged:

export async function POST(request: Request) {
  const { message, sessionId } = await request.json();
  const result = await client.chat({
    agentId,
    message,
    ...(sessionId ? { sessionId } : {}),
  });
  return result.toResponse();
}

Without a sessionId, the call starts a new session and the response carries its ID in the location header. On the frontend, useChat with BlazingAgentsChatTransport renders the stream, reads that header, and sends the session ID back on the next message. Build a chatbot shows the full frontend.

What to add next

Before real users reach this endpoint, add the checks below. In TypeScript, createChatRelay does all of them for you; connect Blazing Agents to your app shows it, and the same steps by hand in Python.

  • Sign-in. Find out who the user is before you call Blazing Agents, and reject the request if you cannot.
  • Session ownership. Before you continue a session, check that it belongs to the signed-in user. The session ID is ready before the answer finishes (await result.sessionId in TypeScript, stream.session_id in Python), so save its owner right away.
  • Usage labels. Pass the user's ID as userId (user_id in Python) to label usage per end user. It does not grant access; your ownership check does.
  • Stopping. In TypeScript, pass abortSignal: request.signal so a user who closes the tab stops the turn.

A chat stream has one reader. In TypeScript, call either toResponse() or toStream() once; a second call throws stream_error. sessionId stays available either way.

Send an image

A user message can mix text parts with image file parts. Each image needs a URL and an image/* media type:

const result = await client.chat({
  agentId,
  message: {
    id: crypto.randomUUID(),
    role: "user",
    parts: [
      { type: "text", text: "Describe this diagram." },
      { type: "file", mediaType: "image/png", url: imageUrl },
    ],
  },
});

The image is part of the message only. It is not saved to the workspace or published as an artifact. Check the media type, source, and size in your backend before you send it.

Regenerate an answer

Pass trigger: "regenerate-message" on an existing session to replace an answer. Without messageId, the latest answer is replaced. With the ID of an earlier assistant message, that answer and everything after it is replaced. With the ID of a user message, that message is removed and the one you send takes its place.

const result = await client.chat({
  agentId,
  sessionId,
  message,
  trigger: "regenerate-message",
  messageId: assistantMessageId,
});

The old answer stays until the new one succeeds. If regeneration fails or you stop it, the session is unchanged.

Stops, errors, and what gets saved

  • Stopping. Pass an AbortSignal as abortSignal, or cancel the stream you are reading. The turn stops, and usage up to that point is recorded.
  • Errors before streaming. Problems such as an unknown agent, a bad request, or an exhausted quota reject the call with a typed error. Nothing is saved and nothing is charged.
  • Errors during streaming. A chat stream ends with an { type: "error", errorText } event, which AI SDK clients already understand. For completion, textStream throws, and await result.text rejects with a stream_error.
  • Saved history. A successful chat turn adds the exchange to the session. A failed or stopped turn leaves the history as it was. Completion never saves history.

Tools that need approval cannot wait for a person during client.completion(), because there is no session to resume. Those calls are blocked, and the agent carries on with the work it is allowed to do.

Next

On this page