1use std::collections::BTreeSet;
7use std::sync::{Arc, Condvar, Mutex};
8
9use chrono::{DateTime, Utc};
10use serde::Serialize;
11use uuid::Uuid;
12
13use crate::codec::optimization::{
14 LlmOptimizationContribution, LlmOptimizationModel, LlmOptimizationSummary,
15 LlmOptimizationSummaryStatus, LlmOptimizationTokens,
16};
17use crate::codec::response::{
18 AnnotatedLlmResponse, CostEstimate, CostSource, PricingResolver, Usage,
19};
20
21pub const MAX_LLM_OPTIMIZATION_CONTRIBUTIONS: usize = 64;
23pub const MAX_LLM_OPTIMIZATION_CONTRIBUTION_BYTES: usize = 16 * 1024;
25pub const MAX_LLM_OPTIMIZATION_TOTAL_CONTRIBUTION_BYTES: usize = 256 * 1024;
27pub const MAX_LLM_OPTIMIZATION_CONTRIBUTION_ATTEMPTS: usize = 64;
32
33#[derive(Debug, Default)]
34struct AccumulatorState {
35 contributions: Vec<LlmOptimizationContribution>,
36 recorded_at: Vec<DateTime<Utc>>,
37 total_contribution_bytes: usize,
38 attempted_contributions: usize,
39 in_flight_records: usize,
40 emitted: usize,
41 closed: bool,
42 finished: bool,
43 limitations: BTreeSet<String>,
44 contribution_limit_exceeded: bool,
45 invalid_payload_schema: bool,
46}
47
48#[derive(Debug, Default)]
49struct Accumulator {
50 state: Mutex<AccumulatorState>,
51 records_settled: Condvar,
52}
53
54#[derive(Debug, Clone, Default)]
59pub struct LlmOptimizationRecorder {
60 state: Arc<Accumulator>,
61}
62
63impl LlmOptimizationRecorder {
64 #[must_use]
70 pub fn record(&self, contribution: LlmOptimizationContribution) -> bool {
71 let Some(_attempt) = self.reserve_record_attempt() else {
72 return false;
73 };
74 if !self.payload_schema_is_valid(&contribution) {
75 return false;
76 }
77 let mut contribution = Some(contribution);
81 let Some(record) = contribution.as_mut() else {
82 return false;
83 };
84 record.id = Some(Uuid::now_v7());
85 loop {
86 let Some(sequence) = self.next_contribution_sequence() else {
87 return false;
88 };
89 let Some(record) = contribution.as_mut() else {
90 return false;
91 };
92 record.sequence = Some(sequence);
93 let Some(contribution_bytes) = self.serialized_contribution_size(record) else {
94 return false;
95 };
96 match self.commit_contribution(&mut contribution, contribution_bytes, sequence) {
97 ContributionCommit::Committed => return true,
98 ContributionCommit::Retry => continue,
99 ContributionCommit::Rejected => return false,
100 }
101 }
102 }
103
104 fn reserve_record_attempt(&self) -> Option<RecordAttempt> {
105 let Ok(mut state) = self.state.state.lock() else {
106 return None;
107 };
108 if state.closed {
109 return None;
110 }
111 if state.attempted_contributions >= MAX_LLM_OPTIMIZATION_CONTRIBUTION_ATTEMPTS {
112 seal_for_contribution_limit(&mut state);
113 return None;
114 }
115 state.attempted_contributions += 1;
116 state.in_flight_records += 1;
117 Some(RecordAttempt {
118 state: Arc::clone(&self.state),
119 })
120 }
121
122 #[cfg(test)]
123 pub(crate) fn reserve_record_attempt_for_test(&self) -> Option<RecordAttempt> {
124 self.reserve_record_attempt()
125 }
126
127 fn payload_schema_is_valid(&self, contribution: &LlmOptimizationContribution) -> bool {
128 if contribution.payload.is_some() && contribution.payload_schema.is_none() {
129 self.note_invalid_payload_schema();
130 return false;
131 }
132 true
133 }
134
135 fn next_contribution_sequence(&self) -> Option<u64> {
136 let Ok(state) = self.state.state.lock() else {
137 return None;
138 };
139 if state.closed {
140 return None;
141 }
142 if state.contributions.len() >= MAX_LLM_OPTIMIZATION_CONTRIBUTIONS {
143 drop(state);
144 self.note_contribution_limit_exceeded();
145 return None;
146 }
147 Some(state.contributions.len() as u64)
148 }
149
150 fn serialized_contribution_size(
151 &self,
152 contribution: &LlmOptimizationContribution,
153 ) -> Option<usize> {
154 match bounded_json_size(contribution, MAX_LLM_OPTIMIZATION_CONTRIBUTION_BYTES) {
155 Ok(size) => Some(size),
156 Err(SerializedSizeError::LimitExceeded) => {
157 self.note_contribution_limit_exceeded();
158 None
159 }
160 Err(SerializedSizeError::Serialization) => {
161 self.note_invalid_payload_schema();
162 None
163 }
164 }
165 }
166
167 fn commit_contribution(
168 &self,
169 contribution: &mut Option<LlmOptimizationContribution>,
170 contribution_bytes: usize,
171 sequence: u64,
172 ) -> ContributionCommit {
173 let Ok(mut state) = self.state.state.lock() else {
174 return ContributionCommit::Rejected;
175 };
176 if state.closed {
177 return ContributionCommit::Rejected;
178 }
179 if state.contributions.len() as u64 != sequence {
180 return ContributionCommit::Retry;
181 }
182 let Some(total_contribution_bytes) = state
183 .total_contribution_bytes
184 .checked_add(contribution_bytes)
185 else {
186 seal_for_contribution_limit(&mut state);
187 return ContributionCommit::Rejected;
188 };
189 if total_contribution_bytes > MAX_LLM_OPTIMIZATION_TOTAL_CONTRIBUTION_BYTES {
190 seal_for_contribution_limit(&mut state);
191 return ContributionCommit::Rejected;
192 }
193 let Some(contribution) = contribution.take() else {
194 return ContributionCommit::Rejected;
195 };
196 state.total_contribution_bytes = total_contribution_bytes;
197 state.contributions.push(contribution);
198 state.recorded_at.push(Utc::now());
199 ContributionCommit::Committed
200 }
201
202 fn note_invalid_payload_schema(&self) {
203 if let Ok(mut state) = self.state.state.lock()
204 && !state.finished
205 {
206 state.invalid_payload_schema = true;
207 }
208 }
209
210 fn note_contribution_limit_exceeded(&self) {
211 if let Ok(mut state) = self.state.state.lock()
212 && !state.finished
213 {
214 seal_for_contribution_limit(&mut state);
215 }
216 }
217
218 pub(crate) fn record_all(
219 &self,
220 contributions: impl IntoIterator<Item = LlmOptimizationContribution>,
221 ) {
222 for contribution in contributions {
223 if !self.record(contribution) && self.is_closed() {
224 break;
225 }
226 }
227 }
228
229 fn is_closed(&self) -> bool {
230 self.state
231 .state
232 .lock()
233 .map(|state| state.closed)
234 .unwrap_or(true)
235 }
236
237 #[cfg(test)]
238 pub(crate) fn is_closed_for_test(&self) -> bool {
239 self.is_closed()
240 }
241
242 #[cfg(test)]
247 pub(crate) fn unemitted(&self) -> Vec<LlmOptimizationContribution> {
248 self.unemitted_with_timestamps()
249 .into_iter()
250 .map(|(contribution, _)| contribution)
251 .collect()
252 }
253
254 pub(crate) fn unemitted_with_timestamps(
260 &self,
261 ) -> Vec<(LlmOptimizationContribution, DateTime<Utc>)> {
262 let Ok(state) = self.state.state.lock() else {
263 return Vec::new();
264 };
265 let start = state.emitted.min(state.contributions.len());
266 state.contributions[start..]
267 .iter()
268 .cloned()
269 .zip(state.recorded_at[start..].iter().copied())
270 .collect()
271 }
272
273 pub(crate) fn mark_emitted(&self, count: usize) {
275 let Ok(mut state) = self.state.state.lock() else {
276 return;
277 };
278 state.emitted = state
279 .emitted
280 .saturating_add(count)
281 .min(state.contributions.len());
282 }
283
284 #[cfg(test)]
286 pub(crate) fn note_limitation(&self, limitation: impl Into<String>) {
287 if let Ok(mut state) = self.state.state.lock()
288 && !state.closed
289 {
290 state.limitations.insert(limitation.into());
291 }
292 }
293
294 pub(crate) fn close_for_finalization(&self, conditional_limitation: Option<&str>) -> bool {
301 let Ok(mut state) = self.state.state.lock() else {
302 return false;
303 };
304 if state.finished {
305 return false;
306 }
307 let has_evidence = state.has_evidence();
308 if has_evidence && let Some(limitation) = conditional_limitation {
309 state.limitations.insert(limitation.to_string());
310 }
311 state.closed = true;
312 has_evidence
313 }
314
315 fn finish(&self) -> FinishedContributions {
316 let Ok(mut state) = self.state.state.lock() else {
317 return FinishedContributions {
318 contributions: Vec::new(),
319 limitations: vec!["optimization_accumulator_unavailable".to_string()],
320 };
321 };
322 if state.finished {
323 return FinishedContributions {
324 contributions: Vec::new(),
325 limitations: Vec::new(),
326 };
327 }
328 state.closed = true;
329 while state.in_flight_records > 0 {
330 let Ok(waiting) = self.state.records_settled.wait(state) else {
331 return FinishedContributions {
332 contributions: Vec::new(),
333 limitations: vec!["optimization_accumulator_unavailable".to_string()],
334 };
335 };
336 state = waiting;
337 if state.finished {
338 return FinishedContributions {
339 contributions: Vec::new(),
340 limitations: Vec::new(),
341 };
342 }
343 }
344 state.finished = true;
345 let mut limitations = std::mem::take(&mut state.limitations)
346 .into_iter()
347 .collect::<Vec<_>>();
348 if state.contribution_limit_exceeded {
349 limitations.push("contribution_limit_exceeded".to_string());
350 state.contribution_limit_exceeded = false;
351 }
352 if state.invalid_payload_schema {
353 limitations.push("invalid_contribution_payload_schema".to_string());
354 state.invalid_payload_schema = false;
355 }
356 state.recorded_at.clear();
357 FinishedContributions {
358 contributions: std::mem::take(&mut state.contributions),
359 limitations,
360 }
361 }
362}
363
364enum ContributionCommit {
365 Committed,
366 Retry,
367 Rejected,
368}
369
370pub(crate) struct RecordAttempt {
371 state: Arc<Accumulator>,
372}
373
374impl Drop for RecordAttempt {
375 fn drop(&mut self) {
376 let Ok(mut state) = self.state.state.lock() else {
377 return;
378 };
379 state.in_flight_records = state.in_flight_records.saturating_sub(1);
380 self.state.records_settled.notify_all();
381 }
382}
383
384impl AccumulatorState {
385 fn has_evidence(&self) -> bool {
386 !self.contributions.is_empty()
387 || !self.limitations.is_empty()
388 || self.contribution_limit_exceeded
389 || self.invalid_payload_schema
390 }
391}
392
393fn seal_for_contribution_limit(state: &mut AccumulatorState) {
394 state.contribution_limit_exceeded = true;
395 state.closed = true;
396}
397
398#[derive(Debug)]
399enum SerializedSizeError {
400 LimitExceeded,
401 Serialization,
402}
403
404fn bounded_json_size<T: Serialize>(value: &T, limit: usize) -> Result<usize, SerializedSizeError> {
405 struct CountingWriter {
406 size: usize,
407 limit: usize,
408 exceeded: bool,
409 }
410
411 impl std::io::Write for CountingWriter {
412 fn write(&mut self, bytes: &[u8]) -> std::io::Result<usize> {
413 if self.size.saturating_add(bytes.len()) > self.limit {
414 self.exceeded = true;
415 return Err(std::io::Error::other(
416 "optimization contribution limit exceeded",
417 ));
418 }
419 self.size += bytes.len();
420 Ok(bytes.len())
421 }
422
423 fn flush(&mut self) -> std::io::Result<()> {
424 Ok(())
425 }
426 }
427
428 let mut writer = CountingWriter {
429 size: 0,
430 limit,
431 exceeded: false,
432 };
433 if serde_json::to_writer(&mut writer, value).is_err() {
434 return Err(if writer.exceeded {
435 SerializedSizeError::LimitExceeded
436 } else {
437 SerializedSizeError::Serialization
438 });
439 }
440 Ok(writer.size)
441}
442
443struct FinishedContributions {
444 contributions: Vec<LlmOptimizationContribution>,
445 limitations: Vec<String>,
446}
447
448tokio::task_local! {
449 static CURRENT_LLM_OPTIMIZATION_RECORDER: LlmOptimizationRecorder;
450}
451
452#[must_use]
454pub fn current_llm_optimization_recorder() -> Option<LlmOptimizationRecorder> {
455 CURRENT_LLM_OPTIMIZATION_RECORDER
456 .try_with(Clone::clone)
457 .ok()
458}
459
460#[must_use]
462pub fn record_llm_optimization_contribution(contribution: LlmOptimizationContribution) -> bool {
463 current_llm_optimization_recorder().is_some_and(|recorder| recorder.record(contribution))
464}
465
466pub(crate) async fn scope_llm_optimization_recorder<F: std::future::Future>(
467 recorder: LlmOptimizationRecorder,
468 future: F,
469) -> F::Output {
470 CURRENT_LLM_OPTIMIZATION_RECORDER
471 .scope(recorder, future)
472 .await
473}
474
475struct ContributionAnalysis {
476 limitations: Vec<String>,
477 token_totals: CheckedTokenTotals,
478 baseline_model: Option<LlmOptimizationModel>,
479 contributed_effective_model: Option<LlmOptimizationModel>,
480 use_effective_as_baseline: bool,
481}
482
483fn analyze_contributions(finished: &FinishedContributions) -> ContributionAnalysis {
484 let applied_routing = finished
485 .contributions
486 .iter()
487 .filter(|contribution| contribution.applied)
488 .filter(|contribution| {
489 contribution.kind.as_str()
490 == crate::codec::optimization::LlmOptimizationKind::MODEL_ROUTING
491 })
492 .collect::<Vec<_>>();
493 let routing_ambiguous = applied_routing.len() > 1;
494 let mut limitations = finished.limitations.clone();
495 if routing_ambiguous {
496 limitations.push("multiple_routing_contributions".to_string());
497 }
498 let mut token_totals = CheckedTokenTotals::default();
499 for contribution in finished
500 .contributions
501 .iter()
502 .filter(|contribution| contribution.applied)
503 {
504 let is_routing = contribution.kind.as_str()
505 == crate::codec::optimization::LlmOptimizationKind::MODEL_ROUTING;
506 if routing_ambiguous && is_routing {
507 continue;
508 }
509 if let Some(saved) = contribution
510 .token_impact
511 .as_ref()
512 .and_then(|impact| impact.saved.as_ref())
513 {
514 token_totals.add_contribution(saved);
515 }
516 }
517 if token_totals.missing_total {
518 limitations.push("missing_token_savings_total".to_string());
519 }
520 if token_totals.inconsistent_total {
521 limitations.push("inconsistent_token_savings_total".to_string());
522 }
523 let authoritative_transition = (applied_routing.len() == 1)
524 .then(|| applied_routing[0].model_transition.as_ref())
525 .flatten();
526 ContributionAnalysis {
527 limitations,
528 token_totals,
529 baseline_model: authoritative_transition.and_then(|route| route.baseline.clone()),
530 contributed_effective_model: authoritative_transition
531 .and_then(|route| route.effective.clone()),
532 use_effective_as_baseline: applied_routing.is_empty() || routing_ambiguous,
533 }
534}
535
536fn resolve_effective_model(
537 contributed: Option<LlmOptimizationModel>,
538 response: Option<&AnnotatedLlmResponse>,
539 requested_model: Option<&str>,
540) -> Option<LlmOptimizationModel> {
541 contributed
542 .or_else(|| {
543 response
544 .and_then(|response| response.model.as_ref())
545 .map(|model| LlmOptimizationModel::new(model.clone()))
546 })
547 .or_else(|| requested_model.map(LlmOptimizationModel::new))
548}
549
550struct UsageAnalysis {
551 effective: Option<Usage>,
552 baseline: Option<Usage>,
553 token_count_overflow: bool,
554 baseline_derivation_incomplete: bool,
555}
556
557fn derive_optimization_usage(
558 mut response: Option<&mut AnnotatedLlmResponse>,
559 tokens_saved: &LlmOptimizationTokens,
560 token_totals: &CheckedTokenTotals,
561 limitations: &mut Vec<String>,
562) -> UsageAnalysis {
563 let mut effective = response
564 .as_ref()
565 .and_then(|response| response.usage.clone());
566 let mut token_count_overflow = token_totals.overflow.any();
567 let mut baseline_derivation_incomplete =
568 token_totals.missing_total || token_totals.inconsistent_total;
569 if let Some(usage) = effective.as_mut() {
570 note_missing_core_usage(usage, limitations, &mut token_count_overflow);
571 }
572 if let (Some(inferred), Some(response_usage)) = (
573 effective.as_ref().and_then(|usage| usage.total_tokens),
574 response
575 .as_mut()
576 .and_then(|response| response.usage.as_mut()),
577 ) && response_usage.total_tokens.is_none()
578 {
579 response_usage.total_tokens = Some(inferred);
580 }
581 let baseline = effective.as_ref().map(|usage| {
582 derive_baseline_usage(
583 usage,
584 tokens_saved,
585 token_totals,
586 limitations,
587 &mut token_count_overflow,
588 &mut baseline_derivation_incomplete,
589 )
590 });
591 if token_count_overflow {
592 limitations.push("token_count_overflow".to_string());
593 }
594 UsageAnalysis {
595 effective,
596 baseline,
597 token_count_overflow,
598 baseline_derivation_incomplete,
599 }
600}
601
602fn note_missing_core_usage(
603 usage: &mut Usage,
604 limitations: &mut Vec<String>,
605 token_count_overflow: &mut bool,
606) {
607 if usage.prompt_tokens.is_none() {
608 limitations.push("missing_effective_prompt_tokens".to_string());
609 }
610 if usage.completion_tokens.is_none() {
611 limitations.push("missing_effective_completion_tokens".to_string());
612 }
613 if usage.total_tokens.is_none() {
614 match (usage.prompt_tokens, usage.completion_tokens) {
615 (Some(prompt), Some(completion)) => match prompt.checked_add(completion) {
616 Some(total) => usage.total_tokens = Some(total),
617 None => *token_count_overflow = true,
618 },
619 _ => limitations.push("missing_effective_total_tokens".to_string()),
620 }
621 }
622}
623
624fn derive_baseline_usage(
625 usage: &Usage,
626 tokens_saved: &LlmOptimizationTokens,
627 token_totals: &CheckedTokenTotals,
628 limitations: &mut Vec<String>,
629 token_count_overflow: &mut bool,
630 baseline_derivation_incomplete: &mut bool,
631) -> Usage {
632 let mut baseline = usage.clone();
633 baseline.cost = None;
634 let fields = [
635 (
636 &mut baseline.prompt_tokens,
637 tokens_saved.prompt_tokens,
638 token_totals.overflow.prompt,
639 "missing_effective_prompt_tokens",
640 ),
641 (
642 &mut baseline.completion_tokens,
643 tokens_saved.completion_tokens,
644 token_totals.overflow.completion,
645 "missing_effective_completion_tokens",
646 ),
647 (
648 &mut baseline.cache_read_tokens,
649 tokens_saved.cache_read_tokens,
650 token_totals.overflow.cache_read,
651 "missing_effective_cache_read_tokens",
652 ),
653 (
654 &mut baseline.cache_write_tokens,
655 tokens_saved.cache_write_tokens,
656 token_totals.overflow.cache_write,
657 "missing_effective_cache_write_tokens",
658 ),
659 (
660 &mut baseline.total_tokens,
661 tokens_saved.total_tokens,
662 token_totals.overflow.total,
663 "missing_effective_total_tokens",
664 ),
665 ];
666 for (observed, saved, overflowed, missing_limitation) in fields {
667 *token_count_overflow |= checked_add_observed_tokens(
668 observed,
669 saved,
670 overflowed,
671 missing_limitation,
672 limitations,
673 baseline_derivation_incomplete,
674 );
675 }
676 baseline
677}
678
679struct PricingAnalysis {
680 baseline_cost: Option<CostEstimate>,
681 actual_cost: Option<CostEstimate>,
682 complete_core_usage: bool,
683}
684
685#[allow(clippy::too_many_arguments)]
686fn price_optimization_usage(
687 effective_usage: &mut Option<Usage>,
688 response: Option<&mut AnnotatedLlmResponse>,
689 effective_model: Option<&LlmOptimizationModel>,
690 baseline_model: Option<&LlmOptimizationModel>,
691 baseline_usage: Option<&Usage>,
692 token_count_overflow: bool,
693 baseline_derivation_incomplete: bool,
694 pricing: &PricingResolver,
695) -> PricingAnalysis {
696 let provider_reported_cost = effective_usage
697 .as_ref()
698 .and_then(|usage| usage.cost.as_ref())
699 .filter(|cost| cost.source == CostSource::ProviderReported)
700 .cloned();
701 let complete_core_usage = effective_usage
702 .as_ref()
703 .is_some_and(|usage| usage.prompt_tokens.is_some() && usage.completion_tokens.is_some());
704 let actual_cost = provider_reported_cost.or_else(|| {
705 let model = complete_core_usage.then_some(effective_model).flatten()?;
706 pricing.estimate_cost_for_provider(
707 model.provider.as_deref(),
708 &model.model,
709 effective_usage.as_ref()?,
710 )
711 });
712 if let Some(usage) = effective_usage.as_mut() {
713 usage.cost.clone_from(&actual_cost);
714 }
715 if let Some(usage) = response.and_then(|response| response.usage.as_mut()) {
716 usage.cost.clone_from(&actual_cost);
717 }
718 let baseline_cost =
719 (!token_count_overflow && !baseline_derivation_incomplete && complete_core_usage)
720 .then_some(baseline_model)
721 .flatten()
722 .and_then(|model| {
723 pricing.estimate_cost_for_provider(
724 model.provider.as_deref(),
725 &model.model,
726 baseline_usage?,
727 )
728 });
729 PricingAnalysis {
730 baseline_cost,
731 actual_cost,
732 complete_core_usage,
733 }
734}
735
736#[allow(clippy::too_many_arguments)]
737fn add_summary_limitations(
738 limitations: &mut Vec<String>,
739 effective_usage: Option<&Usage>,
740 effective_model: Option<&LlmOptimizationModel>,
741 baseline_model: Option<&LlmOptimizationModel>,
742 baseline_cost: Option<&CostEstimate>,
743 actual_cost: Option<&CostEstimate>,
744 token_count_overflow: bool,
745 baseline_derivation_incomplete: bool,
746 complete_core_usage: bool,
747) {
748 if effective_usage.is_none() {
749 limitations.push("missing_effective_usage".to_string());
750 }
751 if effective_model.is_none() {
752 limitations.push("missing_effective_model".to_string());
753 }
754 if baseline_model.is_none() {
755 limitations.push("missing_baseline_model".to_string());
756 }
757 if baseline_cost.is_none()
758 && baseline_model.is_some()
759 && !token_count_overflow
760 && !baseline_derivation_incomplete
761 && complete_core_usage
762 {
763 limitations.push("missing_baseline_pricing".to_string());
764 }
765 if actual_cost.is_none() {
766 limitations.push("missing_actual_cost".to_string());
767 }
768}
769
770pub(crate) fn finalize_optimization_summary(
771 recorder: &LlmOptimizationRecorder,
772 mut response: Option<&mut AnnotatedLlmResponse>,
773 requested_model: Option<&str>,
774 pricing: &PricingResolver,
775) -> Option<LlmOptimizationSummary> {
776 let finished = recorder.finish();
777 if finished.contributions.is_empty() && finished.limitations.is_empty() {
778 return None;
779 }
780
781 let mut analysis = analyze_contributions(&finished);
782 let effective_model = resolve_effective_model(
783 analysis.contributed_effective_model.take(),
784 response.as_deref(),
785 requested_model,
786 );
787 if analysis.use_effective_as_baseline && analysis.baseline_model.is_none() {
788 analysis.baseline_model = effective_model.clone();
789 }
790 let baseline_model = analysis.baseline_model;
791 let tokens_saved = analysis.token_totals.values.clone();
792 let mut limitations = analysis.limitations;
793 let token_totals = analysis.token_totals;
794 let mut token_count_overflow = token_totals.overflow.any();
795
796 let usage = derive_optimization_usage(
797 response.as_deref_mut(),
798 &tokens_saved,
799 &token_totals,
800 &mut limitations,
801 );
802 let mut effective_usage = usage.effective;
803 let baseline_usage = usage.baseline;
804 token_count_overflow |= usage.token_count_overflow;
805 let baseline_derivation_incomplete = usage.baseline_derivation_incomplete;
806
807 let pricing_analysis = price_optimization_usage(
808 &mut effective_usage,
809 response.as_deref_mut(),
810 effective_model.as_ref(),
811 baseline_model.as_ref(),
812 baseline_usage.as_ref(),
813 token_count_overflow,
814 baseline_derivation_incomplete,
815 pricing,
816 );
817 let baseline_cost = pricing_analysis.baseline_cost;
818 let actual_cost = pricing_analysis.actual_cost;
819 add_summary_limitations(
820 &mut limitations,
821 effective_usage.as_ref(),
822 effective_model.as_ref(),
823 baseline_model.as_ref(),
824 baseline_cost.as_ref(),
825 actual_cost.as_ref(),
826 token_count_overflow,
827 baseline_derivation_incomplete,
828 pricing_analysis.complete_core_usage,
829 );
830
831 let (estimated_cost_saved, currency) = calculate_estimated_cost_saved(
832 baseline_cost.as_ref(),
833 actual_cost.as_ref(),
834 &mut limitations,
835 );
836
837 limitations.sort();
838 limitations.dedup();
839 let summary = LlmOptimizationSummary {
840 schema_version: "1".to_string(),
841 calculation_version: "1".to_string(),
842 status: if limitations.is_empty() {
843 LlmOptimizationSummaryStatus::Complete
844 } else {
845 LlmOptimizationSummaryStatus::Partial
846 },
847 limitations,
848 baseline_model,
849 effective_model,
850 effective_usage,
851 baseline_usage,
852 tokens_saved,
853 baseline_cost,
854 actual_cost,
855 estimated_cost_saved,
856 currency,
857 contributions: finished.contributions,
858 };
859 if let Some(response) = response {
860 response.optimization_summary = Some(summary.clone());
861 }
862 Some(summary)
863}
864
865fn calculate_estimated_cost_saved(
866 baseline_cost: Option<&crate::codec::response::CostEstimate>,
867 actual_cost: Option<&crate::codec::response::CostEstimate>,
868 limitations: &mut Vec<String>,
869) -> (Option<f64>, Option<String>) {
870 let baseline_total = baseline_cost.and_then(|cost| cost.total_or_component_sum());
871 let actual_total = actual_cost.and_then(|cost| cost.total_or_component_sum());
872 if baseline_cost.is_some() && baseline_total.is_none() {
873 limitations.push("missing_baseline_cost_total".to_string());
874 }
875 if actual_cost.is_some() && actual_total.is_none() {
876 limitations.push("missing_actual_cost_total".to_string());
877 }
878
879 match (baseline_cost, actual_cost) {
880 (Some(baseline), Some(actual))
881 if baseline.currency.eq_ignore_ascii_case(&actual.currency) =>
882 {
883 let saved = baseline_total
884 .zip(actual_total)
885 .map(|(baseline, actual)| baseline - actual);
886 let currency = saved.is_some().then(|| baseline.currency.clone());
887 (saved, currency)
888 }
889 (Some(_), Some(_)) => {
890 limitations.push("cost_currency_mismatch".to_string());
891 (None, None)
892 }
893 _ => (None, None),
894 }
895}
896
897#[derive(Debug, Clone, Copy, Default)]
898struct TokenOverflow {
899 prompt: bool,
900 completion: bool,
901 cache_read: bool,
902 cache_write: bool,
903 total: bool,
904}
905
906impl TokenOverflow {
907 fn any(self) -> bool {
908 self.prompt || self.completion || self.cache_read || self.cache_write || self.total
909 }
910}
911
912#[derive(Debug, Default)]
913struct CheckedTokenTotals {
914 values: LlmOptimizationTokens,
915 overflow: TokenOverflow,
916 missing_total: bool,
917 inconsistent_total: bool,
918}
919
920impl CheckedTokenTotals {
921 fn add_contribution(&mut self, other: &LlmOptimizationTokens) {
922 checked_accumulate(
923 &mut self.values.prompt_tokens,
924 other.prompt_tokens,
925 &mut self.overflow.prompt,
926 );
927 checked_accumulate(
928 &mut self.values.completion_tokens,
929 other.completion_tokens,
930 &mut self.overflow.completion,
931 );
932 checked_accumulate(
933 &mut self.values.cache_read_tokens,
934 other.cache_read_tokens,
935 &mut self.overflow.cache_read,
936 );
937 checked_accumulate(
938 &mut self.values.cache_write_tokens,
939 other.cache_write_tokens,
940 &mut self.overflow.cache_write,
941 );
942
943 let (derived_total, derived_overflow) =
944 checked_option_sum([other.prompt_tokens, other.completion_tokens]);
945 self.overflow.total |= derived_overflow;
946 if derived_overflow {
947 self.values.total_tokens = None;
948 }
949 if let (Some(explicit), Some(prompt), Some(completion)) = (
950 other.total_tokens,
951 other.prompt_tokens,
952 other.completion_tokens,
953 ) && prompt
954 .checked_add(completion)
955 .is_some_and(|derived| derived != explicit)
956 {
957 self.inconsistent_total = true;
958 }
959 let contribution_total = other.total_tokens.or(derived_total);
960 if contribution_total.is_none() {
961 self.missing_total = true;
962 }
963 checked_accumulate(
964 &mut self.values.total_tokens,
965 contribution_total,
966 &mut self.overflow.total,
967 );
968 }
969}
970
971fn checked_accumulate(target: &mut Option<u64>, value: Option<u64>, overflowed: &mut bool) {
972 if *overflowed {
973 return;
974 }
975 let Some(value) = value else {
976 return;
977 };
978 match target.unwrap_or(0).checked_add(value) {
979 Some(total) => *target = Some(total),
980 None => {
981 *target = None;
982 *overflowed = true;
983 }
984 }
985}
986
987fn checked_add_observed_tokens(
988 target: &mut Option<u64>,
989 value: Option<u64>,
990 value_overflowed: bool,
991 missing_limitation: &'static str,
992 limitations: &mut Vec<String>,
993 baseline_derivation_incomplete: &mut bool,
994) -> bool {
995 if value_overflowed {
996 *target = None;
997 *baseline_derivation_incomplete = true;
998 return true;
999 }
1000 let Some(value) = value else {
1001 return false;
1002 };
1003 let Some(observed) = *target else {
1004 limitations.push(missing_limitation.to_string());
1005 *baseline_derivation_incomplete = true;
1006 return false;
1007 };
1008 match observed.checked_add(value) {
1009 Some(total) => {
1010 *target = Some(total);
1011 false
1012 }
1013 None => {
1014 *target = None;
1015 true
1016 }
1017 }
1018}
1019
1020fn checked_option_sum(values: impl IntoIterator<Item = Option<u64>>) -> (Option<u64>, bool) {
1021 let mut present = false;
1022 let mut total = 0_u64;
1023 for value in values.into_iter().flatten() {
1024 present = true;
1025 let Some(next) = total.checked_add(value) else {
1026 return (None, true);
1027 };
1028 total = next;
1029 }
1030 (present.then_some(total), false)
1031}
1032
1033#[cfg(test)]
1034#[path = "../../tests/unit/optimization_tests.rs"]
1035mod tests;