Skip to content

feat(instrument): Port LangGraph framework adapter (M2)#100

Closed
mmercuri wants to merge 2 commits into
feat/instrument-frameworks-orchestrationfrom
feat/instrument-frameworks-langgraph
Closed

feat(instrument): Port LangGraph framework adapter (M2)#100
mmercuri wants to merge 2 commits into
feat/instrument-frameworks-orchestrationfrom
feat/instrument-frameworks-langgraph

Conversation

@mmercuri

Copy link
Copy Markdown
Contributor

Summary

M2 fan-out PR completing the LangGraph framework adapter port. The
mechanical multi-file copy from ateam/stratix/sdk/python/adapters/langgraph/
(7 files, ~2,248 LOC) landed via the M1.C orchestration PR (#96, this PR's
base); this PR layers the M2 deliverables on top:

  • Round-2 deliberation item 23 — STRATIX* deprecation alias.
    STRATIXLangGraphAdapter is now resolved through PEP 562
    module-level __getattr__. Accessing the old name still returns
    LayerLensLangGraphAdapter but raises a DeprecationWarning
    pointing at the v2.0 removal, fired only at attribute-access time
    so bare import keeps working without warnings.
  • Round-2 deliberation item 20 — Pydantic v2-only manifest field.
    get_adapter_info() now sets requires_pydantic = PydanticCompat.V2_ONLY
    explicitly. Both the manifest wrapper (info()) and the subclass
    override now agree, so the atlas-app catalog UI shows the right
    compat badge regardless of which entrypoint the manifest emitter
    ends up calling.
  • Dedicated unit-test module at
    tests/instrument/adapters/frameworks/test_langgraph.py — 29 tests
    modelled after the SmolAgents / Langfuse adapter test pattern.
    Mocks LangGraph at the SDK shape level (_FakeCompiledGraph with
    invoke / ainvoke); covers lifecycle, info() reporting,
    alias deprecation, graph wrapping (success + error), handoff
    detection, trace_node / trace_langgraph_tool decorators,
    wrap_llm_for_langgraph (sync + async), state adapter, and
    replay serialization.
  • Expanded sample. samples/instrument/langgraph/main.py now
    builds a 3-node planner -> researcher -> writer graph instead of
    the single-node smoke. LLM call inside the writer uses a MockLLM
    (no API key required); HttpEventSink import is best-effort so
    the sample runs cleanly even before the M1.E transport PR (instrument: HTTP/OTLP transport sinks + extras matrix CI #98)
    lands. Added samples/instrument/langgraph/README.md covering
    topology, expected output, and a "going to production" path.
  • Docs. docs/adapters/frameworks-langgraph.md clarified — the
    backward-compat section now mentions the DeprecationWarning and
    a new Pydantic-compatibility section explains the v2-only stance.

Reference template followed: the already-shipped LangChain adapter at
src/layerlens/instrument/adapters/frameworks/langchain/.

Pydantic compatibility

LangGraph >= 0.2 inherits langchain-core's Pydantic v2-only
requirement. The package's __init__.py calls requires_pydantic(V2_ONLY)
at import time and the manifest declares it on every entry point, so users
on v1 see a clear RuntimeError instead of an opaque ImportError mid-
callback.

Stacks on

Test plan

  • uv run pytest tests/instrument/adapters/frameworks/test_langgraph.py -x
    --> 29 passed
  • uv run mypy --strict src/layerlens/instrument/adapters/frameworks/langgraph
    --> Success: no issues found in 7 source files
  • uv run ruff check src/.../langgraph tests/.../test_langgraph.py
    --> All checks passed
  • test_lazy_imports.py (the two non-protocols-dependent guards)
    and test_default_install.py still green
  • python samples/instrument/langgraph/main.py exits 0 with the
    3-node graph result + event-type counts printed
  • Reviewer (m-peko) verifies the PEP 562 alias pattern + the
    requires_pydantic propagation matches the conventions the
    remaining M2 fan-out PRs will adopt.

M2 fan-out work — completes the LangGraph adapter port that landed
mechanically in the M1.C orchestration PR (#96) by adding:

* Round-2 item 23: ``STRATIXLangGraphAdapter`` is now a deprecation
  alias served via PEP 562 ``__getattr__`` on the package. Accessing
  the old name returns ``LayerLensLangGraphAdapter`` and raises a
  ``DeprecationWarning`` pointing at the v2.0 removal — silent on
  bare ``import`` so existing star-imports stay quiet.
* Round-2 item 20: ``get_adapter_info()`` now sets
  ``requires_pydantic = PydanticCompat.V2_ONLY`` explicitly (was
  V1_OR_V2 default), so the catalog manifest emitter reports the
  right compat badge regardless of which entrypoint it calls.
* tests/instrument/adapters/frameworks/test_langgraph.py — 29 unit
  tests modelled after the SmolAgents / Langfuse adapter test
  pattern. Mocks LangGraph at the SDK shape level (``_FakeCompiledGraph``
  with ``invoke`` / ``ainvoke``); covers lifecycle, info(),
  alias deprecation, graph wrapping (success + error), handoff
  detection, ``trace_node`` / ``trace_langgraph_tool`` decorators,
  ``wrap_llm_for_langgraph`` (sync + async), state adapter, and
  replay serialization.
* samples/instrument/langgraph/main.py — expanded from 1 node to a
  3-node ``planner -> researcher -> writer`` graph. LLM call inside
  the writer is mocked (no API key); ``HttpEventSink`` import is
  best-effort so the sample runs even before the M1.E transport
  PR (#98) lands.
* samples/instrument/langgraph/README.md — usage, topology, expected
  output, "going to production" steps.
* docs/adapters/frameworks-langgraph.md — clarified backward-compat
  section with the new DeprecationWarning behaviour and added a
  Pydantic compatibility section.

Source: ateam/stratix/sdk/python/adapters/langgraph/ (~2,248 LOC, 7 files).
Reference template: layerlens/instrument/adapters/frameworks/langchain/.

Acceptance:
* uv run pytest tests/instrument/adapters/frameworks/test_langgraph.py
  --> 29 passed
* uv run mypy --strict src/layerlens/instrument/adapters/frameworks/langgraph
  --> Success: no issues found in 7 source files
* uv run ruff check src/.../langgraph tests/.../test_langgraph.py
  --> All checks passed
* test_lazy_imports + test_default_install guards still green
* python samples/instrument/langgraph/main.py exits 0 with the
  3-node graph result printed and event counts surfaced.

Stacks on: feat/instrument-frameworks-orchestration (PR #96).
@mmercuri mmercuri requested a review from m-peko April 26, 2026 05:39
…#119 deferred)

LangGraph wraps llm.stream / llm.astream (see frameworks/langgraph/llm.py)
and accumulates per-chunk events in TracedLLM. The atlas-app catalog UI
reads AdapterCapability.STREAMING off info() to surface streaming
support, but the langgraph adapter only declared REPLAY here.

PR #119 (brand leak + capability declarations) wired STREAMING for the
six adapters that lived on its branch; langgraph was deferred because
it lives on its own source-port branch (PR #100). This closes that
deferral per CLAUDE.md item 5/11.

Capabilities declared honestly per CLAUDE.md 'no fake claims': REPLAY
matches serialize_for_replay (already present); STREAMING matches the
wrapped llm.stream / llm.astream entry-points.

Tests: added test_declares_replay_and_streaming_capabilities regression
asserting both capabilities surface via adapter.info().capabilities.

Verification:
* uv run python -m pytest tests/instrument/adapters/frameworks/test_langgraph.py -x
    -> 30 passed
@m-peko m-peko closed this May 21, 2026
mmercuri added a commit that referenced this pull request May 25, 2026
Inventory before implementing the realignment pass. 16 SDK resource
handlers analyzed against ateam's actually-registered routes:
- 10 aligned to a registered ateam route
- 5 marked not_implemented (no ateam route)
- 1 removed (empty directory)

Scope confirmed manageable for Phase 0 (<30 handler realignments).
Realignment work itself was killed by session rate limit before
landing — re-dispatch the agent or do the realignment inline.

See ateam audit log entry for #27 / Fix #100 for context.
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.

2 participants