looprs_core/ports/session_store.rs
1//! SessionStore port — abstraction over session event persistence.
2
3use std::path::Path;
4
5use serde::Serialize;
6
7/// A discrete event that can be recorded in a session log.
8#[derive(Debug, Serialize)]
9#[serde(tag = "event", rename_all = "snake_case")]
10pub enum SessionEvent {
11 UserMessage {
12 content: String,
13 provider: String,
14 },
15 Inference {
16 content: String,
17 provider: String,
18 },
19 ToolUse {
20 tool_name: String,
21 input: serde_json::Value,
22 tool_use_id: String,
23 provider: String,
24 },
25 ToolResult {
26 tool_use_id: String,
27 output: String,
28 is_error: bool,
29 provider: String,
30 },
31 SessionEnd,
32}
33
34// TODO: hex refactor Phase 3 + persistent observation layer (ideas #8, #9) —
35// Agent constructs SessionLogger internally; ObservationManager is in-memory only.
36// Add a SQLite adapter (rusqlite already a dep) that implements this trait and
37// persists events + observations across sessions. Enables cost tracking and replay.
38/// Port: append session events to a durable store.
39///
40/// Implementations decide the storage backend (filesystem JSONL, SQLite, etc.).
41pub trait SessionStore: Send {
42 /// Record a session event.
43 fn log(&mut self, event: SessionEvent) -> Result<(), anyhow::Error>;
44
45 /// Return the canonical path associated with this session's log, if any.
46 fn path(&self) -> Option<&Path>;
47
48 /// Return the unique identifier for this session.
49 fn session_id(&self) -> &str;
50}