cargo fmt
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
//! - Session log: `{root}/{session_id}.jsonl`
|
||||
//! - Event trace: `{root}/{session_id}.trace.jsonl`
|
||||
|
||||
use crate::SessionId;
|
||||
use crate::event_trace::TraceEntry;
|
||||
use crate::session_log::{EntryHash, HashedEntry};
|
||||
use crate::store::{Store, StoreError};
|
||||
use crate::SessionId;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::fs;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
@@ -50,19 +50,16 @@ impl FsStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_jsonl<T: serde::de::DeserializeOwned>(
|
||||
content: &str,
|
||||
) -> Result<Vec<T>, StoreError> {
|
||||
fn parse_jsonl<T: serde::de::DeserializeOwned>(content: &str) -> Result<Vec<T>, StoreError> {
|
||||
let mut entries = Vec::new();
|
||||
for (i, line) in content.lines().enumerate() {
|
||||
if line.trim().is_empty() {
|
||||
continue;
|
||||
}
|
||||
let entry: T =
|
||||
serde_json::from_str(line).map_err(|e| StoreError::Corrupt {
|
||||
line: i + 1,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
let entry: T = serde_json::from_str(line).map_err(|e| StoreError::Corrupt {
|
||||
line: i + 1,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
entries.push(entry);
|
||||
}
|
||||
Ok(entries)
|
||||
@@ -122,10 +119,7 @@ impl Store for FsStore {
|
||||
Ok(self.log_path(id).exists())
|
||||
}
|
||||
|
||||
async fn read_head_hash(
|
||||
&self,
|
||||
id: SessionId,
|
||||
) -> Result<Option<EntryHash>, StoreError> {
|
||||
async fn read_head_hash(&self, id: SessionId) -> Result<Option<EntryHash>, StoreError> {
|
||||
let path = self.log_path(id);
|
||||
if !path.exists() {
|
||||
return Err(StoreError::NotFound(id));
|
||||
@@ -134,23 +128,18 @@ impl Store for FsStore {
|
||||
let last_line = content.lines().rev().find(|l| !l.trim().is_empty());
|
||||
match last_line {
|
||||
Some(line) => {
|
||||
let entry: HashedEntry = serde_json::from_str(line).map_err(|e| {
|
||||
StoreError::Corrupt {
|
||||
let entry: HashedEntry =
|
||||
serde_json::from_str(line).map_err(|e| StoreError::Corrupt {
|
||||
line: content.lines().count(),
|
||||
message: e.to_string(),
|
||||
}
|
||||
})?;
|
||||
})?;
|
||||
Ok(Some(entry.hash))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
async fn append_trace(
|
||||
&self,
|
||||
id: SessionId,
|
||||
entry: &TraceEntry,
|
||||
) -> Result<(), StoreError> {
|
||||
async fn append_trace(&self, id: SessionId, entry: &TraceEntry) -> Result<(), StoreError> {
|
||||
let line = serde_json::to_string(entry)?;
|
||||
self.append_line(&self.trace_path(id), &line).await
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ pub mod store;
|
||||
pub use event_trace::TraceEntry;
|
||||
pub use fs_store::FsStore;
|
||||
pub use session::{
|
||||
SessionStartState, create_compacted_session, create_session, ensure_head_or_fork, fork, fork_at,
|
||||
restore, save_cache_locked, save_cache_unlocked, save_config_changed, save_delta, save_outcome,
|
||||
save_turn_end, save_usage,
|
||||
SessionStartState, create_compacted_session, create_session, ensure_head_or_fork, fork,
|
||||
fork_at, restore, save_cache_locked, save_cache_unlocked, save_config_changed, save_delta,
|
||||
save_outcome, save_turn_end, save_usage,
|
||||
};
|
||||
pub use session_log::{
|
||||
EntryHash, HashedEntry, LogEntry, Outcome, RestoredState, SessionOrigin, UsageRecord,
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
//! The caller (typically Pod) holds the Worker directly and calls these
|
||||
//! functions after state-mutating operations.
|
||||
|
||||
use crate::SessionId;
|
||||
use crate::session_log::{self, EntryHash, HashedEntry, LogEntry, Outcome, SessionOrigin};
|
||||
use crate::store::{Store, StoreError};
|
||||
use crate::SessionId;
|
||||
use llm_worker::llm_client::types::Item;
|
||||
use llm_worker::llm_client::RequestConfig;
|
||||
use llm_worker::llm_client::types::Item;
|
||||
|
||||
/// State snapshot for creating a SessionStart entry.
|
||||
pub struct SessionStartState<'a> {
|
||||
@@ -142,10 +142,15 @@ pub async fn save_delta(
|
||||
while i < new_items.len() {
|
||||
let item = &new_items[i];
|
||||
if item.is_user_message() {
|
||||
append_entry(store, session_id, head_hash, LogEntry::UserInput {
|
||||
ts,
|
||||
item: new_items[i].clone(),
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::UserInput {
|
||||
ts,
|
||||
item: new_items[i].clone(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
i += 1;
|
||||
} else if item.is_tool_result() {
|
||||
@@ -153,10 +158,15 @@ pub async fn save_delta(
|
||||
while i < new_items.len() && new_items[i].is_tool_result() {
|
||||
i += 1;
|
||||
}
|
||||
append_entry(store, session_id, head_hash, LogEntry::ToolResults {
|
||||
ts,
|
||||
items: new_items[start..i].to_vec(),
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::ToolResults {
|
||||
ts,
|
||||
items: new_items[start..i].to_vec(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
} else if item.is_assistant_message() || item.is_tool_call() || item.is_reasoning() {
|
||||
let start = i;
|
||||
@@ -167,16 +177,26 @@ pub async fn save_delta(
|
||||
{
|
||||
i += 1;
|
||||
}
|
||||
append_entry(store, session_id, head_hash, LogEntry::AssistantItems {
|
||||
ts,
|
||||
items: new_items[start..i].to_vec(),
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::AssistantItems {
|
||||
ts,
|
||||
items: new_items[start..i].to_vec(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
append_entry(store, session_id, head_hash, LogEntry::HookInjectedItems {
|
||||
ts,
|
||||
items: vec![new_items[i].clone()],
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::HookInjectedItems {
|
||||
ts,
|
||||
items: vec![new_items[i].clone()],
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
i += 1;
|
||||
}
|
||||
@@ -191,10 +211,15 @@ pub async fn save_turn_end(
|
||||
head_hash: &mut Option<EntryHash>,
|
||||
turn_count: usize,
|
||||
) -> Result<(), StoreError> {
|
||||
append_entry(store, session_id, head_hash, LogEntry::TurnEnd {
|
||||
ts: session_log::now_millis(),
|
||||
turn_count,
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::TurnEnd {
|
||||
ts: session_log::now_millis(),
|
||||
turn_count,
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -206,11 +231,16 @@ pub async fn save_outcome(
|
||||
outcome: Outcome,
|
||||
interrupted: bool,
|
||||
) -> Result<(), StoreError> {
|
||||
append_entry(store, session_id, head_hash, LogEntry::RunOutcome {
|
||||
ts: session_log::now_millis(),
|
||||
outcome,
|
||||
interrupted,
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::RunOutcome {
|
||||
ts: session_log::now_millis(),
|
||||
outcome,
|
||||
interrupted,
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -230,14 +260,19 @@ pub async fn save_usage(
|
||||
cache_write_tokens: u64,
|
||||
output_tokens: u64,
|
||||
) -> Result<(), StoreError> {
|
||||
append_entry(store, session_id, head_hash, LogEntry::LlmUsage {
|
||||
ts: session_log::now_millis(),
|
||||
history_len,
|
||||
input_total_tokens,
|
||||
cache_read_tokens,
|
||||
cache_write_tokens,
|
||||
output_tokens,
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::LlmUsage {
|
||||
ts: session_log::now_millis(),
|
||||
history_len,
|
||||
input_total_tokens,
|
||||
cache_read_tokens,
|
||||
cache_write_tokens,
|
||||
output_tokens,
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -248,10 +283,15 @@ pub async fn save_cache_locked(
|
||||
head_hash: &mut Option<EntryHash>,
|
||||
locked_prefix_len: usize,
|
||||
) -> Result<(), StoreError> {
|
||||
append_entry(store, session_id, head_hash, LogEntry::Locked {
|
||||
ts: session_log::now_millis(),
|
||||
locked_prefix_len,
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::Locked {
|
||||
ts: session_log::now_millis(),
|
||||
locked_prefix_len,
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -261,9 +301,14 @@ pub async fn save_cache_unlocked(
|
||||
session_id: SessionId,
|
||||
head_hash: &mut Option<EntryHash>,
|
||||
) -> Result<(), StoreError> {
|
||||
append_entry(store, session_id, head_hash, LogEntry::CacheUnlocked {
|
||||
ts: session_log::now_millis(),
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::CacheUnlocked {
|
||||
ts: session_log::now_millis(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -274,10 +319,15 @@ pub async fn save_config_changed(
|
||||
head_hash: &mut Option<EntryHash>,
|
||||
config: &RequestConfig,
|
||||
) -> Result<(), StoreError> {
|
||||
append_entry(store, session_id, head_hash, LogEntry::ConfigChanged {
|
||||
ts: session_log::now_millis(),
|
||||
config: config.clone(),
|
||||
})
|
||||
append_entry(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
LogEntry::ConfigChanged {
|
||||
ts: session_log::now_millis(),
|
||||
config: config.clone(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,9 @@ pub enum Outcome {
|
||||
/// Worker yielded control to the caller for external processing.
|
||||
/// Distinct from `Paused`: caller handles internally and resumes.
|
||||
Yielded,
|
||||
Error { message: String },
|
||||
Error {
|
||||
message: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// State collected from log entries.
|
||||
@@ -409,7 +411,11 @@ mod tests {
|
||||
},
|
||||
LogEntry::AssistantItems {
|
||||
ts: 3000,
|
||||
items: vec![Item::tool_call("call_1", "get_weather", r#"{"city":"Tokyo"}"#)],
|
||||
items: vec![Item::tool_call(
|
||||
"call_1",
|
||||
"get_weather",
|
||||
r#"{"city":"Tokyo"}"#,
|
||||
)],
|
||||
},
|
||||
LogEntry::ToolResults {
|
||||
ts: 3500,
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
//! [`Store`] defines the async interface for reading and writing session logs.
|
||||
//! Implementations handle the physical storage (filesystem, database, etc.).
|
||||
|
||||
use crate::SessionId;
|
||||
use crate::event_trace::TraceEntry;
|
||||
use crate::session_log::{EntryHash, HashedEntry};
|
||||
use crate::SessionId;
|
||||
use std::future::Future;
|
||||
|
||||
/// Errors from the persistence store.
|
||||
@@ -43,9 +43,7 @@ pub trait Store: Send + Sync {
|
||||
) -> impl Future<Output = Result<Vec<HashedEntry>, StoreError>> + Send;
|
||||
|
||||
/// List all session IDs, most recent first.
|
||||
fn list_sessions(
|
||||
&self,
|
||||
) -> impl Future<Output = Result<Vec<SessionId>, StoreError>> + Send;
|
||||
fn list_sessions(&self) -> impl Future<Output = Result<Vec<SessionId>, StoreError>> + Send;
|
||||
|
||||
/// Create a new session with initial entries.
|
||||
fn create_session(
|
||||
@@ -55,10 +53,7 @@ pub trait Store: Send + Sync {
|
||||
) -> impl Future<Output = Result<(), StoreError>> + Send;
|
||||
|
||||
/// Check if a session exists.
|
||||
fn exists(
|
||||
&self,
|
||||
id: SessionId,
|
||||
) -> impl Future<Output = Result<bool, StoreError>> + Send;
|
||||
fn exists(&self, id: SessionId) -> impl Future<Output = Result<bool, StoreError>> + Send;
|
||||
|
||||
/// Read the hash of the last entry in a session (the head).
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user