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

# Feature Integration

> Customize and extend the chat experience

## Welcome Messages

Display an initial greeting:

```dart theme={null}
AgentChatView(
  welcomeMessage: 'Hello and welcome to Dartantic Chat!',
  provider: DartanticProvider(
    agent: Agent('gemini'),
  ),
)
```

## Suggested Prompts

Show predefined prompts (only when no history exists):

```dart theme={null}
AgentChatView(
  suggestions: [
    'I\'m a Star Wars fan. What should I wear for Halloween?',
    'I\'m allergic to peanuts. What candy should I avoid at Halloween?',
    'What\'s the difference between a pumpkin and a squash?',
  ],
  provider: DartanticProvider(
    agent: Agent('gemini'),
  ),
)
```

## Disable Attachments and Audio Input

```dart theme={null}
AgentChatView(
  provider: DartanticProvider(agent: Agent('gemini')),
  enableAttachments: false,
  enableVoiceNotes: false,
)
```

## Custom Speech-to-Text

Provide your own implementation:

```dart theme={null}
AgentChatView(
  provider: DartanticProvider(agent: Agent('gemini')),
  speechToText: MyCustomSpeechToText(),
)
```

## Cancel and Error Behavior

Override default cancel/error handling:

```dart theme={null}
AgentChatView(
  provider: DartanticProvider(agent: Agent('gemini')),
  onCancelCallback: (context) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('Chat cancelled')),
    );
  },
  cancelMessage: 'Request cancelled',
)
```

## Manage History

Access and modify history via the provider:

```dart theme={null}
void _clearHistory() => _provider.history = [];
```

## Chat Serialization/Deserialization

Save history:

```dart theme={null}
Future<void> _saveHistory() async {
  final history = _provider.history.toList();
  for (var i = 0; i != history.length; ++i) {
    final file = await _messageFile(i);
    if (file.existsSync()) continue;
    final map = history[i].toJson();
    final json = JsonEncoder.withIndent('  ').convert(map);
    await file.writeAsString(json);
  }
}
```

Restore history:

```dart theme={null}
Future<void> _loadHistory() async {
  final history = <ChatMessage>[];
  for (var i = 0;; ++i) {
    final file = await _messageFile(i);
    if (!file.existsSync()) break;
    final map = jsonDecode(await file.readAsString());
    history.add(ChatMessage.fromJson(map));
  }
  _provider.history = history;
}
```

## Custom Response Widgets

Replace default Markdown rendering:

```dart theme={null}
AgentChatView(
  provider: _provider,
  welcomeMessage: _welcomeMessage,
  responseBuilder: (context, response) => RecipeResponseView(response),
)
```

## Custom Styling

Fully customize the appearance:

```dart theme={null}
AgentChatView(
  provider: DartanticProvider(agent: Agent('gemini')),
  style: ChatViewStyle(...),
)
```

See the [styles
example](https://github.com/csells/dartantic/tree/main/packages/dartantic_chat/blob/main/example/lib/styles/styles.dart)
for complete options.

## Drag and Drop

On desktop and web platforms, users can drag and drop files directly into the
chat to attach them. The drop zone overlay can be customized:

```dart theme={null}
AgentChatView(
  provider: DartanticProvider(agent: Agent('gemini')),
  style: ChatViewStyle(
    fileDropOverlayStyle: FileDropOverlayStyle(
      iconSize: 64.0,
      iconColor: Colors.blue,
      backgroundColor: Colors.blue.withOpacity(0.1),
      text: 'Drop files here',
      textStyle: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500),
    ),
  ),
)
```

Drag and drop is automatically enabled when `enableAttachments` is true (the
default). It's not available on mobile platforms (Android/iOS) where users
should use the attachment buttons instead.

## Rerouting Prompts

Debug, log, or manipulate the connection:

```dart theme={null}
AgentChatView(
  provider: _provider,
  messageSender: _logMessage,
)

Stream<String> _logMessage(
  String prompt, {
  required Iterable<Part> attachments,
}) async* {
  debugPrint('# Sending Message');
  debugPrint('## Prompt\n$prompt');

  final response = _provider.sendMessageStream(prompt, attachments: attachments);
  final text = await response.join();
  debugPrint('## Response\n$text');

  yield text;
}
```
