Skip to content

feat: allow custom session metadata enrichment in watch() API#439

Open
arcgod-design wants to merge 5 commits into
sreerevanth:mainfrom
arcgod-design:feat/issue-147-session-metadata
Open

feat: allow custom session metadata enrichment in watch() API#439
arcgod-design wants to merge 5 commits into
sreerevanth:mainfrom
arcgod-design:feat/issue-147-session-metadata

Conversation

@arcgod-design

@arcgod-design arcgod-design commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds metadata keyword argument to watch() and GenericAdapter.__init__()
  • Custom metadata is attached to all events emitted in the session
  • Session metadata is seeded from the first event's metadata in TraceCollector.ingest()
  • Adds 5 new tests for metadata enrichment

Changes

  • agentwatch/core/watcher.py: Added metadata param to GenericAdapter.__init__, _emit_safely, _async_emit, and watch(). Merges session metadata into all events.
  • agentwatch/tracing/collector.py: Seeds session metadata from first event's metadata on session creation.
  • tests/test_watcher.py: Added 5 new tests for metadata functionality.

Usage

from agentwatch import watch

agent = MyAgent()
watch(agent, metadata={"user_id": "u-123", "tenant": "acme", "env": "prod"})

Testing

All 28 watcher tests pass, including 5 new metadata tests:

  • test_watch_metadata_attached_to_events
  • test_watch_metadata_merged_with_call_metadata
  • test_watch_no_metadata_empty_dict
  • test_generic_adapter_metadata_stored
  • test_generic_adapter_empty_metadata

Closes

closes #147

Summary by CodeRabbit

  • New Features
    • Added metadata support to agent watching via watch(...), attaching it to SESSION_START events and merging it into later emitted agent events.
    • Session metadata is included in safety-related tool-call events.
  • Bug Fixes
    • Improved trace ingestion so incoming event metadata is reflected in the associated trace session.
  • Tests
    • Added coverage for custom session metadata enrichment, merge behavior, safety tool-call metadata, and default handling when metadata isn’t provided.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a3f6a450-d28c-4993-862a-9446ab35c75a

📥 Commits

Reviewing files that changed from the base of the PR and between ca686b7 and bbcf7a5.

📒 Files selected for processing (2)
  • agentwatch/core/watcher.py
  • agentwatch/tracing/collector.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • agentwatch/tracing/collector.py
  • agentwatch/core/watcher.py

📝 Walkthrough

Walkthrough

Adds an optional metadata parameter to watch() and GenericAdapter, merges it into emitted AgentEvent metadata, seeds session metadata during trace ingestion, and adds tests for the new behavior.

Changes

Custom Session Metadata Enrichment

Layer / File(s) Summary
watch() and GenericAdapter constructor updates
agentwatch/core/watcher.py
watch() adds metadata: dict[str, Any] | None = None to its signature and docstring, and forwards it to GenericAdapter. GenericAdapter.__init__ accepts the same parameter and stores it as _session_metadata, defaulting to {}.
Framework-specific metadata attachment helpers
agentwatch/core/watcher.py
_attach_langchain, _attach_langgraph, _attach_autogen, and _attach_smolagents now accept metadata and assign it into each adapter’s _session_metadata when provided.
Metadata merging in event emission
agentwatch/core/watcher.py
_emit_safely and _async_emit merge _session_metadata with per-event metadata before building AgentEvent.
Safety-gated tool-call metadata wiring
agentwatch/core/watcher.py
Async and sync safety TOOL_CALL event creation now includes _session_metadata in the payload.
TraceCollector session metadata seeding
agentwatch/tracing/collector.py
TraceCollector.ingest updates trace.session.metadata from event.metadata after creating a new session for an unseen session_id, when metadata is present.
Tests
tests/test_watcher.py
Adds tests for SESSION_START metadata, merged event metadata, the no-metadata case, and GenericAdapter storage/defaults.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐇 Hop hop, a metadata breeze,
user_id and friends now ride with ease.
From watch to trace, the context glows,
In every event, the session shows.
A carrot toast for this tidy chore,
Custom trace crumbs, and a little more!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.37% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding custom session metadata support to watch().
Linked Issues check ✅ Passed The PR implements issue #147 by adding metadata to watch(), GenericAdapter, event emission, and trace ingestion.
Out of Scope Changes check ✅ Passed The changes stay focused on session metadata enrichment and related tests, with no clear unrelated additions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
agentwatch/core/watcher.py (1)

583-599: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Metadata is not propagated for framework-specific adapters.

Line 584, Line 588, Line 592, and Line 596 call framework-specific attachers without forwarding metadata, while only the generic fallback receives it at Line 609. This breaks the watch-level contract for LangChain/LangGraph/Autogen/Smolagents sessions.

Also applies to: 609-610

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agentwatch/core/watcher.py` around lines 583 - 599, The framework-specific
attacher functions _attach_langchain, _attach_langgraph, _attach_autogen, and
_attach_smolagents are being called without passing the metadata argument, while
the generic fallback case does pass it. Add metadata as an argument to each of
these four function calls to ensure consistent metadata propagation across all
framework adapters and maintain the watch-level contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@agentwatch/core/watcher.py`:
- Line 243: The metadata dictionary is stored by reference in
self._session_metadata at line 243 and reused directly in TOOL_CALL events at
lines 310-311 and 386-387. Any downstream mutation of the metadata dict will
affect all future events. Fix this by creating a snapshot copy when storing
metadata in self._session_metadata initialization, and creating independent
copies of self._session_metadata when emitting TOOL_CALL events at those
locations to ensure each event has its own isolated metadata dictionary.

---

Outside diff comments:
In `@agentwatch/core/watcher.py`:
- Around line 583-599: The framework-specific attacher functions
_attach_langchain, _attach_langgraph, _attach_autogen, and _attach_smolagents
are being called without passing the metadata argument, while the generic
fallback case does pass it. Add metadata as an argument to each of these four
function calls to ensure consistent metadata propagation across all framework
adapters and maintain the watch-level contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 78293598-1cdf-43a0-b099-2f28a82db6cf

📥 Commits

Reviewing files that changed from the base of the PR and between 3b1f4b5 and ec26add.

📒 Files selected for processing (3)
  • agentwatch/core/watcher.py
  • agentwatch/tracing/collector.py
  • tests/test_watcher.py

Comment thread agentwatch/core/watcher.py Outdated
@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

🧪 PR Test Results

Check Result
Tests (pytest tests/) ✅ success
Lint (ruff check .) ❌ failure
Coverage (agentwatch) 74.71%

Python 3.12 · commit bbcf7a5

@sreerevanth

Copy link
Copy Markdown
Owner

@arcgod-design please check your prs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] allow custom session metadata enrichment in watch() API

2 participants