Skip to content

feat: add LangGraph adapter with atomic fan-out reserve/settle and typed budget advisory (#33)#34

Merged
achris7 merged 5 commits into
Floe-Labs:mainfrom
SpowZy:feat/langgraph-adapter
Jul 18, 2026
Merged

feat: add LangGraph adapter with atomic fan-out reserve/settle and typed budget advisory (#33)#34
achris7 merged 5 commits into
Floe-Labs:mainfrom
SpowZy:feat/langgraph-adapter

Conversation

@SpowZy

@SpowZy SpowZy commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

LangGraph adapter for floe-guard (issue #33): every branch of a StateGraph fan-out gets its own atomic slice of the ceiling (reserve-before / settle-after, the same contract the OpenAI and Anthropic adapters use), and a typed BudgetAdvisory channel in graph state lets a router downshift models before the hard-stop.

Changes

  • src/floe_guard/integrations/langgraph.py: guarded_node (sync + async, decorator or plain wrapper): reserve() before the node runs, settle(reserved=...) from the usage it reports, release() on error or when the node metered its call elsewhere (no double-counting). latest_advisory reducer + AdvisoryChannel, so state["budget"] always carries the freshest utilization under parallel writes.
  • tests/test_langgraph_adapter.py: 8 tests mapping the acceptance criteria. A real 16-branch over-budget StateGraph fan-out never crosses limit_usd (the graph port of the 16-concurrent-agents test), a within-budget fan-out settles exactly with zero leaked holds, the router downshifts on near_limit with zero BudgetExceeded, error and no-usage paths release the hold, async nodes are guarded, reducer ordering is write-order independent, and the example runs end to end on budget.
  • examples/langgraph_budget_aware.py: LangGraph port of examples/budget_aware.py (no API key, no network). Full model until the 70% advisory trips, tapers to the cheap model, finishes at $0.0998 under a $0.10 ceiling.
  • pyproject.toml: langgraph = ["langgraph>=1.0"] extra + keyword. .github/workflows/ci.yml: install the extra in the test matrix so the adapter tests run instead of skipping (mirrors the langchain/litellm rationale). README section, CHANGELOG (Unreleased), CONTRIBUTING extras list, integrations docstring.

Testing

  • pytest passes: 123 passed, 1 skipped (baseline 115 passed, 1 skipped)
  • ruff check . and ruff format . are clean
  • Cost-map copies untouched (no JS changes)
  • CHANGELOG.md updated

Acceptance criteria from #33:

  • A LangGraph fan-out with N parallel sub-agents never crosses limit_usd (test_fan_out_over_budget_never_crosses_ceiling, 16 branches on the superstep thread pool)
  • Graph State exposes a typed BudgetAdvisory; a router downshifts on near_limit before any BudgetExceeded (test_router_downshifts_on_near_limit_before_hard_stop)
  • Ships as the optional extra floe-guard[langgraph], mirroring the crewai/langchain extras

Related issues

Closes #33

Summary by CodeRabbit

  • New Features
    • Added a LangGraph adapter enabling budget-aware node wrapping with automatic reserve/settle.
    • Nodes provide budget advisories for routing and near-limit downshifting, including concurrent fan-out handling.
    • Added a no-API-key budget-aware LangGraph example.
  • Documentation
    • Updated README and CHANGELOG with LangGraph usage, plus guidance for the LangGraph optional setup.
  • Tests
    • Added LangGraph acceptance tests for ceiling enforcement, async/error handling, malformed/missing usage, and advisory aggregation/order.
  • Chores
    • Updated CI to install LangGraph extras for the test suite.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@achris7, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 3 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: aec951f8-2af8-4365-97b7-83127992e31e

📥 Commits

Reviewing files that changed from the base of the PR and between 491e0b2 and b2481de.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • README.md
  • pyproject.toml
  • src/floe_guard/__init__.py
📝 Walkthrough

Walkthrough

Adds an optional LangGraph adapter with guarded sync/async nodes, atomic budget reservation and settlement, typed advisory state, near-limit routing, a runnable example, package and documentation updates, and concurrency-focused acceptance tests.

Changes

LangGraph budget-aware integration

Layer / File(s) Summary
Adapter contract and packaging
.github/workflows/ci.yml, pyproject.toml, src/floe_guard/integrations/__init__.py, README.md, CONTRIBUTING.md, CHANGELOG.md
Adds the langgraph extra, CI installation coverage, setup guidance, documentation, and changelog entry.
Guarded node implementation
src/floe_guard/integrations/langgraph.py
Adds AdvisoryChannel, latest_advisory, and guarded_node with sync/async execution, reserve/settle handling, exception release, and advisory injection.
Budget-aware router example
examples/langgraph_budget_aware.py
Builds guarded worker nodes and routes between full, cheap, and terminal paths based on budget advisory state.
Concurrency and routing validation
tests/test_langgraph_adapter.py
Tests fan-out ceilings, settlement cleanup, near-limit downshifting, malformed and missing usage, async nodes, the example, and advisory reduction.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant StateGraph
  participant guarded_node
  participant BudgetGuard
  participant WorkerNode
  participant Router
  StateGraph->>guarded_node: invoke worker branch
  guarded_node->>BudgetGuard: reserve estimated cost
  guarded_node->>WorkerNode: execute model call
  WorkerNode-->>guarded_node: return usage update
  guarded_node->>BudgetGuard: settle actual usage
  guarded_node-->>StateGraph: write BudgetAdvisory
  StateGraph->>Router: evaluate graph state
  Router-->>StateGraph: select full step, cheap step, or END
Loading

Possibly related PRs

Suggested reviewers: achris7, shivamfloe

Poem

I’m a rabbit guarding tokens tight,
Reserving by day, settling by night.
When limits glow near, I hop to cheap,
While advisory channels softly speak.
LangGraph branches bloom—then sleep.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% 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
Linked Issues check ✅ Passed The PR adds the LangGraph adapter, typed advisory channel, budget-aware router example, and optional extra required by #33.
Out of Scope Changes check ✅ Passed The changes stay focused on the LangGraph feature, with docs, tests, CI, and packaging updates supporting the same scope.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: a LangGraph adapter with atomic reserve/settle handling and typed budget advisories.
✨ 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 commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@SpowZy

SpowZy commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@README.md`:
- Around line 242-245: Update the README example’s guarded_node usage to pass a
conservative explicit estimated_cost for each initial fan-out branch, rather
than relying on the cold guard’s zero recorded cost. Revise the nearby guidance
to explain that this estimate is used for the first parallel reservation, while
retaining the existing guard limit and settle/release behavior.

In `@src/floe_guard/integrations/langgraph.py`:
- Around line 94-110: The usage extraction in _usage_from_update must handle
malformed prompt_tokens or completion_tokens without raising. Convert both
values defensively and return None when either cannot be parsed, allowing
_settle_update() to continue to the guard.release(reserved) cleanup path;
preserve valid numeric values and the existing missing-usage behavior.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 7637c83a-2dcf-4c8b-880c-44150019974f

📥 Commits

Reviewing files that changed from the base of the PR and between ea7b429 and ed9c908.

📒 Files selected for processing (9)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • README.md
  • examples/langgraph_budget_aware.py
  • pyproject.toml
  • src/floe_guard/integrations/__init__.py
  • src/floe_guard/integrations/langgraph.py
  • tests/test_langgraph_adapter.py

Comment thread README.md
Comment thread src/floe_guard/integrations/langgraph.py
@SpowZy

SpowZy commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@README.md`:
- Around line 257-259: Update the README guidance around estimated_cost to
describe 0.01 as a conservative fixed hold reused on every invocation, while
noting that only omitted estimates use the guard’s last settled cost; in
src/floe_guard/integrations/langgraph.py lines 32-34, remove the claim that the
decorated node later re-estimates automatically.

In `@src/floe_guard/integrations/langgraph.py`:
- Around line 116-124: Update the exception handling around _usage_from_update()
to also catch OverflowError, alongside TypeError and ValueError. Ensure
guard.release(reserved) runs before re-raising so reservations are released for
all token-conversion failures.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 3e0e68a0-794e-4b69-9e78-0fdece671bc2

📥 Commits

Reviewing files that changed from the base of the PR and between ed9c908 and f5f54e8.

📒 Files selected for processing (3)
  • README.md
  • src/floe_guard/integrations/langgraph.py
  • tests/test_langgraph_adapter.py

Comment thread README.md Outdated
Comment thread src/floe_guard/integrations/langgraph.py
@SpowZy

SpowZy commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@SpowZy

SpowZy commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

OverflowError case addressed in 491e0b2 alongside TypeError and ValueError, with an inf-usage test locking the release path.

@SpowZy
SpowZy marked this pull request as ready for review July 11, 2026 18:36
@achris7

achris7 commented Jul 16, 2026

Copy link
Copy Markdown
Member

up for review this is great!

@achris7

achris7 commented Jul 16, 2026

Copy link
Copy Markdown
Member

per #33

Copilot AI 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.

Pull request overview

Adds first-class LangGraph integration to floe-guard, enabling concurrency-safe budgeting for StateGraph fan-out via the existing atomic reserve()/settle()/release() primitive, plus a typed budget advisory channel in LangGraph state to support “near limit” routing decisions.

Changes:

  • Introduces floe_guard.integrations.langgraph with guarded_node (sync/async) and an AdvisoryChannel reducer (latest_advisory) to keep the freshest BudgetAdvisory under parallel writes.
  • Adds comprehensive acceptance tests covering fan-out ceiling enforcement, advisory-driven routing, async nodes, and hold-release behavior on error/malformed/no-usage paths.
  • Wires packaging/docs/CI for the new optional extra floe-guard[langgraph], including a no-network example.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/floe_guard/integrations/langgraph.py Implements LangGraph node wrapper with atomic reserve/settle/release and advisory injection + reducer.
tests/test_langgraph_adapter.py Adds acceptance tests validating ceiling safety under fan-out concurrency and advisory-driven routing behavior.
examples/langgraph_budget_aware.py Provides an end-to-end, no-network LangGraph example demonstrating near-limit tapering.
pyproject.toml Adds langgraph optional dependency extra and keyword metadata.
.github/workflows/ci.yml Installs the langgraph extra so adapter tests run in CI.
README.md Documents LangGraph integration usage and points to the example.
CHANGELOG.md Records the new LangGraph adapter and example under Unreleased.
CONTRIBUTING.md Lists the new .[langgraph] extra for running adapter tests locally.
src/floe_guard/integrations/__init__.py Updates integrations docstring to include floe-guard[langgraph].

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

achris7 added 2 commits July 18, 2026 10:45
# Conflicts:
#	.github/workflows/ci.yml
#	CHANGELOG.md
The LangGraph adapter adds new package source, so version-guard requires a
bump over main's 0.5.0. Minor bump per SemVer (additive feature): pyproject
version -> 0.6.0, __version__ in lockstep, and promote the CHANGELOG entry from
Unreleased to a dated py 0.6.0 section.
@achris7
achris7 self-requested a review July 18, 2026 17:49
@achris7
achris7 merged commit 7ef97e4 into Floe-Labs:main Jul 18, 2026
10 checks passed
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.

floe-guard: LangGraph adapter (atomic reserve/settle nodes + typed budget advisory in graph state)

3 participants