# Conversation Memory

`boru/ai` now includes a first-class conversation-memory layer.

It is intended for durable conversation state that should survive across turns and be available to both application code and runtime-managed tool flows.

## What it stores

Conversation memory currently includes:

- title
- rolling summary
- structured notes

Structured notes support:

- `kind`
- `text`
- `confidence`
- `source_turn_number`
- `metadata`

## Core API

The `AI` facade now exposes simple helpers for reading and updating conversation memory:

```php
$memory = AI::provider('openai')
    ->reference('weekend_planning')
    ->conversationMemory();

AI::provider('openai')
    ->reference('weekend_planning')
    ->updateConversationTitle('Weekend Planning');

AI::provider('openai')
    ->reference('weekend_planning')
    ->updateConversationSummary('User is planning a relaxed weekend in Atlanta.');

AI::provider('openai')
    ->reference('weekend_planning')
    ->addConversationNote('Prefers independent bookstores.', 'preference');
```

These helpers rely on persistence if you want the values to survive beyond the current process.

## Built-in memory tools

The runtime also includes built-in conversation-memory tools:

- `update_conversation_title`
- `update_conversation_summary`
- `append_conversation_note`
- `replace_conversation_notes`

These tools are intended for model-managed memory updates and are auto-registered only when enabled through config.

## Configuring memory tools

Configure them under `runtime.conversation_memory.tools`:

```php
$config->runtime(array(
    'conversation_memory' => array(
        'tools' => array(
            'enabled' => true,
            'title' => true,
            'summary' => true,
            'append_note' => true,
            'replace_notes' => false,
            'require_persistence' => true,
            'only_after_turn' => 2,
        ),
    ),
));
```

Supported keys:

- `enabled`
- `title`
- `summary`
- `append_note`
- `replace_notes`
- `require_persistence`
- `only_after_turn`

Default behavior is intentionally conservative:

- memory tools are off by default
- they require persistence by default
- they are only auto-exposed starting on turn 2 by default

That avoids exposing memory tools for one-shot calls or transient non-persisted requests.

Provider-specific overrides are also supported:

```php
$config->provider('openai', array(
    'conversation_memory' => array(
        'tools' => array(
            'append_note' => false,
            'replace_notes' => true,
        ),
    ),
));
```

## Prompt guidance for active tools

If a tool should contribute prompt guidance only when it is active, implement `ToolPromptAdditionInterface`.

The built-in conversation-memory tools already do this, so when they are enabled the runtime automatically merges short memory guidance into the effective instructions for that request.

This keeps tool exposure and prompt guidance coupled in one place.

For the generic tool-level prompt-addition pattern, see `tools.md`.

## Persistence model

When DB persistence is enabled, conversation memory is stored in:

- `ai_conversations`
  - `title`
  - `summary`
  - `memory_metadata`
- `ai_conversation_notes`

If you are upgrading an existing install, make sure the persistence schema has been updated before using conversation memory:

```php
Bootstrap::ensurePersistenceSchema($config);
Bootstrap::registerDefaults($config);
```

`persistence.auto_schema = true` will also attempt to ensure the schema during bootstrap.

## Example

See:

- `examples/conversation_memory_tools.php`

That example enables the built-in memory tools through config, runs a real conversation, and then prints the persisted title, summary, and notes.

## See also

- `configuration.md`
- `tools.md`
- `persistence.md`
- `replay.md`
