baml-cc 0.208.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/exe/baml +1 -0
- data/exe/baml-cli +4 -0
- data/ext/ruby_ffi/Cargo.toml +52 -0
- data/ext/ruby_ffi/build.rs +21 -0
- data/ext/ruby_ffi/extconf.rb +17 -0
- data/ext/ruby_ffi/src/function_result.rs +75 -0
- data/ext/ruby_ffi/src/function_result_stream.rs +63 -0
- data/ext/ruby_ffi/src/lib.rs +388 -0
- data/ext/ruby_ffi/src/ruby_to_json.rs +651 -0
- data/ext/ruby_ffi/src/types/client_registry.rs +71 -0
- data/ext/ruby_ffi/src/types/lang_wrapper.rs +60 -0
- data/ext/ruby_ffi/src/types/log_collector.rs +607 -0
- data/ext/ruby_ffi/src/types/media.rs +142 -0
- data/ext/ruby_ffi/src/types/mod.rs +8 -0
- data/ext/ruby_ffi/src/types/request.rs +107 -0
- data/ext/ruby_ffi/src/types/response.rs +48 -0
- data/ext/ruby_ffi/src/types/runtime_ctx_manager.rs +18 -0
- data/ext/ruby_ffi/src/types/type_builder.rs +334 -0
- data/lib/baml.rb +63 -0
- data/lib/checked.rb +36 -0
- data/lib/stream.rb +87 -0
- data/lib/struct.rb +66 -0
- metadata +69 -0
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
#![allow(dead_code)]
|
|
2
|
+
|
|
3
|
+
use std::{
|
|
4
|
+
str::FromStr,
|
|
5
|
+
sync::{Arc, Mutex},
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
use baml_runtime::tracingv2::storage::storage::BAML_TRACER;
|
|
9
|
+
use magnus::{
|
|
10
|
+
class, function, method,
|
|
11
|
+
scan_args::{get_kwargs, scan_args},
|
|
12
|
+
try_convert::TryConvertOwned,
|
|
13
|
+
Error, IntoValueFromNative, Module, Object, RArray, RModule, Ruby, Value,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
use super::{
|
|
17
|
+
request::{HTTPBody, HTTPRequest},
|
|
18
|
+
response::HTTPResponse,
|
|
19
|
+
};
|
|
20
|
+
use crate::Result;
|
|
21
|
+
|
|
22
|
+
crate::lang_wrapper!(
|
|
23
|
+
Collector,
|
|
24
|
+
"Baml::Ffi::Collector",
|
|
25
|
+
baml_runtime::tracingv2::storage::storage::Collector,
|
|
26
|
+
clone_safe
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
unsafe impl TryConvertOwned for &Collector {}
|
|
30
|
+
|
|
31
|
+
crate::lang_wrapper!(
|
|
32
|
+
Usage,
|
|
33
|
+
"Baml::Ffi::Usage",
|
|
34
|
+
baml_runtime::tracingv2::storage::storage::Usage,
|
|
35
|
+
clone_safe
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
crate::lang_wrapper!(
|
|
39
|
+
Timing,
|
|
40
|
+
"Baml::Ffi::Timing",
|
|
41
|
+
baml_runtime::tracingv2::storage::storage::Timing,
|
|
42
|
+
clone_safe
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
crate::lang_wrapper!(
|
|
46
|
+
StreamTiming,
|
|
47
|
+
"Baml::Ffi::StreamTiming",
|
|
48
|
+
baml_runtime::tracingv2::storage::storage::StreamTiming,
|
|
49
|
+
clone_safe
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
crate::lang_wrapper!(
|
|
53
|
+
FunctionLog,
|
|
54
|
+
"Baml::Ffi::FunctionLog",
|
|
55
|
+
baml_runtime::tracingv2::storage::storage::FunctionLog,
|
|
56
|
+
sync_thread_safe
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
crate::lang_wrapper!(
|
|
60
|
+
LLMCall,
|
|
61
|
+
"Baml::Ffi::LLMCall",
|
|
62
|
+
baml_runtime::tracingv2::storage::storage::LLMCall,
|
|
63
|
+
clone_safe
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
unsafe impl IntoValueFromNative for LLMCall {}
|
|
67
|
+
|
|
68
|
+
unsafe impl IntoValueFromNative for LLMStreamCall {}
|
|
69
|
+
crate::lang_wrapper!(
|
|
70
|
+
LLMStreamCall,
|
|
71
|
+
"Baml::Ffi::LLMStreamCall",
|
|
72
|
+
baml_runtime::tracingv2::storage::storage::LLMStreamCall,
|
|
73
|
+
clone_safe
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
unsafe impl TryConvertOwned for &FunctionLog {}
|
|
77
|
+
|
|
78
|
+
impl Collector {
|
|
79
|
+
pub fn new(args: &[Value]) -> Result<Self> {
|
|
80
|
+
let args = scan_args::<(), (), (), (), _, ()>(args)?;
|
|
81
|
+
let kwargs = get_kwargs::<_, (), (Option<String>,), ()>(args.keywords, &[], &["name"])?;
|
|
82
|
+
|
|
83
|
+
let name = kwargs.optional.0;
|
|
84
|
+
let collector = baml_runtime::tracingv2::storage::storage::Collector::new(name);
|
|
85
|
+
Ok(Self {
|
|
86
|
+
inner: Arc::new(collector),
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
pub fn clear(&self) {
|
|
91
|
+
let _ = self.inner.clear();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
pub fn logs(&self) -> RArray {
|
|
95
|
+
let function_logs = self.inner.function_logs();
|
|
96
|
+
function_logs
|
|
97
|
+
.iter()
|
|
98
|
+
.map(|inner_function_log| FunctionLog {
|
|
99
|
+
inner: Arc::new(Mutex::new(inner_function_log.clone())),
|
|
100
|
+
})
|
|
101
|
+
.collect()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
pub fn last(&self) -> Option<FunctionLog> {
|
|
105
|
+
self.inner
|
|
106
|
+
.last_function_log()
|
|
107
|
+
.map(|inner_function_log| FunctionLog {
|
|
108
|
+
inner: Arc::new(Mutex::new(inner_function_log.clone())),
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
pub fn id(&self, function_log_id: String) -> Option<FunctionLog> {
|
|
113
|
+
self.inner
|
|
114
|
+
.function_log_by_id(&baml_ids::FunctionCallId::from_str(&function_log_id).ok()?)
|
|
115
|
+
.map(|inner_function_log| FunctionLog {
|
|
116
|
+
inner: Arc::new(Mutex::new(inner_function_log.clone())),
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
pub fn usage(&self) -> Usage {
|
|
121
|
+
Usage {
|
|
122
|
+
inner: self.inner.usage().into(),
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
pub fn to_s(&self) -> String {
|
|
127
|
+
let logs = self.inner.function_logs();
|
|
128
|
+
let log_ids: Vec<String> = logs.iter().map(|log| log.id().to_string()).collect();
|
|
129
|
+
format!(
|
|
130
|
+
"LogCollector(name={}, function_log_ids=[{}])",
|
|
131
|
+
self.inner.name(),
|
|
132
|
+
log_ids.join(", ")
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
pub fn __function_call_count() -> u32 {
|
|
137
|
+
let span_count = BAML_TRACER.lock().unwrap().function_call_count();
|
|
138
|
+
span_count as u32
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
pub fn __print_storage() {
|
|
142
|
+
let tracer = BAML_TRACER.lock().unwrap();
|
|
143
|
+
println!("Storage: {tracer:#?}");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
pub fn define_in_ruby(module: &RModule) -> Result<()> {
|
|
147
|
+
let cls = module.define_class("Collector", class::object())?;
|
|
148
|
+
|
|
149
|
+
cls.define_singleton_method("new", function!(Collector::new, -1))?;
|
|
150
|
+
cls.define_method("logs", method!(Collector::logs, 0))?;
|
|
151
|
+
cls.define_method("last", method!(Collector::last, 0))?;
|
|
152
|
+
cls.define_method("id", method!(Collector::id, 1))?;
|
|
153
|
+
cls.define_method("usage", method!(Collector::usage, 0))?;
|
|
154
|
+
cls.define_method("clear", method!(Collector::clear, 0))?;
|
|
155
|
+
cls.define_method("to_s", method!(Collector::to_s, 0))?;
|
|
156
|
+
cls.define_singleton_method(
|
|
157
|
+
"__function_call_count",
|
|
158
|
+
function!(Collector::__function_call_count, 0),
|
|
159
|
+
)?;
|
|
160
|
+
cls.define_singleton_method("__print_storage", function!(Collector::__print_storage, 0))?;
|
|
161
|
+
|
|
162
|
+
Ok(())
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
impl FunctionLog {
|
|
167
|
+
pub fn to_s(&self) -> String {
|
|
168
|
+
// Acquire the lock once and extract all needed data
|
|
169
|
+
let mut guard = self.inner.lock().unwrap();
|
|
170
|
+
let id = guard.id().to_string();
|
|
171
|
+
let function_name = guard.function_name();
|
|
172
|
+
let log_type = guard.log_type().to_string();
|
|
173
|
+
let timing_data = guard.timing().clone();
|
|
174
|
+
let usage_data = guard.usage().clone();
|
|
175
|
+
let calls_data = guard.calls();
|
|
176
|
+
let raw_llm_response = guard.raw_llm_response().unwrap_or("null".to_string());
|
|
177
|
+
// Release the lock by dropping the guard
|
|
178
|
+
drop(guard);
|
|
179
|
+
|
|
180
|
+
// Now process calls without holding the lock
|
|
181
|
+
let calls_str = calls_data
|
|
182
|
+
.into_iter()
|
|
183
|
+
.map(|call| match call {
|
|
184
|
+
baml_runtime::tracingv2::storage::storage::LLMCallKind::Basic(inner) => {
|
|
185
|
+
let llm_call = LLMCall {
|
|
186
|
+
inner: Arc::new(inner.clone()),
|
|
187
|
+
};
|
|
188
|
+
llm_call.to_s()
|
|
189
|
+
}
|
|
190
|
+
baml_runtime::tracingv2::storage::storage::LLMCallKind::Stream(inner) => {
|
|
191
|
+
let stream_call = LLMStreamCall {
|
|
192
|
+
inner: Arc::new(inner.clone()),
|
|
193
|
+
};
|
|
194
|
+
stream_call.to_s()
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
.collect::<Vec<_>>()
|
|
198
|
+
.join(", ");
|
|
199
|
+
|
|
200
|
+
// Create timing and usage objects from cloned data
|
|
201
|
+
let timing = Timing {
|
|
202
|
+
inner: timing_data.into(),
|
|
203
|
+
};
|
|
204
|
+
let usage = Usage {
|
|
205
|
+
inner: usage_data.into(),
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// Format the string with all the extracted data
|
|
209
|
+
format!(
|
|
210
|
+
"FunctionLog(id={}, function_name={}, type={}, timing={}, usage={}, calls=[{}], raw_llm_response={})",
|
|
211
|
+
id,
|
|
212
|
+
function_name,
|
|
213
|
+
log_type,
|
|
214
|
+
timing.to_s(),
|
|
215
|
+
usage.to_s(),
|
|
216
|
+
calls_str,
|
|
217
|
+
raw_llm_response
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
pub fn id(&self) -> String {
|
|
222
|
+
self.inner.lock().unwrap().id().to_string()
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
pub fn function_name(&self) -> String {
|
|
226
|
+
self.inner.lock().unwrap().function_name()
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
pub fn log_type(&self) -> String {
|
|
230
|
+
self.inner.lock().unwrap().log_type().to_string()
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
pub fn timing(&self) -> Timing {
|
|
234
|
+
Timing {
|
|
235
|
+
inner: self.inner.lock().unwrap().timing().into(),
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
pub fn usage(&self) -> Usage {
|
|
240
|
+
Usage {
|
|
241
|
+
inner: self.inner.lock().unwrap().usage().into(),
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
pub fn calls(&self) -> RArray {
|
|
246
|
+
let calls = self.inner.lock().unwrap().calls();
|
|
247
|
+
let array = RArray::new();
|
|
248
|
+
|
|
249
|
+
for call in calls {
|
|
250
|
+
match call {
|
|
251
|
+
baml_runtime::tracingv2::storage::storage::LLMCallKind::Basic(inner) => {
|
|
252
|
+
let llm_call = LLMCall {
|
|
253
|
+
inner: Arc::new(inner.clone()),
|
|
254
|
+
};
|
|
255
|
+
array.push(llm_call).unwrap();
|
|
256
|
+
}
|
|
257
|
+
baml_runtime::tracingv2::storage::storage::LLMCallKind::Stream(inner) => {
|
|
258
|
+
let stream_call = LLMStreamCall {
|
|
259
|
+
inner: Arc::new(inner.clone()),
|
|
260
|
+
};
|
|
261
|
+
array.push(stream_call).unwrap();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
array
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
pub fn raw_llm_response(&self) -> Option<String> {
|
|
270
|
+
self.inner.lock().unwrap().raw_llm_response()
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
pub fn selected_call(ruby: &Ruby, rb_self: &Self) -> Option<Value> {
|
|
274
|
+
let calls = rb_self.inner.lock().unwrap().calls();
|
|
275
|
+
calls.into_iter().find_map(|call| match call {
|
|
276
|
+
baml_runtime::tracingv2::storage::storage::LLMCallKind::Basic(inner) => {
|
|
277
|
+
if inner.selected {
|
|
278
|
+
Some(
|
|
279
|
+
LLMCall {
|
|
280
|
+
inner: Arc::new(inner.clone()),
|
|
281
|
+
}
|
|
282
|
+
.to_value(ruby)
|
|
283
|
+
.unwrap(),
|
|
284
|
+
)
|
|
285
|
+
} else {
|
|
286
|
+
None
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
baml_runtime::tracingv2::storage::storage::LLMCallKind::Stream(inner) => {
|
|
290
|
+
if inner.llm_call.selected {
|
|
291
|
+
let stream_call = LLMStreamCall {
|
|
292
|
+
inner: Arc::new(inner.clone()),
|
|
293
|
+
};
|
|
294
|
+
Some(stream_call.to_value(ruby).unwrap())
|
|
295
|
+
} else {
|
|
296
|
+
None
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
pub fn define_in_ruby(module: &RModule) -> Result<()> {
|
|
303
|
+
let cls = module.define_class("FunctionLog", class::object())?;
|
|
304
|
+
|
|
305
|
+
cls.define_method("to_s", method!(FunctionLog::to_s, 0))?;
|
|
306
|
+
cls.define_method("id", method!(FunctionLog::id, 0))?;
|
|
307
|
+
cls.define_method("function_name", method!(FunctionLog::function_name, 0))?;
|
|
308
|
+
cls.define_method("log_type", method!(FunctionLog::log_type, 0))?;
|
|
309
|
+
cls.define_method("timing", method!(FunctionLog::timing, 0))?;
|
|
310
|
+
cls.define_method("usage", method!(FunctionLog::usage, 0))?;
|
|
311
|
+
cls.define_method("calls", method!(FunctionLog::calls, 0))?;
|
|
312
|
+
cls.define_method(
|
|
313
|
+
"raw_llm_response",
|
|
314
|
+
method!(FunctionLog::raw_llm_response, 0),
|
|
315
|
+
)?;
|
|
316
|
+
cls.define_method("selected_call", method!(FunctionLog::selected_call, 0))?;
|
|
317
|
+
|
|
318
|
+
Ok(())
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
impl Timing {
|
|
323
|
+
pub fn to_s(&self) -> String {
|
|
324
|
+
format!(
|
|
325
|
+
"Timing(start_time_utc_ms={}, duration_ms={})",
|
|
326
|
+
self.inner.start_time_utc_ms,
|
|
327
|
+
self.inner
|
|
328
|
+
.duration_ms
|
|
329
|
+
.map_or("null".to_string(), |v| v.to_string())
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
pub fn start_time_utc_ms(&self) -> i64 {
|
|
334
|
+
self.inner.start_time_utc_ms
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
pub fn duration_ms(&self) -> Option<i64> {
|
|
338
|
+
self.inner.duration_ms
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
pub fn define_in_ruby(module: &RModule) -> Result<()> {
|
|
342
|
+
let cls = module.define_class("Timing", class::object())?;
|
|
343
|
+
|
|
344
|
+
cls.define_method("to_s", method!(Timing::to_s, 0))?;
|
|
345
|
+
cls.define_method("start_time_utc_ms", method!(Timing::start_time_utc_ms, 0))?;
|
|
346
|
+
cls.define_method("duration_ms", method!(Timing::duration_ms, 0))?;
|
|
347
|
+
|
|
348
|
+
Ok(())
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
pub fn into_value(self, ruby: &Ruby) -> crate::Result<Value> {
|
|
352
|
+
serde_magnus::serialize(&self.inner)
|
|
353
|
+
.map_err(|e| Error::new(ruby.exception_runtime_error(), format!("{e:?}")))
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
impl StreamTiming {
|
|
358
|
+
pub fn to_s(&self) -> String {
|
|
359
|
+
format!(
|
|
360
|
+
"StreamTiming(start_time_utc_ms={}, duration_ms={})",
|
|
361
|
+
self.inner.start_time_utc_ms,
|
|
362
|
+
self.inner
|
|
363
|
+
.duration_ms
|
|
364
|
+
.map_or("null".to_string(), |v| v.to_string())
|
|
365
|
+
)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
pub fn start_time_utc_ms(&self) -> i64 {
|
|
369
|
+
self.inner.start_time_utc_ms
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
pub fn duration_ms(&self) -> Option<i64> {
|
|
373
|
+
self.inner.duration_ms
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
pub fn define_in_ruby(module: &RModule) -> Result<()> {
|
|
377
|
+
let cls = module.define_class("StreamTiming", class::object())?;
|
|
378
|
+
|
|
379
|
+
cls.define_method("to_s", method!(StreamTiming::to_s, 0))?;
|
|
380
|
+
cls.define_method(
|
|
381
|
+
"start_time_utc_ms",
|
|
382
|
+
method!(StreamTiming::start_time_utc_ms, 0),
|
|
383
|
+
)?;
|
|
384
|
+
cls.define_method("duration_ms", method!(StreamTiming::duration_ms, 0))?;
|
|
385
|
+
|
|
386
|
+
Ok(())
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
impl Usage {
|
|
391
|
+
pub fn to_s(&self) -> String {
|
|
392
|
+
format!(
|
|
393
|
+
"Usage(input_tokens={}, output_tokens={}, cached_input_tokens={})",
|
|
394
|
+
self.inner
|
|
395
|
+
.input_tokens
|
|
396
|
+
.map_or_else(|| "null".to_string(), |v| v.to_string()),
|
|
397
|
+
self.inner
|
|
398
|
+
.output_tokens
|
|
399
|
+
.map_or_else(|| "null".to_string(), |v| v.to_string()),
|
|
400
|
+
self.inner
|
|
401
|
+
.cached_input_tokens
|
|
402
|
+
.map_or_else(|| "null".to_string(), |v| v.to_string())
|
|
403
|
+
)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
pub fn input_tokens(&self) -> Option<i64> {
|
|
407
|
+
self.inner.input_tokens
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
pub fn output_tokens(&self) -> Option<i64> {
|
|
411
|
+
self.inner.output_tokens
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
pub fn cached_input_tokens(&self) -> Option<i64> {
|
|
415
|
+
self.inner.cached_input_tokens
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
pub fn define_in_ruby(module: &RModule) -> Result<()> {
|
|
419
|
+
let cls = module.define_class("Usage", class::object())?;
|
|
420
|
+
|
|
421
|
+
cls.define_method("to_s", method!(Usage::to_s, 0))?;
|
|
422
|
+
cls.define_method("input_tokens", method!(Usage::input_tokens, 0))?;
|
|
423
|
+
cls.define_method("output_tokens", method!(Usage::output_tokens, 0))?;
|
|
424
|
+
cls.define_method(
|
|
425
|
+
"cached_input_tokens",
|
|
426
|
+
method!(Usage::cached_input_tokens, 0),
|
|
427
|
+
)?;
|
|
428
|
+
|
|
429
|
+
Ok(())
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
struct SerializationError {
|
|
434
|
+
position: Vec<String>,
|
|
435
|
+
message: String,
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
unsafe impl TryConvertOwned for &LLMCall {}
|
|
439
|
+
|
|
440
|
+
impl LLMCall {
|
|
441
|
+
pub fn selected(&self) -> bool {
|
|
442
|
+
self.inner.selected
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
pub fn http_request(&self) -> Option<HTTPRequest> {
|
|
446
|
+
self.inner
|
|
447
|
+
.request
|
|
448
|
+
.clone()
|
|
449
|
+
.map(|req| HTTPRequest { inner: req })
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
pub fn http_response(&self) -> Option<HTTPResponse> {
|
|
453
|
+
self.inner
|
|
454
|
+
.response
|
|
455
|
+
.clone()
|
|
456
|
+
.map(|resp| HTTPResponse { inner: resp })
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
pub fn usage(&self) -> Option<Usage> {
|
|
460
|
+
self.inner.usage.clone().map(|u| Usage { inner: u.into() })
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
pub fn timing(&self) -> Timing {
|
|
464
|
+
Timing {
|
|
465
|
+
inner: self.inner.timing.clone().into(),
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
pub fn provider(&self) -> String {
|
|
470
|
+
self.inner.provider.clone()
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
pub fn client_name(&self) -> String {
|
|
474
|
+
self.inner.client_name.clone()
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
pub fn to_s(&self) -> String {
|
|
478
|
+
format!(
|
|
479
|
+
"LLMCall(provider={}, client_name={}, selected={}, usage={}, timing={:?}, http_request={}, http_response={})",
|
|
480
|
+
self.inner.provider,
|
|
481
|
+
self.inner.client_name,
|
|
482
|
+
self.inner.selected,
|
|
483
|
+
self.inner.usage.as_ref().map_or("null".to_string(), |u| format!("{u:?}")),
|
|
484
|
+
self.inner.timing,
|
|
485
|
+
self.inner.request.as_ref().map_or("null".to_string(), |req| format!("{req:?}")),
|
|
486
|
+
self.inner.response.as_ref().map_or("null".to_string(), |resp| format!("{resp:?}"))
|
|
487
|
+
)
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
pub fn to_value(&self, ruby: &Ruby) -> crate::Result<Value> {
|
|
491
|
+
serde_magnus::serialize(&self.inner)
|
|
492
|
+
.map_err(|e| Error::new(ruby.exception_runtime_error(), format!("{e:?}")))
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
pub fn define_in_ruby(module: &RModule) -> Result<()> {
|
|
496
|
+
let cls = module.define_class("LLMCall", class::object())?;
|
|
497
|
+
|
|
498
|
+
cls.define_method("selected", method!(LLMCall::selected, 0))?;
|
|
499
|
+
cls.define_method("http_request", method!(LLMCall::http_request, 0))?;
|
|
500
|
+
cls.define_method("http_response", method!(LLMCall::http_response, 0))?;
|
|
501
|
+
cls.define_method("usage", method!(LLMCall::usage, 0))?;
|
|
502
|
+
cls.define_method("timing", method!(LLMCall::timing, 0))?;
|
|
503
|
+
cls.define_method("provider", method!(LLMCall::provider, 0))?;
|
|
504
|
+
cls.define_method("client_name", method!(LLMCall::client_name, 0))?;
|
|
505
|
+
cls.define_method("to_s", method!(LLMCall::to_s, 0))?;
|
|
506
|
+
|
|
507
|
+
Ok(())
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// TODO: remove?
|
|
512
|
+
unsafe impl TryConvertOwned for &LLMStreamCall {}
|
|
513
|
+
|
|
514
|
+
impl LLMStreamCall {
|
|
515
|
+
pub fn to_s(&self) -> String {
|
|
516
|
+
format!(
|
|
517
|
+
"LLMStreamCall(provider={}, client_name={}, selected={}, usage={}, timing={:?}, http_request={}, http_response={})",
|
|
518
|
+
self.inner.llm_call.provider,
|
|
519
|
+
self.inner.llm_call.client_name,
|
|
520
|
+
self.inner.llm_call.selected,
|
|
521
|
+
self.inner.llm_call.usage.as_ref().map_or("null".to_string(), |u| format!("{u:?}")),
|
|
522
|
+
self.inner.timing,
|
|
523
|
+
self.inner.llm_call.request.as_ref().map_or("null".to_string(), |req| format!("{req:?}")),
|
|
524
|
+
self.inner.llm_call.response.as_ref().map_or("null".to_string(), |resp| format!("{resp:?}"))
|
|
525
|
+
)
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
pub fn http_request(&self) -> Option<HTTPRequest> {
|
|
529
|
+
self.inner
|
|
530
|
+
.llm_call
|
|
531
|
+
.request
|
|
532
|
+
.clone()
|
|
533
|
+
.map(|req| HTTPRequest { inner: req })
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
pub fn http_response(&self) -> Option<HTTPResponse> {
|
|
537
|
+
self.inner
|
|
538
|
+
.llm_call
|
|
539
|
+
.response
|
|
540
|
+
.clone()
|
|
541
|
+
.map(|resp| HTTPResponse {
|
|
542
|
+
inner: resp.clone(),
|
|
543
|
+
})
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
pub fn provider(&self) -> String {
|
|
547
|
+
self.inner.llm_call.provider.clone()
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
pub fn client_name(&self) -> String {
|
|
551
|
+
self.inner.llm_call.client_name.clone()
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
pub fn selected(&self) -> bool {
|
|
555
|
+
self.inner.llm_call.selected
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
pub fn usage(&self) -> Option<Usage> {
|
|
559
|
+
self.inner
|
|
560
|
+
.llm_call
|
|
561
|
+
.usage
|
|
562
|
+
.clone()
|
|
563
|
+
.map(|u| Usage { inner: u.into() })
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
pub fn timing(&self) -> StreamTiming {
|
|
567
|
+
StreamTiming {
|
|
568
|
+
inner: self.inner.timing.clone().into(),
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
pub fn to_value(&self, ruby: &Ruby) -> crate::Result<Value> {
|
|
573
|
+
// Serialize to Ruby value - handle errors gracefully
|
|
574
|
+
serde_magnus::serialize(&self.inner)
|
|
575
|
+
.map_err(|e| Error::new(ruby.exception_runtime_error(), format!("{e:?}")))
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
pub fn define_in_ruby(module: &RModule) -> Result<()> {
|
|
579
|
+
let cls = module.define_class("LLMStreamCall", class::object())?;
|
|
580
|
+
|
|
581
|
+
cls.define_method("to_s", method!(LLMStreamCall::to_s, 0))?;
|
|
582
|
+
cls.define_method("http_request", method!(LLMStreamCall::http_request, 0))?;
|
|
583
|
+
cls.define_method("http_response", method!(LLMStreamCall::http_response, 0))?;
|
|
584
|
+
cls.define_method("provider", method!(LLMStreamCall::provider, 0))?;
|
|
585
|
+
cls.define_method("client_name", method!(LLMStreamCall::client_name, 0))?;
|
|
586
|
+
cls.define_method("selected", method!(LLMStreamCall::selected, 0))?;
|
|
587
|
+
cls.define_method("usage", method!(LLMStreamCall::usage, 0))?;
|
|
588
|
+
cls.define_method("timing", method!(LLMStreamCall::timing, 0))?;
|
|
589
|
+
|
|
590
|
+
Ok(())
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
pub fn define_all_in_ruby(module: &RModule) -> Result<()> {
|
|
595
|
+
Collector::define_in_ruby(module)?;
|
|
596
|
+
FunctionLog::define_in_ruby(module)?;
|
|
597
|
+
Timing::define_in_ruby(module)?;
|
|
598
|
+
StreamTiming::define_in_ruby(module)?;
|
|
599
|
+
Usage::define_in_ruby(module)?;
|
|
600
|
+
LLMCall::define_in_ruby(module)?;
|
|
601
|
+
LLMStreamCall::define_in_ruby(module)?;
|
|
602
|
+
HTTPRequest::define_in_ruby(module)?;
|
|
603
|
+
HTTPResponse::define_in_ruby(module)?;
|
|
604
|
+
HTTPBody::define_in_ruby(module)?;
|
|
605
|
+
|
|
606
|
+
Ok(())
|
|
607
|
+
}
|