microsoft-agents-a365-observability-core 0.2.1.dev33__tar.gz → 0.2.1.dev36__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.
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/PKG-INFO +1 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/__init__.py +7 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/agent_details.py +4 -6
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/config.py +39 -12
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/constants.py +39 -39
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/execute_tool_scope.py +25 -10
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/__init__.py +2 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/agent365_exporter.py +0 -20
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/enriched_span.py +10 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/enriching_span_processor.py +30 -0
- microsoft_agents_a365_observability_core-0.2.1.dev36/microsoft_agents_a365/observability/core/exporters/spectra_exporter_options.py +56 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_call_details.py +13 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_scope.py +19 -14
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/invoke_agent_scope.py +22 -22
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/middleware/baggage_builder.py +11 -63
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/caller_details.py +2 -5
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/opentelemetry_scope.py +36 -21
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/span_processor.py +1 -10
- microsoft_agents_a365_observability_core-0.2.1.dev36/microsoft_agents_a365/observability/core/trace_processor/util.py +43 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/utils.py +13 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/PKG-INFO +1 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/SOURCES.txt +1 -0
- microsoft_agents_a365_observability_core-0.2.1.dev33/microsoft_agents_a365/observability/core/trace_processor/util.py +0 -50
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/README.md +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/execution_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/agent365_exporter_options.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/utils.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_operation_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/invoke_agent_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/middleware/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/agent_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/operation_source.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/response.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/request.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/source_metadata.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/spans_scopes/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/spans_scopes/output_scope.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tenant_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tool_call_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tool_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/dependency_links.txt +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/requires.txt +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/top_level.txt +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/pyproject.toml +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/setup.cfg +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev33 → microsoft_agents_a365_observability_core-0.2.1.dev36}/setup.py +0 -0
|
@@ -12,13 +12,15 @@ from .config import (
|
|
|
12
12
|
)
|
|
13
13
|
from .execute_tool_scope import ExecuteToolScope
|
|
14
14
|
from .execution_type import ExecutionType
|
|
15
|
+
from .exporters.agent365_exporter_options import Agent365ExporterOptions
|
|
15
16
|
from .exporters.enriched_span import EnrichedReadableSpan
|
|
16
17
|
from .exporters.enriching_span_processor import (
|
|
17
18
|
get_span_enricher,
|
|
18
19
|
register_span_enricher,
|
|
19
20
|
unregister_span_enricher,
|
|
20
21
|
)
|
|
21
|
-
from .
|
|
22
|
+
from .exporters.spectra_exporter_options import SpectraExporterOptions
|
|
23
|
+
from .inference_call_details import InferenceCallDetails, ServiceEndpoint
|
|
22
24
|
from .inference_operation_type import InferenceOperationType
|
|
23
25
|
from .inference_scope import InferenceScope
|
|
24
26
|
from .invoke_agent_details import InvokeAgentDetails
|
|
@@ -38,6 +40,9 @@ __all__ = [
|
|
|
38
40
|
"is_configured",
|
|
39
41
|
"get_tracer",
|
|
40
42
|
"get_tracer_provider",
|
|
43
|
+
# Exporter options
|
|
44
|
+
"Agent365ExporterOptions",
|
|
45
|
+
"SpectraExporterOptions",
|
|
41
46
|
# Span enrichment
|
|
42
47
|
"register_span_enricher",
|
|
43
48
|
"unregister_span_enricher",
|
|
@@ -61,6 +66,7 @@ __all__ = [
|
|
|
61
66
|
"SourceMetadata",
|
|
62
67
|
"Request",
|
|
63
68
|
"InferenceCallDetails",
|
|
69
|
+
"ServiceEndpoint",
|
|
64
70
|
# Enums
|
|
65
71
|
"ExecutionType",
|
|
66
72
|
"InferenceOperationType",
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from typing import Optional
|
|
6
6
|
|
|
7
|
-
from .models.agent_type import AgentType
|
|
8
|
-
|
|
9
7
|
|
|
10
8
|
@dataclass
|
|
11
9
|
class AgentDetails:
|
|
@@ -29,8 +27,8 @@ class AgentDetails:
|
|
|
29
27
|
agent_blueprint_id: Optional[str] = None
|
|
30
28
|
"""Blueprint/Application ID for the agent."""
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
"""
|
|
30
|
+
agent_platform_id: Optional[str] = None
|
|
31
|
+
"""Platform ID for the agent."""
|
|
34
32
|
|
|
35
33
|
tenant_id: Optional[str] = None
|
|
36
34
|
"""Tenant ID for the agent."""
|
|
@@ -41,5 +39,5 @@ class AgentDetails:
|
|
|
41
39
|
icon_uri: Optional[str] = None
|
|
42
40
|
"""Optional icon URI for the agent."""
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
"""
|
|
42
|
+
provider_name: Optional[str] = None
|
|
43
|
+
"""The provider name (e.g., openai, anthropic)."""
|
|
@@ -8,6 +8,9 @@ from collections.abc import Callable
|
|
|
8
8
|
from typing import Any, Optional
|
|
9
9
|
|
|
10
10
|
from opentelemetry import trace
|
|
11
|
+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
|
|
12
|
+
OTLPSpanExporter as GrpcOTLPSpanExporter,
|
|
13
|
+
)
|
|
11
14
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
12
15
|
from opentelemetry.sdk.resources import SERVICE_NAME, SERVICE_NAMESPACE, Resource
|
|
13
16
|
from opentelemetry.sdk.trace import TracerProvider
|
|
@@ -18,6 +21,7 @@ from .exporters.agent365_exporter_options import Agent365ExporterOptions
|
|
|
18
21
|
from .exporters.enriching_span_processor import (
|
|
19
22
|
_EnrichingBatchSpanProcessor,
|
|
20
23
|
)
|
|
24
|
+
from .exporters.spectra_exporter_options import SpectraExporterOptions
|
|
21
25
|
from .exporters.utils import is_agent365_exporter_enabled
|
|
22
26
|
from .trace_processor.span_processor import SpanProcessor
|
|
23
27
|
|
|
@@ -58,7 +62,7 @@ class TelemetryManager:
|
|
|
58
62
|
logger_name: str = DEFAULT_LOGGER_NAME,
|
|
59
63
|
token_resolver: Callable[[str, str], str | None] | None = None,
|
|
60
64
|
cluster_category: str = "prod",
|
|
61
|
-
exporter_options:
|
|
65
|
+
exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
|
|
62
66
|
suppress_invoke_agent_input: bool = False,
|
|
63
67
|
**kwargs: Any,
|
|
64
68
|
) -> bool:
|
|
@@ -72,9 +76,10 @@ class TelemetryManager:
|
|
|
72
76
|
Use exporter_options instead.
|
|
73
77
|
:param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
|
|
74
78
|
Use exporter_options instead.
|
|
75
|
-
:param exporter_options: Agent365ExporterOptions
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
:param exporter_options: Exporter configuration. Pass Agent365ExporterOptions for A365 API
|
|
80
|
+
export, SpectraExporterOptions for Spectra Collector sidecar export, or None (default)
|
|
81
|
+
to construct Agent365ExporterOptions from legacy parameters.
|
|
82
|
+
:param suppress_invoke_agent_input: If True, suppress input messages for InvokeAgent spans.
|
|
78
83
|
:return: True if configuration succeeded, False otherwise.
|
|
79
84
|
"""
|
|
80
85
|
try:
|
|
@@ -100,7 +105,7 @@ class TelemetryManager:
|
|
|
100
105
|
logger_name: str,
|
|
101
106
|
token_resolver: Callable[[str, str], str | None] | None = None,
|
|
102
107
|
cluster_category: str = "prod",
|
|
103
|
-
exporter_options:
|
|
108
|
+
exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
|
|
104
109
|
suppress_invoke_agent_input: bool = False,
|
|
105
110
|
**kwargs: Any,
|
|
106
111
|
) -> bool:
|
|
@@ -156,25 +161,43 @@ class TelemetryManager:
|
|
|
156
161
|
"max_export_batch_size": exporter_options.max_export_batch_size,
|
|
157
162
|
}
|
|
158
163
|
|
|
159
|
-
|
|
164
|
+
# Type-based exporter dispatch
|
|
165
|
+
if isinstance(exporter_options, SpectraExporterOptions):
|
|
166
|
+
# Spectra path — OTLP exporter to sidecar
|
|
167
|
+
# ENABLE_A365_OBSERVABILITY_EXPORTER is intentionally ignored.
|
|
168
|
+
if exporter_options.protocol == "grpc":
|
|
169
|
+
exporter = GrpcOTLPSpanExporter(
|
|
170
|
+
endpoint=exporter_options.endpoint,
|
|
171
|
+
insecure=exporter_options.insecure,
|
|
172
|
+
)
|
|
173
|
+
else:
|
|
174
|
+
exporter = OTLPSpanExporter(
|
|
175
|
+
endpoint=exporter_options.endpoint,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
elif is_agent365_exporter_enabled() and exporter_options.token_resolver is not None:
|
|
160
179
|
exporter = _Agent365Exporter(
|
|
161
180
|
token_resolver=exporter_options.token_resolver,
|
|
162
181
|
cluster_category=exporter_options.cluster_category,
|
|
163
182
|
use_s2s_endpoint=exporter_options.use_s2s_endpoint,
|
|
164
|
-
suppress_invoke_agent_input=suppress_invoke_agent_input,
|
|
165
183
|
)
|
|
166
184
|
|
|
167
185
|
else:
|
|
168
186
|
exporter = ConsoleSpanExporter()
|
|
169
187
|
self._logger.warning(
|
|
170
|
-
"is_agent365_exporter_enabled() not enabled or token_resolver not set.
|
|
188
|
+
"is_agent365_exporter_enabled() not enabled or token_resolver not set."
|
|
189
|
+
" Falling back to console exporter."
|
|
171
190
|
)
|
|
172
191
|
|
|
173
192
|
# Add span processors
|
|
174
193
|
|
|
175
194
|
# Create _EnrichingBatchSpanProcessor with optimized settings
|
|
176
195
|
# This allows extensions to enrich spans before export
|
|
177
|
-
batch_processor = _EnrichingBatchSpanProcessor(
|
|
196
|
+
batch_processor = _EnrichingBatchSpanProcessor(
|
|
197
|
+
exporter,
|
|
198
|
+
suppress_invoke_agent_input=suppress_invoke_agent_input,
|
|
199
|
+
**batch_processor_kwargs,
|
|
200
|
+
)
|
|
178
201
|
agent_processor = SpanProcessor()
|
|
179
202
|
|
|
180
203
|
tracer_provider.add_span_processor(batch_processor)
|
|
@@ -248,7 +271,8 @@ def configure(
|
|
|
248
271
|
logger_name: str = DEFAULT_LOGGER_NAME,
|
|
249
272
|
token_resolver: Callable[[str, str], str | None] | None = None,
|
|
250
273
|
cluster_category: str = "prod",
|
|
251
|
-
exporter_options:
|
|
274
|
+
exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
|
|
275
|
+
suppress_invoke_agent_input: bool = False,
|
|
252
276
|
**kwargs: Any,
|
|
253
277
|
) -> bool:
|
|
254
278
|
"""
|
|
@@ -261,8 +285,10 @@ def configure(
|
|
|
261
285
|
Use exporter_options instead.
|
|
262
286
|
:param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
|
|
263
287
|
Use exporter_options instead.
|
|
264
|
-
:param exporter_options: Agent365ExporterOptions
|
|
265
|
-
|
|
288
|
+
:param exporter_options: Exporter configuration. Pass Agent365ExporterOptions for A365 API
|
|
289
|
+
export, SpectraExporterOptions for Spectra Collector sidecar export, or None (default)
|
|
290
|
+
to construct Agent365ExporterOptions from legacy parameters.
|
|
291
|
+
:param suppress_invoke_agent_input: If True, suppress input messages for InvokeAgent spans.
|
|
266
292
|
:return: True if configuration succeeded, False otherwise.
|
|
267
293
|
"""
|
|
268
294
|
return _telemetry_manager.configure(
|
|
@@ -272,6 +298,7 @@ def configure(
|
|
|
272
298
|
token_resolver,
|
|
273
299
|
cluster_category,
|
|
274
300
|
exporter_options,
|
|
301
|
+
suppress_invoke_agent_input,
|
|
275
302
|
**kwargs,
|
|
276
303
|
)
|
|
277
304
|
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
# Span operation names
|
|
7
7
|
INVOKE_AGENT_OPERATION_NAME = "invoke_agent"
|
|
8
8
|
EXECUTE_TOOL_OPERATION_NAME = "execute_tool"
|
|
9
|
+
OUTPUT_MESSAGES_OPERATION_NAME = "output_messages"
|
|
10
|
+
CHAT_OPERATION_NAME = "chat"
|
|
9
11
|
|
|
10
12
|
# OpenTelemetry semantic conventions
|
|
11
13
|
ERROR_TYPE_KEY = "error.type"
|
|
@@ -30,81 +32,79 @@ GEN_AI_REQUEST_MAX_TOKENS_KEY = "gen_ai.request.max_tokens"
|
|
|
30
32
|
GEN_AI_REQUEST_MODEL_KEY = "gen_ai.request.model"
|
|
31
33
|
GEN_AI_REQUEST_TEMPERATURE_KEY = "gen_ai.request.temperature"
|
|
32
34
|
GEN_AI_REQUEST_TOP_P_KEY = "gen_ai.request.top_p"
|
|
33
|
-
GEN_AI_RESPONSE_ID_KEY = "gen_ai.response.id"
|
|
34
35
|
GEN_AI_RESPONSE_FINISH_REASONS_KEY = "gen_ai.response.finish_reasons"
|
|
35
36
|
GEN_AI_RESPONSE_MODEL_KEY = "gen_ai.response.model"
|
|
36
|
-
|
|
37
|
-
GEN_AI_SYSTEM_VALUE = "az.ai.agent365"
|
|
38
|
-
GEN_AI_THOUGHT_PROCESS_KEY = "gen_ai.agent.thought.process"
|
|
39
|
-
|
|
37
|
+
GEN_AI_RESPONSE_ID_KEY = "gen_ai.response.id"
|
|
40
38
|
GEN_AI_AGENT_ID_KEY = "gen_ai.agent.id"
|
|
41
39
|
GEN_AI_AGENT_NAME_KEY = "gen_ai.agent.name"
|
|
42
40
|
GEN_AI_AGENT_DESCRIPTION_KEY = "gen_ai.agent.description"
|
|
41
|
+
GEN_AI_AGENT_PLATFORM_ID_KEY = "microsoft.a365.agent.platform.id"
|
|
42
|
+
GEN_AI_AGENT_THOUGHT_PROCESS_KEY = "microsoft.a365.agent.thought.process"
|
|
43
43
|
GEN_AI_CONVERSATION_ID_KEY = "gen_ai.conversation.id"
|
|
44
|
-
GEN_AI_CONVERSATION_ITEM_LINK_KEY = "
|
|
44
|
+
GEN_AI_CONVERSATION_ITEM_LINK_KEY = "microsoft.conversation.item.link"
|
|
45
45
|
GEN_AI_TOKEN_TYPE_KEY = "gen_ai.token.type"
|
|
46
46
|
GEN_AI_USAGE_INPUT_TOKENS_KEY = "gen_ai.usage.input_tokens"
|
|
47
47
|
GEN_AI_USAGE_OUTPUT_TOKENS_KEY = "gen_ai.usage.output_tokens"
|
|
48
48
|
GEN_AI_CHOICE = "gen_ai.choice"
|
|
49
49
|
GEN_AI_PROVIDER_NAME_KEY = "gen_ai.provider.name"
|
|
50
|
-
GEN_AI_AGENT_TYPE_KEY = "gen_ai.agent.type"
|
|
51
50
|
|
|
52
51
|
GEN_AI_SYSTEM_INSTRUCTIONS_KEY = "gen_ai.system_instructions"
|
|
53
52
|
GEN_AI_INPUT_MESSAGES_KEY = "gen_ai.input.messages"
|
|
54
53
|
GEN_AI_OUTPUT_MESSAGES_KEY = "gen_ai.output.messages"
|
|
55
|
-
GEN_AI_EVENT_CONTENT = "gen_ai.event.content"
|
|
56
54
|
|
|
57
55
|
# Tool execution constants
|
|
58
56
|
GEN_AI_TOOL_CALL_ID_KEY = "gen_ai.tool.call.id"
|
|
59
57
|
GEN_AI_TOOL_NAME_KEY = "gen_ai.tool.name"
|
|
60
58
|
GEN_AI_TOOL_DESCRIPTION_KEY = "gen_ai.tool.description"
|
|
61
|
-
GEN_AI_TOOL_ARGS_KEY = "gen_ai.tool.arguments"
|
|
62
|
-
GEN_AI_TOOL_CALL_RESULT_KEY =
|
|
59
|
+
GEN_AI_TOOL_ARGS_KEY = "gen_ai.tool.call.arguments"
|
|
60
|
+
GEN_AI_TOOL_CALL_RESULT_KEY = "gen_ai.tool.call.result"
|
|
63
61
|
GEN_AI_TOOL_TYPE_KEY = "gen_ai.tool.type"
|
|
64
62
|
|
|
65
|
-
# Agent user(user tied to agent instance during creation) or caller dimensions
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
GEN_AI_CALLER_NAME_KEY = "gen_ai.caller.name"
|
|
71
|
-
GEN_AI_CALLER_UPN_KEY = "gen_ai.caller.upn"
|
|
72
|
-
GEN_AI_CALLER_CLIENT_IP_KEY = "gen_ai.caller.client.ip"
|
|
63
|
+
# Agent user (user tied to agent instance during creation) or caller dimensions
|
|
64
|
+
GEN_AI_CALLER_ID_KEY = "microsoft.caller.id"
|
|
65
|
+
GEN_AI_CALLER_NAME_KEY = "microsoft.caller.name"
|
|
66
|
+
GEN_AI_CALLER_UPN_KEY = "microsoft.caller.upn"
|
|
67
|
+
GEN_AI_CALLER_CLIENT_IP_KEY = "client.address"
|
|
73
68
|
|
|
74
69
|
# Agent to Agent caller agent dimensions
|
|
75
|
-
GEN_AI_CALLER_AGENT_USER_ID_KEY = "
|
|
76
|
-
GEN_AI_CALLER_AGENT_UPN_KEY = "
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
GEN_AI_CALLER_AGENT_TYPE_KEY = "gen_ai.caller.agent.type"
|
|
82
|
-
GEN_AI_CALLER_AGENT_USER_CLIENT_IP = "gen_ai.caller.agent.user.client.ip"
|
|
70
|
+
GEN_AI_CALLER_AGENT_USER_ID_KEY = "microsoft.a365.caller.agent.user.id"
|
|
71
|
+
GEN_AI_CALLER_AGENT_UPN_KEY = "microsoft.a365.caller.agent.user.upn"
|
|
72
|
+
GEN_AI_CALLER_AGENT_NAME_KEY = "microsoft.a365.caller.agent.name"
|
|
73
|
+
GEN_AI_CALLER_AGENT_ID_KEY = "microsoft.a365.caller.agent.id"
|
|
74
|
+
GEN_AI_CALLER_AGENT_APPLICATION_ID_KEY = "microsoft.a365.caller.agent.blueprint.id"
|
|
75
|
+
GEN_AI_CALLER_AGENT_PLATFORM_ID_KEY = "microsoft.a365.caller.agent.platform.id"
|
|
83
76
|
|
|
84
77
|
# Agent-specific dimensions
|
|
85
78
|
AGENT_ID_KEY = "gen_ai.agent.id"
|
|
86
79
|
GEN_AI_TASK_ID_KEY = "gen_ai.task.id"
|
|
87
|
-
SESSION_ID_KEY = "session.id"
|
|
80
|
+
SESSION_ID_KEY = "microsoft.session.id"
|
|
81
|
+
SESSION_DESCRIPTION_KEY = "microsoft.session.description"
|
|
88
82
|
GEN_AI_ICON_URI_KEY = "gen_ai.agent365.icon_uri"
|
|
89
|
-
TENANT_ID_KEY = "tenant.id"
|
|
83
|
+
TENANT_ID_KEY = "microsoft.tenant.id"
|
|
90
84
|
|
|
91
85
|
# Baggage keys
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
GEN_AI_AGENT_BLUEPRINT_ID_KEY = "gen_ai.agent.applicationid"
|
|
96
|
-
CORRELATION_ID_KEY = "correlation.id"
|
|
97
|
-
HIRING_MANAGER_ID_KEY = "hiring.manager.id"
|
|
98
|
-
SESSION_DESCRIPTION_KEY = "session.description"
|
|
86
|
+
GEN_AI_AGENT_AUID_KEY = "microsoft.agent.user.id"
|
|
87
|
+
GEN_AI_AGENT_UPN_KEY = "microsoft.agent.user.upn"
|
|
88
|
+
GEN_AI_AGENT_BLUEPRINT_ID_KEY = "microsoft.a365.agent.blueprint.id"
|
|
99
89
|
|
|
100
90
|
# Execution context dimensions
|
|
101
91
|
GEN_AI_EXECUTION_TYPE_KEY = "gen_ai.execution.type"
|
|
102
92
|
GEN_AI_EXECUTION_PAYLOAD_KEY = "gen_ai.execution.payload"
|
|
103
93
|
|
|
104
|
-
#
|
|
105
|
-
|
|
106
|
-
|
|
94
|
+
# Channel dimensions
|
|
95
|
+
CHANNEL_NAME_KEY = "microsoft.channel.name"
|
|
96
|
+
CHANNEL_LINK_KEY = "microsoft.channel.link"
|
|
107
97
|
|
|
108
|
-
#
|
|
98
|
+
# Custom parent id and parent name key
|
|
109
99
|
CUSTOM_PARENT_SPAN_ID_KEY = "custom.parent.span.id"
|
|
110
100
|
CUSTOM_SPAN_NAME_KEY = "custom.span.name"
|
|
101
|
+
|
|
102
|
+
# Service attributes
|
|
103
|
+
SERVICE_NAME_KEY = "service.name"
|
|
104
|
+
|
|
105
|
+
# Telemetry SDK attributes
|
|
106
|
+
TELEMETRY_SDK_NAME_KEY = "telemetry.sdk.name"
|
|
107
|
+
TELEMETRY_SDK_LANGUAGE_KEY = "telemetry.sdk.language"
|
|
108
|
+
TELEMETRY_SDK_VERSION_KEY = "telemetry.sdk.version"
|
|
109
|
+
TELEMETRY_SDK_NAME_VALUE = "A365ObservabilitySDK"
|
|
110
|
+
TELEMETRY_SDK_LANGUAGE_VALUE = "python"
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
|
|
6
|
+
from opentelemetry.trace import SpanKind
|
|
7
|
+
|
|
6
8
|
from .agent_details import AgentDetails
|
|
7
9
|
from .constants import (
|
|
10
|
+
CHANNEL_LINK_KEY,
|
|
11
|
+
CHANNEL_NAME_KEY,
|
|
8
12
|
EXECUTE_TOOL_OPERATION_NAME,
|
|
9
|
-
GEN_AI_EVENT_CONTENT,
|
|
10
|
-
GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY,
|
|
11
|
-
GEN_AI_EXECUTION_SOURCE_NAME_KEY,
|
|
12
13
|
GEN_AI_TOOL_ARGS_KEY,
|
|
13
14
|
GEN_AI_TOOL_CALL_ID_KEY,
|
|
14
15
|
GEN_AI_TOOL_DESCRIPTION_KEY,
|
|
@@ -35,6 +36,7 @@ class ExecuteToolScope(OpenTelemetryScope):
|
|
|
35
36
|
parent_id: str | None = None,
|
|
36
37
|
start_time: datetime | None = None,
|
|
37
38
|
end_time: datetime | None = None,
|
|
39
|
+
span_kind: SpanKind | None = None,
|
|
38
40
|
) -> "ExecuteToolScope":
|
|
39
41
|
"""Creates and starts a new scope for tool execution tracing.
|
|
40
42
|
|
|
@@ -50,12 +52,21 @@ class ExecuteToolScope(OpenTelemetryScope):
|
|
|
50
52
|
end_time: Optional explicit end time as a datetime object. When provided,
|
|
51
53
|
the span will use this timestamp when disposed instead of the
|
|
52
54
|
current wall-clock time.
|
|
55
|
+
span_kind: Optional span kind override. Defaults to ``SpanKind.INTERNAL``.
|
|
56
|
+
Use ``SpanKind.CLIENT`` when the tool calls an external service.
|
|
53
57
|
|
|
54
58
|
Returns:
|
|
55
59
|
A new ExecuteToolScope instance
|
|
56
60
|
"""
|
|
57
61
|
return ExecuteToolScope(
|
|
58
|
-
details,
|
|
62
|
+
details,
|
|
63
|
+
agent_details,
|
|
64
|
+
tenant_details,
|
|
65
|
+
request,
|
|
66
|
+
parent_id,
|
|
67
|
+
start_time,
|
|
68
|
+
end_time,
|
|
69
|
+
span_kind,
|
|
59
70
|
)
|
|
60
71
|
|
|
61
72
|
def __init__(
|
|
@@ -67,6 +78,7 @@ class ExecuteToolScope(OpenTelemetryScope):
|
|
|
67
78
|
parent_id: str | None = None,
|
|
68
79
|
start_time: datetime | None = None,
|
|
69
80
|
end_time: datetime | None = None,
|
|
81
|
+
span_kind: SpanKind | None = None,
|
|
70
82
|
):
|
|
71
83
|
"""Initialize the tool execution scope.
|
|
72
84
|
|
|
@@ -82,9 +94,11 @@ class ExecuteToolScope(OpenTelemetryScope):
|
|
|
82
94
|
end_time: Optional explicit end time as a datetime object. When provided,
|
|
83
95
|
the span will use this timestamp when disposed instead of the
|
|
84
96
|
current wall-clock time.
|
|
97
|
+
span_kind: Optional span kind override. Defaults to ``SpanKind.INTERNAL``.
|
|
98
|
+
Use ``SpanKind.CLIENT`` when the tool calls an external service.
|
|
85
99
|
"""
|
|
86
100
|
super().__init__(
|
|
87
|
-
kind=
|
|
101
|
+
kind=span_kind if span_kind is not None else SpanKind.INTERNAL,
|
|
88
102
|
operation_name=EXECUTE_TOOL_OPERATION_NAME,
|
|
89
103
|
activity_name=f"{EXECUTE_TOOL_OPERATION_NAME} {details.tool_name}",
|
|
90
104
|
agent_details=agent_details,
|
|
@@ -115,15 +129,16 @@ class ExecuteToolScope(OpenTelemetryScope):
|
|
|
115
129
|
|
|
116
130
|
# Set request metadata if provided
|
|
117
131
|
if request and request.source_metadata:
|
|
118
|
-
self.set_tag_maybe(
|
|
119
|
-
self.set_tag_maybe(
|
|
120
|
-
GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY, request.source_metadata.description
|
|
121
|
-
)
|
|
132
|
+
self.set_tag_maybe(CHANNEL_NAME_KEY, request.source_metadata.name)
|
|
133
|
+
self.set_tag_maybe(CHANNEL_LINK_KEY, request.source_metadata.description)
|
|
122
134
|
|
|
123
135
|
def record_response(self, response: str) -> None:
|
|
124
136
|
"""Records response information for telemetry tracking.
|
|
125
137
|
|
|
138
|
+
Note: This method is intentionally a no-op as GEN_AI_EVENT_CONTENT was removed.
|
|
139
|
+
The method is kept for interface compatibility.
|
|
140
|
+
|
|
126
141
|
Args:
|
|
127
142
|
response: The response to record
|
|
128
143
|
"""
|
|
129
|
-
|
|
144
|
+
pass
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
# Licensed under the MIT License.
|
|
3
3
|
|
|
4
4
|
from .agent365_exporter_options import Agent365ExporterOptions
|
|
5
|
+
from .spectra_exporter_options import SpectraExporterOptions
|
|
5
6
|
|
|
6
7
|
# Agent365Exporter is not exported intentionally.
|
|
7
8
|
# It should only be used internally by the observability core module.
|
|
8
|
-
__all__ = ["Agent365ExporterOptions"]
|
|
9
|
+
__all__ = ["Agent365ExporterOptions", "SpectraExporterOptions"]
|
|
@@ -17,11 +17,6 @@ from opentelemetry.sdk.trace import ReadableSpan
|
|
|
17
17
|
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
|
|
18
18
|
from opentelemetry.trace import StatusCode
|
|
19
19
|
|
|
20
|
-
from ..constants import (
|
|
21
|
-
GEN_AI_INPUT_MESSAGES_KEY,
|
|
22
|
-
GEN_AI_OPERATION_NAME_KEY,
|
|
23
|
-
INVOKE_AGENT_OPERATION_NAME,
|
|
24
|
-
)
|
|
25
20
|
from .utils import (
|
|
26
21
|
build_export_url,
|
|
27
22
|
get_validated_domain_override,
|
|
@@ -59,7 +54,6 @@ class _Agent365Exporter(SpanExporter):
|
|
|
59
54
|
token_resolver: Callable[[str, str], str | None],
|
|
60
55
|
cluster_category: str = "prod",
|
|
61
56
|
use_s2s_endpoint: bool = False,
|
|
62
|
-
suppress_invoke_agent_input: bool = False,
|
|
63
57
|
):
|
|
64
58
|
if token_resolver is None:
|
|
65
59
|
raise ValueError("token_resolver must be provided.")
|
|
@@ -69,7 +63,6 @@ class _Agent365Exporter(SpanExporter):
|
|
|
69
63
|
self._token_resolver = token_resolver
|
|
70
64
|
self._cluster_category = cluster_category
|
|
71
65
|
self._use_s2s_endpoint = use_s2s_endpoint
|
|
72
|
-
self._suppress_invoke_agent_input = suppress_invoke_agent_input
|
|
73
66
|
# Read domain override once at initialization
|
|
74
67
|
self._domain_override = get_validated_domain_override()
|
|
75
68
|
|
|
@@ -270,19 +263,6 @@ class _Agent365Exporter(SpanExporter):
|
|
|
270
263
|
# attributes
|
|
271
264
|
attrs = dict(sp.attributes or {})
|
|
272
265
|
|
|
273
|
-
# Suppress input messages if configured and current span is an InvokeAgent span
|
|
274
|
-
if self._suppress_invoke_agent_input:
|
|
275
|
-
# Check if current span is an InvokeAgent span by:
|
|
276
|
-
# 1. Span name starts with "invoke_agent"
|
|
277
|
-
# 2. Has attribute gen_ai.operation.name set to INVOKE_AGENT_OPERATION_NAME
|
|
278
|
-
operation_name = attrs.get(GEN_AI_OPERATION_NAME_KEY)
|
|
279
|
-
if (
|
|
280
|
-
sp.name.startswith(INVOKE_AGENT_OPERATION_NAME)
|
|
281
|
-
and operation_name == INVOKE_AGENT_OPERATION_NAME
|
|
282
|
-
):
|
|
283
|
-
# Remove input messages attribute
|
|
284
|
-
attrs.pop(GEN_AI_INPUT_MESSAGES_KEY, None)
|
|
285
|
-
|
|
286
266
|
# events
|
|
287
267
|
events = []
|
|
288
268
|
for ev in sp.events:
|
|
@@ -19,22 +19,31 @@ class EnrichedReadableSpan(ReadableSpan):
|
|
|
19
19
|
the original span.
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
def __init__(
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
span: ReadableSpan,
|
|
25
|
+
extra_attributes: dict,
|
|
26
|
+
excluded_attribute_keys: set[str] | None = None,
|
|
27
|
+
):
|
|
23
28
|
"""
|
|
24
29
|
Initialize the enriched span wrapper.
|
|
25
30
|
|
|
26
31
|
Args:
|
|
27
32
|
span: The original ReadableSpan to wrap.
|
|
28
33
|
extra_attributes: Additional attributes to merge with the original.
|
|
34
|
+
excluded_attribute_keys: Attribute keys to remove after merging.
|
|
29
35
|
"""
|
|
30
36
|
self._span = span
|
|
31
37
|
self._extra_attributes = extra_attributes
|
|
38
|
+
self._excluded_attribute_keys = excluded_attribute_keys or set()
|
|
32
39
|
|
|
33
40
|
@property
|
|
34
41
|
def attributes(self) -> types.Attributes:
|
|
35
42
|
"""Return merged attributes from original span and extra attributes."""
|
|
36
43
|
original = dict(self._span.attributes or {})
|
|
37
44
|
original.update(self._extra_attributes)
|
|
45
|
+
for key in self._excluded_attribute_keys:
|
|
46
|
+
original.pop(key, None)
|
|
38
47
|
return original
|
|
39
48
|
|
|
40
49
|
@property
|
|
@@ -10,6 +10,13 @@ from collections.abc import Callable
|
|
|
10
10
|
from opentelemetry.sdk.trace import ReadableSpan
|
|
11
11
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
12
12
|
|
|
13
|
+
from ..constants import (
|
|
14
|
+
GEN_AI_INPUT_MESSAGES_KEY,
|
|
15
|
+
GEN_AI_OPERATION_NAME_KEY,
|
|
16
|
+
INVOKE_AGENT_OPERATION_NAME,
|
|
17
|
+
)
|
|
18
|
+
from .enriched_span import EnrichedReadableSpan
|
|
19
|
+
|
|
13
20
|
logger = logging.getLogger(__name__)
|
|
14
21
|
|
|
15
22
|
# Single span enricher - only one platform instrumentor should be active at a time
|
|
@@ -65,6 +72,15 @@ def get_span_enricher() -> Callable[[ReadableSpan], ReadableSpan] | None:
|
|
|
65
72
|
class _EnrichingBatchSpanProcessor(BatchSpanProcessor):
|
|
66
73
|
"""BatchSpanProcessor that applies the registered enricher before batching."""
|
|
67
74
|
|
|
75
|
+
def __init__(
|
|
76
|
+
self,
|
|
77
|
+
*args: object,
|
|
78
|
+
suppress_invoke_agent_input: bool = False,
|
|
79
|
+
**kwargs: object,
|
|
80
|
+
):
|
|
81
|
+
super().__init__(*args, **kwargs)
|
|
82
|
+
self._suppress_invoke_agent_input = suppress_invoke_agent_input
|
|
83
|
+
|
|
68
84
|
def on_end(self, span: ReadableSpan) -> None:
|
|
69
85
|
"""Apply the span enricher and pass to parent for batching.
|
|
70
86
|
|
|
@@ -83,4 +99,18 @@ class _EnrichingBatchSpanProcessor(BatchSpanProcessor):
|
|
|
83
99
|
enricher.__name__,
|
|
84
100
|
)
|
|
85
101
|
|
|
102
|
+
# Apply input message suppression for InvokeAgent spans
|
|
103
|
+
if self._suppress_invoke_agent_input:
|
|
104
|
+
attrs = enriched_span.attributes or {}
|
|
105
|
+
operation_name = attrs.get(GEN_AI_OPERATION_NAME_KEY)
|
|
106
|
+
if (
|
|
107
|
+
enriched_span.name.startswith(INVOKE_AGENT_OPERATION_NAME)
|
|
108
|
+
and operation_name == INVOKE_AGENT_OPERATION_NAME
|
|
109
|
+
):
|
|
110
|
+
enriched_span = EnrichedReadableSpan(
|
|
111
|
+
enriched_span,
|
|
112
|
+
extra_attributes={},
|
|
113
|
+
excluded_attribute_keys={GEN_AI_INPUT_MESSAGES_KEY},
|
|
114
|
+
)
|
|
115
|
+
|
|
86
116
|
super().on_end(enriched_span)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SpectraExporterOptions:
|
|
8
|
+
"""
|
|
9
|
+
Configuration for exporting traces to a Spectra Collector sidecar via OTLP.
|
|
10
|
+
|
|
11
|
+
Spectra Collector is deployed as a Kubernetes sidecar that accepts
|
|
12
|
+
standard OTLP telemetry on localhost. Defaults are tuned for this
|
|
13
|
+
deployment topology — most consumers should not need to override them.
|
|
14
|
+
|
|
15
|
+
Note: Batch processor fields (max_queue_size, scheduled_delay_ms, etc.)
|
|
16
|
+
are duplicated from Agent365ExporterOptions intentionally — these two
|
|
17
|
+
options classes have no shared base class per design decision C4.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
_DEFAULT_GRPC_ENDPOINT = "http://localhost:4317"
|
|
21
|
+
_DEFAULT_HTTP_ENDPOINT = "http://localhost:4318"
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
endpoint: str | None = None,
|
|
26
|
+
protocol: Literal["grpc", "http"] = "grpc",
|
|
27
|
+
insecure: bool = True,
|
|
28
|
+
max_queue_size: int = 2048,
|
|
29
|
+
scheduled_delay_ms: int = 5000,
|
|
30
|
+
exporter_timeout_ms: int = 30000,
|
|
31
|
+
max_export_batch_size: int = 512,
|
|
32
|
+
):
|
|
33
|
+
"""
|
|
34
|
+
Args:
|
|
35
|
+
endpoint: Spectra sidecar OTLP endpoint. Defaults to
|
|
36
|
+
http://localhost:4317 for gRPC or http://localhost:4318 for HTTP.
|
|
37
|
+
protocol: OTLP protocol — "grpc" or "http". Default: grpc.
|
|
38
|
+
insecure: Use insecure (no TLS) connection. Default: True (localhost sidecar).
|
|
39
|
+
max_queue_size: Batch processor queue size. Default: 2048.
|
|
40
|
+
scheduled_delay_ms: Export interval in milliseconds. Default: 5000.
|
|
41
|
+
exporter_timeout_ms: Export timeout in milliseconds. Default: 30000.
|
|
42
|
+
max_export_batch_size: Max spans per export batch. Default: 512.
|
|
43
|
+
"""
|
|
44
|
+
if protocol not in ("grpc", "http"):
|
|
45
|
+
raise ValueError(f"protocol must be 'grpc' or 'http', got '{protocol}'")
|
|
46
|
+
if endpoint is None:
|
|
47
|
+
endpoint = (
|
|
48
|
+
self._DEFAULT_GRPC_ENDPOINT if protocol == "grpc" else self._DEFAULT_HTTP_ENDPOINT
|
|
49
|
+
)
|
|
50
|
+
self.endpoint = endpoint
|
|
51
|
+
self.protocol = protocol
|
|
52
|
+
self.insecure = insecure
|
|
53
|
+
self.max_queue_size = max_queue_size
|
|
54
|
+
self.scheduled_delay_ms = scheduled_delay_ms
|
|
55
|
+
self.exporter_timeout_ms = exporter_timeout_ms
|
|
56
|
+
self.max_export_batch_size = max_export_batch_size
|
|
@@ -6,6 +6,17 @@ from dataclasses import dataclass
|
|
|
6
6
|
from .inference_operation_type import InferenceOperationType
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
@dataclass
|
|
10
|
+
class ServiceEndpoint:
|
|
11
|
+
"""Represents a service endpoint with hostname and optional port."""
|
|
12
|
+
|
|
13
|
+
hostname: str
|
|
14
|
+
"""The hostname of the service endpoint."""
|
|
15
|
+
|
|
16
|
+
port: int | None = None
|
|
17
|
+
"""The port of the service endpoint."""
|
|
18
|
+
|
|
19
|
+
|
|
9
20
|
@dataclass
|
|
10
21
|
class InferenceCallDetails:
|
|
11
22
|
"""Details of an inference call for generative AI operations."""
|
|
@@ -16,4 +27,5 @@ class InferenceCallDetails:
|
|
|
16
27
|
inputTokens: int | None = None
|
|
17
28
|
outputTokens: int | None = None
|
|
18
29
|
finishReasons: list[str] | None = None
|
|
19
|
-
|
|
30
|
+
thoughtProcess: str | None = None
|
|
31
|
+
endpoint: ServiceEndpoint | None = None
|