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

# Conversation

> Stateful multi-turn chat helper that accumulates message history and sends it with every request automatically.

`Conversation` manages a running message history so you don't have to track prior turns yourself. Create one via `client.conversation()` and call `send()` or `stream()` for each user turn. Both methods append the user message and the assistant response to `messages` automatically.

```typescript theme={null}
const conv = client.conversation(options: ConversationOptions)
```

See [`GatelitClient.conversation()`](/sdk/gatelit-client#conversation-options) for the constructor details.

***

## Options

<ParamField body="model" type="string" required>
  Model in `"provider/model-name"` format. For example: `"openai/gpt-4o"`.
</ParamField>

<ParamField body="systemPrompt" type="string">
  Optional system prompt prepended to every request. Useful for setting a persona or task scope that persists across all turns.
</ParamField>

<ParamField body="maxTokens" type="number">
  Maximum output tokens per request.
</ParamField>

<ParamField body="temperature" type="number">
  Sampling temperature applied to every request in the conversation.
</ParamField>

***

## Properties

### `messages`

```typescript theme={null}
readonly messages: ChatMessage[]
```

The accumulated message history for this conversation. Each entry has a `role` (`"system"`, `"user"`, or `"assistant"`) and a `content` string. Read-only — do not mutate this array directly. Use [`reset()`](#reset) to clear it.

***

## Methods

### `send(content, signal?)`

Sends a user message and returns the assistant's full response. Appends both turns to `messages`.

```typescript theme={null}
async send(content: string, signal?: AbortSignal): Promise<ChatResponse>
```

<ParamField body="content" type="string" required>
  The user's message text.
</ParamField>

<ParamField body="signal" type="AbortSignal">
  An optional `AbortSignal` to cancel the in-flight request.
</ParamField>

Returns a [`ChatResponse`](/sdk/gatelit-client#returns-chatresponse) — the same type returned by `client.chat()`.

***

### `stream(content, signal?)`

Sends a user message and streams the response. Appends the user turn immediately; the completed assistant turn is appended once the stream finishes.

```typescript theme={null}
async *stream(content: string, signal?: AbortSignal): AsyncGenerator<StreamChunk>
```

<ParamField body="content" type="string" required>
  The user's message text.
</ParamField>

<ParamField body="signal" type="AbortSignal">
  An optional `AbortSignal` to cancel the stream.
</ParamField>

Yields [`StreamChunk`](/sdk/gatelit-client#returns-asyncgeneratorstreamchunk) values — the same type produced by `client.stream()`.

***

### `reset()`

Clears the conversation history. The next call to `send()` or `stream()` starts a fresh conversation.

```typescript theme={null}
reset(): void
```

***

## Examples

### Multi-turn conversation

```typescript theme={null}
import { GatelitClient } from "@gatelit/sdk"

const client = new GatelitClient({
  gatewayUrl: "https://gateway.yourapp.com",
  getToken: async () => {
    const { token } = await fetch("/api/ai-token").then(r => r.json())
    return { token, scheme: "GatelitSigned" }
  },
})

const conv = client.conversation({ model: "openai/gpt-4o" })

const r1 = await conv.send("What is the capital of France?")
console.log(r1.content) // "The capital of France is Paris."

const r2 = await conv.send("And what's the population?") // full history sent automatically
console.log(r2.content) // answer in context of the previous question

console.log(conv.messages) // all turns — user + assistant pairs
```

### Streaming conversation

```typescript theme={null}
const conv = client.conversation({
  model: "anthropic/claude-3-5-sonnet-20241022",
  systemPrompt: "You are a concise technical writing assistant.",
})

async function chat(userMessage: string) {
  process.stdout.write("Assistant: ")
  for await (const chunk of conv.stream(userMessage)) {
    process.stdout.write(chunk.delta)
    if (chunk.usage) {
      console.log(`\n[${chunk.usage.totalTokens} tokens]`)
    }
  }
}

await chat("Explain what an async generator is.")
await chat("Now give me a short code example.") // previous answer is in context
```

### Using a system prompt

```typescript theme={null}
const conv = client.conversation({
  model: "openai/gpt-4o",
  systemPrompt: "You are a helpful customer support agent for Acme Inc. Be concise and friendly.",
  maxTokens: 300,
})

const response = await conv.send("How do I reset my password?")
console.log(response.content)
```

### Resetting between sessions

```typescript theme={null}
const conv = client.conversation({ model: "openai/gpt-4o" })

// First session
await conv.send("My order number is 12345.")
await conv.send("When will it arrive?")

// Start a new session — clear prior context
conv.reset()

await conv.send("Hello, I have a question about returns.")
// No memory of the previous order conversation
```

<Note>
  `reset()` clears `messages` entirely. If you want to preserve context across resets, copy `conv.messages` before calling `reset()`.
</Note>
