Skip to content

Add OutputScope, BaggageMiddleware, OutputLoggingMiddleware, and ObservabilityHostingManager#210

Merged
nikhilNava merged 5 commits intomainfrom
users/pefan/middleware2
Mar 2, 2026
Merged

Add OutputScope, BaggageMiddleware, OutputLoggingMiddleware, and ObservabilityHostingManager#210
nikhilNava merged 5 commits intomainfrom
users/pefan/middleware2

Conversation

@fpfp100
Copy link
Contributor

@fpfp100 fpfp100 commented Feb 24, 2026

Summary

  • Add OutputScope to @microsoft/agents-a365-observability for tracing output messages with parent span linking, caller details, and custom start/end time support
  • Split MessageLoggingMiddleware into BaggageMiddleware (baggage propagation) and OutputLoggingMiddleware (output span tracing)
  • Add ObservabilityHostingManager as an entry point for configuring hosting-layer middleware
  • Remove InputScope (not supported in current schema)
  • Remove parseExecutionType (execution type removed in new telemetry schema)

Middleware setup

import { ObservabilityHostingManager } from '@microsoft/agents-a365-observability-hosting';

// Create a manager and register middleware on the adapter
const manager = new ObservabilityHostingManager();
manager.configure(adapter, {
  enableOutputLogging: true,  // default: false
  // enableBaggage: true,     // default: true
});

BaggageMiddleware is registered by default and propagates caller, agent, tenant, channel, conversation, and execution type as OpenTelemetry baggage. Set enableBaggage: false to disable.

OutputLoggingMiddleware creates OutputScope spans for outgoing messages. To link output spans as children of an InvokeAgentScope, set A365_PARENT_SPAN_KEY in turnState:

import { A365_PARENT_SPAN_KEY } from '@microsoft/agents-a365-observability-hosting';

// Inside your agent handler, after creating an InvokeAgentScope:
context.turnState.set(A365_PARENT_SPAN_KEY, {
  traceId: scope.spanContext.traceId,
  spanId: scope.spanContext.spanId,
  traceFlags: scope.spanContext.traceFlags,
});

Span hierarchy

invoke_agent A365 Agent [root]
├── output_messages A365 Agent [child — linked via A365_PARENT_SPAN_KEY]
└── output_messages A365 Agent [child — linked via A365_PARENT_SPAN_KEY]

Test plan

  • 3 unit tests for BaggageMiddleware (baggage propagation, async reply skip, pass-through)
  • 8 unit tests for OutputLoggingMiddleware (span creation, caller details, parent linking, async reply, error re-throw, skip conditions)
  • 4 unit tests for ObservabilityHostingManager (default middleware, options, idempotency)
  • 3 unit tests for OutputScope (attributes, parent ref, message recording)
  • All 56 suites / 1070 tests pass

🤖 Generated with Claude Code

… tracing

Introduces message-level tracing via InputScope and OutputScope, registered
through MessageLoggingMiddleware and ObservabilityMiddlewareRegistrar. Both
scopes lazily read A365_PARENT_SPAN_KEY from turnState so the agent handler
can link them as children of an InvokeAgentScope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@fpfp100 fpfp100 requested a review from a team as a code owner February 24, 2026 09:29
Copilot AI review requested due to automatic review settings February 24, 2026 09:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive tracing support for input and output messages in the observability pipeline by introducing InputScope and OutputScope for message tracing, along with MessageLoggingMiddleware for automatic integration into the adapter pipeline. The PR also standardizes message recording across all scopes to use JSON array format instead of comma-separated strings.

Changes:

  • Added InputScope and OutputScope classes with lazy parent span linking via turnState, supporting caller details, conversation IDs, execution types, and source metadata
  • Added MessageLoggingMiddleware to automatically create input/output spans with baggage propagation and optional parent span linking through A365_PARENT_SPAN_KEY
  • Changed message recording format from comma-separated to JSON arrays across InvokeAgentScope, InferenceScope, and new scopes
  • Added parseExecutionType() helper function for safe string-to-enum conversion with validation

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/agents-a365-observability/src/tracing/scopes/InputScope.ts New scope class for tracing input messages with caller details, conversation ID, execution type, and lazy flush optimization
packages/agents-a365-observability/src/tracing/scopes/OutputScope.ts Enhanced to accept caller details, execution type, source metadata, and conversation ID; implements lazy flush for recordOutputMessages
packages/agents-a365-observability-hosting/src/middleware/MessageLoggingMiddleware.ts New middleware for automatic input/output tracing with baggage propagation and parent span linking support
packages/agents-a365-observability-hosting/src/middleware/ObservabilityMiddlewareRegistrar.ts Fluent builder for registering observability middleware on adapters
packages/agents-a365-observability/src/tracing/scopes/InvokeAgentScope.ts Updated recordInputMessages and recordOutputMessages to use JSON.stringify instead of join
packages/agents-a365-observability/src/tracing/scopes/InferenceScope.ts Updated recordInputMessages and recordOutputMessages to use JSON.stringify instead of join
packages/agents-a365-observability/src/tracing/contracts.ts Added parseExecutionType helper for safe string-to-enum conversion with Set-based validation
packages/agents-a365-observability/src/tracing/constants.ts Added INPUT_MESSAGES_OPERATION_NAME constant
packages/agents-a365-observability-hosting/src/utils/ScopeUtils.ts Updated to use parseExecutionType with fallback to base execution type
packages/agents-a365-observability/src/index.ts Exported InputScope and parseExecutionType
packages/agents-a365-observability-hosting/src/index.ts Exported MessageLoggingMiddleware, A365_PARENT_SPAN_KEY, MessageLoggingMiddlewareOptions, and ObservabilityMiddlewareRegistrar
tests/observability/core/input-scope.test.ts Comprehensive test coverage for InputScope including parent linking, caller details, and message recording
tests/observability/core/output-scope.test.ts Refactored and consolidated tests for OutputScope
tests/observability/extension/hosting/message-logging-middleware.test.ts Extensive test coverage including error handling, parent linking, baggage propagation, and async replies
tests/observability/extension/hosting/observability-middleware-registrar.test.ts Tests for fluent builder pattern and middleware registration
tests/observability/extension/hosting/scope-utils.test.ts Updated assertions to expect JSON.stringify format for input messages

@fpfp100 fpfp100 changed the title Add InputScope, OutputScope, and MessageLoggingMiddleware Add OutputScope, BaggageMiddleware, OutputLoggingMiddleware, and ObservabilityHostingManager Feb 25, 2026
- Remove parseExecutionType (execution type removed in new schema)
- Make ObservabilityHostingManager.configure() an instance method with required params
- Remove static singleton pattern and getInstance() from ObservabilityHostingManager
- Update CHANGELOG with unreleased changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 27, 2026 21:34
@fpfp100 fpfp100 requested a review from a team as a code owner February 27, 2026 21:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 2, 2026 12:25
@nikhilNava nikhilNava merged commit ddf4902 into main Mar 2, 2026
9 checks passed
@nikhilNava nikhilNava deleted the users/pefan/middleware2 branch March 2, 2026 12:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

* TurnState key for the parent span reference.
* Set this in `turnState` to link OutputScope spans as children of an InvokeAgentScope.
*/
export const A365_PARENT_SPAN_KEY = 'A365ParentSpanId';
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A365_PARENT_SPAN_KEY stores a full ParentSpanRef (traceId/spanId/traceFlags), but the underlying string value 'A365ParentSpanId' implies it contains only a spanId. This is likely to confuse consumers and can lead to incorrect usage. Consider renaming the key string to reflect that it stores a parent span reference/context (and keep the exported constant name/value aligned).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants