oxi_agent/compaction.rs
1/// Context compaction events
2use oxi_ai::CompactedContext as AiCompactedContext;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6/// CompactionEvent.
7pub enum CompactionEvent {
8 /// Variant.
9 Triggered {
10 /// context_tokens.
11 context_tokens: usize,
12 /// iteration.
13 iteration: usize,
14 /// Source of the `context_tokens` value:
15 /// - `"provider-reported"`: the agent state's
16 /// `last_input_tokens` (ground truth from the most recent
17 /// provider `usage.input_tokens`).
18 /// - `"bytes/4 heuristic (cold start)"`: the legacy
19 /// `serialized_json.len() / 4` estimate — used only on the
20 /// very first turn before any provider count is available.
21 /// - `"empty"`: no messages have been sent yet.
22 ///
23 /// Added for issue #28 (gap 2) so consumers can tell whether
24 /// a compaction trigger is based on real token accounting or
25 /// the heuristic.
26 source: String,
27 },
28 /// Variant.
29 Started {
30 /// message_count.
31 message_count: usize,
32 },
33 /// Variant.
34 Completed {
35 /// result.
36 result: CompactedContext,
37 /// duration_ms.
38 duration_ms: u64,
39 },
40 /// Variant.
41 Skipped {
42 /// reason.
43 reason: String,
44 },
45 /// Variant.
46 Failed {
47 /// error.
48 error: String,
49 },
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
53/// CompactedContext.
54pub struct CompactedContext {
55 /// pub.
56 pub summary: String,
57 /// pub.
58 pub kept_messages: Vec<oxi_ai::Message>,
59 /// pub.
60 pub compacted_count: usize,
61}
62
63impl From<AiCompactedContext> for CompactedContext {
64 fn from(ctx: AiCompactedContext) -> Self {
65 Self {
66 summary: ctx.summary,
67 kept_messages: ctx.kept_messages,
68 compacted_count: ctx.compacted_count,
69 }
70 }
71}