Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds support for a new telemetry attribute schema (gated behind A365_USE_NEW_TELEMETRY_SCHEMA) in the observability SDK by renaming/selectively emitting span/baggage attributes and introducing caller metadata propagation into base scopes.
Changes:
- Add
CallerDetailssupport inOpenTelemetryScopeand plumb it throughExecuteToolScope,InferenceScope, andInvokeAgentScope. - Gate/adjust exported attributes for the new schema (e.g., removing some legacy dimensions; switching to
telemetry.sdk.*attributes). - Extend inference telemetry with
thoughtProcessand add/expand unit tests around caller tagging.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/observability/core/scopes.test.ts | Adds assertions that caller tags are applied for ExecuteTool/Inference scopes. |
| packages/agents-a365-observability/src/tracing/scopes/OpenTelemetryScope.ts | Adds callerDetails param and applies caller tags in the base scope. |
| packages/agents-a365-observability/src/tracing/scopes/InvokeAgentScope.ts | Routes callerDetails into base scope; handles InvokeAgent-only attrs in new schema. |
| packages/agents-a365-observability/src/tracing/scopes/InferenceScope.ts | Plumbs callerDetails; adds gen_ai.agent.thought.process tagging. |
| packages/agents-a365-observability/src/tracing/scopes/ExecuteToolScope.ts | Plumbs callerDetails into scope creation. |
| packages/agents-a365-observability/src/tracing/processors/util.ts | Gates which baggage keys are copied into span attrs depending on schema. |
| packages/agents-a365-observability/src/tracing/processors/SpanProcessor.ts | Switches from operation.source to telemetry.sdk.* attributes under new schema. |
| packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts | Stops emitting correlation/hiring-manager baggage keys in new schema. |
| packages/agents-a365-observability/src/tracing/contracts.ts | Adds InferenceDetails.thoughtProcess. |
| packages/agents-a365-observability/src/tracing/constants.ts | Introduces schema flag and conditional key renames/new constants. |
packages/agents-a365-observability/src/tracing/processors/SpanProcessor.ts
Outdated
Show resolved
Hide resolved
f167507 to
203104a
Compare
203104a to
6eee457
Compare
…LEMETRY_SCHEMA env var Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6eee457 to
7564849
Compare
Add prebuild script to generate src/version.ts from package.json (same pattern as agents-a365-runtime) so the telemetry SDK version stays correct automatically instead of being hardcoded. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use jest.isolateModules to validate raw old/new schema key strings for caller attributes, catching regressions in constant definitions regardless of which schema is active at runtime. Also skip GEN_AI_AGENT_USER_ID_KEY from GENERIC_ATTRIBUTES in new schema to avoid duplicate propagation (collides with GEN_AI_AGENT_AUID_KEY). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… agent keys - Restore GEN_AI_CALLER_TENANT_ID_KEY and wire it through base scope, INVOKE_AGENT_ATTRIBUTES, and TurnContextUtils baggage pairs - Add isolated-module tests validating caller agent key schema mappings - Skip GEN_AI_AGENT_USER_ID_KEY from GENERIC_ATTRIBUTES in new schema to avoid duplicate propagation with GEN_AI_AGENT_AUID_KEY Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This constant duplicated GEN_AI_AGENT_AUID_KEY functionality. The .NET SDK uses gen_ai.agent.userid as GenAiAgentAUIDKey, so only GEN_AI_AGENT_AUID_KEY is needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- TELEMETRY_SDK_NAME_VALUE: Agent365Sdk → A365ObservabilitySDK - GEN_AI_AGENT_AUID_KEY: microsoft.a365.agent.user.id → microsoft.agent.user.id - GEN_AI_AGENT_BLUEPRINT_ID_KEY: microsoft.agent.blueprint.id → microsoft.a365.agent.blueprint.id Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nikhilNava
left a comment
There was a problem hiding this comment.
Thanks for putting this together, can you post the generated post body by the SDK for easy review?
Also please share the post body with Akhil and Jason to help with service implementation
packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/processors/SpanProcessor.ts
Outdated
Show resolved
Hide resolved
….call.result, remove GEN_AI_EXECUTION_SOURCE_ID_KEY, add server.address/port to InferenceScope - Remove GEN_AI_RESPONSE_ID_KEY constant and all responseId references from InferenceScope, contracts, extensions-openai, and samples - Rename gen_ai.event.content to gen_ai.tool.call.result for GEN_AI_EVENT_CONTENT and GEN_AI_TOOL_CALL_RESULT_KEY constants - Remove GEN_AI_EXECUTION_SOURCE_ID_KEY from constants, util.ts, InvokeAgentScope, and BaggageBuilder.sourceMetadataId() - Add endpoint (server.address/server.port) support to InferenceScope and InferenceDetails contract - Update capture-post-body sample and agent.ts samples - Update all affected tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
48679f9 to
a083413
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
packages/agents-a365-observability/package.json:16
- The new
prebuildscript generatessrc/version.ts, but nothing in this package’s lifecycle ensures it exists before the repo’s ts-jest test run (which imports packagesrc/directly viamoduleNameMapper). Consider adding a lifecycle hook (prepare/postinstall) or at least apretestscript to generatesrc/version.tsso clean checkouts can run tests without requiring a manualbuildfirst.
"prebuild": "node -p \"'export const LIB_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
"build:cjs": "npx tsc --project tsconfig.cjs.json",
"build:esm": "npx tsc --project tsconfig.esm.json",
"build": "npm run build:cjs && npm run build:esm",
"build:watch": "npx tsc --watch",
"clean": "npx rimraf dist",
"test": "jest --passWithNoTests",
"test:watch": "jest --watch",
packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts
Show resolved
Hide resolved
post body is added to the description section. |
- Remove gen_ai.system constant; replace all usages with gen_ai.provider.name - Remove gen_ai.agent.type, gen_ai.caller.tenantid, gen_ai.caller.agent.tenantid, microsoft.a365.caller.agent.type, gen_ai.caller.agent.user.client.ip, operation.duration - Rename gen_ai.caller.agent.upn to microsoft.a365.caller.agent.user.upn - Fix microsoft.a365.agent.user.id to microsoft.agent.user.id - Fix microsoft.agent.blueprint.id to microsoft.a365.agent.blueprint.id - Remove agentType and agentClientIP from contracts - Update all tests and extensions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ans) Schema defines microsoft.a365.agent.blueprint.id as common across all span types. Previously it was only set in InvokeAgentScope. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Emit gen_ai.usage.input_tokens and output_tokens as int (not string) - Emit gen_ai.response.finish_reasons as string[] (not comma-joined string) - Emit server.port as string (not number) across all scope types - Widen setTagMaybe to accept string[] and number[] for array attributes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
packages/agents-a365-observability/src/tracing/scopes/OpenTelemetryScope.ts
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/scopes/OpenTelemetryScope.ts
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/scopes/InvokeAgentScope.ts
Show resolved
Hide resolved
| [OpenTelemetryConstants.GEN_AI_CALLER_ID_KEY, from.aadObjectId], | ||
| [OpenTelemetryConstants.GEN_AI_CALLER_NAME_KEY, from.name], | ||
| [OpenTelemetryConstants.GEN_AI_CALLER_UPN_KEY, upn], | ||
| [OpenTelemetryConstants.GEN_AI_CALLER_TENANT_ID_KEY, from.tenantId], | ||
| [OpenTelemetryConstants.GEN_AI_AGENT_BLUEPRINT_ID_KEY, from.agenticAppBlueprintId] | ||
| ]; |
There was a problem hiding this comment.
This function no longer includes a tenant ID baggage pair (the GEN_AI_CALLER_TENANT_ID_KEY entry was removed), but the JSDoc above still says it returns pairs for caller identity and tenant. Update the JSDoc to match, or re-add the tenant pair if it’s still required by the schema/back-end.
packages/agents-a365-observability/src/tracing/scopes/OpenTelemetryScope.ts
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/scopes/OpenTelemetryScope.ts
Outdated
Show resolved
Hide resolved
| * @param value The channel name | ||
| * @returns Self for method chaining | ||
| */ | ||
| sourceMetadataName(value: string | null | undefined): BaggageBuilder { |
There was a problem hiding this comment.
rename to channelName and channelLinks ?
There was a problem hiding this comment.
This is not schema change. Will create a separated PR once this one is in.
| * @param correlationId The correlation ID | ||
| * @returns A context manager that restores the previous baggage on exit | ||
| */ | ||
| static setRequestContext( |
There was a problem hiding this comment.
This method can be removed as it doesnt do much. developer will have to use other setters anyway
There was a problem hiding this comment.
It is also used in dotnet.
| @@ -37,9 +39,10 @@ export class InferenceScope extends OpenTelemetryScope { | |||
| sourceMetadata?: Pick<SourceMetadata, "name" | "description">, | |||
There was a problem hiding this comment.
This is not schema change and will be in a separated PR as mentioned above.
| */ | ||
| public recordInputTokens(inputTokens: number): void { | ||
| this.setTagMaybe(OpenTelemetryConstants.GEN_AI_USAGE_INPUT_TOKENS_KEY, inputTokens.toString()); | ||
| this.setTagMaybe(OpenTelemetryConstants.GEN_AI_USAGE_INPUT_TOKENS_KEY, inputTokens); |
There was a problem hiding this comment.
is there a reason to drop the conversion?
the service has it as a string
https://microsoft.ghe.com/bic/mvn-mavenservice/blob/76531733d8ba1e3d15de30a7eb5f8d43e4027c25/src/MVN/Kairo/Observability/Sentinel/SentinelIngestion/SentinelModels.cs#L570
There was a problem hiding this comment.
according to https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/, the type should be int. This matches with the latest schema.
| startTime, | ||
| attributes: { | ||
| [OpenTelemetryConstants.GEN_AI_SYSTEM_KEY]: OpenTelemetryConstants.GEN_AI_SYSTEM_VALUE, | ||
| [OpenTelemetryConstants.GEN_AI_PROVIDER_NAME_KEY]: 'az.ai.agent365', |
There was a problem hiding this comment.
provider name refers to model provider provider name like anthropic, meta, openai
There was a problem hiding this comment.
maybe we need to come up with constants for those
There was a problem hiding this comment.
removed. new field is introduced in agentscope
…oviderName to AgentDetails Remove hardcoded gen_ai.provider.name from OpenTelemetryScope base class. Set it dynamically in InvokeAgentScope from AgentDetails.providerName, matching InferenceScope which already uses InferenceDetails.providerName. ExecuteTool spans no longer emit gen_ai.provider.name. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
packages/agents-a365-observability/src/tracing/scopes/InvokeAgentScope.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/scopes/OpenTelemetryScope.ts
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/processors/SpanProcessor.ts
Show resolved
Hide resolved
- Fix OutputScope: rename old schema constants (GEN_AI_EXECUTION_SOURCE_* to CHANNEL_*, remove GEN_AI_CALLER_TENANT_ID_KEY, remove executionType param) - Fix scope-utils tests: use new schema attribute names, update input message format to match JSON.stringify change from main - Fix output-scope test: adjust for removed executionType parameter - Fix output-logging-middleware and baggage-middleware tests: use CHANNEL_NAME_KEY Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eneric attributes, add callerDetails JSDoc Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
packages/agents-a365-observability/src/tracing/scopes/OutputScope.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability/src/tracing/scopes/OutputScope.ts
Outdated
Show resolved
Hide resolved
…remove dead code, fix copyright headers and stale JSDoc - OutputScope: pass callerDetails to super() instead of manual caller tagging - OutputScope: fix JSDoc removing stale "tenant" from callerDetails description - OpenTelemetryScope: remove unused finalTags variable and exception field - OpenTelemetryScope: remove unused Attributes import - TurnContextUtils: fix stale JSDoc mentioning tenant in getCallerBaggagePairs - constants.ts: remove misleading "server spans only" comment on SERVICE_NAME_KEY - Fix copyright headers in contracts.ts, BaggageBuilder.ts, OpenAIAgentsTraceProcessor.ts, Utils.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
packages/agents-a365-observability-hosting/src/utils/TurnContextUtils.ts:27
if (!turnContext|| !turnContext.activity?.from)is missing whitespace around the||operator (and has a trailing space before{). This is likely to violate the repo's formatting/lint rules and should be fixed to keep CI lint clean.
if (!turnContext|| !turnContext.activity?.from) {
return [];
…hannelLink Address nikhilNava review: rename methods to match schema naming convention. Also update design doc to reflect new method names and attribute keys. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverting to sourceMetadataName/sourceMetadataDescription — the full sourceMetadata→channel rename will be done in a follow-up PR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| const calls = spy.mock.calls.map(args => ({ key: args[0], val: args[1] })); | ||
| expect(calls).toEqual(expect.arrayContaining([ | ||
| expect.objectContaining({ key: OpenTelemetryConstants.GEN_AI_CALLER_CLIENT_IP_KEY, val: '10.0.0.5' }), | ||
| expect.objectContaining({ key: OpenTelemetryConstants.GEN_AI_CALLER_AGENT_CLIENT_IP_KEY, val: '192.168.1.100' }) | ||
| ])); |
There was a problem hiding this comment.
This assertion covers only GEN_AI_CALLER_CLIENT_IP_KEY now, but the test setup above still builds a callerAgentDetails object with the removed agentClientIP field (cast via as any). Since caller-agent client IP is no longer emitted, please remove that unused field from the test data to avoid confusion about what is expected to be tagged.
Summary
gen_ai.*attributes tomicrosoft.*namespacegen_ai.systemconstant; replace withgen_ai.provider.namegen_ai.provider.nameout of base scope — set dynamically in InvokeAgentScope (fromAgentDetails.providerName) and InferenceScope (fromInferenceDetails.providerName)providerNamefield toAgentDetailsinterfacegen_ai.agent.type,gen_ai.execution.type,correlation.id,hiring.manager.id,gen_ai.caller.tenantidgen_ai.caller.agent.tenantid,microsoft.a365.caller.agent.type,gen_ai.caller.agent.user.client.ipoperation.durationfrom span attributesgen_ai.response.idfrom SDKgen_ai.event.contenttogen_ai.tool.call.result, remove duplicateGEN_AI_EVENT_CONTENTconstantgen_ai.caller.agent.upntomicrosoft.a365.caller.agent.user.upnmicrosoft.a365.agent.user.idtomicrosoft.agent.user.idmicrosoft.agent.blueprint.idtomicrosoft.a365.agent.blueprint.idmicrosoft.a365.agent.blueprint.idto base scope (common across all span types per schema)gen_ai.execution.sourceMetadata.idoperation.sourcewithtelemetry.sdk.*attributesgen_ai.agent.thought.processsupport on InferenceScopeserver.address/server.portsupport on InferenceScopeCallerDetailsto base scope class (matching .NET SDK pattern)TELEMETRY_SDK_VERSION_VALUEfrom package.json versionversion.ts(matching runtime package pattern)gen_ai.usage.input_tokens/output_tokensasint,gen_ai.response.finish_reasonsasstring[],server.portasstringTest plan
Generated POST Body
Full POST body captured from SDK export (click to expand)
{ "resourceSpans": [ { "resource": { "attributes": { "host.name": "pefan4-0", "host.arch": "amd64", "host.id": "3dc679db-f652-4002-98b7-5e05e5071507", "process.pid": 29332, "process.runtime.version": "20.18.3", "process.runtime.name": "nodejs", "process.runtime.description": "Node.js", "process.owner": "pefan", "service.name": "TypeScript Sample Agent-1.0.0" } }, "scopeSpans": [ { "scope": { "name": "Agent365Sdk" }, "spans": [ { "traceId": "74ddd591d5b1558b6929b790856f6873", "spanId": "d8dae84064b39ebd", "name": "invoke_agent ComplianceAssistant", "kind": "CLIENT", "attributes": { "gen_ai.operation.name": "invoke_agent", "gen_ai.provider.name": "openai", "telemetry.sdk.name": "A365ObservabilitySDK", "telemetry.sdk.language": "nodejs", "telemetry.sdk.version": "0.0.0-placeholder", "microsoft.tenant.id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "microsoft.session.id": "session-abc-123", "gen_ai.conversation.id": "conv-001-xyz", "microsoft.conversation.item.link": "https://teams.microsoft.com/l/message/conv-001-xyz/msg-42", "gen_ai.agent.id": "30ed5699-b157-4e87-bb45-9b0cfb13b8e5", "gen_ai.agent.name": "ComplianceAssistant", "gen_ai.agent.description": "Helps with compliance queries and policy documents", "microsoft.session.description": "Initial onboarding session", "microsoft.agent.user.upn": "compliance-agent@contoso.com", "microsoft.agent.user.id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "microsoft.a365.agent.platform.id": "platform-agent-001", "service.name": "TypeScript Sample Agent", "microsoft.caller.id": "c8a7b6d5-e4f3-2110-9876-543210fedcba", "microsoft.caller.name": "Jane Smith", "microsoft.caller.upn": "jane.smith@contoso.com", "client.address": "10.0.0.42", "microsoft.channel.name": "msteams", "microsoft.channel.link": "https://teams.microsoft.com/l/channel/general", "microsoft.a365.caller.agent.platform.id": "caller-platform-001", "microsoft.a365.agent.blueprint.id": "bp-9f8e7d6c-5b4a-3210-fedc-ba0987654321", "server.address": "agent365.contoso.com", "server.port": "8443", "microsoft.a365.caller.agent.name": "OrchestratorAgent", "microsoft.a365.caller.agent.id": "caller-agent-1a2b3c4d", "microsoft.a365.caller.agent.blueprint.id": "bp-caller-0001", "microsoft.a365.caller.agent.user.id": "a1234567-b890-cdef-1234-567890abcdef", "microsoft.a365.caller.agent.user.upn": "orchestrator@contoso.com", "gen_ai.input.messages": "What are the data retention policies for GDPR compliance?", "gen_ai.output.messages": "Based on GDPR Article 5(1)(e)..." }, "status": { "code": "UNSET", "message": "" } }, { "traceId": "74ddd591d5b1558b6929b790856f6873", "spanId": "2d4fcf82d15dc2f2", "parentSpanId": "d8dae84064b39ebd", "name": "Chat gpt-4o", "kind": "CLIENT", "attributes": { "gen_ai.operation.name": "Chat", "gen_ai.provider.name": "openai", "telemetry.sdk.name": "A365ObservabilitySDK", "telemetry.sdk.language": "nodejs", "telemetry.sdk.version": "0.0.0-placeholder", "microsoft.tenant.id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "microsoft.session.id": "session-abc-123", "gen_ai.conversation.id": "conv-001-xyz", "microsoft.conversation.item.link": "https://teams.microsoft.com/l/message/conv-001-xyz/msg-42", "gen_ai.agent.id": "30ed5699-b157-4e87-bb45-9b0cfb13b8e5", "gen_ai.agent.name": "ComplianceAssistant", "gen_ai.agent.description": "Helps with compliance queries and policy documents", "microsoft.session.description": "Initial onboarding session", "microsoft.agent.user.upn": "compliance-agent@contoso.com", "microsoft.agent.user.id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "microsoft.a365.agent.platform.id": "platform-agent-001", "service.name": "TypeScript Sample Agent", "microsoft.caller.id": "c8a7b6d5-e4f3-2110-9876-543210fedcba", "microsoft.caller.name": "Jane Smith", "microsoft.caller.upn": "jane.smith@contoso.com", "client.address": "10.0.0.42", "microsoft.channel.name": "msteams", "microsoft.channel.link": "https://teams.microsoft.com/l/channel/general", "microsoft.a365.agent.blueprint.id": "bp-9f8e7d6c-5b4a-3210-fedc-ba0987654321", "gen_ai.request.model": "gpt-4o", "gen_ai.usage.input_tokens": 152, "gen_ai.usage.output_tokens": 287, "gen_ai.response.finish_reasons": ["stop"], "microsoft.a365.agent.thought.process": "Analyzing GDPR data retention query...", "server.address": "api.openai.com", "server.port": "8080", "gen_ai.input.messages": "System: You are a compliance assistant.\nUser: What are the data retention policies for GDPR compliance?", "gen_ai.output.messages": "Based on GDPR Article 5(1)(e)..." }, "status": { "code": "UNSET", "message": "" } }, { "traceId": "74ddd591d5b1558b6929b790856f6873", "spanId": "789b0f09a411741b", "parentSpanId": "d8dae84064b39ebd", "name": "execute_tool search-policy-documents", "kind": "INTERNAL", "attributes": { "gen_ai.operation.name": "execute_tool", "telemetry.sdk.name": "A365ObservabilitySDK", "telemetry.sdk.language": "nodejs", "telemetry.sdk.version": "0.0.0-placeholder", "microsoft.tenant.id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "microsoft.session.id": "session-abc-123", "gen_ai.conversation.id": "conv-001-xyz", "microsoft.conversation.item.link": "https://teams.microsoft.com/l/message/conv-001-xyz/msg-42", "gen_ai.agent.id": "30ed5699-b157-4e87-bb45-9b0cfb13b8e5", "gen_ai.agent.name": "ComplianceAssistant", "gen_ai.agent.description": "Helps with compliance queries and policy documents", "microsoft.session.description": "Initial onboarding session", "microsoft.agent.user.upn": "compliance-agent@contoso.com", "microsoft.agent.user.id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "microsoft.a365.agent.platform.id": "platform-agent-001", "service.name": "TypeScript Sample Agent", "microsoft.caller.id": "c8a7b6d5-e4f3-2110-9876-543210fedcba", "microsoft.caller.name": "Jane Smith", "microsoft.caller.upn": "jane.smith@contoso.com", "client.address": "10.0.0.42", "microsoft.channel.name": "msteams", "microsoft.channel.link": "https://teams.microsoft.com/l/channel/general", "microsoft.a365.agent.blueprint.id": "bp-9f8e7d6c-5b4a-3210-fedc-ba0987654321", "gen_ai.tool.name": "search-policy-documents", "gen_ai.tool.call.arguments": "{\"query\":\"GDPR data retention\",...}", "gen_ai.tool.type": "function", "gen_ai.tool.call.id": "call_abc123", "gen_ai.tool.description": "Searches internal policy document repository...", "server.address": "policy-search.contoso.com", "server.port": "8080", "gen_ai.tool.call.result": "{\"results\":[...]}" }, "status": { "code": "UNSET", "message": "" } } ] } ] } ] }🤖 Generated with Claude Code