# Streaming

URL: https://docs.boldvideo.com/sdk/streaming



AI methods return a stream of typed events: the SDK handles the SSE plumbing, you get an async iterator.

## The pattern

```typescript
const stream = await bold.ai.chat({ prompt: 'Explain the pricing framework' });

for await (const event of stream) {
  switch (event.type) {
    case 'message_start':
      // conversation is starting; store the ID for follow-ups
      saveConversationId(event.conversationId);
      break;

    case 'progress':
      // Bold is planning/retrieving: show a status line
      setStatus(event.message);        // e.g. "Working out the angle…"
      break;

    case 'text_delta':
      appendToAnswer(event.delta);     // concatenate deltas
      break;

    case 'sources':
      showCitations(event.sources);    // clips with video + timestamps
      break;

    case 'message_complete':
      finalize(event.content, event.citations, event.responseType);
      break;

    case 'error':
      if (event.retryable) retry();
      else showError(event.message);
      break;
  }
}
```

## Event reference

The `AIEvent` union, as shipped in the SDK:

| `type`             | Fields                                                                           | Notes                                                              |
| ------------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `message_start`    | `conversationId?`, `videoId?`                                                    | First event                                                        |
| `progress`         | `stage`, `message`                                                               | Planning/retrieval status, great for "thinking…" UI                |
| `text_delta`       | `delta`                                                                          | Incremental answer text                                            |
| `sources`          | `sources: Segment[]`                                                             | Clips found during retrieval                                       |
| `recommendations`  | `recommendations`                                                                | From `ai.recommendations`                                          |
| `message_complete` | `content`, `citations`, `responseType`, `conversationId?`, `usage?`, `guidance?` | The full answer; `responseType` is `'answer'` or `'clarification'` |
| `image_analysis`   | `status`, `description?`                                                         | When images are attached                                           |
| `error`            | `code`, `message`, `retryable`                                                   | Handle and decide whether to retry                                 |

Each `Segment` in `sources`/`citations` carries `videoId`, `videoTitle`, `start`, `end`, and the transcript `text`: everything you need to render a "jump to 12:34" citation link.

<Callout>
  New event types may be added over time. A `default:` branch that ignores unknown events keeps you forward-compatible.
</Callout>

## Non-streaming mode

Every AI method accepts `stream: false` and returns a single object instead:

```typescript
const response = await bold.ai.chat({ prompt: '…', stream: false });
console.log(response.content);   // the answer
console.log(response.sources);   // citations
console.log(response.usage);     // token usage
```

## A complete chat helper

```typescript
async function askBold(prompt: string, conversationId?: string) {
  const stream = await bold.ai.chat({ prompt, conversationId });

  let answer = '';
  let citations: Segment[] = [];
  let convId = conversationId;

  for await (const event of stream) {
    if (event.type === 'message_start') convId = event.conversationId ?? convId;
    if (event.type === 'text_delta') answer += event.delta;
    if (event.type === 'message_complete') citations = event.citations;
    if (event.type === 'error') throw new Error(event.message);
  }

  return { answer, citations, conversationId: convId };
}
```

For the raw SSE format (if you're not using the SDK), see [API Streaming](/api/streaming).
