All notable changes to this package will be documented in this file.
- OBS exports always use
/observabilityService— Theuse_s2s_endpointoption is deprecated and ignored, even whenFalse. Exports no longer select or fall back to/observability. Provide an app-only OBS token independently of your agent's workload auth; the S2S service rejects delegatedscptokens. - OBS export requires the configured app-only resolver — The exporter uses
only
token_resolver(agent_id, tenant_id)for Agent 365 authentication. If the Agent 365 exporter is enabled without a resolver, the existing console fallback is kept and nothing is sent to Agent 365. Empty tokens or acquisition failures fail export without an HTTP request or delegated fallback. The exporter invokes the resolver on every export batch/identity group, so resolvers must cache the acquired token and refresh only near expiry. - Manual inference operation names and span-name prefixes now use canonical
OpenTelemetry values —
Chat,TextCompletion, andGenerateContentbecomechat,text_completion, andgenerate_content, respectively. For example,Chat gpt-4becomeschat gpt-4. The Agent 365 exporter recognizes the canonical names (the legacyChatvalue is still accepted), so text-completion and generate-content spans that were previously filtered out are now exported to Agent 365. InferenceCallDetailsnow validates model identity during construction —modelandresponseModelare stripped and whitespace-only values are treated asNone. If both are missing, empty, or whitespace-only, construction raisesValueError. Previously these values were accepted without validation. This happens before anInferenceScopeis created.- Message payloads serialize as a plain JSON array —
gen_ai.input.messagesandgen_ai.output.messagesare now serialized per the OpenTelemetry GenAI semantic conventions as[{"role": ..., "parts": [...]}]instead of the{"version": "0.1.0", "messages": [...]}wrapper. TheA365_MESSAGE_SCHEMA_VERSIONconstant and theversionfield onInputMessages/OutputMessagesare removed, andOutputMessage.finish_reasonnow defaults to"stop"instead ofNone.
ApplyGuardrailScopefor tracing security guardrail evaluations (apply_guardrailoperation), with supportingGuardrailDetails,GuardrailFinding,GuardrailDecisionType,GuardrailRiskSeverity, andGuardrailTargetTypetypes andmicrosoft.guardian.*/microsoft.security.*attribute constants.apply_guardrailspans are exported to Agent 365.AgentDetails.agent_typeandBaggageBuilder.agent_type()emitgen_ai.agent.type. Both accept anAgentTypeenum member or a string; enum members are emitted as their string.value. The new dataclass field is appended after existing fields, preserving positional-argument compatibility.InferenceCallDetails.responseModel,cacheReadInputTokens, andcacheWriteInputTokensemitgen_ai.response.model,gen_ai.usage.cache_read.input_tokens, andgen_ai.usage.cache_write.input_tokens.modelis now optional whenresponseModelis supplied. The new fields are appended after existing fields, preserving positional-argument compatibility.InferenceScope.record_cache_read_input_tokens()andrecord_cache_write_input_tokens().InferenceOperationType.canonical_namereturns the canonical lowercase OpenTelemetry operation name.
InferenceScopeemitsserver.portas an integer instead of a string.
- Scopes and the Agent 365 exporter no longer raise
AttributeErrorwhen the tracer returns aNonRecordingSpan(for example, when the token resolver returnsNoneon the first turn); span context is read viaget_span_context().
- Request the OBS resource
/.defaultscope (api://9b975845-388f-4429-889e-eab1ef63949c/.default) for the exporting agent identity. Do not use delegatedAgent365.Observability.OtelWritetokens for OBS export. - Validate resolver tokens before returning them: reject any
scpclaim and anyidtypother thanapp; whenidtypis absent, accept only a non-emptyrolesarray or a non-emptyoidequal tosub; verifyaudis the OBS resource and the token is not expired. - Update case-sensitive operation-name and span-name filters, dashboards, and alerts to the canonical values above, or compare case-insensitively.
- Supply a non-blank
modelorresponseModelwhen constructingInferenceCallDetails; validate optional configuration before constructing the telemetry object so missing model identity does not interrupt a request. - Update consumers that parse
gen_ai.input.messages/gen_ai.output.messagesto expect a JSON array rather than a{version, messages}object, and remove references toA365_MESSAGE_SCHEMA_VERSION.
- New permission required:
Agent365.Observability.OtelWrite— The observability exporter now requires this scope as both a delegated and application permission on your agent blueprint. See Upgrade Instructions below.
Existing agent blueprints need Agent365.Observability.OtelWrite granted as both a delegated permission and an application permission. Choose either option below.
Requires a365.config.json and a365.generated.config.json in your config directory, a Global Administrator account, and Agent 365 CLI v1.1.139-preview or later.
a365 setup admin --config-dir "<path-to-config-dir>"
This grants all missing permissions including the new Observability scopes.
Requires Global Administrator access to the blueprint app registration.
- Go to Entra portal > App registrations > select your Blueprint app
- Go to API permissions > Add a permission > APIs my organization uses > search for
9b975845-388f-4429-889e-eab1ef63949c - Select Delegated permissions > check
Agent365.Observability.OtelWrite> Add permissions - Repeat step 2–3, this time select Application permissions > check
Agent365.Observability.OtelWrite> Add permissions - Click Grant admin consent and confirm
Both Agent365.Observability.OtelWrite (Delegated) and Agent365.Observability.OtelWrite (Application) should show Granted status.
Note: If your agent is autonomous, you only need the Application permission. The delegated permission is required for agents that authenticate via a user session.
InvokeAgentDetailsrenamed toInvokeAgentScopeDetails— Now contains only scope-level config (endpoint). Agent identity (AgentDetails) is a separate parameter.session_idmoved toRequest.InvokeAgentScope.start(): New signaturestart(request, invoke_scope_details, agent_details, caller_details?, span_details?).requestis required.InferenceScope.start(): New signaturestart(request, details, agent_details, user_details?, span_details?).requestis required.ExecuteToolScope.start(): New signaturestart(request, details, agent_details, user_details?, span_details?). Same pattern asInferenceScope.OutputScope.start(): New signaturestart(request, response, agent_details, user_details?, span_details?). Same pattern.CallerDetailsrenamed toUserDetails— Fields renamed:caller_id→user_id,caller_upn→user_email,caller_name→user_name,caller_client_ip→user_client_ip.CallerDetailsis now a composite wrapper — Groupsuser_details: UserDetailsandcaller_agent_details: AgentDetailsfor A2A scenarios.TenantDetailsremoved —tenant_idis now onAgentDetails.tenant_id. Removed from all scopestart()methods.ExecutionTypeenum removed — Removed fromRequest.GEN_AI_EXECUTION_TYPE_KEYconstant also removed.AgentDetailsfields renamed —agent_auid→agentic_user_id,agent_upn→agentic_user_email.conversation_idmoved toRequest.Requestmodel updated — Removedexecution_type. Addedconversation_id.contentis now optional.BaggageBuildermethods 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().
SpanDetails— Groupsspan_kind,parent_context,start_time,end_timefor scope construction.UserDetails— Human caller identity withuser_id,user_email,user_name,user_client_ip.CallerDetails(new wrapper) — Groupsuser_detailsandcaller_agent_detailsfor A2A scenarios.InvokeAgentScopeDetails— Scope-level config withendpointonly.Request.conversation_id— Conversation ID field on the unifiedRequestmodel.ERROR_TYPE_CANCELLEDconstant —"TaskCanceledException", used byrecord_cancellation().OutputScopenow exported frommicrosoft_agents_a365.observability.core.