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

# Chat Completion

> Generate text responses using the generate() function

The `generate()` function provides synchronous chat completion, returning a complete response from the language model.

## Basic Usage

Generate a simple chat completion:

```typescript theme={null}
import { generate } from '@core-ai/core-ai';
import { createOpenAI } from '@core-ai/openai';

const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
const model = openai.chatModel('gpt-5-mini');

const result = await generate({
  model,
  messages: [
    {
      role: 'system',
      content: 'You are a concise technical assistant.',
    },
    {
      role: 'user',
      content: 'Explain what an embedding vector is in one short paragraph.',
    },
  ],
});

console.log('Response:', result.content);
console.log('Usage:', result.usage);
```

## Using Different Providers

core-ai supports multiple providers with the same API:

<Tabs>
  <Tab title="OpenAI">
    ```typescript theme={null}
    import { generate } from '@core-ai/core-ai';
    import { createOpenAI } from '@core-ai/openai';

    const openai = createOpenAI({ 
      apiKey: process.env.OPENAI_API_KEY 
    });
    const model = openai.chatModel('gpt-5-mini');

    const result = await generate({
      model,
      messages: [{ role: 'user', content: 'Hello!' }],
    });
    ```
  </Tab>

  <Tab title="Anthropic">
    ```typescript theme={null}
    import { generate } from '@core-ai/core-ai';
    import { createAnthropic } from '@core-ai/anthropic';

    const anthropic = createAnthropic({ 
      apiKey: process.env.ANTHROPIC_API_KEY 
    });
    const model = anthropic.chatModel('claude-haiku-4-5');

    const result = await generate({
      model,
      messages: [{ role: 'user', content: 'Hello!' }],
      maxTokens: 256,
    });
    ```
  </Tab>

  <Tab title="Google">
    ```typescript theme={null}
    import { generate } from '@core-ai/core-ai';
    import { createGoogleGenAI } from '@core-ai/google-genai';

    const google = createGoogleGenAI({ 
      apiKey: process.env.GOOGLE_API_KEY 
    });
    const model = google.chatModel('gemini-3.1-pro');

    const result = await generate({
      model,
      messages: [{ role: 'user', content: 'Hello!' }],
      maxTokens: 256,
    });
    ```
  </Tab>

  <Tab title="Mistral">
    ```typescript theme={null}
    import { generate } from '@core-ai/core-ai';
    import { createMistral } from '@core-ai/mistral';

    const mistral = createMistral({ 
      apiKey: process.env.MISTRAL_API_KEY 
    });
    const model = mistral.chatModel('mistral-small-2506');

    const result = await generate({
      model,
      messages: [{ role: 'user', content: 'Hello!' }],
      maxTokens: 256,
    });
    ```
  </Tab>
</Tabs>

## Configuration options

Customize model behavior with configuration parameters:

```typescript theme={null}
import { generate } from '@core-ai/core-ai';
import { createOpenAICompat } from '@core-ai/openai/compat';

const openai = createOpenAICompat({ apiKey: process.env.OPENAI_API_KEY });
const model = openai.chatModel('gpt-5-mini');

const result = await generate({
  model,
  messages: [{ role: 'user', content: 'Tell me a story.' }],
  temperature: 0.7,
  maxTokens: 500,
  topP: 0.9,
  providerOptions: {
    openai: {
      stopSequences: ['\n\n'],
      frequencyPenalty: 0.5,
      presencePenalty: 0.3,
    },
  },
});
```

<Note>
  `temperature`, `maxTokens`, and `topP` are top-level options. `stopSequences`, `frequencyPenalty`, and `presencePenalty` are provider-specific and passed via `providerOptions`. Options like `stopSequences` and `frequencyPenalty` are available with `createOpenAICompat` (Chat Completions API). The default `createOpenAI` (Responses API) supports a different set of options — see [Configuration](/concepts/configuration) for details.
</Note>

## Response Structure

The `generate()` function returns a `GenerateResult` object:

```typescript theme={null}
type GenerateResult = {
  parts: AssistantContentPart[];  // Raw response parts
  content: string | null;          // Text content (null if only tool calls)
  reasoning: string | null;        // Reasoning content (if available)
  toolCalls: ToolCall[];          // Tool calls made by model
  finishReason: FinishReason;     // Why generation stopped
  usage: ChatUsage;               // Token usage information
};
```

### Understanding Token Usage

```typescript theme={null}
const result = await generate({ model, messages });

console.log('Input tokens:', result.usage.inputTokens);
console.log('Output tokens:', result.usage.outputTokens);

// Token details breakdown
console.log('Cache read:', result.usage.inputTokenDetails.cacheReadTokens);
console.log('Cache write:', result.usage.inputTokenDetails.cacheWriteTokens);

if (result.usage.outputTokenDetails.reasoningTokens) {
  console.log('Reasoning tokens:', result.usage.outputTokenDetails.reasoningTokens);
}
```

## Multi-turn conversations

Build conversations by including previous messages. Use `resultToMessage()` to convert a `GenerateResult` into an `AssistantMessage`:

```typescript theme={null}
import { generate, resultToMessage } from '@core-ai/core-ai';

const messages = [
  { role: 'system', content: 'You are a helpful assistant.' },
  { role: 'user', content: 'What is TypeScript?' },
];

const firstResponse = await generate({ model, messages });

messages.push(resultToMessage(firstResponse));
messages.push({
  role: 'user',
  content: 'How is it different from JavaScript?',
});

const secondResponse = await generate({ model, messages });
console.log(secondResponse.content);
```

## Error Handling

Handle errors gracefully:

```typescript theme={null}
import { CoreAIError, ProviderError } from '@core-ai/core-ai';

try {
  const result = await generate({ model, messages });
  console.log(result.content);
} catch (error) {
  if (error instanceof ProviderError) {
    console.error('Provider error:', error.message);
    console.error('Status code:', error.statusCode);
  } else if (error instanceof CoreAIError) {
    console.error('CoreAIError:', error.message);
  } else {
    console.error('Unknown error:', error);
  }
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use system messages for consistent behavior">
    System messages set the assistant's behavior and context:

    ```typescript theme={null}
    const result = await generate({
      model,
      messages: [
        {
          role: 'system',
          content: 'You are a concise technical writer. Always use examples.',
        },
        { role: 'user', content: 'Explain async/await' },
      ],
    });
    ```
  </Accordion>

  <Accordion title="Set appropriate token limits">
    Control costs and response length with `maxTokens`:

    ```typescript theme={null}
    const result = await generate({
      model,
      messages,
      maxTokens: 200,
    });

    if (result.finishReason === 'length') {
      console.warn('Response was truncated');
    }
    ```
  </Accordion>

  <Accordion title="Handle finish reasons appropriately">
    Check why generation stopped:

    ```typescript theme={null}
    const result = await generate({ model, messages });

    switch (result.finishReason) {
      case 'stop':
        // Normal completion
        break;
      case 'length':
        // Hit token limit
        console.warn('Response truncated');
        break;
      case 'tool-calls':
        // Model wants to use tools
        break;
      case 'content-filter':
        // Content filtered by provider
        console.warn('Content filtered');
        break;
    }
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Streaming" icon="water" href="/guides/streaming">
    Stream responses in real-time for better UX
  </Card>

  <Card title="Tool Calling" icon="wrench" href="/guides/tool-calling">
    Let models use tools and functions
  </Card>

  <Card title="Multi-Modal" icon="images" href="/guides/multi-modal">
    Work with images and files
  </Card>

  <Card title="Structured Outputs" icon="brackets-curly" href="/guides/structured-outputs">
    Get type-safe JSON responses
  </Card>
</CardGroup>
