ai-agent 0.13.4

Idiomatic agent sdk inspired by the claude code source leak
Documentation
use std::collections::HashMap;

pub struct CacheEntry<T> {
    pub value: T,
    pub created_at: u64,
    pub expires_at: Option<u64>,
}

pub struct MemoryCache<K, V> {
    store: HashMap<K, CacheEntry<V>>,
    max_size: usize,
}

impl<K: std::hash::Hash + Eq, V> MemoryCache<K, V> {
    pub fn new(max_size: usize) -> Self {
        Self {
            store: HashMap::new(),
            max_size,
        }
    }

    pub fn set(&mut self, key: K, value: V, ttl_secs: Option<u64>) {
        let now = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_millis() as u64;

        let expires_at = ttl_secs.map(|secs| now + secs * 1000);

        if self.store.len() >= self.max_size {
            if let Some(oldest_key) = self.store.keys().next().cloned() {
                self.store.remove(&oldest_key);
            }
        }

        self.store.insert(
            key,
            CacheEntry {
                value,
                created_at: now,
                expires_at,
            },
        );
    }

    pub fn get(&self, key: &K) -> Option<&V> {
        let now = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_millis() as u64;

        self.store.get(key).and_then(|entry| {
            if let Some(expires_at) = entry.expires_at {
                if now > expires_at {
                    return None;
                }
            }
            Some(&entry.value)
        })
    }

    pub fn remove(&mut self, key: &K) -> Option<V> {
        self.store.remove(key).map(|e| e.value)
    }

    pub fn clear(&mut self) {
        self.store.clear();
    }

    pub fn len(&self) -> usize {
        self.store.len()
    }

    pub fn is_empty(&self) -> bool {
        self.store.is_empty()
    }
}