use std::collections::BTreeMap;
use sim_kernel::{ContentId, Result};
use crate::{
content_id::{content_id_for_expr, request_content_id},
objects::{GatewayEvent, GatewayRequest, GatewayResponse, GatewayRun},
storage::{
GatewayBatch, GatewayFile, GatewayResponseObjectStore, GatewayStateStore, GatewayStore,
GatewayThread, GatewayThreadMessage, GatewayVectorStore, StoredGatewayResponse,
},
};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct GatewayStoreCounts {
pub request_count: usize,
pub run_count: usize,
pub event_count: usize,
pub response_count: usize,
pub response_object_count: usize,
pub file_count: usize,
pub file_bytes_count: usize,
pub batch_count: usize,
pub thread_count: usize,
pub thread_message_count: usize,
pub vector_store_count: usize,
}
#[derive(Clone, Debug, Default)]
pub struct MemoryGatewayStore {
requests: BTreeMap<ContentId, GatewayRequest>,
runs: BTreeMap<ContentId, GatewayRun>,
events: BTreeMap<ContentId, GatewayEvent>,
responses: BTreeMap<ContentId, GatewayResponse>,
response_objects: BTreeMap<String, StoredGatewayResponse>,
files: BTreeMap<String, GatewayFile>,
file_bytes: BTreeMap<String, Vec<u8>>,
batches: BTreeMap<String, GatewayBatch>,
threads: BTreeMap<String, GatewayThread>,
thread_messages: BTreeMap<String, Vec<GatewayThreadMessage>>,
vector_stores: BTreeMap<String, GatewayVectorStore>,
}
impl MemoryGatewayStore {
pub fn new() -> Self {
Self::default()
}
pub fn put_request_content(&mut self, request: GatewayRequest) -> Result<ContentId> {
let id = request_content_id(&request)?;
self.put_request(id.clone(), request)?;
Ok(id)
}
pub fn put_run_content(&mut self, run: GatewayRun) -> Result<ContentId> {
let id = content_id_for_expr(&run.to_expr())?;
self.put_run(id.clone(), run)?;
Ok(id)
}
pub fn put_event_content(&mut self, event: GatewayEvent) -> Result<ContentId> {
let id = content_id_for_expr(&event.to_expr())?;
self.put_event(id.clone(), event)?;
Ok(id)
}
pub fn put_response_content(&mut self, response: GatewayResponse) -> Result<ContentId> {
let id = content_id_for_expr(&response.to_expr())?;
self.put_response(id.clone(), response)?;
Ok(id)
}
pub fn counts(&self) -> GatewayStoreCounts {
GatewayStoreCounts {
request_count: self.requests.len(),
run_count: self.runs.len(),
event_count: self.events.len(),
response_count: self.responses.len(),
response_object_count: self.response_objects.len(),
file_count: self.files.len(),
file_bytes_count: self.file_bytes.len(),
batch_count: self.batches.len(),
thread_count: self.threads.len(),
thread_message_count: self.thread_messages.values().map(Vec::len).sum(),
vector_store_count: self.vector_stores.len(),
}
}
pub fn requests(&self) -> Vec<(ContentId, GatewayRequest)> {
self.requests
.iter()
.map(|(id, request)| (id.clone(), request.clone()))
.collect()
}
pub fn runs(&self) -> Vec<(ContentId, GatewayRun)> {
self.runs
.iter()
.map(|(id, run)| (id.clone(), run.clone()))
.collect()
}
pub fn run_by_id(&self, run_id: &str) -> Option<(ContentId, GatewayRun)> {
self.runs
.iter()
.find_map(|(id, run)| (run.id() == run_id).then(|| (id.clone(), run.clone())))
}
pub fn events(&self) -> Vec<(ContentId, GatewayEvent)> {
self.events
.iter()
.map(|(id, event)| (id.clone(), event.clone()))
.collect()
}
}
impl GatewayStore for MemoryGatewayStore {
fn put_request(&mut self, id: ContentId, request: GatewayRequest) -> Result<()> {
self.requests.insert(id, request);
Ok(())
}
fn request(&self, id: &ContentId) -> Option<GatewayRequest> {
self.requests.get(id).cloned()
}
fn put_run(&mut self, id: ContentId, run: GatewayRun) -> Result<()> {
self.runs.insert(id, run);
Ok(())
}
fn run(&self, id: &ContentId) -> Option<GatewayRun> {
self.runs.get(id).cloned()
}
fn put_event(&mut self, id: ContentId, event: GatewayEvent) -> Result<()> {
self.events.insert(id, event);
Ok(())
}
fn event(&self, id: &ContentId) -> Option<GatewayEvent> {
self.events.get(id).cloned()
}
fn put_response(&mut self, id: ContentId, response: GatewayResponse) -> Result<()> {
self.responses.insert(id, response);
Ok(())
}
fn response(&self, id: &ContentId) -> Option<GatewayResponse> {
self.responses.get(id).cloned()
}
}
impl GatewayResponseObjectStore for MemoryGatewayStore {
fn put_response_object(&mut self, response: StoredGatewayResponse) -> Result<()> {
self.responses
.insert(response.content_id().clone(), response.response().clone());
self.response_objects
.insert(response.response_id().to_owned(), response);
Ok(())
}
fn response_object(&self, response_id: &str) -> Option<StoredGatewayResponse> {
self.response_objects.get(response_id).cloned()
}
}
impl GatewayStateStore for MemoryGatewayStore {
fn put_file(&mut self, file: GatewayFile, bytes: Vec<u8>) -> Result<()> {
self.file_bytes.insert(file.id().to_owned(), bytes);
self.files.insert(file.id().to_owned(), file);
Ok(())
}
fn file(&self, file_id: &str) -> Option<GatewayFile> {
self.files.get(file_id).cloned()
}
fn file_bytes(&self, file_id: &str) -> Option<Vec<u8>> {
self.file_bytes.get(file_id).cloned()
}
fn put_batch(&mut self, batch: GatewayBatch) -> Result<()> {
self.batches.insert(batch.id().to_owned(), batch);
Ok(())
}
fn batch(&self, batch_id: &str) -> Option<GatewayBatch> {
self.batches.get(batch_id).cloned()
}
fn put_thread(&mut self, thread: GatewayThread) -> Result<()> {
self.threads.insert(thread.id().to_owned(), thread);
Ok(())
}
fn thread(&self, thread_id: &str) -> Option<GatewayThread> {
self.threads.get(thread_id).cloned()
}
fn put_thread_message(&mut self, message: GatewayThreadMessage) -> Result<()> {
self.thread_messages
.entry(message.thread_id().to_owned())
.or_default()
.push(message);
Ok(())
}
fn thread_messages(&self, thread_id: &str) -> Vec<GatewayThreadMessage> {
self.thread_messages
.get(thread_id)
.cloned()
.unwrap_or_default()
}
fn put_vector_store(&mut self, vector_store: GatewayVectorStore) -> Result<()> {
self.vector_stores
.insert(vector_store.id().to_owned(), vector_store);
Ok(())
}
fn vector_store(&self, vector_store_id: &str) -> Option<GatewayVectorStore> {
self.vector_stores.get(vector_store_id).cloned()
}
}