Skip to content

docs: correct the per-run cap guidance on the Deep Agents page - #338

Merged
r-marques merged 1 commit into
mainfrom
docs/deep-agents-run-scope
Sep 1, 2026
Merged

docs: correct the per-run cap guidance on the Deep Agents page#338
r-marques merged 1 commit into
mainfrom
docs/deep-agents-run-scope

Conversation

@r-marques

Copy link
Copy Markdown
Member

What

Corrects a factual error in the Deep Agents page shipped by #336.

The page told readers to key the paid-call cap on config["configurable"]["thread_id"] (or run_id). Probing the real graph (langgraph 1.2 / deepagents 0.7) with a scripted model shows there is no run id anywhere in a tool's config:

configurable keys: __pregel_*, checkpoint_id, checkpoint_map, checkpoint_ns,
                   ls_agent_type, payment_token, thread_id
conf_run_id: None   top_run_id: None   meta_run_id: None

two runs, same thread ->  budget key run1 = 'SAME-THREAD'
                          budget key run2 = 'SAME-THREAD'

Since thread_id is stable for a whole conversation, anyone following the old guidance gets a per-conversation cap that never resets — not the per-run cap the section promises. After N paid calls the tool refuses forever.

Caught by @aaitor reviewing the companion tutorial (tutorials#61), where the same bug was live and is now fixed.

Changes

  • The caller supplies a per-run nonce (nvm_run_id), since it is the only party that knows where a run ends; the agent keys on it and falls back to thread_id.
  • The agent reports which scope is actually in force rather than promising a reset that will not happen — a browser chat UI whose proxy injects only the token lands in the conversation-scoped case.
  • Adds the two details that bite in production: refund the reservation on PaymentRequiredError, and bound the counter map in a long-running server.
  • Records that InjectedState is not the tidier alternative it looks like — it does work in a subagent tool, but exposes the subagent's own isolated conversation, reset on every task() hop, so it cannot see sibling delegations within one turn.

Verification

mintlify broken-links clean. The mechanism described here is the one now shipping in langchain-deep-agent-py, verified against the real graph with no LLM and no charges: cap resets across three runs on one thread with a nonce, falls back to thread scope without one, stays bounded past the eviction threshold, and unpaid attempts never consume budget.

The page told readers to key the paid-call cap on
`config["configurable"]["thread_id"]` (or `run_id`). Probing the real
graph (langgraph 1.2 / deepagents 0.7) shows there is no run id anywhere
in a tool's config — only `thread_id`, checkpoint bookkeeping, and
whatever the caller passed. Since `thread_id` is stable for a whole
conversation, following that guidance yields a per-conversation cap that
never resets, not the per-run cap the section promises.

Caught by aaitor reviewing the companion tutorial
(nevermined-io/tutorials#61), where the same bug was live.

Rewrites the section so the caller supplies a per-run nonce, shows the
agent reporting which scope is actually in force, and adds the two
details that bite in production: refund on PaymentRequiredError, and
bound the counter map in a long-running server.

Also records that InjectedState is not the tidier alternative it looks
like — it exposes the subagent's own isolated conversation, reset on
every task() hop, so it cannot see sibling delegations within one turn.

`mintlify broken-links` clean.
@r-marques
r-marques requested a review from a team as a code owner September 1, 2026 12:24
@mintlify

mintlify Bot commented Sep 1, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Nevermined 🟢 Ready View Preview Sep 1, 2026, 12:25 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@aaitor

aaitor commented Sep 1, 2026

Copy link
Copy Markdown
Member

🤖 Fallback review bot picking this up.

@aaitor aaitor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Fallback docs review (docs#338) — corrects the deep-agents.mdx 'cap it per run' guidance to match the tutorials#61 fix.

This fixes the exact wrong instruction the page shipped ('keyed on thread_id (or run_id)'): it now explains that LangGraph puts no run id in configurable, so keying on thread_id silently makes a 'per-run' cap per-conversation; the caller must supply nvm_run_id, and the agent falls back to thread scope with an honest message instead of promising a reset it can't deliver. The code samples line up with the tutorial implementation I reviewed (scope_of, nvm_run_id, the LRU bound), and the refund detail, the browser-chat-UI conversation-scoped fail-safe, and the InjectedState dead-end are all covered.

Accurate and consistent with the shipping code. No blockers, no should-fix.

@aaitor aaitor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approved — no blockers, nothing to address.

Inline review: #338 (review)

@r-marques
r-marques merged commit a1dd539 into main Sep 1, 2026
3 checks passed
@r-marques
r-marques deleted the docs/deep-agents-run-scope branch September 1, 2026 12:33
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