rig_tap/
observed_memory.rs1use rig::completion::Message;
10use rig::memory::{ConversationMemory, MemoryError};
11use rig::wasm_compat::WasmBoxedFuture;
12
13use crate::emit::emit_kind;
14use crate::event::EventKind;
15
16pub struct ObservedMemory<M> {
30 inner: M,
31}
32
33impl<M> ObservedMemory<M> {
34 pub fn new(inner: M) -> Self {
36 Self { inner }
37 }
38
39 pub fn inner(&self) -> &M {
41 &self.inner
42 }
43
44 pub fn into_inner(self) -> M {
46 self.inner
47 }
48}
49
50impl<M> std::fmt::Debug for ObservedMemory<M>
51where
52 M: std::fmt::Debug,
53{
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 f.debug_struct("ObservedMemory")
56 .field("inner", &self.inner)
57 .finish()
58 }
59}
60
61impl<M> Clone for ObservedMemory<M>
62where
63 M: Clone,
64{
65 fn clone(&self) -> Self {
66 Self {
67 inner: self.inner.clone(),
68 }
69 }
70}
71
72impl<M> ConversationMemory for ObservedMemory<M>
73where
74 M: ConversationMemory,
75{
76 fn load<'a>(
77 &'a self,
78 conversation_id: &'a str,
79 ) -> WasmBoxedFuture<'a, Result<Vec<Message>, MemoryError>> {
80 Box::pin(async move {
81 let messages = self.inner.load(conversation_id).await?;
82 let message_count = messages.len();
83 let byte_size = approx_json_size(&messages);
84 emit_kind(
85 conversation_id,
86 EventKind::ContextSampled {
87 message_count,
88 byte_size,
89 token_estimate: None,
90 },
91 );
92 Ok(messages)
93 })
94 }
95
96 fn append<'a>(
97 &'a self,
98 conversation_id: &'a str,
99 messages: Vec<Message>,
100 ) -> WasmBoxedFuture<'a, Result<(), MemoryError>> {
101 self.inner.append(conversation_id, messages)
102 }
103
104 fn clear<'a>(
105 &'a self,
106 conversation_id: &'a str,
107 ) -> WasmBoxedFuture<'a, Result<(), MemoryError>> {
108 self.inner.clear(conversation_id)
109 }
110}
111
112#[derive(Default)]
116struct CountingWriter {
117 bytes: usize,
118}
119
120impl std::io::Write for CountingWriter {
121 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
122 self.bytes = self.bytes.saturating_add(buf.len());
123 Ok(buf.len())
124 }
125 fn flush(&mut self) -> std::io::Result<()> {
126 Ok(())
127 }
128}
129
130fn approx_json_size(messages: &[Message]) -> usize {
135 let mut writer = CountingWriter::default();
136 if serde_json::to_writer(&mut writer, messages).is_err() {
137 return 0;
138 }
139 writer.bytes
140}