Add project documentation and reference materials
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.
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# Session Management
|
||||
|
||||
OpenClaw employs a centralized, file-based session management system that handles persistence, lifecycle events, and automated store maintenance. Unlike simple memory-only stores, this system is designed for high-concurrency environments with atomic write guarantees and strict disk budget enforcement.
|
||||
|
||||
***
|
||||
|
||||
## SessionEntry type
|
||||
|
||||
The `SessionEntry` structure in `src/config/sessions/types.ts` is the core data model, containing nearly 80 fields that track everything from model overrides to granular token usage and skill snapshots.
|
||||
|
||||
```typescript
|
||||
export type SessionEntry = {
|
||||
sessionId: string;
|
||||
updatedAt: number;
|
||||
sessionFile?: string;
|
||||
|
||||
// Model and Provider Overrides
|
||||
modelProvider?: string;
|
||||
model?: string;
|
||||
providerOverride?: string;
|
||||
modelOverride?: string;
|
||||
thinkingLevel?: string;
|
||||
|
||||
// Token Tracking and Context
|
||||
inputTokens?: number;
|
||||
outputTokens?: number;
|
||||
totalTokens?: number;
|
||||
totalTokensFresh?: boolean;
|
||||
compactionCount?: number;
|
||||
|
||||
// Delivery and Origin
|
||||
deliveryContext?: DeliveryContext;
|
||||
lastChannel?: SessionChannelId;
|
||||
origin?: SessionOrigin;
|
||||
|
||||
// Meta and Snapshots
|
||||
skillsSnapshot?: SessionSkillSnapshot;
|
||||
systemPromptReport?: SessionSystemPromptReport;
|
||||
acp?: SessionAcpMeta; // Agent Control Plane metadata
|
||||
queueMode?: "steer" | "followup" | "collect" | "queue" | "interrupt";
|
||||
};
|
||||
```
|
||||
|
||||
Key features of the type system:
|
||||
* **Model Overrides**: Allows per-session binding to specific models or providers, bypassing global defaults.
|
||||
* **Token Intelligence**: Tracks `totalTokensFresh` to determine if usage displays need a refresh.
|
||||
* **ACP Meta**: Preserves state for the Agent Control Plane, ensuring persistent agent behaviors across turns.
|
||||
* **Skill Snapshots**: Captures the state of available [[Skills]] at the time of the session turn.
|
||||
|
||||
***
|
||||
|
||||
## Store Maintenance
|
||||
|
||||
Automated maintenance is handled in `src/config/sessions/store-maintenance.ts` to prevent unbounded growth of the session file and ensure performance.
|
||||
|
||||
### Pruning and Capping
|
||||
* **`pruneStaleEntries()`**: Removes sessions older than a configured threshold (default: 30 days). It iterates through the store and deletes entries where `updatedAt` is before the cutoff.
|
||||
* **`capEntryCount()`**: Enforces a maximum number of sessions (default: 500). It sorts sessions by `updatedAt` descending and keeps only the most recent $N$ entries.
|
||||
|
||||
### File Rotation
|
||||
The `rotateSessionFile()` function monitors the `sessions.json` file size. If it exceeds the limit (default: 10MB), the system:
|
||||
1. Renames the current file to `sessions.json.bak.{timestamp}`.
|
||||
2. Maintains a maximum of 3 rotation backups, unlinking older ones.
|
||||
|
||||
### Maintenance Configuration
|
||||
The `resolveMaintenanceConfig()` function aggregates parameters from [[Configuration]]:
|
||||
* `pruneAfterMs`: Max age before eviction.
|
||||
* `maxEntries`: Hard limit on session count.
|
||||
* `rotateBytes`: File size trigger for rotation.
|
||||
* `maxDiskBytes`: Total disk budget for session transcripts.
|
||||
|
||||
***
|
||||
|
||||
## Session Store
|
||||
|
||||
The `SessionStore` in `src/config/sessions/store.ts` manages the I/O layer with a focus on reliability and cross-platform compatibility.
|
||||
|
||||
### Key Features
|
||||
* **Atomic Writes**: Uses `writeTextAtomic` to prevent file corruption during crashes.
|
||||
* **Write Locks**: Implements a `withSessionStoreLock` mechanism using a file-based lock to prevent race conditions between concurrent agent turns.
|
||||
* **Normalization**: Session keys are case-insensitive and trimmed via `normalizeStoreSessionKey()`. Legacy keys are automatically migrated to the normalized format on load.
|
||||
* **Windows Retry Semantics**: Includes specialized retry logic for Windows to handle transient file locks during the "truncate and write" phase.
|
||||
* **ACP Metadata Preservation**: Specifically protects `acp` metadata during updates, ensuring agent state isn't lost if a partial patch is applied.
|
||||
|
||||
```typescript
|
||||
export async function updateSessionStore<T>(
|
||||
storePath: string,
|
||||
mutator: (store: Record<string, SessionEntry>) => Promise<T> | T,
|
||||
opts?: SaveSessionStoreOptions,
|
||||
): Promise<T> {
|
||||
return await withSessionStoreLock(storePath, async () => {
|
||||
const store = loadSessionStore(storePath, { skipCache: true });
|
||||
const previousAcpByKey = collectAcpMetadataSnapshot(store);
|
||||
const result = await mutator(store);
|
||||
preserveExistingAcpMetadata({
|
||||
previousAcpByKey,
|
||||
nextStore: store,
|
||||
});
|
||||
await saveSessionStoreUnlocked(storePath, store, opts);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
## Session Lifecycle Events
|
||||
|
||||
A lightweight pub/sub system in `src/sessions/session-lifecycle-events.ts` allows other subsystems to react to session changes.
|
||||
|
||||
```typescript
|
||||
export type SessionLifecycleEvent = {
|
||||
sessionKey: string;
|
||||
reason: string;
|
||||
parentSessionKey?: string;
|
||||
label?: string;
|
||||
};
|
||||
|
||||
export function onSessionLifecycleEvent(listener: SessionLifecycleListener): () => void {
|
||||
SESSION_LIFECYCLE_LISTENERS.add(listener);
|
||||
return () => { SESSION_LIFECYCLE_LISTENERS.delete(listener); };
|
||||
}
|
||||
|
||||
export function emitSessionLifecycleEvent(event: SessionLifecycleEvent): void {
|
||||
for (const listener of SESSION_LIFECYCLE_LISTENERS) {
|
||||
listener(event);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This system is used to trigger [[Memory]] indexing, update [[Channels]] status, or log audit trails when sessions are created or deleted.
|
||||
|
||||
***
|
||||
|
||||
## Relevance to Luna
|
||||
|
||||
Luna's current `SessionManager` is a basic dictionary-backed store that lacks persistence and maintenance. To reach parity with OpenClaw, Luna should adopt several patterns:
|
||||
|
||||
1. **Atomic Persistence**: Implement a background saver for [[Core]] sessions that uses atomic file swaps to prevent data loss.
|
||||
2. **Maintenance Tasks**: Add a background service to prune old sessions and cap the total count to prevent memory leaks in the .NET runtime.
|
||||
3. **Locking**: Use a `SemaphoreSlim` or file-system lock for session updates to support concurrent requests from different [[Channels]].
|
||||
4. **Detailed Metadata**: Expand Luna's session objects to include token tracking and model overrides, allowing for better cost management and user customization.
|
||||
|
||||
Refer to [[Core]] for the current implementation status of Luna's session handling.
|
||||
Reference in New Issue
Block a user