Skip to main content

bookforge_core/
progress.rs

1pub fn now_ms() -> u64 {
2    std::time::SystemTime::now()
3        .duration_since(std::time::UNIX_EPOCH)
4        .unwrap_or_default()
5        .as_millis() as u64
6}
7
8use serde::Serialize;
9
10pub trait ProgressSink: Send + Sync + 'static {
11    fn emit(&self, event: ProgressEvent);
12}
13
14pub struct NullProgressSink;
15
16impl ProgressSink for NullProgressSink {
17    fn emit(&self, _event: ProgressEvent) {}
18}
19
20#[derive(Debug, Clone, Serialize)]
21pub enum ProgressEvent {
22    JobCreated {
23        job_id: String,
24        input_path: String,
25        output_path: String,
26        timestamp_ms: u64,
27    },
28    StageStarted {
29        stage: String,
30        timestamp_ms: u64,
31    },
32    StageFinished {
33        stage: String,
34        timestamp_ms: u64,
35    },
36    RuntimeConfigResolved {
37        profile: String,
38        provider_preset: Option<String>,
39        provider: String,
40        model: String,
41        concurrency: usize,
42        max_attempts: usize,
43        provider_max_attempts: usize,
44        validation_max_attempts: usize,
45        retry_after_policy: String,
46        max_backoff_seconds: u64,
47        timeout_seconds: u64,
48        batch_enabled: bool,
49        batch_target_tokens: usize,
50        batch_max_items: usize,
51        adaptive_batch_sizing: bool,
52        adaptive_concurrency: bool,
53        compact_prompts: bool,
54        thinking_disabled: bool,
55        json_mode: String,
56        model_context_tokens: Option<u32>,
57        max_output_tokens: Option<u32>,
58        batch_max_output_tokens: Option<u32>,
59        timestamp_ms: u64,
60    },
61    SegmentationFinished {
62        segment_count: usize,
63        timestamp_ms: u64,
64    },
65    CacheScanFinished {
66        hits: usize,
67        misses: usize,
68        timestamp_ms: u64,
69    },
70    BatchQueued {
71        batch_id: String,
72        item_count: usize,
73        timestamp_ms: u64,
74    },
75    BatchSplit {
76        batch_id: String,
77        left_items: usize,
78        right_items: usize,
79        timestamp_ms: u64,
80    },
81    BatchRepairStarted {
82        failed_item_count: usize,
83        timestamp_ms: u64,
84    },
85    BatchRepairFinished {
86        repaired_items: usize,
87        still_failed_items: usize,
88        timestamp_ms: u64,
89    },
90    RequestStarted {
91        request_id: String,
92        batch_id: Option<String>,
93        segment_id: Option<String>,
94        provider: Option<String>,
95        model: Option<String>,
96        prompt_template: Option<String>,
97        items: usize,
98        estimated_input_tokens: usize,
99        max_output_tokens: Option<u32>,
100        active_requests: usize,
101        target_concurrency: usize,
102        timestamp_ms: u64,
103    },
104    RequestFinished {
105        request_id: String,
106        batch_id: Option<String>,
107        segment_id: Option<String>,
108        status: String,
109        latency_ms: u64,
110        status_code: Option<u16>,
111        finish_reason: Option<String>,
112        retry_count: usize,
113        input_tokens: Option<u64>,
114        output_tokens: Option<u64>,
115        error_kind: Option<String>,
116        timestamp_ms: u64,
117    },
118    SegmentStarted {
119        segment_id: String,
120        ordinal: usize,
121        timestamp_ms: u64,
122    },
123    SegmentFinished {
124        segment_id: String,
125        status: String,
126        input_tokens: Option<u64>,
127        output_tokens: Option<u64>,
128        timestamp_ms: u64,
129    },
130    CheckpointQueued {
131        queued: usize,
132        timestamp_ms: u64,
133    },
134    CheckpointFlushed {
135        segment_id: Option<String>,
136        flushed_count: usize,
137        latency_ms: Option<u64>,
138        timestamp_ms: u64,
139    },
140    ConcurrencyChanged {
141        previous: usize,
142        current: usize,
143        reason: String,
144        timestamp_ms: u64,
145    },
146    BatchSizingChanged {
147        batch_id: Option<String>,
148        previous_target: usize,
149        new_target: usize,
150        previous_max_items: usize,
151        new_max_items: usize,
152        reason: String,
153        timestamp_ms: u64,
154    },
155    ArtifactWritten {
156        path: String,
157        timestamp_ms: u64,
158    },
159    Warning {
160        kind: String,
161        message: String,
162        timestamp_ms: u64,
163    },
164    Error {
165        kind: String,
166        message: String,
167        timestamp_ms: u64,
168    },
169    TranslationFinished {
170        succeeded: usize,
171        cached: usize,
172        needs_review: usize,
173        failed: usize,
174        input_tokens: u64,
175        output_tokens: u64,
176        elapsed_ms: u64,
177        timestamp_ms: u64,
178    },
179    DroppedEvents {
180        count: usize,
181        timestamp_ms: u64,
182    },
183}