feat: trace pre-stream lifecycle

This commit is contained in:
2026-05-26 21:05:45 +09:00
parent 372a99bc0b
commit 8416533695
5 changed files with 204 additions and 15 deletions
+24 -7
View File
@@ -1,21 +1,38 @@
//! Debug-only raw stream event recording.
//! Debug-only LLM request/stream trace recording.
//!
//! [`TraceEntry`] captures every LLM stream event verbatim for debugging
//! and post-hoc analysis. Written to a separate `.trace.jsonl` file,
//! [`TraceEntry`] captures stream lifecycle markers and raw provider stream
//! events for debugging stalls. Written to a separate `.trace.jsonl` file,
//! completely independent of the segment log used for state restoration.
//!
//! Disabled by default. Enable via `SessionConfig::record_event_trace`.
use llm_worker::llm_client::event::Event;
use serde::{Deserialize, Serialize};
use serde_json::Value;
/// A single trace entry recording a raw stream event.
#[derive(Debug, Clone, Serialize, Deserialize)]
/// A single trace entry recording either a lifecycle marker or raw stream event.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TraceEntry {
/// Timestamp in milliseconds since Unix epoch.
pub ts: u64,
/// Turn number at the time of recording.
pub turn: usize,
/// The raw stream event.
pub event: Event,
/// LLM call index within the worker, when known.
#[serde(skip_serializing_if = "Option::is_none")]
pub llm_call: Option<usize>,
#[serde(flatten)]
pub payload: TracePayload,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum TracePayload {
/// Normalized provider stream event.
StreamEvent { event: Event },
/// Marker for code that runs before/around provider stream events.
Lifecycle {
label: String,
#[serde(default, skip_serializing_if = "Value::is_null")]
data: Value,
},
}
+1 -1
View File
@@ -39,7 +39,7 @@ pub mod segment_log;
pub mod store;
pub mod system_item;
pub use event_trace::TraceEntry;
pub use event_trace::{TraceEntry, TracePayload};
pub use fs_store::FsStore;
pub use llm_worker::UsageRecord;
pub use llm_worker::llm_client::types::{ContentPart, Item, Role};
+6 -3
View File
@@ -174,9 +174,12 @@ fn trace_entries_in_separate_file() {
let trace = TraceEntry {
ts: 1500,
turn: 0,
event: llm_worker::llm_client::event::Event::Ping(
llm_worker::llm_client::event::PingEvent { timestamp: None },
),
llm_call: Some(0),
payload: session_store::TracePayload::StreamEvent {
event: llm_worker::llm_client::event::Event::Ping(
llm_worker::llm_client::event::PingEvent { timestamp: None },
),
},
};
store.append_trace(sid, segid, &trace).unwrap();