Skip to content

fix(orchestrator): forward credential input masks to tool node execution - #13151

Merged
majdyz merged 9 commits into
Significant-Gravitas:devfrom
mangod12:fix/orchestrator-credentials-library-autopilot
May 28, 2026
Merged

fix(orchestrator): forward credential input masks to tool node execution#13151
majdyz merged 9 commits into
Significant-Gravitas:devfrom
mangod12:fix/orchestrator-credentials-library-autopilot

Conversation

@mangod12

Copy link
Copy Markdown
Contributor

Summary

  • Fixed orchestrator tool blocks missing credentials when launched from Library or AutoPilot
  • Root cause: OrchestratorBlock._execute_single_tool_with_manager passed nodes_input_masks=None to on_node_execution, so credential metadata was never forwarded to tool nodes

Why Builder worked but Library/AutoPilot didn't

  • Builder sends credentials_inputs in the request body → gets merged into nodes_input_masks at execution creation time → flows through the normal execution path
  • Library/AutoPilot also creates nodes_input_masks correctly (via make_node_credentials_input_map) → stored on graph_exec.nodes_input_masks
  • But the orchestrator's internal tool dispatch bypassed this by hardcoding nodes_input_masks=None at orchestrator.py:1145

Fix (2 lines)

  1. executor/manager.py: Store graph_exec.nodes_input_masks on ExecutionProcessor so it's accessible during orchestrator tool dispatch
  2. blocks/orchestrator.py: Pass execution_processor.nodes_input_masks instead of None

Fixes #13144

Test plan

  • Traced the full credential flow: execute_graphadd_graph_executionvalidate_and_construct_node_execution_inputmake_node_credentials_input_mapnodes_input_maskson_node_execution
  • Confirmed the orchestrator was the only callsite passing None for nodes_input_masks
  • Fix is consistent with how the normal execution path passes masks (see manager.py:1107)

🤖 Generated with Claude Code

OrchestratorBlock._execute_single_tool_with_manager passed
nodes_input_masks=None when calling on_node_execution for tool blocks.
This meant credential metadata (stored in the graph execution's
nodes_input_masks) was never forwarded to tool nodes, causing
"missing credentials" errors when agents were launched from the
Library or AutoPilot (where credentials come from stored presets
via graph_credentials_inputs → nodes_input_masks).

The Builder path worked because it sends credentials_inputs directly
in the request body, which gets merged into nodes_input_masks at
graph execution creation time — but the orchestrator's internal
tool dispatch bypassed this by passing None.

Fix:
- Store nodes_input_masks on ExecutionProcessor during graph execution
- Pass execution_processor.nodes_input_masks to on_node_execution
  in the orchestrator's tool dispatch path

Fixes Significant-Gravitas#13144

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 18, 2026 03:50
@mangod12
mangod12 requested a review from a team as a code owner May 18, 2026 03:50
@mangod12
mangod12 requested review from Pwuts and removed request for a team May 18, 2026 03:50
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban May 18, 2026
@mangod12
mangod12 requested a review from Bentlybro May 18, 2026 03:50
@github-actions

Copy link
Copy Markdown
Contributor

This PR targets the master branch but does not come from dev or a hotfix/* branch.

Automatically setting the base branch to dev.

@github-actions
github-actions Bot changed the base branch from master to dev May 18, 2026 03:50
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

ExecutionProcessor stores graph-level nodes_input_masks on the instance. OrchestratorBlock reads and validates that mapping, merges a sink-node mask into the tool node's NodeExecutionEntry.inputs when present, and forwards the full nodes_input_masks to execution_processor.on_node_execution(). Tests cover forwarding, coercion, empty, and selective-merge cases.

Changes

Node Input Mask Threading

Layer / File(s) Summary
Store graph masks on ExecutionProcessor
autogpt_platform/backend/backend/executor/manager.py
ExecutionProcessor._on_graph_execution assigns self.nodes_input_masks = graph_exec.nodes_input_masks so graph-provided per-node masks are available during execution.
Merge per-node masks and forward to on_node_execution
autogpt_platform/backend/backend/blocks/orchestrator.py
OrchestratorBlock._execute_single_tool_with_manager reads execution_processor.nodes_input_masks (validates it's a Mapping), coerces non-mappings to None, merges nodes_input_masks[sink_node_id] into the created NodeExecutionEntry.inputs for the sink node if present, and passes nodes_input_masks=nodes_input_masks into execution_processor.on_node_execution(...) instead of None.
Tests: forwarding, None, coercion, empty, and selective merge
autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.py
Adds pytest coverage asserting that the full masks mapping is forwarded to on_node_execution, non-mapping masks are coerced to None, an empty mapping is forwarded unchanged, and only the matching sink-node mask is merged into the sink node's inputs.

Sequence Diagram(s)

sequenceDiagram
  participant GraphExecution
  participant ExecutionProcessor
  participant OrchestratorBlock
  participant ExecutionManager
  GraphExecution->>ExecutionProcessor: provide graph_exec.nodes_input_masks
  OrchestratorBlock->>ExecutionProcessor: getattr(nodes_input_masks) -> mapping or None
  OrchestratorBlock->>OrchestratorBlock: merge nodes_input_masks[sink_node_id] into node_exec_entry.inputs (if present)
  OrchestratorBlock->>ExecutionProcessor: on_node_execution(node_exec_entry, nodes_input_masks)
  ExecutionProcessor->>ExecutionManager: execute node with merged inputs and forwarded masks
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

size/m

Suggested reviewers

  • ntindle
  • kcze

Poem

🐇 I stitched the threads from graph to tool,
Keys find their place, no longer a hole.
Masks travel true through each small hop,
Inputs merge right, leaks now stop.
A tiny hop — credentials whole.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% 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
Title check ✅ Passed The title clearly describes the main fix: forwarding credential input masks to tool node execution in the orchestrator, which is the core issue being addressed.
Description check ✅ Passed The description is directly related to the changeset, explaining the root cause (nodes_input_masks=None passed to on_node_execution), why Builder worked but Library/AutoPilot didn't, and the two-line fix implemented.
Linked Issues check ✅ Passed The pull request fully addresses issue #13144 by ensuring nodes_input_masks are forwarded from ExecutionProcessor to on_node_execution, making credentials available regardless of run origin (Builder, Library, AutoPilot).
Out of Scope Changes check ✅ Passed All changes are directly in scope: storing nodes_input_masks in ExecutionProcessor, passing them to on_node_execution, and comprehensive test coverage validating the fix and edge cases.

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

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

This PR aims to fix a production issue where Orchestrator-triggered tool blocks lose credential metadata when runs are started from Library/AutoPilot (vs Builder) by ensuring node input masks (which include credential meta) are forwarded into the orchestrator’s internal tool-node execution path.

Changes:

  • Persist graph_exec.nodes_input_masks onto the ExecutionProcessor instance during graph execution setup.
  • Use execution_processor.nodes_input_masks when the Orchestrator directly dispatches a tool node via on_node_execution.

Reviewed changes

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

File Description
autogpt_platform/backend/backend/executor/manager.py Stores graph_exec.nodes_input_masks on ExecutionProcessor for later access during nested/orchestrated dispatch.
autogpt_platform/backend/backend/blocks/orchestrator.py Forwards nodes_input_masks into on_node_execution during orchestrator tool-node execution.

Comment thread autogpt_platform/backend/backend/blocks/orchestrator.py
Comment thread autogpt_platform/backend/backend/blocks/orchestrator.py
@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 72.28%. Comparing base (cae869f) to head (e3f87ac).
⚠️ Report is 4 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #13151      +/-   ##
==========================================
- Coverage   72.33%   72.28%   -0.05%     
==========================================
  Files        2299     2299              
  Lines      173127   173125       -2     
  Branches    17518    17519       +1     
==========================================
- Hits       125235   125147      -88     
- Misses      44177    44269      +92     
+ Partials     3715     3709       -6     
Flag Coverage Δ
platform-backend 80.29% <87.50%> (-0.05%) ⬇️
platform-frontend-e2e 30.94% <ø> (-0.28%) ⬇️

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

Components Coverage Δ
Platform Backend 80.29% <87.50%> (-0.05%) ⬇️
Platform Frontend 43.61% <ø> (-0.10%) ⬇️
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.

Verify that _execute_single_tool_with_manager forwards
execution_processor.nodes_input_masks to on_node_execution,
ensuring Library/AutoPilot credential overrides reach tool nodes.

Covers:
- Masks forwarded when present
- None masks handled gracefully
- ExecutionProcessor stores masks from graph_exec
@CLAassistant

CLAassistant commented May 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added size/l and removed size/s labels May 18, 2026

@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

🧹 Nitpick comments (1)
autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.py (1)

217-217: ⚡ Quick win

Move ExecutionProcessor import to module scope.

This local import is not a heavy optional dependency and should be top-level for consistency with backend import rules.

As per coding guidelines, “Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies like openpyxl.”

🤖 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 `@autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.py`
at line 217, Move the local import of ExecutionProcessor to the module/top-level
scope in the test module so it follows import guidelines; remove the
in-function/local import and add "from backend.executor.manager import
ExecutionProcessor" alongside the other top-level imports in
test_orchestrator_credential_masks.py so the symbol is imported once at module
load time.
🤖 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 `@autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.py`:
- Around line 221-225: The test is only checking direct attribute assignment on
ExecutionProcessor instead of exercising the real flow that sets
nodes_input_masks from a GraphExecution; update the test to call the actual
method that receives the graph execution (use
ExecutionProcessor._on_graph_execution or whichever public initializer handles
graph_exec) with a fake/mocked graph_exec containing
nodes_input_masks==expected_masks, then assert that processor.nodes_input_masks
is expected_masks; reference ExecutionProcessor, _on_graph_execution (or the
real method that accepts graph_exec), graph_exec.nodes_input_masks and
nodes_input_masks in the test to ensure the production wiring is validated.

---

Nitpick comments:
In `@autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.py`:
- Line 217: Move the local import of ExecutionProcessor to the module/top-level
scope in the test module so it follows import guidelines; remove the
in-function/local import and add "from backend.executor.manager import
ExecutionProcessor" alongside the other top-level imports in
test_orchestrator_credential_masks.py so the symbol is imported once at module
load time.
🪄 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

Run ID: cbaeeb35-841f-408d-85e9-9f7847e4c75f

📥 Commits

Reviewing files that changed from the base of the PR and between b06e580 and b075b36.

📒 Files selected for processing (1)
  • autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.py
📜 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). (11)
  • GitHub Check: check API types
  • GitHub Check: Check PR Status
  • GitHub Check: end-to-end tests
  • GitHub Check: test (3.13)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: test (3.12)
  • GitHub Check: type-check (3.12)
  • GitHub Check: Analyze (python)
  • GitHub Check: type-check (3.13)
  • GitHub Check: test (3.11)
  • GitHub Check: type-check (3.11)
🧰 Additional context used
📓 Path-based instructions (4)
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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.py
🧠 Learnings (9)
📚 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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.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/test/blocks/test_orchestrator_credential_masks.py

Comment thread autogpt_platform/backend/test/blocks/test_orchestrator_credential_masks.py Outdated
The orchestrator dispatch path forwarded nodes_input_masks to
on_node_execution but never merged the sink node's mask into
node_exec_entry.inputs. The normal queue-based path in
_on_graph_execution does `queued_node_exec.inputs.update(node_input_mask)`
before execution — this commit mirrors that behavior so credential
fields from Library/AutoPilot are present for the block run.

Also rewrites tests to verify masks are actually merged into inputs
(not just forwarded), adds edge case for masks targeting different
nodes, and removes tautological ExecutionProcessor attribute test.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mangod12

Copy link
Copy Markdown
Contributor Author

@mangod12

Copy link
Copy Markdown
Contributor Author

Pushed a follow-up for the failing backend CI checks.

Changes:

  • Ran Black on the two PR files flagged by lint.
  • Guarded nodes_input_masks so _execute_single_tool_with_manager only merges/forwards it when it is an actual mapping. This fixes the test_orchestrator_agent_mode failure where an unset AsyncMock.nodes_input_masks produced a coroutine-like mock value and caused Tool execution failed: 'coroutine' object is not iterable.

Local checks run:

python -m black --check backend/blocks/orchestrator.py test/blocks/test_orchestrator_credential_masks.py
python -m ruff check backend/blocks/orchestrator.py test/blocks/test_orchestrator_credential_masks.py

I also attempted the targeted pytest run, but this local checkout is missing the generated Prisma/client dependency (ModuleNotFoundError: No module named 'prisma'), so CI should be the authoritative pytest verification.

@montanaflynn

Copy link
Copy Markdown
Contributor

@mangod12 why was I tagged?

@mangod12

Copy link
Copy Markdown
Contributor Author

For review if anyone else has not taken up this pr and the solution is good

@ntindle
ntindle requested a review from majdyz May 27, 2026 17:16
majdyz and others added 3 commits May 27, 2026 22:40
Adds two regression tests for _execute_single_tool_with_manager that
exercise the new defensive paths in orchestrator.py:
- non-Mapping nodes_input_masks is coerced to None (lines 1113-1114)
- empty Mapping masks skip the merge but are still forwarded

Brings codecov/patch coverage on the orchestrator change from 60% to
100% on the new branch logic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…patch tests

The tool-dispatch tests left charge_node_usage as a plain MagicMock and
get_execution_outputs_by_node_exec_id unmocked, so the post-execution path
raised TypeError (await on MagicMock) and json.dumps recursed on a MagicMock.
The swallowed failure produced ~2390 warnings and made the recorded
on_node_execution call args unreliable under an exhausted recursion stack.
Mock both so the tool path completes cleanly and assertions are deterministic.
@majdyz

majdyz commented May 27, 2026

Copy link
Copy Markdown
Contributor

E2E Test Report — PR #13151 (NATIVE mode, --fix)

Tested the orchestrator credential-mask forwarding fix natively (docker infra deps + poetry run app + pnpm dev on host). The change is internal plumbing (no dedicated UI surface), so the headline evidence is the unit suite + a runtime assertion of the loaded code path; browser screenshots serve as a full-stack regression-health check on the Library/AutoPilot surfaces the fix targets.

# Scenario Result Evidence
1 Unit: mask merged into sink-node inputs PASS test_execute_single_tool_merges_masks_into_inputs
2 Unit: no masks → forwards None, inputs untouched PASS test_execute_single_tool_no_masks_no_crash
3 Negative: mask for a different node does NOT leak into sink inputs PASS test_execute_single_tool_masks_for_different_node_not_merged
4 Negative: non-Mapping masks coerced to None (no crash) PASS test_execute_single_tool_non_mapping_masks_coerced_to_none
5 Negative: empty-mask dict → no merge, forwarded as-is PASS test_execute_single_tool_empty_masks_no_merge
6 Runtime: loaded backend wires the full data path PASS source assertions (below)
7 Regression: login + authenticated Copilot/AutoPilot home PASS screenshots 1–2
8 Regression: Library (Agents) page loads PASS screenshot 3

Final: 8/8 scenarios pass. Orchestrator unit suites: 27 passed (credential-masks + execution-mode), no regressions.

Runtime data-path assertions (against the running native backend)

Confirmed the PR's wiring is present in the loaded modules:

  • manager_stores_masks=TrueExecutionProcessor.__init__ stores graph_exec.nodes_input_masks
  • orch_reads_guarded=True — orchestrator reads it via getattr(...) + isinstance(..., Mapping) guard
  • orch_merges_into_inputs=True — sink-node mask merged into node_exec_entry.inputs
  • orch_forwards_masks=True — masks forwarded to on_node_execution (no longer hardcoded None)
  • orch_no_hardcoded_none=True

Fix applied during this run (--fix mode)

The PR's own test file left two mocks incomplete: charge_node_usage (plain MagicMock → await raised TypeError) and get_execution_outputs_by_node_exec_id (unmocked → json.dumps(MagicMock) recursed). The swallowed mid-flight failure produced ~2390 warnings and made the recorded on_node_execution call-args nondeterministic under an exhausted recursion stack. Mocked both so the tool path completes cleanly — warnings dropped 2392 → 2, all 5 tests deterministic. Committed as 17b3d00. Product code in the PR was already correct.

Screenshots

Login Page

01-login-before.png
Login page renders cleanly with the new marketing panel (motion/aurora background deps from the dev merge compile and run). Confirms the full native frontend stack is healthy before testing.

Authenticated Copilot / AutoPilot Home

02-login-after-copilot.png
After login the user lands on the authenticated AutoPilot/Copilot home ("Hey, prtest-local"), proving the session and the AutoPilot surface — one of the two entry points whose orchestrator runs the fix targets — work end to end.

Library (Agents) Page

03-library-page.png
The Library/Agents page loads with no errors — the other entry point (Library-launched orchestrator runs) the credential-mask fix is meant to repair.

majdyz
majdyz previously approved these changes May 27, 2026

@majdyz majdyz 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.

E2E Test Evaluation — APPROVED

Results: 8/8 scenarios passed (native mode).

Coverage: The fix forwards nodes_input_masks from ExecutionProcessor to orchestrator tool-node dispatch. Verified end to end: the unit suite covers the merge path and three negative paths (other-node isolation, non-Mapping coercion, empty-mask), and a runtime assertion against the running native backend confirms manager.py stores graph_exec.nodes_input_masks, the orchestrator reads it through the Mapping guard, merges the sink-node mask into inputs, and forwards the masks (no longer hardcoded None).

Negative tests: Other-node mask isolation, non-Mapping coercion, and empty-mask no-merge all pass.

Evidence: Source/runtime assertions logged for the data path; full-stack regression screenshots for login + authenticated Copilot/AutoPilot home + Library — the two entry points this fix targets — all healthy.

Regressions: None. Orchestrator unit suites 27 passed (credential-masks + execution-mode).

Note (addressed in this run): The PR's test file left charge_node_usage and get_execution_outputs_by_node_exec_id unmocked, so the tool-dispatch path crashed mid-flight (TypeError on awaiting a MagicMock + json.dumps recursion), emitting ~2390 warnings and making on_node_execution call-args nondeterministic. Hardened the fixtures (commit 17b3d00) — warnings 2392 → 2, all 5 tests deterministic. The product change itself was already correct.

@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban May 27, 2026
… getattr/isinstance

ExecutionProcessor's per-graph-execution state attributes are populated in
on_graph_execution; nodes_input_masks now has a class-level annotation
(`Optional[NodesInputMasks] = None`) matching how the other state holders
(running_node_execution, execution_stats, execution_stats_lock) are accessed
from the tool-dispatch path. The orchestrator can now read it directly, and
the runtime isinstance(..., Mapping) check is dropped — NodesInputMasks is
already typed as Mapping[str, NodeInputMask], so the guard was paranoia
against a type-system lie. Drops the matching defensive test.
… compat

Removing the isinstance(..., Mapping) check broke three test shards: orchestrator
tests pass MagicMock/AsyncMock processors whose attribute chain returns
coroutines under AsyncMock semantics, and node_exec_entry.inputs.update(...) on
those crashed with 'coroutine object is not iterable'. The coercion is a small
runtime safety boundary that's load-bearing for the test harness; keep it
alongside the typed direct attribute access. Restores the matching test.

@majdyz majdyz 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.

Re-approving after the refactor commit. e3f87ac3f9 swaps the getattr-based duck-typed access for typed attribute access (ExecutionProcessor.nodes_input_masks: Optional[NodesInputMasks] = None), so callers get pyright-clean reads. The isinstance(..., Mapping) coercion is kept — orchestrator tests pass MagicMock/AsyncMock processors where the attribute chain otherwise returns a coroutine, breaking inputs.update(...). All required CI green; only Vercel fails (non-required fork-preview auth limitation, this PR is backend-only).

@majdyz
majdyz added this pull request to the merge queue May 28, 2026
Merged via the queue into Significant-Gravitas:dev with commit bef67a1 May 28, 2026
39 of 40 checks passed
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban May 28, 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.

Orchestrator tool credentials missing when run from Library or AutoPilot (works from Builder)

5 participants