@@ -45,11 +45,29 @@ pub(crate) fn encode_path_segment(segment: &str) -> String {
4545 utf8_percent_encode ( segment, PATH_SEGMENT_ENCODE_SET ) . to_string ( )
4646}
4747
48+ /// OpenTelemetry and OpenInference semantic conventions for the provider.
49+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
50+ pub struct ProviderSemanticConventions {
51+ pub gen_ai_provider_name : & ' static str ,
52+ pub llm_system : & ' static str ,
53+ pub llm_provider : Option < & ' static str > ,
54+ }
55+
4856/// Provider metadata with no data transformation logic.
4957pub trait ProviderMeta : Send + Sync + ' static {
5058 fn name ( & self ) -> & ' static str ;
5159 fn default_base_url ( & self ) -> & ' static str ;
5260
61+ /// Get the provider's semantic conventions.
62+ /// Used for OpenTelemetry and OpenInference semantic conventions.
63+ fn semantic_conventions ( & self ) -> ProviderSemanticConventions {
64+ ProviderSemanticConventions {
65+ gen_ai_provider_name : self . name ( ) ,
66+ llm_system : self . name ( ) ,
67+ llm_provider : None ,
68+ }
69+ }
70+
5371 /// Chat endpoint path for the provider. Implementations may use `model`
5472 /// for providers whose route shape depends on the model name.
5573 fn chat_endpoint_path ( & self , _model : & str ) -> Cow < ' static , str > {
@@ -306,7 +324,10 @@ mod tests {
306324 use http:: HeaderMap ;
307325 use serde_json:: json;
308326
309- use super :: { ChatTransform , CompatQuirks , EmbedTransform , ProviderMeta , StreamReaderKind } ;
327+ use super :: {
328+ ChatTransform , CompatQuirks , EmbedTransform , ProviderMeta , ProviderSemanticConventions ,
329+ StreamReaderKind ,
330+ } ;
310331 use crate :: gateway:: {
311332 provider_instance:: ProviderAuth ,
312333 traits:: chat_format:: ChatStreamState ,
@@ -421,6 +442,20 @@ mod tests {
421442 assert_eq ! ( body[ "stream_options" ] [ "include_usage" ] , true ) ;
422443 }
423444
445+ #[ test]
446+ fn provider_meta_uses_name_based_default_semantic_conventions ( ) {
447+ let provider = DummyProvider ;
448+
449+ assert_eq ! (
450+ provider. semantic_conventions( ) ,
451+ ProviderSemanticConventions {
452+ gen_ai_provider_name: "dummy" ,
453+ llm_system: "dummy" ,
454+ llm_provider: None ,
455+ }
456+ ) ;
457+ }
458+
424459 #[ test]
425460 fn apply_to_request_skips_stream_usage_for_non_streaming_requests ( ) {
426461 let quirks = CompatQuirks {
0 commit comments