next_web_ai/chat/observation/
default_chat_model_observation_convention.rs1use crate::{
2 chat::observation::{
3 chat_model_observation_context::ChatModelObservationContext,
4 chat_model_observation_convention::ChatModelObservationConvention,
5 observation_convention::ObservationConvention,
6 },
7 util::key_value::{KeyValue, NoneKeyValue, NONE_VALUE},
8};
9
10use super::chat_model_observation_documentation::{ChatModelObservationDocumentation, LowNames};
11
12const DEFAULT_NAME: &str = "gen_ai.client.operation";
13
14#[derive(Clone)]
15pub struct DefaultChatModelObservationConvention {
16 request_model_none: Box<dyn KeyValue>,
17 response_model_name: Box<dyn KeyValue>,
18}
19
20impl ChatModelObservationConvention for DefaultChatModelObservationConvention {
21 fn name(&self) -> &str {
22 DEFAULT_NAME
23 }
24
25 fn contextual_name(&self, context: &ChatModelObservationContext) -> Option<String> {
26 let model = context.request().chat_options().get_model();
27 if model.is_empty() {
28 return Some(format!("{:?} {}", context.operation_metadata(), model));
29 }
30 return Some(context.operation_metadata().operation_type.clone());
31 }
32}
33
34impl<T> ObservationConvention<T> for DefaultChatModelObservationConvention {
35 fn supports_context(&self, context: &dyn crate::observation::observation::Context) -> bool {
36 true
37 }
38}
39
40impl Default for DefaultChatModelObservationConvention {
41 fn default() -> Self {
42 Self {
43 request_model_none: Box::new(NoneKeyValue::of_immutable(
44 ChatModelObservationDocumentation::LowCardinalityKeyNames(LowNames::RequestModel)
45 .value(),
46 NONE_VALUE,
47 )),
48 response_model_name: Box::new(NoneKeyValue::of_immutable(
49 ChatModelObservationDocumentation::LowCardinalityKeyNames(LowNames::ResponseModel)
50 .value(),
51 NONE_VALUE,
52 )),
53 }
54 }
55}