telemetry-dev 0.2.5__tar.gz → 0.2.6__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: telemetry-dev
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: telemetry.dev SDK for Python — OpenTelemetry-native GenAI tracing, logs, and metrics
5
5
  Keywords: telemetry,opentelemetry,llm,genai,tracing,observability
6
6
  Author: telemetry.dev
@@ -135,9 +135,12 @@ the core SDK with provider integrations to enable the new metric.
135
135
  ### Span fields (start/update/end)
136
136
 
137
137
  `input`, `output`, `model`, `provider`, `system_instructions`, `response_model`, `response_id`,
138
- `output_type`, `finish_reason`, `usage` (dict with exactly `input_tokens`, `output_tokens`,
138
+ `output_type`, `finish_reason`, `usage` (dict with `input_tokens`, `output_tokens`,
139
139
  `total_tokens`, `cache_read_input_tokens`, `cache_creation_input_tokens`,
140
- `reasoning_output_tokens`), `cost_usd`, `temperature`, `top_p`, `top_k`, `max_tokens`,
140
+ `reasoning_output_tokens`, `text_input_tokens`, `text_output_tokens`, `image_input_tokens`,
141
+ `image_output_tokens`, `audio_input_tokens`, `audio_output_tokens`,
142
+ `text_cache_read_input_tokens`, `image_cache_read_input_tokens`, and
143
+ `audio_cache_read_input_tokens`), `cost_usd`, `temperature`, `top_p`, `top_k`, `max_tokens`,
141
144
  `stop_sequences`, `seed`, `frequency_penalty`, `presence_penalty`, `time_to_first_chunk_ms`,
142
145
  `tool_name`, `tool_call_id`, `tool_description`, `agent_name`, `agent_id`, `metadata`
143
146
  (→ `td.metadata.*`, this span only), `attributes` (raw escape hatch, merged last), `error`.
@@ -111,9 +111,12 @@ the core SDK with provider integrations to enable the new metric.
111
111
  ### Span fields (start/update/end)
112
112
 
113
113
  `input`, `output`, `model`, `provider`, `system_instructions`, `response_model`, `response_id`,
114
- `output_type`, `finish_reason`, `usage` (dict with exactly `input_tokens`, `output_tokens`,
114
+ `output_type`, `finish_reason`, `usage` (dict with `input_tokens`, `output_tokens`,
115
115
  `total_tokens`, `cache_read_input_tokens`, `cache_creation_input_tokens`,
116
- `reasoning_output_tokens`), `cost_usd`, `temperature`, `top_p`, `top_k`, `max_tokens`,
116
+ `reasoning_output_tokens`, `text_input_tokens`, `text_output_tokens`, `image_input_tokens`,
117
+ `image_output_tokens`, `audio_input_tokens`, `audio_output_tokens`,
118
+ `text_cache_read_input_tokens`, `image_cache_read_input_tokens`, and
119
+ `audio_cache_read_input_tokens`), `cost_usd`, `temperature`, `top_p`, `top_k`, `max_tokens`,
117
120
  `stop_sequences`, `seed`, `frequency_penalty`, `presence_penalty`, `time_to_first_chunk_ms`,
118
121
  `tool_name`, `tool_call_id`, `tool_description`, `agent_name`, `agent_id`, `metadata`
119
122
  (→ `td.metadata.*`, this span only), `attributes` (raw escape hatch, merged last), `error`.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "telemetry-dev"
3
- version = "0.2.5"
3
+ version = "0.2.6"
4
4
  description = "telemetry.dev SDK for Python — OpenTelemetry-native GenAI tracing, logs, and metrics"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "telemetry-dev"
3
- version = "0.2.5"
3
+ version = "0.2.6"
4
4
  description = "telemetry.dev SDK for Python — OpenTelemetry-native GenAI tracing, logs, and metrics"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -122,31 +122,34 @@ class CaptureBudget:
122
122
  if value_id in seen:
123
123
  return byte_count, item_count
124
124
  seen.add(value_id)
125
- mapping: dict[object, object] | None = None
126
- children: Iterable[object] = ()
127
- if isinstance(value, dict):
128
- mapping = cast("dict[object, object]", value)
129
- elif isinstance(value, list | tuple | set | frozenset):
130
- children = cast("Iterable[object]", value)
131
- else:
132
- attributes = getattr(value, "__dict__", None)
133
- if isinstance(attributes, dict):
134
- mapping = cast("dict[object, object]", attributes)
135
-
136
- if mapping is not None:
137
- children = chain.from_iterable(mapping.items())
138
-
139
- for child in children:
140
- measured = cls._measure(
141
- child,
142
- remaining_bytes=remaining_bytes - byte_count,
143
- remaining_items=remaining_items - item_count,
144
- depth=depth + 1,
145
- seen=seen,
146
- )
147
- if measured is None:
148
- return None
149
- child_bytes, child_items = measured
150
- byte_count += child_bytes
151
- item_count += child_items
152
- return byte_count, item_count
125
+ try:
126
+ mapping: dict[object, object] | None = None
127
+ children: Iterable[object] = ()
128
+ if isinstance(value, dict):
129
+ mapping = cast("dict[object, object]", value)
130
+ elif isinstance(value, list | tuple | set | frozenset):
131
+ children = cast("Iterable[object]", value)
132
+ else:
133
+ attributes = getattr(value, "__dict__", None)
134
+ if isinstance(attributes, dict):
135
+ mapping = cast("dict[object, object]", attributes)
136
+
137
+ if mapping is not None:
138
+ children = chain.from_iterable(mapping.items())
139
+
140
+ for child in children:
141
+ measured = cls._measure(
142
+ child,
143
+ remaining_bytes=remaining_bytes - byte_count,
144
+ remaining_items=remaining_items - item_count,
145
+ depth=depth + 1,
146
+ seen=seen,
147
+ )
148
+ if measured is None:
149
+ return None
150
+ child_bytes, child_items = measured
151
+ byte_count += child_bytes
152
+ item_count += child_items
153
+ return byte_count, item_count
154
+ finally:
155
+ seen.remove(value_id)
@@ -91,6 +91,15 @@ USAGE_ATTRS: dict[str, str] = {
91
91
  "cache_read_input_tokens": "gen_ai.usage.cache_read.input_tokens",
92
92
  "cache_creation_input_tokens": "gen_ai.usage.cache_creation.input_tokens",
93
93
  "reasoning_output_tokens": "gen_ai.usage.reasoning.output_tokens",
94
+ "text_input_tokens": "gen_ai.usage.text.input_tokens",
95
+ "text_output_tokens": "gen_ai.usage.text.output_tokens",
96
+ "text_cache_read_input_tokens": "gen_ai.usage.text.cache_read.input_tokens",
97
+ "image_input_tokens": "gen_ai.usage.image.input_tokens",
98
+ "image_output_tokens": "gen_ai.usage.image.output_tokens",
99
+ "image_cache_read_input_tokens": "gen_ai.usage.image.cache_read.input_tokens",
100
+ "audio_input_tokens": "gen_ai.usage.audio.input_tokens",
101
+ "audio_output_tokens": "gen_ai.usage.audio.output_tokens",
102
+ "audio_cache_read_input_tokens": "gen_ai.usage.audio.cache_read.input_tokens",
94
103
  }
95
104
 
96
105
  SAMPLING_ATTRS: dict[str, str] = {
@@ -72,7 +72,7 @@ NOT_GIVEN: Any = _NotGiven()
72
72
 
73
73
 
74
74
  class Usage(TypedDict, total=False):
75
- """Token usage — exactly these six fields are emitted; unknown keys are dropped."""
75
+ """Token usage; unknown keys are dropped."""
76
76
 
77
77
  input_tokens: int
78
78
  output_tokens: int
@@ -80,6 +80,15 @@ class Usage(TypedDict, total=False):
80
80
  cache_read_input_tokens: int
81
81
  cache_creation_input_tokens: int
82
82
  reasoning_output_tokens: int
83
+ text_input_tokens: int
84
+ text_output_tokens: int
85
+ text_cache_read_input_tokens: int
86
+ image_input_tokens: int
87
+ image_output_tokens: int
88
+ image_cache_read_input_tokens: int
89
+ audio_input_tokens: int
90
+ audio_output_tokens: int
91
+ audio_cache_read_input_tokens: int
83
92
 
84
93
 
85
94
  ParentType = str | Context | SpanContext | None
File without changes