use crate::token_counter::TokenCounter;
use crate::Message;
use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Priority(pub u8);
impl Priority {
pub const CRITICAL: Priority = Priority(0);
pub const HIGH: Priority = Priority(64);
pub const NORMAL: Priority = Priority(128);
pub const LOW: Priority = Priority(192);
}
pub struct ContextSlot {
pub name: String,
pub priority: Priority,
pub messages: Vec<Message>,
pub reserved_tokens: usize,
}
pub struct ContextBudget {
max_tokens: usize,
counter: Arc<dyn TokenCounter>,
}
impl ContextBudget {
pub fn new(max_tokens: usize, counter: Arc<dyn TokenCounter>) -> Self {
Self {
max_tokens,
counter,
}
}
pub fn assemble(&self, mut slots: Vec<ContextSlot>) -> Vec<Message> {
slots.sort_by_key(|s| s.priority);
let mut result = Vec::new();
let mut used_tokens = 0;
for slot in slots {
let slot_tokens = self.counter.count_messages(&slot.messages);
if slot.reserved_tokens > 0 {
if used_tokens + slot_tokens <= self.max_tokens {
used_tokens += slot_tokens;
result.extend(slot.messages);
}
} else if used_tokens + slot_tokens <= self.max_tokens {
used_tokens += slot_tokens;
result.extend(slot.messages);
}
}
result
}
}