Use Activity helpers and ResolveAgentIdentity for agent telemetry#211
Use Activity helpers and ResolveAgentIdentity for agent telemetry#211
Conversation
Replace direct ChannelAccount property access with Activity class helpers (getAgenticInstanceId, getAgenticUser, getAgenticTenantId) in ScopeUtils and TurnContextUtils. Use RuntimeUtility.ResolveAgentIdentity for blueprint ID resolution when authToken is provided, falling back to recipient.agenticAppBlueprintId. Add authToken parameter with overloaded signatures (required + deprecated no-arg) for backward compatibility. Upgrade @microsoft/agents-hosting and agents-activity to ^1.3.1. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This pull request refactors agent telemetry collection to use Activity class helper methods instead of direct ChannelAccount property access, adds authentication token-based agent identity resolution, and upgrades key dependencies. The changes aim to improve blueprint ID resolution for telemetry and standardize how agent identity information is extracted from TurnContext.
Changes:
- Replace direct ChannelAccount property access with Activity helper methods (
getAgenticInstanceId(),getAgenticUser(),getAgenticTenantId()) - Add
authTokenparameter to telemetry scope population methods with TypeScript overloads for backward compatibility - Upgrade
@microsoft/agents-hostingand@microsoft/agents-activityfrom alpha to stable release (1.3.1)
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Updates catalog versions for agents-hosting and agents-activity to 1.3.1 |
| pnpm-lock.yaml | Reflects dependency upgrades including msal-node 5.0.4, axios 1.13.5, jwks-rsa 3.2.2, and @types/express 5.0.6 |
| packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts | Adds authToken parameter with overloads to scope population methods; uses RuntimeUtility.ResolveAgentIdentity for blueprint resolution; switches to Activity helpers |
| packages/agents-a365-observability-hosting/src/utils/TurnContextUtils.ts | Replaces direct property access with getAgenticInstanceId() and getAgenticTenantId() helpers; removes channelData tenant ID fallback |
| tests/observability/extension/hosting/scope-utils.test.ts | Updates test fixtures to use Activity helper methods and removes agenticAppBlueprintId from recipient to test undefined fallback |
| tests/observability/extension/hosting/TurnContextUtils.test.ts | Updates test fixtures to use Activity helpers and adjusts assertions to expect undefined for aadObjectId and agenticAppBlueprintId |
| tests/observability/extension/hosting/BaggageBuilderUtils.test.ts | Updates test fixtures to use Activity helpers and adjusts baggage assertions to expect undefined values |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
…atures - Extract deriveAgentDetailsCore and buildInvokeAgentDetailsCore as private methods so internal callers bypass deprecated overloads (fixes @typescript-eslint/no-deprecated lint errors) - Remove `public` from implementation signatures of overloaded methods (only the two declared overloads should be public-facing) - Fix stale JSDoc on getTenantIdPair (removed ChannelData reference) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
…token blueprint claim for agentBlueprintId - agentId now uses ResolveAgentIdentity (works for both app-based and blueprint agents) - agentBlueprintId now reads xms_par_app_azp from token for blueprint agents - Remove deprecated overloads and backward-compat code, authToken is now required - Consolidate deriveAgentDetailsCore into deriveAgentDetails Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
…adoption Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gMiddleware - Resolve merge conflicts in ScopeUtils.ts and CHANGELOG.md - OutputLoggingMiddleware reads auth token from turnState (A365_AUTH_TOKEN_KEY) for non-agentic requests, passes empty string for agentic requests - Add Activity helper methods to test mocks for new middleware tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
packages/agents-a365-observability-hosting/src/middleware/OutputLoggingMiddleware.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/TurnContextUtils.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/TurnContextUtils.ts
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nikhilNava
left a comment
There was a problem hiding this comment.
BlueprintId is a critical identifier used for downstream analytics and reporting.
While it is technically possible to derive the BlueprintId on the server (since it may be present in the token), this is not currently enforced because the value is not guaranteed to exist on every token.
To ensure accuracy and intentionality, the I recommend BlueprintId should be explicitly set by the agent developer rather than inferred implicitly on the SDK or the server.
packages/agents-a365-observability-hosting/src/middleware/OutputLoggingMiddleware.ts
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts
Outdated
Show resolved
Hide resolved
…rage - Extract resolveEmbodiedAgentIds() into TurnContextUtils as shared helper - Align getTargetAgentBaggagePairs with deriveAgentDetails (no agentId for non-agentic) - Add resolveAuthToken to OutputLoggingMiddleware with per-request/cache dual path - Export isPerRequestExportEnabled from observability public API - Fix CHANGELOG to reflect actual agentId resolution behavior - Add test coverage for resolveAuthToken (per-request, cache, fallback paths) - Remove unused ResolveAgentIdentity mock from scope-utils tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts:226
- In
buildInvokeAgentDetailsCore, spreading...agentafter...detailscan overwrite caller-provided values withundefined(e.g.,details.agentIdbecomesundefinedwhenderiveAgentDetailsreturns{ agentId: undefined, ... }). This can silently drop required fields and lead to incorrect telemetry. Consider only overriding fields when the derived value is defined/non-empty, or havederiveAgentDetailsreturnundefined(so the spread doesn’t occur) when no agent id can be derived.
private static buildInvokeAgentDetailsCore(details: InvokeAgentDetails, turnContext: TurnContext, authToken: string): InvokeAgentDetails {
const agent = ScopeUtils.deriveAgentDetails(turnContext, authToken);
const srcMetaFromContext = ScopeUtils.deriveSourceMetadataObject(turnContext);
const baseRequest = details.request ?? {};
const baseSource = baseRequest.sourceMetadata ?? {};
const mergedSourceMetadata = {
...baseSource,
...(srcMetaFromContext.name !== undefined ? { name: srcMetaFromContext.name } : {}),
...(srcMetaFromContext.description !== undefined ? { description: srcMetaFromContext.description } : {}),
};
return {
...details,
...agent,
conversationId: ScopeUtils.deriveConversationId(turnContext),
request: {
...baseRequest,
sourceMetadata: mergedSourceMetadata
}
};
packages/agents-a365-observability-hosting/src/middleware/OutputLoggingMiddleware.ts
Show resolved
Hide resolved
packages/agents-a365-observability-hosting/src/utils/TurnContextUtils.ts
Outdated
Show resolved
Hide resolved
…mbodiedAgentIds - Correct JSDoc for A365_AUTH_TOKEN_KEY: token is used for embodied/agentic requests (blueprint ID resolution), not non-agentic requests - Normalize empty strings to undefined in resolveEmbodiedAgentIds to prevent noisy telemetry attributes from empty agentId/agentBlueprintId values Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
ScopeUtils.deriveAgentDetailsnow usesRuntimeUtility.ResolveAgentIdentity()foragentId(works for both app-based and blueprint-based agents) instead ofrecipient.agenticAppIdwhich only worked for blueprint agents.agentBlueprintIdis now resolved from the JWTxms_par_app_azpclaim viaRuntimeUtility.getAgentIdFromToken()for agentic requests, instead of incorrectly using the instance ID.ChannelAccountproperty access with Activity helpers (getAgenticInstanceId(),getAgenticUser(),getAgenticTenantId()) inScopeUtilsandTurnContextUtils.channelDatatenant ID fallback ingetTenantIdPair()— now usesgetAgenticTenantId().@microsoft/agents-hostingand@microsoft/agents-activityfrom^1.1.0-alpha.85to^1.3.1.Breaking Changes
ScopeUtils.deriveAgentDetails(turnContext, authToken)— new requiredauthTokenparameter.ScopeUtils.populateInferenceScopeFromTurnContext(details, turnContext, authToken, ...)— new requiredauthTokenparameter.ScopeUtils.populateInvokeAgentScopeFromTurnContext(details, turnContext, authToken, ...)— new requiredauthTokenparameter.ScopeUtils.populateExecuteToolScopeFromTurnContext(details, turnContext, authToken, ...)— new requiredauthTokenparameter.ScopeUtils.buildInvokeAgentDetails(details, turnContext, authToken)— new requiredauthTokenparameter.Test plan
pnpm buildsucceeds (including CJS + ESM for all packages)deriveAgentDetailsresolvesagentIdviaResolveAgentIdentity()andagentBlueprintIdviagetAgentIdFromToken()deriveTenantDetailsusesgetAgenticTenantId()helpergetTargetAgentBaggagePairsusesgetAgenticInstanceId()getTenantIdPairusesgetAgenticTenantId()🤖 Generated with Claude Code