Skip to main content
The generate() function provides synchronous chat completion, returning a complete response from the language model.

Basic Usage

Generate a simple chat completion:
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:
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!' }],
});

Configuration options

Customize model behavior with configuration parameters:
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,
    },
  },
});
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 for details.

Response Structure

The generate() function returns a GenerateResult object:
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

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:
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:
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

System messages set the assistant’s behavior and context:
const result = await generate({
  model,
  messages: [
    {
      role: 'system',
      content: 'You are a concise technical writer. Always use examples.',
    },
    { role: 'user', content: 'Explain async/await' },
  ],
});
Control costs and response length with maxTokens:
const result = await generate({
  model,
  messages,
  maxTokens: 200,
});

if (result.finishReason === 'length') {
  console.warn('Response was truncated');
}
Check why generation stopped:
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;
}

Next Steps

Streaming

Stream responses in real-time for better UX

Tool Calling

Let models use tools and functions

Multi-Modal

Work with images and files

Structured Outputs

Get type-safe JSON responses