vv_agent/memory/
provider.rs1use std::future::Future;
2use std::pin::Pin;
3
4use crate::events::RunEvent;
5use crate::types::Metadata;
6
7pub type MemoryFuture<T> = Pin<Box<dyn Future<Output = Result<T, MemoryError>> + Send>>;
8
9pub trait MemoryProvider: Send + Sync {
10 fn search(&self, request: MemorySearchRequest) -> MemoryFuture<Vec<MemorySearchResult>>;
11 fn save(&self, request: MemorySaveRequest) -> MemoryFuture<MemorySaveResult>;
12
13 fn before_compact(&self, _event: &RunEvent) -> MemoryFuture<MemoryProviderResult> {
14 Box::pin(async { Ok(MemoryProviderResult::default()) })
15 }
16
17 fn after_compact(&self, _event: &RunEvent) -> MemoryFuture<()> {
18 Box::pin(async { Ok(()) })
19 }
20}
21
22#[derive(Debug, Clone, Default, PartialEq)]
23pub struct MemorySearchRequest {
24 pub query: String,
25 pub metadata: Metadata,
26}
27
28#[derive(Debug, Clone, Default, PartialEq)]
29pub struct MemorySearchResult {
30 pub content: String,
31 pub score: Option<f64>,
32 pub metadata: Metadata,
33}
34
35#[derive(Debug, Clone, Default, PartialEq)]
36pub struct MemorySaveRequest {
37 pub content: String,
38 pub metadata: Metadata,
39}
40
41#[derive(Debug, Clone, Default, PartialEq)]
42pub struct MemorySaveResult {
43 pub id: Option<String>,
44 pub metadata: Metadata,
45}
46
47#[derive(Debug, Clone, Default, PartialEq)]
48pub struct MemoryProviderResult {
49 pub metadata: Metadata,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub struct MemoryError {
54 message: String,
55}
56
57impl MemoryError {
58 pub fn new(message: impl Into<String>) -> Self {
59 Self {
60 message: message.into(),
61 }
62 }
63}
64
65impl std::fmt::Display for MemoryError {
66 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 formatter.write_str(&self.message)
68 }
69}
70
71impl std::error::Error for MemoryError {}
72
73pub(crate) fn block_on_memory_future<T: Send>(future: MemoryFuture<T>) -> Result<T, MemoryError> {
74 if let Ok(handle) = tokio::runtime::Handle::try_current() {
75 if handle.runtime_flavor() == tokio::runtime::RuntimeFlavor::MultiThread {
76 tokio::task::block_in_place(|| handle.block_on(future))
77 } else {
78 handle.block_on(future)
79 }
80 } else {
81 tokio::runtime::Builder::new_current_thread()
82 .enable_all()
83 .build()
84 .map_err(|error| MemoryError::new(error.to_string()))?
85 .block_on(future)
86 }
87}