Include Luna AI Assistant design docs covering channels, configuration, core architecture, memory, scheduler, and skills. Add reference docs from OpenClaw and ZeroClaw projects, plus Mistral and OpenAI API specs.
85 lines
3.0 KiB
Markdown
85 lines
3.0 KiB
Markdown
# Memory Module
|
|
|
|
## Overview
|
|
|
|
The Memory module provides persistent conversation storage for the Luna AI Assistant. It uses a simple **filesystem-based** approach — conversation logs are written as plain text files and read back to seed new sessions with prior context.
|
|
|
|
The module consists of a single project: `Luna.Memory`.
|
|
|
|
---
|
|
|
|
## Interface
|
|
|
|
```csharp
|
|
public interface IMemoryStore
|
|
{
|
|
Task AddMemoryAsync(string memory);
|
|
Task<string> GetMemoriesAsync();
|
|
}
|
|
```
|
|
|
|
- `AddMemoryAsync` — persists a conversation log or compaction summary to storage.
|
|
- `GetMemoriesAsync` — retrieves recent memories as a single concatenated string, used to seed new conversations.
|
|
|
|
---
|
|
|
|
## Implementation
|
|
|
|
### MemoryStore
|
|
|
|
`MemoryStore` is the concrete `IMemoryStore` implementation. It stores conversation logs as individual files on disk.
|
|
|
|
**Storage path**: `~/.luna/memory/conversations/`
|
|
|
|
**File naming**: `Luna_Conversation_Log_{yyyyMMddHHmmss}`
|
|
|
|
```csharp
|
|
public class MemoryStore : IMemoryStore
|
|
```
|
|
|
|
| Method | Behavior |
|
|
|--------|----------|
|
|
| `AddMemoryAsync` | Creates the storage directory if it does not exist, then writes the memory string to a new timestamped file. |
|
|
| `GetMemoriesAsync` | Reads the **last 10 files** (ordered by timestamp descending, parsed from the filename), concatenates their contents, and returns the result. Returns an empty string if no files exist. |
|
|
|
|
There is no database, no Redis, and no SQLite involved — persistence is purely filesystem-based.
|
|
|
|
---
|
|
|
|
## Integration with the System
|
|
|
|
The `SessionManager` in [[Core]] injects `IMemoryStore` and uses it at three points:
|
|
|
|
1. **Session creation** — On the first message in a new conversation, `SessionManager` calls `GetMemoriesAsync()` and, if non-empty, prepends the result as a `ChatMessage` with `ChatRole.System`. This gives the agent prior conversational context.
|
|
|
|
2. **Client disconnect** — When a client disconnects, `SessionManager.ClientDisconnectedAsync` triggers `SaveSessionLogAsync`, which formats all user and assistant messages from the session and calls `AddMemoryAsync` to persist the log.
|
|
|
|
3. **Compaction** — When the session's token count exceeds the configured threshold (see [[Configuration]] `SessionOptions`), `SessionManager` uses the Librarian agent to summarize older messages. The summary is retained in-session as an assistant message wrapped in:
|
|
```
|
|
<---- MEMORY BEGIN ---->
|
|
[Meta] Conversation Recorded at: {timestamp}
|
|
{summary}
|
|
<---- MEMORY END ---->
|
|
```
|
|
|
|
---
|
|
|
|
## DI Registration
|
|
|
|
Memory services are registered via the `AddMemory()` extension method on `IServiceCollection`.
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
**Project references**: None (standalone module).
|
|
|
|
**NuGet packages**:
|
|
- `Microsoft.Extensions.Caching.Memory`
|
|
- `Microsoft.Extensions.DependencyInjection.Abstractions`
|
|
- `Microsoft.Extensions.Logging.Abstractions`
|
|
- `Microsoft.Extensions.Options`
|
|
- `StackExchange.Redis` (present in csproj, currently unused)
|
|
- `Microsoft.Data.Sqlite` (present in csproj, currently unused)
|
|
- `Microsoft.EntityFrameworkCore.Sqlite` (present in csproj, currently unused)
|