Skip to content

Commit ff3bc83

Browse files
Align public api (#209)
* align API across observability SDK's * update tests * address pr comments --------- Co-authored-by: Nikhil Chitlur Navakiran (from Dev Box) <nikhilc@microsoft.com>
1 parent 942e809 commit ff3bc83

File tree

44 files changed

+612
-599
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+612
-599
lines changed

docs/design.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,23 @@ The foundation for distributed tracing in agent applications. Built on OpenTelem
8181

8282
| Class | Purpose |
8383
|-------|---------|
84-
| `InvokeAgentDetails` | Agent endpoint, session ID, and invocation metadata |
84+
| `InvokeAgentScopeDetails` | Agent endpoint and invocation metadata |
8585
| `AgentDetails` | Agent identification and metadata |
86-
| `TenantDetails` | Tenant identification for multi-tenant scenarios |
86+
| `UserDetails` | Human caller identification (user ID, email, name, IP) |
87+
| `CallerDetails` | Wrapper for user details and/or caller agent details |
88+
| `SpanDetails` | Parent context, timing, and span kind for custom spans |
8789
| `InferenceCallDetails` | Model name, tokens, provider information |
8890
| `ToolCallDetails` | Tool name, arguments, endpoint |
89-
| `Request` | Execution context and correlation ID |
91+
| `Request` | Content, correlation ID, and conversation ID |
9092

9193
**Usage Example:**
9294

9395
```python
9496
from microsoft_agents_a365.observability.core import (
9597
configure,
9698
InvokeAgentScope,
97-
InvokeAgentDetails,
98-
TenantDetails,
99+
InvokeAgentScopeDetails,
100+
AgentDetails,
99101
Request,
100102
BaggageBuilder,
101103
)
@@ -112,9 +114,9 @@ configure(
112114
with BaggageBuilder().tenant_id(tenant_id).agent_id(agent_id).build():
113115
# Trace agent invocation
114116
with InvokeAgentScope.start(
115-
invoke_agent_details=InvokeAgentDetails(...),
116-
tenant_details=TenantDetails(...),
117-
request=Request(...)
117+
request=Request(content="Hello"),
118+
invoke_scope_details=InvokeAgentScopeDetails(...),
119+
agent_details=AgentDetails(...),
118120
) as scope:
119121
# Agent logic here
120122
scope.record_response("result")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Changelog — microsoft-agents-a365-observability-core
2+
3+
All notable changes to this package will be documented in this file.
4+
5+
## [Unreleased]
6+
7+
### Breaking Changes
8+
9+
- **`InvokeAgentDetails` renamed to `InvokeAgentScopeDetails`** — Now contains only scope-level config (`endpoint`). Agent identity (`AgentDetails`) is a separate parameter. `session_id` moved to `Request`.
10+
- **`InvokeAgentScope.start()`**: New signature `start(request, invoke_scope_details, agent_details, caller_details?, span_details?)`. `request` is required.
11+
- **`InferenceScope.start()`**: New signature `start(request, details, agent_details, user_details?, span_details?)`. `request` is required.
12+
- **`ExecuteToolScope.start()`**: New signature `start(request, details, agent_details, user_details?, span_details?)`. Same pattern as `InferenceScope`.
13+
- **`OutputScope.start()`**: New signature `start(request, response, agent_details, user_details?, span_details?)`. Same pattern.
14+
- **`CallerDetails` renamed to `UserDetails`** — Fields renamed: `caller_id``user_id`, `caller_upn``user_email`, `caller_name``user_name`, `caller_client_ip``user_client_ip`.
15+
- **`CallerDetails` is now a composite wrapper** — Groups `user_details: UserDetails` and `caller_agent_details: AgentDetails` for A2A scenarios.
16+
- **`TenantDetails` removed**`tenant_id` is now on `AgentDetails.tenant_id`. Removed from all scope `start()` methods.
17+
- **`ExecutionType` enum removed** — Removed from `Request`. `GEN_AI_EXECUTION_TYPE_KEY` constant also removed.
18+
- **`AgentDetails` fields renamed**`agent_auid``agentic_user_id`, `agent_upn``agentic_user_email`. `conversation_id` moved to `Request`.
19+
- **`Request` model updated** — Removed `execution_type`. Added `conversation_id`. `content` is now optional.
20+
- **`BaggageBuilder` methods renamed**`agent_upn()``agentic_user_email()`, `agent_auid()``agentic_user_id()`, `caller_id()``user_id()`, `caller_name()``user_name()`, `caller_upn()``user_email()`, `caller_client_ip()``user_client_ip()`.
21+
22+
### Added
23+
24+
- **`SpanDetails`** — Groups `span_kind`, `parent_context`, `start_time`, `end_time` for scope construction.
25+
- **`UserDetails`** — Human caller identity with `user_id`, `user_email`, `user_name`, `user_client_ip`.
26+
- **`CallerDetails`** (new wrapper) — Groups `user_details` and `caller_agent_details` for A2A scenarios.
27+
- **`InvokeAgentScopeDetails`** — Scope-level config with `endpoint` only.
28+
- **`Request.conversation_id`** — Conversation ID field on the unified `Request` model.
29+
- **`ERROR_TYPE_CANCELLED`** constant — `"TaskCanceledException"`, used by `record_cancellation()`.
30+
- **`OutputScope`** now exported from `microsoft_agents_a365.observability.core`.

libraries/microsoft-agents-a365-observability-core/docs/design.md

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ configure(
6565
class OpenTelemetryScope:
6666
"""Base class for OpenTelemetry tracing scopes."""
6767

68-
def __init__(self, kind, operation_name, activity_name, agent_details, tenant_details):
68+
def __init__(self, kind, operation_name, activity_name, agent_details):
6969
# Creates span with given parameters
7070
# Sets common attributes (gen_ai.system, operation name)
71-
# Sets agent/tenant details as span attributes
71+
# Sets agent details as span attributes
7272

7373
def __enter__(self):
7474
# Makes span active in current context
@@ -96,29 +96,23 @@ Traces agent invocation operations (entry point for agent requests):
9696
```python
9797
from microsoft_agents_a365.observability.core import (
9898
InvokeAgentScope,
99-
InvokeAgentDetails,
100-
TenantDetails,
99+
InvokeAgentScopeDetails,
101100
AgentDetails,
101+
Request,
102102
)
103103

104104
with InvokeAgentScope.start(
105-
invoke_agent_details=InvokeAgentDetails(
106-
endpoint=parsed_url,
107-
session_id="session-123",
108-
details=AgentDetails(agent_id="agent-456", agent_name="MyAgent")
109-
),
110-
tenant_details=TenantDetails(tenant_id="tenant-789"),
111-
request=Request(content="Hello", execution_type=ExecutionType.CHAT),
105+
request=Request(content="Hello"),
106+
invoke_scope_details=InvokeAgentScopeDetails(endpoint=parsed_url),
107+
agent_details=AgentDetails(agent_id="agent-456", agent_name="MyAgent"),
112108
) as scope:
113109
# Agent processing
114110
scope.record_response("Agent response")
115111
```
116112

117113
**Span attributes recorded:**
118114
- Server address and port
119-
- Session ID
120115
- Execution source metadata
121-
- Execution type
122116
- Input/output messages
123117
- Caller details (if provided)
124118

@@ -127,15 +121,15 @@ with InvokeAgentScope.start(
127121
Traces LLM/AI model inference calls:
128122

129123
```python
130-
from microsoft_agents_a365.observability.core import InferenceScope, InferenceCallDetails
124+
from microsoft_agents_a365.observability.core import InferenceScope, InferenceCallDetails, Request
131125

132126
with InferenceScope.start(
133-
inference_call_details=InferenceCallDetails(
127+
request=Request(content="Hello"),
128+
details=InferenceCallDetails(
134129
model_name="gpt-4",
135130
provider="openai"
136131
),
137132
agent_details=agent_details,
138-
tenant_details=tenant_details,
139133
) as scope:
140134
# LLM call
141135
scope.record_input_tokens(100)
@@ -148,15 +142,15 @@ with InferenceScope.start(
148142
Traces tool execution operations:
149143

150144
```python
151-
from microsoft_agents_a365.observability.core import ExecuteToolScope, ToolCallDetails
145+
from microsoft_agents_a365.observability.core import ExecuteToolScope, ToolCallDetails, Request
152146

153147
with ExecuteToolScope.start(
154-
tool_call_details=ToolCallDetails(
148+
request=Request(content="search for weather"),
149+
details=ToolCallDetails(
155150
tool_name="search",
156151
tool_arguments={"query": "weather"}
157152
),
158153
agent_details=agent_details,
159-
tenant_details=tenant_details,
160154
) as scope:
161155
# Tool execution
162156
scope.record_response("Tool result")
@@ -174,7 +168,7 @@ with BaggageBuilder() \
174168
.tenant_id("tenant-123") \
175169
.agent_id("agent-456") \
176170
.correlation_id("corr-789") \
177-
.caller_id("user-abc") \
171+
.user_id("user-abc") \
178172
.session_id("session-xyz") \
179173
.build():
180174
# All child spans inherit this baggage
@@ -195,9 +189,11 @@ with BaggageBuilder.set_request_context(
195189
| `tenant_id(value)` | `tenant_id` |
196190
| `agent_id(value)` | `gen_ai.agent.id` |
197191
| `agent_auid(value)` | `gen_ai.agent.auid` |
198-
| `agent_upn(value)` | `gen_ai.agent.upn` |
192+
| `agent_email(value)` | `gen_ai.agent.upn` |
199193
| `correlation_id(value)` | `correlation_id` |
200-
| `caller_id(value)` | `gen_ai.caller.id` |
194+
| `user_id(value)` | `gen_ai.caller.id` |
195+
| `user_name(value)` | `gen_ai.caller.name` |
196+
| `user_email(value)` | `gen_ai.caller.upn` |
201197
| `session_id(value)` | `session_id` |
202198
| `conversation_id(value)` | `gen_ai.conversation.id` |
203199
| `channel_name(value)` | `gen_ai.execution.source.name` |
@@ -246,14 +242,12 @@ options = Agent365ExporterOptions(
246242

247243
## Data Classes
248244

249-
### InvokeAgentDetails
245+
### InvokeAgentScopeDetails
250246

251247
```python
252248
@dataclass
253-
class InvokeAgentDetails:
249+
class InvokeAgentScopeDetails:
254250
endpoint: ParseResult | None # Parsed URL of the agent endpoint
255-
session_id: str | None # Session identifier
256-
details: AgentDetails # Agent metadata
257251
```
258252

259253
### AgentDetails
@@ -265,20 +259,42 @@ class AgentDetails:
265259
agent_name: str | None
266260
agent_description: str | None
267261
agent_auid: str | None # Agent unique identifier
268-
agent_upn: str | None # User principal name
262+
agent_email: str | None # Agent email address
269263
agent_blueprint_id: str | None
270264
agent_type: AgentType | None
271265
tenant_id: str | None
272-
conversation_id: str | None
273266
icon_uri: str | None
274267
```
275268

276-
### TenantDetails
269+
### UserDetails
277270

278271
```python
279272
@dataclass
280-
class TenantDetails:
281-
tenant_id: str | None
273+
class UserDetails:
274+
user_id: str | None
275+
user_email: str | None
276+
user_name: str | None
277+
caller_client_ip: str | None
278+
```
279+
280+
### CallerDetails
281+
282+
```python
283+
@dataclass
284+
class CallerDetails:
285+
user_details: UserDetails | None
286+
caller_agent_details: AgentDetails | None
287+
```
288+
289+
### SpanDetails
290+
291+
```python
292+
@dataclass
293+
class SpanDetails:
294+
parent_context: Context | None
295+
start_time: int | None
296+
end_time: int | None
297+
span_kind: SpanKind | None
282298
```
283299

284300
### InferenceCallDetails
@@ -358,14 +374,15 @@ microsoft_agents_a365/observability/core/
358374
├── invoke_agent_scope.py # Agent invocation tracing
359375
├── inference_scope.py # LLM inference tracing
360376
├── execute_tool_scope.py # Tool execution tracing
377+
├── output_scope.py # Output tracing
361378
├── agent_details.py # AgentDetails dataclass
362-
├── tenant_details.py # TenantDetails dataclass
363-
├── invoke_agent_details.py # InvokeAgentDetails dataclass
379+
├── invoke_agent_scope_details.py # InvokeAgentScopeDetails dataclass
380+
├── user_details.py # UserDetails dataclass
381+
├── span_details.py # SpanDetails dataclass
364382
├── inference_call_details.py # InferenceCallDetails dataclass
365383
├── tool_call_details.py # ToolCallDetails dataclass
366384
├── request.py # Request dataclass
367385
├── source_metadata.py # SourceMetadata dataclass
368-
├── execution_type.py # ExecutionType enum
369386
├── inference_operation_type.py # InferenceOperationType enum
370387
├── tool_type.py # ToolType enum
371388
├── constants.py # Attribute key constants

libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/__init__.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
is_configured,
1212
)
1313
from .execute_tool_scope import ExecuteToolScope
14-
from .execution_type import ExecutionType
1514
from .exporters.agent365_exporter_options import Agent365ExporterOptions
1615
from .exporters.enriched_span import EnrichedReadableSpan
1716
from .exporters.enriching_span_processor import (
@@ -23,13 +22,16 @@
2322
from .inference_call_details import InferenceCallDetails, ServiceEndpoint
2423
from .inference_operation_type import InferenceOperationType
2524
from .inference_scope import InferenceScope
26-
from .invoke_agent_details import InvokeAgentDetails
25+
from .invoke_agent_details import InvokeAgentScopeDetails
2726
from .invoke_agent_scope import InvokeAgentScope
2827
from .middleware.baggage_builder import BaggageBuilder
28+
from .models.caller_details import CallerDetails
29+
from .models.user_details import UserDetails
2930
from .opentelemetry_scope import OpenTelemetryScope
3031
from .request import Request
3132
from .channel import Channel
32-
from .tenant_details import TenantDetails
33+
from .span_details import SpanDetails
34+
from .spans_scopes.output_scope import OutputScope
3335
from .tool_call_details import ToolCallDetails
3436
from .tool_type import ToolType
3537
from .trace_processor.span_processor import SpanProcessor
@@ -57,26 +59,26 @@
5759
"ExecuteToolScope",
5860
"InvokeAgentScope",
5961
"InferenceScope",
62+
"OutputScope",
6063
# Middleware
6164
"BaggageBuilder",
6265
# Data classes
63-
"InvokeAgentDetails",
66+
"InvokeAgentScopeDetails",
6467
"AgentDetails",
65-
"TenantDetails",
68+
"CallerDetails",
69+
"UserDetails",
6670
"ToolCallDetails",
6771
"Channel",
6872
"Request",
73+
"SpanDetails",
6974
"InferenceCallDetails",
7075
"ServiceEndpoint",
7176
# Enums
72-
"ExecutionType",
7377
"InferenceOperationType",
7478
"ToolType",
7579
# Utility functions
7680
"extract_context_from_headers",
7781
"get_traceparent",
78-
# Constants
79-
# all constants from constants.py are exported via *
8082
]
8183

8284
# This is a namespace package

libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/agent_details.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ class AgentDetails:
1818
agent_description: Optional[str] = None
1919
"""A description of the AI agent's purpose or capabilities."""
2020

21-
agent_auid: Optional[str] = None
21+
agentic_user_id: Optional[str] = None
2222
"""Agentic User ID for the agent."""
2323

24-
agent_upn: Optional[str] = None
25-
"""User Principal Name (UPN) for the agentic user."""
24+
agentic_user_email: Optional[str] = None
25+
"""Email address for the agentic user."""
2626

2727
agent_blueprint_id: Optional[str] = None
2828
"""Blueprint/Application ID for the agent."""
@@ -33,9 +33,6 @@ class AgentDetails:
3333
tenant_id: Optional[str] = None
3434
"""Tenant ID for the agent."""
3535

36-
conversation_id: Optional[str] = None
37-
"""Optional conversation ID for compatibility."""
38-
3936
icon_uri: Optional[str] = None
4037
"""Optional icon URI for the agent."""
4138

libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/constants.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,10 @@
8787
GEN_AI_AGENT_EMAIL_KEY = "microsoft.agent.user.email"
8888
GEN_AI_AGENT_BLUEPRINT_ID_KEY = "microsoft.a365.agent.blueprint.id"
8989

90+
# Error type constants
91+
ERROR_TYPE_CANCELLED = "TaskCanceledException"
92+
9093
# Execution context dimensions
91-
GEN_AI_EXECUTION_TYPE_KEY = "gen_ai.execution.type"
9294
GEN_AI_EXECUTION_PAYLOAD_KEY = "gen_ai.execution.payload"
9395

9496
# Channel dimensions

0 commit comments

Comments
 (0)