> ## 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.

# Messages

> Understanding message types, content parts, and multi-modal inputs in core-ai

## Overview

Messages are the fundamental building blocks of conversations in core-ai. They represent the dialogue between users, the assistant, and tools.

## Message Types

core-ai supports four message types:

```typescript theme={null}
type Message =
  | SystemMessage
  | UserMessage
  | AssistantMessage
  | ToolResultMessage;
```

### System Message

System messages set the context and behavior for the assistant.

```typescript theme={null}
type SystemMessage = {
  role: 'system';
  content: string;
};
```

**Example:**

```typescript theme={null}
const systemMessage: SystemMessage = {
  role: 'system',
  content: 'You are a helpful assistant that always responds in haiku format.',
};
```

### User Message

User messages represent input from the user. They can be simple text or multi-modal content with images and files.

```typescript theme={null}
type UserMessage = {
  role: 'user';
  content: string | UserContentPart[];
};
```

**Simple Text:**

```typescript theme={null}
const userMessage: UserMessage = {
  role: 'user',
  content: 'What is the capital of France?',
};
```

**Multi-Modal Content:**

```typescript theme={null}
const userMessage: UserMessage = {
  role: 'user',
  content: [
    { type: 'text', text: 'What is in this image?' },
    {
      type: 'image',
      source: {
        type: 'url',
        url: 'https://example.com/photo.jpg',
      },
    },
  ],
};
```

### Assistant Message

Assistant messages contain the model's responses, including text, reasoning, and tool calls.

```typescript theme={null}
type AssistantMessage = {
  role: 'assistant';
  parts: AssistantContentPart[];
};

type AssistantContentPart =
  | AssistantTextPart
  | ReasoningPart
  | ToolCallPart;
```

**Example:**

```typescript theme={null}
const assistantMessage: AssistantMessage = {
  role: 'assistant',
  parts: [
    { type: 'text', text: 'The capital of France is Paris.' },
  ],
};
```

<Note>
  Assistant messages use a `parts` array to support multiple content types (text, reasoning, tool calls) in a single message.
</Note>

### Tool Result Message

Tool result messages provide the results of tool calls back to the model.

```typescript theme={null}
type ToolResultMessage = {
  role: 'tool';
  toolCallId: string;
  content: string;
  isError?: boolean;
};
```

**Example:**

```typescript theme={null}
const toolResult: ToolResultMessage = {
  role: 'tool',
  toolCallId: 'call_123',
  content: JSON.stringify({ temperature: 72, condition: 'sunny' }),
};
```

## User Content Parts

User messages can include multiple types of content:

```typescript theme={null}
type UserContentPart = TextPart | ImagePart | FilePart;
```

### Text Part

Simple text content:

```typescript theme={null}
type TextPart = {
  type: 'text';
  text: string;
};
```

**Example:**

```typescript theme={null}
const textPart: TextPart = {
  type: 'text',
  text: 'Explain this concept in detail.',
};
```

### Image Part

Images can be provided as URLs or base64-encoded data:

```typescript theme={null}
type ImagePart = {
  type: 'image';
  source:
    | { type: 'base64'; mediaType: string; data: string }
    | { type: 'url'; url: string };
};
```

**URL Image:**

```typescript theme={null}
const urlImage: ImagePart = {
  type: 'image',
  source: {
    type: 'url',
    url: 'https://example.com/diagram.png',
  },
};
```

**Base64 Image:**

```typescript theme={null}
import { readFileSync } from 'fs';

const imageBuffer = readFileSync('./photo.jpg');
const base64Data = imageBuffer.toString('base64');

const base64Image: ImagePart = {
  type: 'image',
  source: {
    type: 'base64',
    mediaType: 'image/jpeg',
    data: base64Data,
  },
};
```

### File Part

Files can be attached with mime type information:

```typescript theme={null}
type FilePart = {
  type: 'file';
  data: string; // Base64-encoded file data
  mimeType: string;
  filename?: string;
};
```

**Example:**

```typescript theme={null}
import { readFileSync } from 'fs';

const pdfBuffer = readFileSync('./document.pdf');
const base64Data = pdfBuffer.toString('base64');

const filePart: FilePart = {
  type: 'file',
  data: base64Data,
  mimeType: 'application/pdf',
  filename: 'document.pdf',
};
```

<Warning>
  Not all providers support all content types. For example, Anthropic accepts PDF file parts only. Check the provider pages for model-specific input limits.
</Warning>

## Assistant Content Parts

Assistant messages can contain text, reasoning, and tool calls:

```typescript theme={null}
type AssistantContentPart =
  | AssistantTextPart
  | ReasoningPart
  | ToolCallPart;
```

### Text Part

Regular text responses:

```typescript theme={null}
type AssistantTextPart = {
  type: 'text';
  text: string;
};
```

### Reasoning Part

Extended thinking and reasoning content from the model:

```typescript theme={null}
type ReasoningPart = {
  type: 'reasoning';
  text: string;
  providerMetadata?: Record<string, Record<string, unknown>>;
};
```

The `providerMetadata` object is provider-namespaced. The top-level key is the provider identifier, such as `'anthropic'`, `'google'`, or `'openai'`.

<Note>
  Use [`getProviderMetadata()`](/api/core/utilities) when you want typed access to provider-specific metadata.
</Note>

**Accessing Reasoning:**

```typescript theme={null}
const result = await generate({
  model,
  messages: [{ role: 'user', content: 'Solve this complex problem...' }],
  reasoning: { effort: 'high' },
});

if (result.reasoning) {
  console.log('Internal reasoning:', result.reasoning);
}
```

### Tool Call Part

Requests to call external tools:

```typescript theme={null}
type ToolCallPart = {
  type: 'tool-call';
  toolCall: ToolCall;
};

type ToolCall = {
  id: string;
  name: string;
  arguments: Record<string, unknown>;
};
```

## Multi-Turn Conversations

Build conversations by passing message history:

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

const messages: Message[] = [
  { role: 'system', content: 'You are a helpful math tutor.' },
  { role: 'user', content: 'What is 15 + 27?' },
];

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

// Add assistant response to history
messages.push({
  role: 'assistant',
  parts: result1.parts,
});

// Continue conversation
messages.push({
  role: 'user',
  content: 'Now multiply that by 2',
});

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

## Helper functions

For message helpers like `resultToMessage()` and `assistantMessage()`, see the [utilities reference](/api/core/utilities).

## Tool Call Flow

Here's a complete example of handling tool calls:

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

const tools = {
  getWeather: defineTool({
    name: 'getWeather',
    description: 'Get weather for a location',
    parameters: z.object({
      location: z.string(),
    }),
  }),
};

const messages: Message[] = [
  { role: 'user', content: 'What\'s the weather in Tokyo?' },
];

// Step 1: Model requests tool call
const result1 = await generate({ model, messages, tools });
messages.push(resultToMessage(result1));

if (result1.toolCalls.length > 0) {
  // Step 2: Execute tool and provide result
  const toolCall = result1.toolCalls[0];
  const weatherData = await getWeather(toolCall.arguments.location);
  
  messages.push({
    role: 'tool',
    toolCallId: toolCall.id,
    content: JSON.stringify(weatherData),
  });
  
  // Step 3: Model generates final response
  const result2 = await generate({ model, messages, tools });
  console.log(result2.content);
}
```

## Best Practices

<Tip>
  **Keep system messages concise:** System messages set the tone but shouldn't contain too much information. For large context, consider using user messages with retrieved content.
</Tip>

<Tip>
  **Use `resultToMessage` for history:** Always convert generation results to messages using `resultToMessage()` to maintain proper conversation history with all content parts.
</Tip>

<Tip>
  **Multi-modal order matters:** When combining text and images, place the text part first to provide context for what you're asking about the image.
</Tip>

## Next Steps

* Configure generation with [Configuration](/concepts/configuration) options
* Learn about [Error Handling](/concepts/error-handling)
* Explore [Providers](/concepts/providers) for provider-specific features
