Fix getCallerBaggagePairs: resolve userId across all channels#249
Fix getCallerBaggagePairs: resolve userId across all channels#249
Conversation
Normalizes SpanKind, caller.agent.name, error.type, handoff lineage, and token usage across both chat-completions and Responses API shapes so that emitted spans match the A365 observability schema's Invoke Agent (Server, Client), Execute Tool, and Inference Call definitions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rd modelName - Remove detached safeJsonDumps JSDoc, fix extractUsageTokens indentation (Utils.ts) - Hoist SERVER/CLIENT_SPAN_TYPES sets to static class fields to avoid per-span allocation - Guard span name update when modelName is missing/empty - Remove unused SpanKind import from unit test - Fix indentation of agent span assertions in integration test - Upgrade @langchain/openai to ^1.4.4 and @langchain/core to ^1.1.39 to resolve peer dep mismatch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use module: ESNext + moduleResolution: bundler so package exports subpaths (e.g. @langchain/langgraph/prebuilt) resolve without @ts-ignore suppression. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The newer @langchain/openai and @langchain/core versions require Node >= 20, which conflicts with the repo's Node >= 18 support. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ts-jest override of module: commonjs implicitly forces moduleResolution node, which cannot resolve package exports subpaths like @langchain/langgraph/prebuilt. Adding moduleResolution: bundler lets ts-jest resolve subpath exports without @ts-ignore. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…path moduleResolution bundler with module commonjs is not supported by ts-jest in CI. Revert tsconfig/jest config changes and keep @ts-ignore for the @langchain/langgraph/prebuilt import which requires package exports subpath resolution not available in ts-jest's commonjs mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
userId was only set from aadObjectId, which is undefined on non-Teams channels and A2A calls. Add fallback chain: aadObjectId → agenticUserId → from.id Port of microsoft/Agent365-dotnet#246 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates observability caller identity handling so userId baggage is populated consistently across Teams, non-Teams channels, and A2A calls, and expands integration/unit test coverage around observability spans (OpenAI Agents + LangChain).
Changes:
- Fix
getCallerBaggagePairsto resolveuserIdviaaadObjectId → agenticUserId → from.id, with new unit tests for precedence and fallbacks. - Add/extend OpenAI + LangChain observability integration tests and shared span validation helpers.
- Update OpenAI/LangChain tracing utilities (usage token extraction, SpanKind/error/caller/conversation+session attribute mapping) and add required test-time dependencies.
Reviewed changes
Copilot reviewed 16 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/tsconfig.json | Formatting cleanup. |
| tests/package.json | Adds LangChain + zod deps for integration tests. |
| tests/observability/integration/openai-agent-instrument.test.ts | Expands OpenAI Agents integration assertions (SpanKind, message schema, baggage, handoff, error.type). |
| tests/observability/integration/langchain-agent-instrument.test.ts | Adds new LangChain integration test suite for span correctness and baggage/error/caller mapping. |
| tests/observability/integration/helpers/span-validators.ts | New shared helpers for span/message-schema validation and span polling. |
| tests/observability/extension/openai/OpenAIAgentsTraceProcessor.test.ts | Removes some handoff unit tests; adds usage mapping unit tests; notes some behaviors moved to integration tests. |
| tests/observability/extension/langchain/LangChainObservabilityAttributes.test.ts | Updates expectations to map conversation_id and session_id separately. |
| tests/observability/extension/hosting/TurnContextUtils.test.ts | Adds unit tests for userId precedence/fallback chain. |
| tests/observability/extension/hosting/BaggageBuilderUtils.test.ts | Updates expectation: caller userId now populated from agenticUserId. |
| tests/jest.config.cjs | Adds moduleNameMapper for @microsoft/agents-a365-observability-hosting. |
| pnpm-workspace.yaml | Adds @langchain/openai to the workspace catalog. |
| pnpm-lock.yaml | Updates lockfile for new LangChain deps and transitive changes. |
| packages/agents-a365-observability-hosting/src/utils/TurnContextUtils.ts | Implements userId fallback chain for caller baggage. |
| packages/agents-a365-observability-extensions-openai/src/Utils.ts | Adds extractUsageTokens to normalize token usage across API shapes. |
| packages/agents-a365-observability-extensions-openai/src/OpenAIAgentsTraceProcessor.ts | Adds SpanKind mapping, error.type attribute, and handoff→invoke_agent/caller mapping changes. |
| packages/agents-a365-observability-extensions-openai/src/Constants.ts | Removes graph-node constants (now mapping to schema keys instead). |
| packages/agents-a365-observability-extensions-langchain/src/Utils.ts | Separates session.id vs gen_ai.conversation.id mapping. |
| packages/agents-a365-observability-extensions-langchain/src/tracer.ts | Sets SpanKind by operation, sets error.type, and derives caller.agent.name via parent-walk. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| '@langchain/core@1.1.40': | ||
| resolution: {integrity: sha512-RJ41GQEMxr9ZEZNoIiPgW0+v9nAY6FEZGlk+MjBghr2GR8He50abLam0XCe1aqUJjuKbqt2lUD6M+6SZ+2NIJg==} | ||
| engines: {node: '>=20'} |
There was a problem hiding this comment.
Fixed — reverted all unrelated changes including pnpm-lock.yaml. PR is now scoped to only the userId fallback fix.
| '@langchain/openai@0.5.18': | ||
| resolution: {integrity: sha512-CX1kOTbT5xVFNdtLjnM0GIYNf+P7oMSu+dGCFxxWRa3dZwWiuyuBXCm+dToUGxDLnsHuV1bKBtIzrY1mLq/A1Q==} | ||
| engines: {node: '>=18'} | ||
| peerDependencies: | ||
| '@langchain/core': '>=0.3.58 <0.4.0' | ||
|
|
There was a problem hiding this comment.
Fixed — reverted. pnpm-lock.yaml is no longer changed in this PR.
| export class OpenAIAgentsTraceProcessor implements TracingProcessor { | ||
| private static readonly MAX_HANDOFFS_IN_FLIGHT = 1000; | ||
| private static readonly MAX_SPANS_IN_FLIGHT = 10_000; | ||
| private static readonly SERVER_SPAN_TYPES = new Set(['agent']); | ||
| private static readonly CLIENT_SPAN_TYPES = new Set(['handoff', 'response', 'generation', 'function', 'mcp_tools']); | ||
|
|
There was a problem hiding this comment.
Fixed — removed all unrelated OpenAI/LangChain tracing changes. PR is now scoped to only the userId fallback chain fix and its tests.
| // SpanKind, caller.agent.name, handoff A→B, and error.type are validated by | ||
| // the integration test (openai-agent-instrument.test.ts). |
There was a problem hiding this comment.
Fixed — reverted. The original unit tests are preserved as-is.
Scope PR to only the userId fallback chain fix and its tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
aadObjectId, which isundefinedon non-Teams channels and A2A callsaadObjectId → agenticUserId → from.idChannel behavior after fix
Test plan
🤖 Generated with Claude Code