Skip to content

fix(backend/blocks): propagate tool credentials in Orchestrator dispatch - #13178

Closed
kcze wants to merge 2 commits into
devfrom
kpczerwinski/open-3132-orchestrator-tool-credentials-missing-when-run-from-library
Closed

fix(backend/blocks): propagate tool credentials in Orchestrator dispatch#13178
kcze wants to merge 2 commits into
devfrom
kpczerwinski/open-3132-orchestrator-tool-credentials-missing-when-run-from-library

Conversation

@kcze

@kcze kcze commented May 21, 2026

Copy link
Copy Markdown
Contributor

Why / What / How

Why — Linear OPEN-3132 (Urgent / production). Agents built with OrchestratorBlock + a credential-bearing tool block run fine from the Builder but fail with a missing-credentials error when launched from the Library or AutoPilot.

Root cause: the Builder persists credential metadata into node.input_default, so it travels with the node. Library/AutoPilot strip that and instead ship credentials separately in graph_exec.nodes_input_masks. The normal queue dispatch in manager._on_graph_execution merges those masks into the queued node's inputs — but OrchestratorBlock._execute_single_tool_with_manager dispatches tool calls directly through on_node_execution, bypassing that merge step. The tool node therefore runs without its credentials.

What — Make the orchestrator's tool-dispatch path honour nodes_input_masks, matching the behaviour of the normal queue dispatch.

How

  • ExecutionProcessor now stores nodes_input_masks on the instance (initialised to None in on_graph_executor_start, set per-execution in _on_graph_execution).
  • _execute_single_tool_with_manager reads the mask for the sink node and merges it into merged_input_data before calling upsert_execution_input.
  • The same nodes_input_masks is now forwarded to on_node_execution (was hardcoded None) so downstream dispatch from the tool node stays consistent with the normal path.

Changes 🏗️

  • backend/executor/manager.py
    • ExecutionProcessor.on_graph_executor_start: declare self.nodes_input_masks: Optional[NodesInputMasks] = None so the attribute is always defined.
    • ExecutionProcessor._on_graph_execution: set self.nodes_input_masks = graph_exec.nodes_input_masks alongside the other per-execution state holders.
  • backend/blocks/orchestrator.py
    • _execute_single_tool_with_manager: merge execution_processor.nodes_input_masks[sink_node_id] into the tool node's inputs before upsert.
    • Same function: pass nodes_input_masks to on_node_execution instead of None.
  • backend/blocks/test/test_orchestrator.py: two new regression tests covering the Library/AutoPilot path (creds in nodes_input_masks) and the Builder path (creds in input_default, masks None).
  • backend/blocks/test/test_orchestrator_responses_api.py, backend/blocks/test/test_orchestrator_dynamic_fields.py: pin mock_execution_processor.nodes_input_masks = None so existing mocks keep the Builder path now that the orchestrator actually reads the attribute.

Checklist 📋

For code changes:

  • I have clearly listed my changes in the PR description
  • I have made a test plan
  • I have tested my changes according to the test plan:
    • Standalone repro: OrchestratorBlock._execute_single_tool_with_manager invoked with nodes_input_masks={sink: {"credentials": {...}}} and empty input_defaultupsert_execution_input is now called with input_name="credentials" (was missing before the fix).
    • Builder regression: same call with creds in input_default and nodes_input_masks=None still works; on_node_execution receives nodes_input_masks=None so behaviour is unchanged.
    • pyright / black / isort clean on the modified files.
    • Manual E2E: build an agent with an Orchestrator + credential-bearing tool block, save it, launch it from the Library — tool block runs with credentials.
    • Manual E2E: launch the same agent from AutoPilot — tool block runs with credentials.
    • Manual regression: launch the same agent from the Builder (unchanged path) — still works.

For configuration changes:

  • .env.default is updated or already compatible with my changes
  • docker-compose.yml is updated or already compatible with my changes
  • I have included a list of my configuration changes in the PR description (under Changes)

…spatch (OPEN-3132)

OrchestratorBlock dispatches tool calls directly via on_node_execution,
bypassing the normal graph queue dispatch in manager._on_graph_execution
where graph_exec.nodes_input_masks gets merged into the queued node's
inputs. As a result, tool blocks launched from Library or AutoPilot —
where credentials live in nodes_input_masks rather than node.input_default —
ran without their credentials and failed with a missing-credentials error.

Expose nodes_input_masks on the ExecutionProcessor and read+merge the
sink-node mask in _execute_single_tool_with_manager before upserting
inputs. Also forward the masks to on_node_execution so downstream
dispatch behaves the same as the normal queue path.
@kcze
kcze requested a review from a team as a code owner May 21, 2026 08:52
@kcze
kcze requested review from 0ubbe and Pwuts and removed request for a team May 21, 2026 08:52
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban May 21, 2026
@github-actions

github-actions Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Overlap Detection

This check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early.

🔴 Merge Conflicts Detected

The following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.

🟢 Low Risk — File Overlap Only

These PRs touch the same files but different sections (click to expand)

Summary: 2 conflict(s), 0 medium risk, 3 low risk (out of 5 PRs with file overlap)


Auto-generated on push. Ignores: openapi.json, lock files.

@coderabbitai

coderabbitai Bot commented May 21, 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

Run ID: 47de1705-921c-45f2-a4a9-ad8e669dc0f0

📥 Commits

Reviewing files that changed from the base of the PR and between 9da159a and 8870f9b.

📒 Files selected for processing (4)
  • autogpt_platform/backend/backend/blocks/orchestrator.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_dynamic_fields.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
✅ Files skipped from review due to trivial changes (1)
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_dynamic_fields.py
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: check API types
  • GitHub Check: Analyze (python)
  • GitHub Check: test (3.11)
  • GitHub Check: end-to-end tests
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (5)
autogpt_platform/backend/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development

autogpt_platform/backend/**/*.py: Use poetry run ... command for executing Python package dependencies
Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies like openpyxl
Use absolute imports with from backend.module import ... for cross-package imports; single-dot relative imports are acceptable for sibling modules within the same package; avoid double-dot relative imports
Do not use duck typing — avoid hasattr/getattr/isinstance for type dispatch; use typed interfaces/unions/protocols instead
Use Pydantic models over dataclass/namedtuple/dict for structured data
Do not use linter suppressors — no # type: ignore, # noqa, # pyright: ignore; fix the type/code instead
Prefer list comprehensions over manual loop-and-append patterns
Use early return with guard clauses first to avoid deep nesting
Use %s for deferred interpolation in debug log statements for efficiency; use f-strings elsewhere for readability (e.g., logger.debug("Processing %s items", count) vs logger.info(f"Processing {count} items"))
Sanitize error paths by using os.path.basename() in error messages to avoid leaking directory structure
Be aware of TOCTOU (Time-Of-Check-Time-Of-Use) issues — avoid check-then-act patterns for file access and credit charging
Use transaction=True for Redis pipelines to ensure atomicity on multi-step operations
Use max(0, value) guards for computed values that should never be negative
Keep files under ~300 lines; if a file grows beyond this, split by responsibility (extract helpers, models, or a sub-module into a new file)
Keep functions under ~40 lines; extract named helpers when a function grows longer
...

Files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
autogpt_platform/backend/backend/blocks/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/backend/blocks/**/*.py: Inherit from 'Block' base class with input/output schemas when adding new blocks in backend
Implement 'run' method with proper error handling in backend blocks
Generate block UUID using 'uuid.uuid4()' when creating new blocks in backend
Write tests alongside block implementation when adding new blocks in backend

autogpt_platform/backend/backend/blocks/**/*.py: For blocks handling files, use store_media_file() with return_format="for_local_processing" when processing with local tools (ffmpeg, MoviePy, PIL)
For blocks handling files, use store_media_file() with return_format="for_external_api" when sending content to external APIs (Replicate, OpenAI)
For blocks returning files, use store_media_file() with return_format="for_block_output" to enable auto-adaptation to execution context (workspace:// in CoPilot, data URI in graphs)
When creating new blocks, inherit from Block base class, define input/output schemas using BlockSchema, implement async run method, and generate unique block ID using uuid.uuid4()

Files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
autogpt_platform/backend/**/test/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use snapshot testing with '--snapshot-update' flag in backend tests when output changes; always review with 'git diff'

Files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
autogpt_platform/backend/**/test_*.py

📄 CodeRabbit inference engine (autogpt_platform/AGENTS.md)

Create a failing test first using @pytest.mark.xfail decorator (backend) when fixing a bug or adding a feature, then implement the fix and remove the xfail marker

Files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
🧠 Learnings (15)
📚 Learning: 2026-02-05T04:11:00.596Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 11796
File: autogpt_platform/backend/backend/blocks/video/concat.py:3-4
Timestamp: 2026-02-05T04:11:00.596Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, when creating a new block, generate a UUID once with uuid.uuid4() and hard-code the resulting string as the block's id parameter. Do not call uuid.uuid4() at runtime; IDs must be constant across all imports and runs to ensure stability.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-03-16T16:32:21.686Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:32:21.686Z
Learning: In autogpt_platform/backend/backend/blocks/, the Block base class execute() already wraps run() in a try/except to convert uncaught exceptions into BlockExecutionError/BlockUnknownError. Do not add per-block try/except in individual block run() methods, as this is not the established pattern (e.g., Gmail, Slack, Todoist blocks omit it). Only use explicit try/except within blocks that need to distinguish between success and error yield paths inside a generator (e.g., attachment blocks). This guidance applies to all Python files under autogpt_platform/backend/backend/blocks/ and similar block implementations; avoid duplicating error handling in run() unless a block requires generator-based branching.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-04-23T12:55:26.122Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: Cost billing via the cost(*costs) decorator is applied at input-evaluation time (before a block’s run() executes). Therefore, mutating input_data inside run() will not change billing. When a block’s billing depends on a field plus URL/sniff-derived signals, treat the explicitly declared billing field (e.g., is_video) as the only billing source—set it correctly before run() (or in the code path that occurs before the decorator evaluates input_data). This should be checked for all blocks under autogpt_platform/backend/backend/blocks/ so billing signals are not mistakenly assumed to update during run().

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-03-16T16:30:11.452Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/threads.py:80-102
Timestamp: 2026-03-16T16:30:11.452Z
Learning: In autogpt_platform/backend/backend/blocks/ (and related blocks under autogpt_platform/backend/backend/blocks/), do not add try/except blocks around a block's run() method for standard error propagation. The block executor framework (backend/executor/manager.py) catches uncaught exceptions from run() and emits them on the 'error' output. Only add explicit try/except blocks when you need to control partial outputs in failure cases (e.g., certain outputs must not be yielded on error, as in attachment blocks). This is the standard pattern across the codebase; apply it broadly to blocks' run() implementations.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-03-16T16:30:23.196Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:30:23.196Z
Learning: In any Python file under autogpt_platform/backend/backend/blocks, do not add a try/except around run() solely for standard error handling. The block framework’s _execute() in _base.py already catches unhandled exceptions and re-raises as BlockExecutionError or BlockUnknownError. If you yield ("error", message), _execute() raises BlockExecutionError immediately, so the error port will not propagate downstream. Reserve explicit try/except for scenarios where you must control partial output (e.g., attachment blocks that must skip yielding content_base64 on failure).

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-03-16T16:30:11.452Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/threads.py:80-102
Timestamp: 2026-03-16T16:30:11.452Z
Learning: Do not wrap synchronous AgentMail SDK calls with asyncio.to_thread() in blocks under autogpt_platform/backend/backend/blocks (and across the codebase). The block executor runs node execution in dedicated threads via asyncio.run_coroutine_threadsafe (see manager.py around lines ~745-752 and ~1079). The existing pattern avoids using asyncio.to_thread for SDK calls inside async run() methods, so maintain that approach and do not add to_thread usage in these code paths.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-03-16T16:35:40.236Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/api/features/workflow_import.py:54-63
Timestamp: 2026-03-16T16:35:40.236Z
Learning: Avoid using the word 'competitor' in public-facing identifiers and text. Use neutral naming for API paths, model names, function names, and UI text. Examples: rename 'CompetitorFormat' to 'SourcePlatform', 'convert_competitor_workflow' to 'convert_workflow', '/competitor-workflow' to '/workflow'. Apply this guideline to files under autogpt_platform/backend and autogpt_platform/frontend.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-03-19T15:10:50.676Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12483
File: autogpt_platform/backend/backend/copilot/tools/test_dry_run.py:298-303
Timestamp: 2026-03-19T15:10:50.676Z
Learning: When using Python’s `unittest.mock.patch` in tests, choose the patch target based on how the imported name is resolved:
- If the code under test uses an **eager/module-level import** (e.g., `from foo.bar import baz` at module top), patch **the module where the name is looked up** (i.e., where it is used in the SUT), e.g. `patch("mymodule.baz")`.
- If the code under test uses a **lazy import** executed later (e.g., `from foo.bar import baz` inside a function/branch), patch **the source module** (e.g., `patch("foo.bar.baz")`) because the late `from ... import` will read the (potentially patched) name from the source module at call time.

For a concrete example: if `simulate_block` is imported inside an `if dry_run:` block in the SUT, then the correct test patch target is the source module path for `simulate_block` as it exists at call time (e.g., `patch("backend.executor.simulator.simulate_block")`), not the test file’s import location.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-04-15T02:43:36.890Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-15T02:43:36.890Z
Learning: When reviewing Python exception handlers, do not flag `isinstance(e, X)` checks as dead/unreachable if the caught exception `X` is a subclass of the exception type being handled. For example, if `X` (e.g., `VirusScanError`) inherits from `ValueError` (directly or via an intermediate class) and it can be raised within an `except ValueError:` block, then `isinstance(e, X)` inside that handler is reachable and should not be treated as dead code.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-04-22T11:46:04.431Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/config.py:0-0
Timestamp: 2026-04-22T11:46:04.431Z
Learning: Do not flag the Claude Sonnet 4.6 model ID as incorrect when it uses the project’s established hyphenated convention: `anthropic/claude-sonnet-4-6`. This hyphen form is the intentional, production convention and should be treated as valid (including in files like llm.py, blocks tests, reasoning.py, `_is_anthropic_model` tests, and config defaults). Note that OpenRouter also accepts the dot variant `anthropic/claude-sonnet-4.6`, so either form may be tolerated, but `anthropic/claude-sonnet-4-6` should be considered the standard to match project usage.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-04-22T11:46:12.892Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/baseline/service.py:322-332
Timestamp: 2026-04-22T11:46:12.892Z
Learning: In this codebase (Significant-Gravitas/AutoGPT), OpenRouter-routed Anthropic model IDs should use the hyphen-separated convention (e.g., `anthropic/claude-sonnet-4-6`, `anthropic/claude-opus-4-6`). Although OpenRouter may accept both hyphen and dot variants, treat the hyphen-separated form as the intended, correct codebase-wide convention and do not flag it as an error. Only flag the dot-separated variant (e.g., `anthropic/claude-sonnet-4.6`) as incorrect when reviewing/validating model ID strings for OpenRouter-routed Anthropic models.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
📚 Learning: 2026-05-07T18:48:14.242Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13040
File: autogpt_platform/backend/backend/blocks/llm.py:0-0
Timestamp: 2026-05-07T18:48:14.242Z
Learning: In this repository, isort may split imports from the same module into separate blocks when some imports are aliased (e.g., `from module import X as Y`) and others are not. Preserve the two-block layout when it results from isort (such as keeping `from openai.types.chat import ChatCompletion as OpenAIChatCompletion` separate from non-aliased imports from `openai.types.chat`). Do not treat that split as a style issue during review; merging them into a single block can fail CI with `Imports are incorrectly sorted and/or formatted`.

Applied to files:

  • autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
  • autogpt_platform/backend/backend/blocks/test/test_orchestrator.py
  • autogpt_platform/backend/backend/blocks/orchestrator.py
🔇 Additional comments (3)
autogpt_platform/backend/backend/blocks/orchestrator.py (1)

1087-1087: LGTM!

autogpt_platform/backend/backend/blocks/test/test_orchestrator.py (1)

918-918: LGTM!

Also applies to: 1227-1232

autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py (1)

957-957: LGTM!


Walkthrough

ExecutionProcessor exposes per-node nodes_input_masks during graph execution. OrchestratorBlock._execute_single_tool_with_manager merges the sink node’s mask into the tool’s merged input and forwards nodes_input_masks to execution_processor.on_node_execution. Tests cover masked and unmasked flows.

Changes

Credential mask propagation through orchestrator tool dispatch

Layer / File(s) Summary
ExecutionProcessor credential-mask storage
autogpt_platform/backend/backend/executor/manager.py
ExecutionProcessor initializes nodes_input_masks = None at executor start and assigns self.nodes_input_masks = graph_exec.nodes_input_masks at graph execution start to expose mask data for orchestrator tool dispatch.
OrchestratorBlock credential merging and propagation
autogpt_platform/backend/backend/blocks/orchestrator.py
_execute_single_tool_with_manager reads execution_processor.nodes_input_masks for the sink node, merges the credential mask into merged_input_data, and passes nodes_input_masks to execution_processor.on_node_execution instead of None.
Credential propagation test coverage
autogpt_platform/backend/backend/blocks/test/test_orchestrator.py, autogpt_platform/backend/backend/blocks/test/test_orchestrator_dynamic_fields.py, autogpt_platform/backend/backend/blocks/test/test_orchestrator_responses_api.py
Adds test_orchestrator_tool_merges_nodes_input_masks and test_orchestrator_tool_works_without_nodes_input_masks; updates agent-mode tests to set mock_execution_processor.nodes_input_masks = None where appropriate to validate both masked and unmasked execution paths.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant OrchestratorBlock
  participant ExecutionProcessor
  participant ToolExecutor
  Client->>OrchestratorBlock: trigger tool dispatch (sink_node)
  OrchestratorBlock->>ExecutionProcessor: read nodes_input_masks[sink_node_id]
  OrchestratorBlock->>OrchestratorBlock: merge mask into merged_input_data
  OrchestratorBlock->>ExecutionProcessor: on_node_execution(node_id, merged_input_data, nodes_input_masks)
  ExecutionProcessor->>ToolExecutor: execute tool with merged inputs and applied masks
  ToolExecutor-->>ExecutionProcessor: execution result
  ExecutionProcessor-->>OrchestratorBlock: completion callback/result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

size/m

Suggested reviewers

  • ntindle
  • Pwuts
  • 0ubbe

Poem

🐰 I hop through code with whiskers bright,
I stitch the masks to inputs right,
From processor state to orchestrator rhyme,
Credentials flow in orderly time,
Hooray — the tools now wear their cloak tonight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(backend/blocks): propagate tool credentials in Orchestrator dispatch' clearly and concisely summarizes the main change—fixing credential propagation in the Orchestrator block's tool dispatch path. It is specific, related to the core fix, and follows conventional commit message conventions.
Description check ✅ Passed The description is comprehensive and directly related to the changeset. It explains the why (production bug OPEN-3132), what (credential propagation fix), how (storing and forwarding nodes_input_masks), detailed changes to three files, test coverage, and validation steps.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kpczerwinski/open-3132-orchestrator-tool-credentials-missing-when-run-from-library

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 and usage tips.

@kcze kcze changed the title fix(backend/blocks): propagate tool credentials in Orchestrator dispatch (OPEN-3132) fix(backend/blocks): propagate tool credentials in Orchestrator dispatch May 21, 2026
@kcze
kcze requested review from majdyz and removed request for 0ubbe May 21, 2026 09:03
@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.40260% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.60%. Comparing base (09368cd) to head (8870f9b).
⚠️ Report is 2 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #13178      +/-   ##
==========================================
+ Coverage   71.43%   71.60%   +0.17%     
==========================================
  Files        2214     2221       +7     
  Lines      166908   169032    +2124     
  Branches    17024    17340     +316     
==========================================
+ Hits       119224   121039    +1815     
- Misses      44127    44447     +320     
+ Partials     3557     3546      -11     
Flag Coverage Δ
platform-backend 79.92% <97.40%> (+0.12%) ⬆️
platform-frontend 36.86% <ø> (-0.01%) ⬇️
platform-frontend-e2e 31.21% <ø> (+0.11%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Platform Backend 79.92% <97.40%> (+0.12%) ⬆️
Platform Frontend 41.69% <ø> (-0.03%) ⬇️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…s_input_masks read

The orchestrator's tool dispatch now reads execution_processor.nodes_input_masks,
so existing tests that mocked the processor with a bare AsyncMock() ended up
with a truthy auto-attribute and tripped the new merge path. Pin
nodes_input_masks = None on those mocks to keep them on the Builder path,
and drop a now-stray ticket reference from comments/docstrings.
@kcze kcze closed this May 21, 2026
@kcze
kcze deleted the kpczerwinski/open-3132-orchestrator-tool-credentials-missing-when-run-from-library branch May 21, 2026 11:24
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to ✅ Done in AutoGPT development kanban May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant