> ## Documentation Index
> Fetch the complete documentation index at: https://www.edgee.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK - Stream Method

> Complete guide to the stream() method in the TypeScript SDK.

The `stream()` method is used to make streaming chat completion requests to the Edgee AI Gateway. It returns an `AsyncGenerator<StreamChunk>` that yields response chunks as they arrive from the API.

## Arguments

The `stream()` method accepts two arguments:

| Parameter                                                                                                                      | Type                    | Description                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | ---------------------------------------------------------------------------------- |
| `model` <Tooltip headline="Required" tip="The field is required."><Icon icon="asterisk" size={15} color="#8924A6" /></Tooltip> | `string`                | The model identifier to use (e.g., `"openai/gpt-5.2"`)                             |
| `input` <Tooltip headline="Required" tip="The field is required."><Icon icon="asterisk" size={15} color="#8924A6" /></Tooltip> | `string \| InputObject` | The input for the completion. Can be a simple string or a structured `InputObject` |

### Input Types

#### String Input

When `input` is a string, it's automatically converted to a user message:

```typescript theme={"dark"}
for await (const chunk of edgee.stream('gpt-5.2', 'Tell me a story')) {
  if (chunk.text) {
    process.stdout.write(chunk.text);
  }
  
  if (chunk.finishReason) {
    console.log(`\nFinished: ${chunk.finishReason}`);
  }
}
// Equivalent to: input: { messages: [{ role: 'user', content: 'Tell me a story' }] }
```

#### InputObject

When `input` is an `InputObject`, you have full control over the conversation:

| Property                                                                                                                          | Type         | Description                                                                                                                                                                     |
| --------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `messages` <Tooltip headline="Required" tip="The field is required."><Icon icon="asterisk" size={15} color="#8924A6" /></Tooltip> | `Message[]`  | Array of conversation messages                                                                                                                                                  |
| `tools`                                                                                                                           | `Tool[]`     | Array of function tools available to the model                                                                                                                                  |
| `tool_choice`                                                                                                                     | `ToolChoice` | Controls which tool (if any) the model should call. See [Tools documentation](/sdk/typescript/tools) for details                                                                |
| `tags`                                                                                                                            | `string[]`   | Optional tags to categorize and label the request for analytics and filtering. Can also be sent via the `x-edgee-tags` header (comma-separated)                                 |
| `compression_model`                                                                                                               | `string`     | Compression model for this request: `"claude"`, `"codex"`, `"opencode"`, `"cursor"`. Each model is a bundle of compression strategies. Overrides API key settings when present. |

For details about `Message` type, see the [Send Method documentation](/sdk/typescript/send#message-object).
For details about `Tool` and `ToolChoice` types, see the [Tools documentation](/sdk/typescript/tools).

**Example - Streaming with Messages:**

```typescript theme={"dark"}
for await (const chunk of edgee.stream('gpt-5.2', {
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Write a poem about coding' }
  ]
})) {
  if (chunk.text) {
    process.stdout.write(chunk.text);
  }
}
```

## Return Value

The `stream()` method returns an `AsyncGenerator<StreamChunk>`. Each chunk contains incremental updates to the response.

### StreamChunk Object

Each chunk yielded by the generator has the following structure:

| Property      | Type                  | Description                                            |
| ------------- | --------------------- | ------------------------------------------------------ |
| `choices`     | `StreamChoice[]`      | Array of streaming choices (typically one)             |
| `compression` | `Compression \| null` | Token compression metrics (if compression was applied) |

### StreamChoice Object

Each choice in the `choices` array contains:

| Property        | Type                          | Description                                                                                                                                              |
| --------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `index`         | `number`                      | The index of this choice in the array                                                                                                                    |
| `delta`         | `StreamDelta`                 | The incremental update to the message                                                                                                                    |
| `finish_reason` | `string \| null \| undefined` | Reason why the generation stopped. Only present in the final chunk. Possible values: `"stop"`, `"length"`, `"tool_calls"`, `"content_filter"`, or `null` |

**Example - Handling Multiple Choices:**

```typescript theme={"dark"}
for await (const chunk of edgee.stream('gpt-5.2', 'Give me creative ideas')) {
  chunk.choices.forEach((choice, index) => {
    if (choice.delta.content) {
      console.log(`Choice ${index}: ${choice.delta.content}`);
    }
  });
}
```

### StreamDelta Object

The `delta` object contains incremental updates:

| Property     | Type                      | Description                                                                                |
| ------------ | ------------------------- | ------------------------------------------------------------------------------------------ |
| `role`       | `string \| undefined`     | The role of the message (typically `"assistant"`). Only present in the **first chunk**     |
| `content`    | `string \| undefined`     | Incremental text content. Each chunk contains a portion of the full response               |
| `tool_calls` | `ToolCall[] \| undefined` | Array of tool calls (if any). See [Tools documentation](/sdk/typescript/tools) for details |

## Convenience Properties

The `StreamChunk` class provides convenience getters for easier access:

| Property       | Type             | Description                                                                   |
| -------------- | ---------------- | ----------------------------------------------------------------------------- |
| `text`         | `string \| null` | Shortcut to `choices[0].delta.content` - the incremental text content         |
| `role`         | `string \| null` | Shortcut to `choices[0].delta.role` - the message role (first chunk only)     |
| `finishReason` | `string \| null` | Shortcut to `choices[0].finish_reason` - the finish reason (final chunk only) |

**Example - Using Convenience Properties:**

```typescript theme={"dark"}
for await (const chunk of edgee.stream('gpt-5.2', 'Explain quantum computing')) {
  // Content chunks
  if (chunk.text) {
    process.stdout.write(chunk.text);
  }

  // First chunk contains the role
  if (chunk.role) {
    console.log(`Role: ${chunk.role}`);
  }

  // Last chunk contains finish reason
  if (chunk.finishReason) {
    console.log(`\nFinish reason: ${chunk.finishReason}`);
  }
}
```

## Understanding Streaming Behavior

### Chunk Structure

1. **First chunk**: Contains `role` (typically `"assistant"`) and may contain initial `content`
2. **Content chunks**: Contain incremental `content` updates
3. **Final chunk**: Contains `finish_reason` indicating why generation stopped

**Example - Collecting Full Response:**

```typescript theme={"dark"}
let fullText = '';

for await (const chunk of edgee.stream('gpt-5.2', 'Tell me a story')) {
  if (chunk.text) {
    fullText += chunk.text;
    process.stdout.write(chunk.text); // Also display as it streams
  }
}

console.log(`\n\nFull response (${fullText.length} characters):`);
console.log(fullText);
```

### Finish Reasons

| Value              | Description                                               |
| ------------------ | --------------------------------------------------------- |
| `"stop"`           | Model generated a complete response and stopped naturally |
| `"length"`         | Response was cut off due to token limit                   |
| `"tool_calls"`     | Model requested tool/function calls                       |
| `"content_filter"` | Content was filtered by safety systems                    |
| `null`             | Generation is still in progress (not the final chunk)     |

### Empty Chunks

Some chunks may not contain `content`. This is normal and can happen when:

* The chunk only contains metadata (role, finish\_reason)
* The chunk is part of tool call processing
* Network buffering creates empty chunks

Always check for `chunk.text` before using it:

```typescript theme={"dark"}
for await (const chunk of edgee.stream('gpt-5.2', 'Hello')) {
  if (chunk.text) {  // ✅ Good: Check before using
    console.log(chunk.text);
  }
  // ❌ Bad: console.log(chunk.text) - may log null
}
```

## Error Handling

The `stream()` method can throw errors:

```typescript theme={"dark"}
try {
  for await (const chunk of edgee.stream('gpt-5.2', 'Hello!')) {
    if (chunk.text) {
      process.stdout.write(chunk.text);
    }
  }
} catch (error) {
  if (error instanceof Error) {
    // API errors: "API error {status}: {message}"
    // Network errors: Standard fetch errors
    console.error('Stream failed:', error.message);
  }
}
```
