Skip to content

Commit 650c3fd

Browse files
committed
clean up
1 parent c320ca6 commit 650c3fd

4 files changed

Lines changed: 27 additions & 60 deletions

File tree

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ def _start(self, invocation: _T) -> _T:
168168
span_name = _get_embedding_span_name(invocation)
169169
elif isinstance(invocation, AgentInvocation):
170170
span_name = _get_agent_span_name(invocation)
171+
kind = invocation.span_kind
171172
else:
172173
span_name = ""
173174
span = self._tracer.start_span(
@@ -315,21 +316,6 @@ def embedding(
315316
raise
316317
self.stop(invocation)
317318

318-
# Agent-specific convenience methods
319-
def start_agent(self, invocation: AgentInvocation) -> AgentInvocation:
320-
"""Start an agent invocation and create a pending span entry."""
321-
return self._start(invocation)
322-
323-
def stop_agent(self, invocation: AgentInvocation) -> AgentInvocation:
324-
"""Finalize an agent invocation successfully and end its span."""
325-
return self._stop(invocation)
326-
327-
def fail_agent(
328-
self, invocation: AgentInvocation, error: Error
329-
) -> AgentInvocation:
330-
"""Fail an agent invocation and end its span with error status."""
331-
return self._fail(invocation, error)
332-
333319
@contextmanager
334320
def agent(
335321
self, invocation: AgentInvocation | None = None

util/opentelemetry-util-genai/src/opentelemetry/util/genai/span_utils.py

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@
4949
should_emit_event,
5050
)
5151

52+
# Constants for semconv attributes not yet available in opentelemetry-semantic-conventions 0.60b0
53+
GEN_AI_AGENT_VERSION = "gen_ai.agent.version"
54+
GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS = (
55+
"gen_ai.usage.cache_creation.input_tokens"
56+
)
57+
GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS = "gen_ai.usage.cache_read.input_tokens"
58+
5259

5360
def _get_llm_common_attributes(
5461
invocation: LLMInvocation,
@@ -109,32 +116,6 @@ def _get_embedding_span_name(invocation: EmbeddingInvocation) -> str:
109116
return _get_span_name(invocation)
110117

111118

112-
def _get_system_instructions_for_span(
113-
system_instruction: list[MessagePart] | None = None,
114-
) -> dict[str, Any]:
115-
"""Get system instructions attribute formatted for span (JSON string format).
116-
117-
Can be used with agent/llm/tool invocations.
118-
Returns empty dict if not in experimental mode or content capturing is disabled.
119-
"""
120-
if (
121-
not is_experimental_mode()
122-
or get_content_capturing_mode()
123-
not in (
124-
ContentCapturingMode.SPAN_ONLY,
125-
ContentCapturingMode.SPAN_AND_EVENT,
126-
)
127-
or not system_instruction
128-
):
129-
return {}
130-
131-
return {
132-
GenAI.GEN_AI_SYSTEM_INSTRUCTIONS: gen_ai_json_dumps(
133-
[asdict(p) for p in system_instruction]
134-
)
135-
}
136-
137-
138119
def _get_llm_messages_attributes_for_span(
139120
input_messages: list[InputMessage],
140121
output_messages: list[OutputMessage],
@@ -405,7 +386,7 @@ def _get_agent_common_attributes(
405386
(GenAI.GEN_AI_AGENT_NAME, invocation.agent_name),
406387
(GenAI.GEN_AI_AGENT_ID, invocation.agent_id),
407388
(GenAI.GEN_AI_AGENT_DESCRIPTION, invocation.agent_description),
408-
("gen_ai.agent.version", invocation.agent_version),
389+
(GEN_AI_AGENT_VERSION, invocation.agent_version),
409390
(GenAI.GEN_AI_CONVERSATION_ID, invocation.conversation_id),
410391
(GenAI.GEN_AI_DATA_SOURCE_ID, invocation.data_source_id),
411392
(GenAI.GEN_AI_OUTPUT_TYPE, invocation.output_type),
@@ -468,11 +449,11 @@ def _get_agent_response_attributes(
468449
(GenAI.GEN_AI_USAGE_INPUT_TOKENS, invocation.input_tokens),
469450
(GenAI.GEN_AI_USAGE_OUTPUT_TOKENS, invocation.output_tokens),
470451
(
471-
"gen_ai.usage.cache_creation_input_tokens",
452+
GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS,
472453
invocation.cache_creation_input_tokens,
473454
),
474455
(
475-
"gen_ai.usage.cache_read_input_tokens",
456+
GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS,
476457
invocation.cache_read_input_tokens,
477458
),
478459
)
@@ -519,7 +500,6 @@ def _apply_agent_finish_attributes(
519500
"_get_embedding_span_name",
520501
"_get_agent_span_name",
521502
"_apply_agent_finish_attributes",
522-
"_get_system_instructions_for_span",
523503
"_get_agent_common_attributes",
524504
"_get_agent_request_attributes",
525505
"_get_agent_response_attributes",

util/opentelemetry-util-genai/src/opentelemetry/util/genai/types.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from opentelemetry.semconv._incubating.attributes import (
2626
gen_ai_attributes as GenAI,
2727
)
28-
from opentelemetry.trace import Span
28+
from opentelemetry.trace import Span, SpanKind
2929

3030
ContextToken: TypeAlias = Token[Context]
3131

@@ -343,6 +343,7 @@ class AgentInvocation(_BaseAgent):
343343
"""
344344

345345
operation_name: str = GenAI.GenAiOperationNameValues.INVOKE_AGENT.value
346+
span_kind: SpanKind = SpanKind.CLIENT
346347
conversation_id: str | None = None
347348
data_source_id: str | None = None
348349
output_type: str | None = None

util/opentelemetry-util-genai/tests/test_handler_agent.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ def test_start_stop_creates_span(self) -> None:
4545
provider="openai",
4646
request_model="gpt-4",
4747
)
48-
handler.start_agent(invocation)
49-
handler.stop_agent(invocation)
48+
handler.start(invocation)
49+
handler.stop(invocation)
5050

5151
spans = self.span_exporter.get_finished_spans()
5252
self.assertEqual(len(spans), 1)
@@ -64,8 +64,8 @@ def test_start_stop_creates_span(self) -> None:
6464
def test_span_kind_client_by_default(self) -> None:
6565
handler = self._make_handler()
6666
invocation = AgentInvocation(agent_name="Agent", provider="openai")
67-
handler.start_agent(invocation)
68-
handler.stop_agent(invocation)
67+
handler.start(invocation)
68+
handler.stop(invocation)
6969
self.assertEqual(
7070
self.span_exporter.get_finished_spans()[0].kind, SpanKind.CLIENT
7171
)
@@ -89,13 +89,13 @@ def test_all_attributes(self) -> None:
8989
server_address="api.openai.com",
9090
server_port=443,
9191
)
92-
handler.start_agent(invocation)
92+
handler.start(invocation)
9393
invocation.response_model_name = "gpt-4-0613"
9494
invocation.response_id = "resp-abc"
9595
invocation.input_tokens = 100
9696
invocation.output_tokens = 200
9797
invocation.finish_reasons = ["stop"]
98-
handler.stop_agent(invocation)
98+
handler.stop(invocation)
9999

100100
attrs = self.span_exporter.get_finished_spans()[0].attributes
101101
self.assertEqual(attrs[GenAI.GEN_AI_AGENT_NAME], "Full Agent")
@@ -115,22 +115,22 @@ def test_cache_token_attributes(self) -> None:
115115
invocation = AgentInvocation(
116116
agent_name="Cache Agent", provider="openai"
117117
)
118-
handler.start_agent(invocation)
118+
handler.start(invocation)
119119
invocation.input_tokens = 100
120120
invocation.cache_creation_input_tokens = 25
121121
invocation.cache_read_input_tokens = 50
122-
handler.stop_agent(invocation)
122+
handler.stop(invocation)
123123

124124
attrs = self.span_exporter.get_finished_spans()[0].attributes
125125
self.assertEqual(attrs[GenAI.GEN_AI_USAGE_INPUT_TOKENS], 100)
126-
self.assertEqual(attrs["gen_ai.usage.cache_creation_input_tokens"], 25)
127-
self.assertEqual(attrs["gen_ai.usage.cache_read_input_tokens"], 50)
126+
self.assertEqual(attrs["gen_ai.usage.cache_creation.input_tokens"], 25)
127+
self.assertEqual(attrs["gen_ai.usage.cache_read.input_tokens"], 50)
128128

129129
def test_fail_sets_error_status(self) -> None:
130130
handler = self._make_handler()
131131
invocation = AgentInvocation(agent_name="Agent", provider="openai")
132-
handler.start_agent(invocation)
133-
handler.fail_agent(
132+
handler.start(invocation)
133+
handler.fail(
134134
invocation, Error(message="agent crashed", type=RuntimeError)
135135
)
136136

@@ -177,14 +177,14 @@ def test_context_manager_default_invocation(self) -> None:
177177
def test_stop_without_start_is_noop(self) -> None:
178178
handler = self._make_handler()
179179
invocation = AgentInvocation(agent_name="Not Started")
180-
result = handler.stop_agent(invocation)
180+
result = handler.stop(invocation)
181181
self.assertIs(result, invocation)
182182
self.assertEqual(len(self.span_exporter.get_finished_spans()), 0)
183183

184184
def test_fail_without_start_is_noop(self) -> None:
185185
handler = self._make_handler()
186186
invocation = AgentInvocation(agent_name="Not Started")
187-
result = handler.fail_agent(
187+
result = handler.fail(
188188
invocation, Error(message="boom", type=RuntimeError)
189189
)
190190
self.assertIs(result, invocation)

0 commit comments

Comments
 (0)