1#[cfg(test)]
2mod cache;
3mod code_mode;
4mod replay;
5mod replay_cache;
6mod tokens;
7
8#[cfg(test)]
9pub(crate) use cache::conversation_cache_material;
10#[cfg(test)]
11pub(crate) use replay::build_conversation_replay;
12pub(crate) use replay::{
13 ConversationReplayLimits, REPLAY_JSONL_MAX_BYTES, REPLAY_JSONL_MAX_LINES,
14 build_conversation_replay_from_events,
15};
16pub(crate) use replay_cache::ConversationReplayCache;
17#[cfg(test)]
18pub(crate) use replay_cache::ReplayCacheMetrics;
19pub(crate) use tokens::estimate_text_tokens;
20pub use tokens::{ContextBudget, ContextBudgetOverride};
21pub(crate) use tokens::{
22 ContextTokenCount, count_supported_provider_conversation_item_tokens,
23 project_provider_conversation_items_tokens, project_provider_request_input_tokens,
24 project_text_tokens, token_encoding_family_for_model,
25};
26
27use crate::sessions::{SessionEvent, SessionEventKind};
28use serde_json::Value;
29#[cfg(test)]
30pub(crate) use serde_json::json;
31
32pub(crate) fn is_local_only_session_event(event: &SessionEvent) -> bool {
33 event.kind().is_some_and(SessionEventKind::is_local_only)
34}
35
36fn event_line(event: &SessionEvent) -> String {
37 let compact_payload = if let Some(text) = event.payload.get("text").and_then(Value::as_str) {
38 text.to_string()
39 } else if let Some(message) = event.payload.get("message").and_then(Value::as_str) {
40 message.to_string()
41 } else {
42 event.payload.to_string()
43 };
44 format!(
45 "{}: {}",
46 event.event_type,
47 compact_payload.replace('\n', "\\n")
48 )
49}
50
51pub(crate) fn canonical_json(value: &Value) -> String {
52 serde_json::to_string(value).unwrap_or_else(|_| "null".to_string())
53}
54
55#[cfg(test)]
56mod profiling;