Skip to content

feat(copilot): add tool/block capability filtering to AutoPilotBlock - #12482

Merged
majdyz merged 14 commits into
devfrom
feat/copilot-permissions
Mar 24, 2026
Merged

feat(copilot): add tool/block capability filtering to AutoPilotBlock#12482
majdyz merged 14 commits into
devfrom
feat/copilot-permissions

Conversation

@majdyz

@majdyz majdyz commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds CopilotPermissions model (copilot/permissions.py) — a capability filter that restricts which tools and blocks the AutoPilot/Copilot may use during a single execution
  • Exposes 4 new advanced=True fields on AutoPilotBlock: tools, tools_exclude, blocks, blocks_exclude
  • Threads permissions through the full execution path: AutoPilotBlockcollect_copilot_responsestream_chat_completion_sdkrun_block
  • Implements recursion inheritance via contextvar: sub-agent executions can only be more restrictive than their parent

Design

Tool filtering (tools + tools_exclude):

  • tools_exclude=True (default): tools is a blacklist — listed tools denied, all others allowed. Empty list = allow all.
  • tools_exclude=False: tools is a whitelist — only listed tools are allowed.
  • Users specify short names (run_block, web_fetch, Read, Task, …) — mapped to full SDK format internally.
  • Validated eagerly at block-run time with a clear error listing valid names.

Block filtering (blocks + blocks_exclude):

  • Same semantics as tool filtering, applied inside run_block via contextvar.
  • Each entry can be a full UUID, an 8-char partial UUID (first segment), or a case-insensitive block name.
  • Validated against the live block registry; invalid identifiers surface a helpful error before the session is created.

Recursion inheritance:

  • _inherited_permissions contextvar stores the parent execution's permissions.
  • On each AutoPilotBlock.run(), the child's permissions are merged with the parent via merged_with_parent() — effective allowed sets are intersected (tools) and the parent chain is kept for block checks.
  • Sub-agents can never expand what the parent allowed.

Test plan

  • 68 new unit tests in copilot/permissions_test.py and blocks/autopilot_permissions_test.py
  • Block identifier matching: full UUID, partial UUID, name, case-insensitivity
  • Tool allow/deny list semantics including edge cases (empty list, unknown tool)
  • Parent/child merging and recursion ceiling correctness
  • validate_tool_names / validate_block_identifiers with mock block registry
  • apply_tool_permissions SDK tool-list integration
  • AutoPilotBlock.run() — invalid tool/block yields error before session creation
  • AutoPilotBlock.run() — valid permissions forwarded to execute_copilot
  • Existing AutoPilotBlock block tests still pass (2/2)
  • All hooks pass (pyright, ruff, black, isort)
  • E2E: CoPilot chat works end-to-end with E2B sandbox (12s stream)
  • E2E: Permission fields render in Builder UI (Tools combobox, exclude toggles)
  • E2E: Agent with restricted permissions (whitelist web_fetch only) executes correctly
  • E2E: Permission values preserved through API round-trip

@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

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

Adds a CopilotPermissions model and permission plumbing: validation, inheritance/merge, context propagation, SDK/service/collect support, AutoPilot input fields and runtime enforcement in RunBlockTool, plus unit and integration tests and docs updates.

Changes

Cohort / File(s) Summary
Permissions model & helpers
autogpt_platform/backend/backend/copilot/permissions.py
New CopilotPermissions Pydantic model with tools/blocks allow/deny semantics, identifier matching (UUID/name/8‑hex prefix), parent-merge rules, and helpers validate_tool_names, validate_block_identifiers, apply_tool_permissions.
Permissions tests
autogpt_platform/backend/backend/copilot/permissions_test.py
Comprehensive unit tests for matching logic, effective tool computation, block allow checks, parent merging, validation helpers, and apply_tool_permissions.
AutoPilot block changes
autogpt_platform/backend/backend/blocks/autopilot.py
Added inputs tools, tools_exclude, blocks, blocks_exclude; execute_copilot accepts permissions; run() builds/validates/merges permissions, yields early on validation errors, forwards merged permissions into copilot execution, and resets inherited permissions after execution.
AutoPilot permission tests
autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
Tests for permission construction, validation failures, inheritance merging, and runtime forwarding/behavior in AutoPilotBlock.run().
Execution context changes
autogpt_platform/backend/backend/copilot/context.py, autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
Added _current_permissions ContextVar; set_execution_context(...) accepts permissions and sets it; new accessor get_current_permissions().
SDK collect/service plumbing
autogpt_platform/backend/backend/copilot/sdk/collect.py, autogpt_platform/backend/backend/copilot/sdk/service.py
collect_copilot_response() and stream_chat_completion_sdk() accept permissions and propagate into execution context; service uses apply_tool_permissions() to derive allowed/disallowed tools when permissions are provided.
Runtime block guard
autogpt_platform/backend/backend/copilot/tools/run_block.py
RunBlockTool._execute consults get_current_permissions() and short-circuits with an ErrorResponse if the target block is disallowed, including tailored messaging about allowed/blocked identifiers.
RunBlock tests
autogpt_platform/backend/backend/copilot/tools/run_block_test.py
Added tests verifying denied/allowed behavior when _current_permissions blocks exclude/include specific block ids.
Docs
docs/integrations/block-integrations/misc.md
Documented four new AutoPilot inputs: tools, tools_exclude, blocks, blocks_exclude with allow/deny semantics.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant AutoPilot as AutoPilotBlock
    participant Validator as PermValidation
    participant Context as ExecutionContext
    participant SDK as SDKService
    participant Runner as RunBlockTool

    User->>AutoPilot: run(input with tools/blocks)
    AutoPilot->>Validator: _build_and_validate_permissions()
    alt validation fails
        Validator-->>AutoPilot: error string
        AutoPilot-->>User: yield("error", ...)
    else validation succeeds
        Validator-->>AutoPilot: CopilotPermissions
        AutoPilot->>Context: set_execution_context(permissions=perms)
        AutoPilot->>SDK: stream_chat_completion_sdk(permissions=perms)
        SDK->>SDK: apply_tool_permissions(permissions)
        loop tool/block calls
            SDK->>Runner: execute(block_id)
            Runner->>Context: get_current_permissions()
            alt block disallowed
                Runner-->>SDK: ErrorResponse
            else allowed
                Runner-->>SDK: success result
            end
        end
        AutoPilot-->>User: yield(response, ...)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

size/m, Review effort 4/5

Suggested reviewers

  • Swiftyos
  • Pwuts
  • Bentlybro
  • kcze

Poem

🐰 I hopped through code with careful paws,
Tools and blocks now answer laws,
I weave a ceiling into nested runs,
Gates close where permissions aren't one,
A tiny rabbit guards the fun.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding tool/block capability filtering to AutoPilotBlock, matching the core objective of the changeset.
Description check ✅ Passed The pull request description provides a detailed explanation of the CopilotPermissions model and permission-filtering feature that directly relates to the changeset, including design principles, implementation approach, and test coverage.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/copilot-permissions

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.

@github-actions

github-actions Bot commented Mar 19, 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: 5 conflict(s), 0 medium risk, 4 low risk (out of 9 PRs with file overlap)


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

Comment thread autogpt_platform/backend/backend/blocks/autopilot.py Outdated
Comment thread autogpt_platform/backend/backend/blocks/autopilot.py Outdated
Comment thread autogpt_platform/backend/backend/copilot/permissions.py Outdated
Comment thread autogpt_platform/backend/backend/copilot/tools/run_block.py

@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 (4)
autogpt_platform/backend/backend/copilot/permissions.py (2)

59-60: Remove empty TYPE_CHECKING block.

The if TYPE_CHECKING: pass block serves no purpose since there are no type-only imports needed here.

🧹 Suggested fix
-if TYPE_CHECKING:
-    pass
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/copilot/permissions.py` around lines 59 -
60, Remove the no-op TYPE_CHECKING block and any now-unused import: delete the
lines containing "if TYPE_CHECKING: pass" in permissions.py, and also remove the
TYPE_CHECKING name from the typing import (or the entire import) if it becomes
unused so there are no dead/no-op constructs remaining.

256-268: Consider caching block instances during validation.

The current implementation instantiates block_cls() for each (identifier, block) pair. While block instantiation is lightweight, this could be optimized for large identifier lists by building a lookup map once.

♻️ Suggested optimization
 async def validate_block_identifiers(
     identifiers: list[str],
 ) -> list[str]:
     from backend.blocks import get_blocks

-    # get_blocks() returns dict[block_id_str, BlockClass]; instantiate to get id/name.
     block_registry = get_blocks()
+    # Build lookup once: [(block_id, block_name), ...]
+    block_info = [(block_id, block_cls().name) for block_id, block_cls in block_registry.items()]
+
     invalid: list[str] = []
     for ident in identifiers:
         matched = any(
-            _block_matches(ident, block_id, block_cls().name)
-            for block_id, block_cls in block_registry.items()
+            _block_matches(ident, block_id, block_name)
+            for block_id, block_name in block_info
         )
         if not matched:
             invalid.append(ident)
     return invalid
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/copilot/permissions.py` around lines 256 -
268, The loop repeatedly calls block_cls() for each (identifier, block) pair;
instead, build a one-time lookup of instantiated blocks or their names from
block_registry (e.g., create block_instances or block_names by iterating
block_registry and calling block_cls() once per entry), then use that lookup in
the validation loop when calling _block_matches(ident, block_id, ...). Update
the code around get_blocks(), block_registry, and the validation loop so matched
uses the prebuilt map rather than instantiating block_cls() repeatedly.
autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py (2)

125-129: Avoid identity-coupling in no-parent merge test.

This assertion couples the test to object reuse (is) rather than contract behavior. Prefer semantic checks (e.g., equality/effective permissions) so refactors that return copies don’t break tests unnecessarily.

Proposed test adjustment
     def test_permissions_no_parent_returned_unchanged(self):
         perms = CopilotPermissions(tools=["bash_exec"], tools_exclude=True)
         result = _merge_inherited_permissions(perms)
-        assert result is perms
+        assert result is not None
+        assert result.tools == ["bash_exec"]
+        assert result.tools_exclude is True
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py` around
lines 125 - 129, The test test_permissions_no_parent_returned_unchanged should
not assert identity; change the assertion so it verifies semantic equivalence of
permissions instead of object reuse: call _merge_inherited_permissions(perms)
and assert the returned CopilotPermissions has the same effective
attributes/values (e.g., tools list, tools_exclude flag, and any other relevant
fields) as the original perms (or use equality if CopilotPermissions implements
__eq__) rather than using "is". This keeps the test focused on behavior for
CopilotPermissions and _merge_inherited_permissions and avoids breaking on
harmless copy/refactor changes.

64-71: Consider extracting a shared block-registry mock fixture.

The same get_blocks mock setup is repeated in several tests; a small fixture/helper would reduce duplication and make intent clearer.

Also applies to: 76-83, 89-94, 217-223

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py` around
lines 64 - 71, Extract the repeated get_blocks mock into a reusable test fixture
or helper function to reduce duplication and clarify intent: create a
fixture/helper (e.g., make_mock_block_registry or fixture named
mock_block_registry) that constructs the MagicMock block class with
return_value.name = "HTTP Request" and patches backend.blocks.get_blocks to
return the mapping used in tests, then replace inline patch usage in tests that
call _make_input and _build_and_validate_permissions (and the other occurrences
around lines 76-83, 89-94, 217-223) to use the new fixture/helper instead of
duplicating mock_block_cls and patch logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@autogpt_platform/backend/backend/blocks/autopilot.py`:
- Around line 501-531: The function _merge_inherited_permissions currently calls
_inherited_permissions.set(merged) but never resets it, causing sequential
AutoPilot invocations to inherit stale permissions; change
_merge_inherited_permissions to perform the contextvar set and return the
ContextVar token (i.e., token = _inherited_permissions.set(merged); return
merged, token or just return token depending on your API), then update
execute_copilot to call _merge_inherited_permissions before running the copilot
block and ensure you call _inherited_permissions.reset(token) in a finally block
(mirroring the recursion depth token pattern used around lines 434-445) so the
inherited permissions are restored after each non-nested execution.

---

Nitpick comments:
In `@autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py`:
- Around line 125-129: The test test_permissions_no_parent_returned_unchanged
should not assert identity; change the assertion so it verifies semantic
equivalence of permissions instead of object reuse: call
_merge_inherited_permissions(perms) and assert the returned CopilotPermissions
has the same effective attributes/values (e.g., tools list, tools_exclude flag,
and any other relevant fields) as the original perms (or use equality if
CopilotPermissions implements __eq__) rather than using "is". This keeps the
test focused on behavior for CopilotPermissions and _merge_inherited_permissions
and avoids breaking on harmless copy/refactor changes.
- Around line 64-71: Extract the repeated get_blocks mock into a reusable test
fixture or helper function to reduce duplication and clarify intent: create a
fixture/helper (e.g., make_mock_block_registry or fixture named
mock_block_registry) that constructs the MagicMock block class with
return_value.name = "HTTP Request" and patches backend.blocks.get_blocks to
return the mapping used in tests, then replace inline patch usage in tests that
call _make_input and _build_and_validate_permissions (and the other occurrences
around lines 76-83, 89-94, 217-223) to use the new fixture/helper instead of
duplicating mock_block_cls and patch logic.

In `@autogpt_platform/backend/backend/copilot/permissions.py`:
- Around line 59-60: Remove the no-op TYPE_CHECKING block and any now-unused
import: delete the lines containing "if TYPE_CHECKING: pass" in permissions.py,
and also remove the TYPE_CHECKING name from the typing import (or the entire
import) if it becomes unused so there are no dead/no-op constructs remaining.
- Around line 256-268: The loop repeatedly calls block_cls() for each
(identifier, block) pair; instead, build a one-time lookup of instantiated
blocks or their names from block_registry (e.g., create block_instances or
block_names by iterating block_registry and calling block_cls() once per entry),
then use that lookup in the validation loop when calling _block_matches(ident,
block_id, ...). Update the code around get_blocks(), block_registry, and the
validation loop so matched uses the prebuilt map rather than instantiating
block_cls() repeatedly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 474a0a42-0b6b-416e-8b8b-6911d74da8fe

📥 Commits

Reviewing files that changed from the base of the PR and between a5f9c43 and c9d4dd1.

📒 Files selected for processing (9)
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/tools/run_block.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). (10)
  • GitHub Check: check API types
  • GitHub Check: Seer Code Review
  • GitHub Check: end-to-end tests
  • GitHub Check: Analyze (python)
  • GitHub Check: type-check (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: type-check (3.13)
  • GitHub Check: Check PR Status
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
🧰 Additional context used
📓 Path-based instructions (8)
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

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
autogpt_platform/backend/**/*.{py,txt}

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use poetry run prefix for all Python commands, including testing, linting, formatting, and migrations

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
autogpt_platform/backend/backend/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
autogpt_platform/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.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

Files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/backend/blocks/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/backend/blocks/*.py: When creating new blocks, inherit from the Block base class and define input/output schemas using BlockSchema
Implement blocks with an async run method and generate unique block IDs using uuid.uuid4()
When working with files in blocks, use store_media_file() from backend.util.file with appropriate return_format parameter: for_local_processing for local tools, for_external_api for external APIs, for_block_output for block outputs
Always use for_block_output format in store_media_file() for block outputs unless there is a specific reason not to
Never hardcode workspace checks when using store_media_file() - let for_block_output handle context adaptation automatically
When adding new blocks, analyze block interfaces to ensure inputs and outputs tie well together for productive graph-based editor connections

Files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/**/*_test.py: Always review snapshot changes with git diff before committing when updating snapshots with poetry run pytest --snapshot-update
Use pytest with snapshot testing for API responses in test files
Colocate test files with source files using the *_test.py naming convention

Files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/**/*test*.py

📄 CodeRabbit inference engine (AGENTS.md)

Run poetry run test for backend testing (runs pytest with docker based postgres + prisma)

Files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
🧠 Learnings (34)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:10.126Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — OpenAPI/codegen
Learning: Ensuring a field is required in generated TS types needs two sides: (1) no default value on the Pydantic field, and (2) the OpenAPI model's "required" array must list it. For MCPToolInfo, making input_schema required in OpenAPI and removing Field(default_factory=dict) in the backend prevents optional typing drift.
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/blocks/**/*.py : Implement 'run' method with proper error handling in backend blocks

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-03-10T08:38:29.078Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:29.078Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review is session-scoped: it uses graph_exec_id (copilot-session-{session_id}) combined with node_id (copilot-node-{block_id}). If the user enables the auto-approve toggle for a CoPilot session, approving a block type in that session automatically approves all future invocations of that same block type within the same session. If the user does not toggle auto-approve (default), each individual invocation requires its own approval. This behavior should be clearly documented in code and comments, and tested to ensure the toggle reliably toggles between session-scoped auto-approval and per-invocation approval.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
📚 Learning: 2026-03-15T15:30:09.706Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:149-185
Timestamp: 2026-03-15T15:30:09.706Z
Learning: In autogpt_platform/backend/backend/copilot/tools/helpers.py, within execute_block, when InsufficientBalanceError occurs after post-execution credit charging (concurrent balance drain after pre-check passed), this is treated as a non-fatal billing leak: log at ERROR level with structured JSON fields `{"billing_leak": True, "user_id": ..., "cost": ...}` for monitoring/alerting, then return BlockOutputResponse normally. Discarding the output would worsen UX since the block already executed with potential side effects. Reuse the credit_model obtained during the pre-execution balance check (guarded by `if cost > 0 and credit_model:`) for the post-execution charge; do not perform a second get_user_credit_model call.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
📚 Learning: 2026-03-16T16:30:30.764Z
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:30.764Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, explicit try/except in the `run()` method is NOT required for standard error handling. The block framework's `_execute()` method in `_base.py` catches unhandled exceptions and re-raises them as `BlockExecutionError` or `BlockUnknownError`. Additionally, when a block yields `("error", message)`, `_execute()` immediately raises `BlockExecutionError` — so the `error` output port never propagates downstream. Explicit try/except is only needed when partial output must be controlled (e.g., attachment blocks that must skip yielding `content_base64` on failure).

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
📚 Learning: 2026-03-16T16:32:29.430Z
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:29.430Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, the Block base class `execute()` method in `backend/blocks/_base.py` already wraps `run()` in a try/except that converts uncaught exceptions into `BlockExecutionError`/`BlockUnknownError`. Therefore, explicit try/except in individual block `run()` methods is redundant and not the established pattern (e.g., Gmail, Slack, Todoist blocks omit it). Exception: blocks like attachment blocks that need to distinguish between success and error yield paths within the generator use explicit try/except for branching control, not for the framework's error routing.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
📚 Learning: 2026-03-10T08:39:22.025Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-03-16T16:30:20.657Z
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:20.657Z
Learning: In autogpt_platform/backend/backend/blocks/agent_mail/ (and other blocks under autogpt_platform/backend/backend/blocks/), the block executor framework (backend/executor/manager.py lines ~708-733) automatically catches all uncaught exceptions from a block's `run()` method and emits them on the `"error"` output. Explicit try/except blocks within `run()` are therefore not required for standard error propagation — they are only needed when partial output behaviour must be controlled (e.g., preventing some outputs from being yielded on failure, as in attachment blocks). This is the standard pattern across the codebase.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.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/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-03-04T08:04:35.881Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12273
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:216-220
Timestamp: 2026-03-04T08:04:35.881Z
Learning: In the AutoGPT Copilot backend, ensure that SVG images are not treated as vision image types by excluding 'image/svg+xml' from INLINEABLE_MIME_TYPES and MULTIMODAL_TYPES in tool_adapter.py; the Claude API supports PNG, JPEG, GIF, and WebP for vision. SVGs (XML text) should be handled via the text path instead, not the vision path.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-03-04T12:19:39.243Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12279
File: autogpt_platform/backend/backend/copilot/tools/base.py:184-188
Timestamp: 2026-03-04T12:19:39.243Z
Learning: In autogpt_platform/backend/backend/copilot/tools/, ensure that anonymous users always pass user_id=None to tool execution methods. The anon_ prefix (e.g., anon_123) is used only for PostHog/analytics distinct_id and must not be used as an actual user_id. Use a simple truthiness check on user_id (e.g., if user_id: ... else: ... or a dedicated is_authenticated flag) to distinguish anonymous from authenticated users, and review all tool execution call sites within this directory to prevent accidentally forwarding an anon_ user_id to tools.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.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/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-03-10T08:38:30.834Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:349-370
Timestamp: 2026-03-10T08:38:30.834Z
Learning: In the AutoGPT CoPilot HITL flow, the review card presents with editable: false, so the input payload cannot be modified. Therefore credentials resolved before is_block_exec_need_review() remain valid and do not need to be recomputed after the review step. Ensure run_block.py uses the original input_data for credential validation and that any credential caching relies on the pre-review input. If there is any logic that would recompute credentials post-review, guard it against input_data mutations and rely on the UI to enforce immutability. This guideline is specific to autogpt_platform/backend/backend/copilot/tools/run_block.py.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block.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/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-02-20T03:28:06.619Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12173
File: autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py:153-179
Timestamp: 2026-02-20T03:28:06.619Z
Learning: The copilot executor (`backend.copilot.executor`) runs in its own Docker container with Python 3.13, so Python 3.11+ features like `asyncio.timeout()` are available in copilot code even though the general backend pyproject.toml specifies `python = ">=3.10,<3.14"`.

Applied to files:

  • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py
📚 Learning: 2026-03-17T10:57:10.126Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:10.126Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.

Applied to files:

  • autogpt_platform/backend/backend/copilot/sdk/collect.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-03-16T17:00:02.827Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).

Applied to files:

  • autogpt_platform/backend/backend/copilot/context.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-03-15T16:52:15.463Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12426
File: autogpt_platform/backend/backend/copilot/sdk/service.py:0-0
Timestamp: 2026-03-15T16:52:15.463Z
Learning: In Significant-Gravitas/AutoGPT (copilot backend), GitHub tokens (GH_TOKEN / GITHUB_TOKEN) for the `gh` CLI are injected lazily per-command in `autogpt_platform/backend/backend/copilot/tools/bash_exec._execute_on_e2b()` by calling `integration_creds.get_integration_env_vars(user_id)`, not on the global SDK subprocess environment in `sdk/service.py`. This scopes credentials to individual E2B sandbox command invocations and prevents token leakage into tool output streams or uploaded transcripts.

Applied to files:

  • autogpt_platform/backend/backend/copilot/context.py
📚 Learning: 2026-03-10T08:38:33.249Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-03-10T08:38:36.655Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:349-370
Timestamp: 2026-03-10T08:38:36.655Z
Learning: In the AutoGPT CoPilot HITL (Human-In-The-Loop) flow (`autogpt_platform/backend/backend/copilot/tools/run_block.py`), the review card presented to users sets `editable: false`, meaning reviewers cannot modify the input payload. Therefore, credentials resolved before `is_block_exec_need_review()` remain valid and do not need to be recomputed after the review step — the original `input_data` is unchanged through the review lifecycle.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-02-27T15:59:00.370Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — OpenAPI/codegen
Learning: Ensuring a field is required in generated TS types needs two sides: (1) no default value on the Pydantic field, and (2) the OpenAPI model's "required" array must list it. For MCPToolInfo, making input_schema required in OpenAPI and removing Field(default_factory=dict) in the backend prevents optional typing drift.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-02-27T15:59:00.370Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — Backend/frontend OpenAPI codegen
Learning: For MCP schema models, required OpenAPI fields must have no defaults in Pydantic. Specifically, MCPToolInfo.input_schema must be required (no Field(default_factory=dict)) so openapi.json emits it in "required", ensuring generated TS types treat input_schema as non-optional.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/**/data/*.py : For changes touching `data/*.py`, validate user ID checks or explain why not needed

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/backend/blocks/*.py : When adding new blocks, analyze block interfaces to ensure inputs and outputs tie well together for productive graph-based editor connections

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 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/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/blocks/**/*.py : Write tests alongside block implementation when adding new blocks in backend

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/**/test/**/*.py : Use snapshot testing with '--snapshot-update' flag in backend tests when output changes; always review with 'git diff'

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : Always review snapshot changes with `git diff` before committing when updating snapshots with `poetry run pytest --snapshot-update`

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : Colocate test files with source files using the `*_test.py` naming convention

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/data/**/*.py : All data access in backend requires user ID checks; verify this for any 'data/*.py' changes

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
🔇 Additional comments (20)
autogpt_platform/backend/backend/copilot/permissions.py (4)

67-86: LGTM!

The constants are well-defined with appropriate immutability (frozenset) and pre-compiled regex patterns for efficient UUID matching.


93-107: LGTM!

The _block_matches function correctly implements the documented resolution order with proper case-insensitive matching.


114-214: LGTM!

The CopilotPermissions model correctly implements whitelist/blacklist semantics with proper parent inheritance via merged_with_parent. The use of PrivateAttr for _parent appropriately hides the internal recursion state from the block input schema.


276-327: LGTM!

The apply_tool_permissions function correctly maps short tool names to SDK format and ensures the internal read_file tool remains available for SDK operations.

autogpt_platform/backend/backend/copilot/permissions_test.py (4)

1-16: LGTM!

The test file is correctly colocated with the source module and imports all the necessary components for comprehensive testing.


22-268: LGTM!

Comprehensive test coverage for block matching logic and CopilotPermissions methods including edge cases for inheritance and merging semantics.


275-322: LGTM!

The async validation tests properly mock the block registry and cover valid/invalid identifier scenarios. The empty list test works correctly since the loop doesn't iterate.


329-439: LGTM!

The apply_tool_permissions tests properly verify blacklist/whitelist behavior with appropriate mocking. The SDK builtin sanity checks ensure the constant stays in sync with expected tool names.

autogpt_platform/backend/backend/copilot/tools/run_block.py (1)

166-188: LGTM!

The permission check is correctly placed before execution with clear error messaging. The conditional hint construction properly distinguishes between allow-list and deny-list modes to help users understand why the block was rejected.

autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py (1)

73-99: LGTM!

The set_execution_context function is correctly extended to accept and store the permissions contextvar alongside existing context values. The backward-compatible signature with permissions=None default is appropriate.

autogpt_platform/backend/backend/copilot/sdk/collect.py (1)

39-90: LGTM!

The collect_copilot_response function correctly accepts and forwards the optional permissions parameter to the SDK streaming layer with proper documentation.

autogpt_platform/backend/backend/copilot/sdk/service.py (2)

1616-1622: LGTM!

The execution context is correctly set with permissions before the SDK stream begins, ensuring tool handlers can access the permission filter via get_current_permissions().


1648-1654: LGTM!

The conditional application of tool permissions correctly uses apply_tool_permissions when a filter is provided, falling back to the standard tool lists otherwise. This maintains backward compatibility while enabling capability restriction.

autogpt_platform/backend/backend/copilot/context.py (3)

49-53: LGTM!

The new _current_permissions ContextVar is correctly defined with a default of None (unrestricted) and properly typed with a forward reference to avoid import cycles.


70-83: LGTM!

The set_execution_context function is correctly extended to accept and store the optional permissions parameter.


91-94: LGTM!

The get_current_permissions accessor provides a clean API for retrieving the active permissions from the execution context.

autogpt_platform/backend/backend/blocks/autopilot.py (3)

102-153: LGTM!

The new Input fields for capability filtering (tools, tools_exclude, blocks, blocks_exclude) are well-documented with clear descriptions of the whitelist/blacklist semantics.


359-364: LGTM!

Permission validation is correctly performed before session creation, preventing orphaned sessions when invalid tool/block identifiers are provided.


459-498: LGTM!

The _build_and_validate_permissions function properly validates tool names against the known registry and block identifiers against the live block registry before constructing the permissions object.

autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py (1)

41-113: Strong coverage for permission validation and inheritance paths.

Nice test surface here: you cover allow/deny semantics, block identifier forms, contextvar inheritance behavior, and run-path integration with permission forwarding.

Also applies to: 120-182, 189-259

Comment thread autogpt_platform/backend/backend/blocks/autopilot.py Outdated
@majdyz
majdyz requested a review from a team as a code owner March 19, 2026 14:29
@majdyz
majdyz requested review from 0ubbe and Swiftyos and removed request for a team March 19, 2026 14:29
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Mar 19, 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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@autogpt_platform/backend/backend/copilot/permissions.py`:
- Around line 315-316: Replace the hardcoded tool name "read_file" with the READ
tool constant so the internal SDK read tool is always included; specifically,
update the code that modifies permitted_sdk (the line with
permitted_sdk.add(f"{MCP_TOOL_PREFIX}read_file")) to use the same symbol used in
tool_adapter.py (i.e., _READ_TOOL_NAME) so the added name is
f"{MCP_TOOL_PREFIX}{_READ_TOOL_NAME}", ensuring MCP_TOOL_PREFIX, _READ_TOOL_NAME
and permitted_sdk are referenced correctly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 71cecda1-acee-42ee-bc7f-8837c44d054f

📥 Commits

Reviewing files that changed from the base of the PR and between c9d4dd1 and 23c75ef.

📒 Files selected for processing (4)
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/copilot/tools/run_block.py
✅ Files skipped from review due to trivial changes (2)
  • autogpt_platform/backend/backend/copilot/tools/run_block.py
  • autogpt_platform/backend/backend/blocks/autopilot.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). (13)
  • GitHub Check: check API types
  • GitHub Check: end-to-end tests
  • GitHub Check: Seer Code Review
  • GitHub Check: check-docs-sync
  • GitHub Check: Check PR Status
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: Analyze (python)
  • GitHub Check: check-overlaps
  • GitHub Check: conflicts
🧰 Additional context used
📓 Path-based instructions (8)
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

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/**/*.{py,txt}

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use poetry run prefix for all Python commands, including testing, linting, formatting, and migrations

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/backend/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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

Files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/**/*_test.py: Always review snapshot changes with git diff before committing when updating snapshots with poetry run pytest --snapshot-update
Use pytest with snapshot testing for API responses in test files
Colocate test files with source files using the *_test.py naming convention

Files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/backend/blocks/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/backend/blocks/*.py: When creating new blocks, inherit from the Block base class and define input/output schemas using BlockSchema
Implement blocks with an async run method and generate unique block IDs using uuid.uuid4()
When working with files in blocks, use store_media_file() from backend.util.file with appropriate return_format parameter: for_local_processing for local tools, for_external_api for external APIs, for_block_output for block outputs
Always use for_block_output format in store_media_file() for block outputs unless there is a specific reason not to
Never hardcode workspace checks when using store_media_file() - let for_block_output handle context adaptation automatically
When adding new blocks, analyze block interfaces to ensure inputs and outputs tie well together for productive graph-based editor connections

Files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
autogpt_platform/backend/**/*test*.py

📄 CodeRabbit inference engine (AGENTS.md)

Run poetry run test for backend testing (runs pytest with docker based postgres + prisma)

Files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
🧠 Learnings (21)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:10.126Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.
📚 Learning: 2026-03-16T17:00:02.827Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-03-10T08:39:22.025Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-03-17T10:57:10.126Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:10.126Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-03-10T08:38:33.249Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-03-04T08:04:35.881Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12273
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:216-220
Timestamp: 2026-03-04T08:04:35.881Z
Learning: In the AutoGPT Copilot backend, ensure that SVG images are not treated as vision image types by excluding 'image/svg+xml' from INLINEABLE_MIME_TYPES and MULTIMODAL_TYPES in tool_adapter.py; the Claude API supports PNG, JPEG, GIF, and WebP for vision. SVGs (XML text) should be handled via the text path instead, not the vision path.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.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/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/blocks/**/*.py : Write tests alongside block implementation when adding new blocks in backend

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/**/test/**/*.py : Use snapshot testing with '--snapshot-update' flag in backend tests when output changes; always review with 'git diff'

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : Always review snapshot changes with `git diff` before committing when updating snapshots with `poetry run pytest --snapshot-update`

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : Colocate test files with source files using the `*_test.py` naming convention

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/**/data/*.py : For changes touching `data/*.py`, validate user ID checks or explain why not needed

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : Use pytest with snapshot testing for API responses in test files

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.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/autopilot_permissions_test.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/autopilot_permissions_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/blocks/**/*.py : Implement 'run' method with proper error handling in backend blocks

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py
📚 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/autopilot_permissions_test.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/autopilot_permissions_test.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/autopilot_permissions_test.py
🔇 Additional comments (9)
autogpt_platform/backend/backend/copilot/permissions.py (5)

1-56: LGTM!

Clear and comprehensive module documentation explaining the permission semantics, tool naming conventions, and recursion inheritance pattern.


58-81: LGTM!

Constants are appropriately defined as immutable frozenset and regex patterns are compiled at module level for efficiency.


89-103: LGTM!

Clean implementation with proper resolution order (full UUID → partial UUID → name) and case-insensitive matching throughout.


110-210: LGTM!

Well-designed model with clean separation between local filtering (_check_block_locally) and parent inheritance (is_block_allowed). The merged_with_parent implementation correctly uses whitelist semantics after intersection to ensure children can only narrow permissions.


217-264: LGTM!

Validation helpers are well-structured with lazy imports to avoid circular dependencies. The validate_block_identifiers instantiation overhead is acceptable since it only runs during block setup, not in the hot path.

autogpt_platform/backend/backend/blocks/autopilot_permissions_test.py (4)

1-34: LGTM!

Clean test setup with a well-designed _make_input helper that provides sensible defaults while allowing specific field overrides.


41-112: LGTM!

Comprehensive test coverage for _build_and_validate_permissions including valid/invalid tool names, block identifiers (by name and partial UUID), SDK built-ins, and the optimization to skip block validation when empty.


120-201: LGTM!

Thorough coverage of permission inheritance semantics with proper contextvar token cleanup in finally blocks. The tests correctly verify that children cannot expand parent permissions.


209-279: LGTM!

Well-designed integration tests that verify error handling order (empty prompt before permission validation) and that valid permissions are correctly forwarded to execute_copilot. The _collect_outputs helper is appropriately simple for these single-yield scenarios.

Comment thread autogpt_platform/backend/backend/copilot/permissions.py Outdated

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/integrations/block-integrations/misc.md (1)

46-49: 🛠️ Refactor suggestion | 🟠 Major

Add technical explanation of the new permission filtering capability.

The "How It Works" section currently omits the new tool and block filtering feature introduced in this PR. Per coding guidelines, this section should include 1-2 paragraphs describing processing logic, validation, and error handling.

Consider adding content that covers:

  • How tool and block identifiers are validated at block-run time
  • How permissions are enforced during copilot tool invocation
  • Parent-child permission inheritance for sub-agent patterns
  • Error handling when invalid tool or block names are provided

As per coding guidelines, the "How It Works" section should "Provide a technical explanation of how the block functions, including 1-2 paragraphs describing processing logic, validation, error handling, or edge cases."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/integrations/block-integrations/misc.md` around lines 46 - 49, Update
the "How it works" section (the paragraph describing the block that invokes the
copilot via `stream_chat_completion_sdk`) to add 1–2 technical paragraphs
explaining the new tool/block permission filtering: describe that tool and block
identifiers are validated at block-run time (reject unknown IDs), explain that
permissions are enforced when invoking copilot tools (only allowed tools/blocks
are passed to the copilot runtime), note parent→child permission inheritance for
sub-agent calls (sub-agents inherit and are intersection-limited by parent
permissions), and detail error handling and responses for invalid or
unauthorized tool/block names (clear validation errors returned and streaming
aborted). Ensure the text explicitly references the runtime validation and
enforcement steps and the failure behavior so readers understand processing
logic, validation, and error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/integrations/block-integrations/misc.md`:
- Line 59: The tools list in misc.md is incomplete; update the tools column to
either include the missing tool names (add_understanding, continue_run_block,
create_feature_request, create_folder, delete_folder, get_agent_building_guide,
get_doc_page, get_mcp_guide, list_folders, move_agents_to_folder, move_folder,
search_feature_requests, update_folder) so the table matches the registry, or
replace the hardcoded list with a short note and a link/reference to the
authoritative all_known_tool_names() function in backend.copilot.permissions so
the documentation stays accurate as tools are added; adjust the description text
to remove “(and others)” if you choose the full list or add the reference
callout if you choose the dynamic source.

---

Outside diff comments:
In `@docs/integrations/block-integrations/misc.md`:
- Around line 46-49: Update the "How it works" section (the paragraph describing
the block that invokes the copilot via `stream_chat_completion_sdk`) to add 1–2
technical paragraphs explaining the new tool/block permission filtering:
describe that tool and block identifiers are validated at block-run time (reject
unknown IDs), explain that permissions are enforced when invoking copilot tools
(only allowed tools/blocks are passed to the copilot runtime), note parent→child
permission inheritance for sub-agent calls (sub-agents inherit and are
intersection-limited by parent permissions), and detail error handling and
responses for invalid or unauthorized tool/block names (clear validation errors
returned and streaming aborted). Ensure the text explicitly references the
runtime validation and enforcement steps and the failure behavior so readers
understand processing logic, validation, and error handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 20a8f2d8-462d-4af0-9acf-4c1d3663c9f7

📥 Commits

Reviewing files that changed from the base of the PR and between 23c75ef and 1a4d14e.

📒 Files selected for processing (1)
  • docs/integrations/block-integrations/misc.md
📜 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). (5)
  • GitHub Check: end-to-end tests
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (2)
docs/integrations/**/*.md

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/integrations/**/*.md: Provide a technical explanation of how the block functions in the 'How It Works' section, including 1-2 paragraphs describing processing logic, validation, error handling, or edge cases, with code examples in backticks when helpful
Provide exactly 3 practical use cases in the 'Use Case' section, formatted with bold headings followed by short one-sentence descriptions

Files:

  • docs/integrations/block-integrations/misc.md
docs/**/*.md

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/**/*.md: Keep documentation descriptions concise and action-oriented, focusing on practical, real-world scenarios
Use consistent terminology with other blocks and avoid overly technical jargon unless necessary in documentation

Files:

  • docs/integrations/block-integrations/misc.md
🧠 Learnings (2)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.
📚 Learning: 2026-03-08T23:28:21.675Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12334
File: docs/integrations/block-integrations/github/repo.md:11-40
Timestamp: 2026-03-08T23:28:21.675Z
Learning: In Significant-Gravitas/AutoGPT, new GitHub block documentation stubs in `docs/integrations/block-integrations/github/` are auto-generated by a docs script with placeholder text (`_Add technical explanation here._` / `_Add practical use case examples here._`) inside `<!-- MANUAL: how_it_works

Applied to files:

  • docs/integrations/block-integrations/misc.md
🔇 Additional comments (1)
docs/integrations/block-integrations/misc.md (1)

60-62: Accurate documentation of permission filtering semantics.

The documentation for tools_exclude, blocks, and blocks_exclude accurately reflects the implementation:

  • Default values (True for both exclude flags) match the code
  • Blacklist/whitelist semantics are correctly described for both modes
  • Empty list behavior (allow everything) is correctly documented
  • Block identifier formats (name, full UUID, 8-char prefix) match the implementation

The descriptions are clear, technically precise, and will help users understand how to configure tool and block filtering correctly.

Comment thread docs/integrations/block-integrations/misc.md Outdated

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
autogpt_platform/backend/backend/blocks/autopilot.py (1)

280-339: ⚠️ Potential issue | 🟠 Major

Move _merge_inherited_permissions() under the cleanup try/finally.

_check_recursion() mutates the task-local depth/limit before the try starts. If _merge_inherited_permissions() or one of its lazy imports throws, _reset_recursion(tokens) never runs, and later executions in the same task inherit a stale recursion state.

🔧 Suggested fix
         from backend.copilot.sdk.collect import collect_copilot_response

         tokens = _check_recursion(max_recursion_depth)
-        effective_permissions, perm_token = _merge_inherited_permissions(permissions)
+        perm_token = None
         try:
+            effective_permissions, perm_token = _merge_inherited_permissions(
+                permissions
+            )
             effective_prompt = prompt
             if system_context:
                 effective_prompt = f"[System Context: {system_context}]\n\n{prompt}"

Based on learnings, the approved recursion-guard pattern stores ContextVar tokens and resets them in a finally block for every execution path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/blocks/autopilot.py` around lines 280 - 339,
Move the call to _merge_inherited_permissions(permissions) so that both
_check_recursion(max_recursion_depth) and _merge_inherited_permissions(...)
happen inside the same try block, ensuring their ContextVar tokens (tokens and
perm_token) are always reset in the finally; specifically, call tokens =
_check_recursion(...) and then effective_permissions, perm_token =
_merge_inherited_permissions(...) after entering the try, keep the rest of the
logic (building effective_prompt, await collect_copilot_response, building
tool_calls/usage, and returning) inside that try, and in the finally call
_reset_recursion(tokens) and if perm_token is not None:
_inherited_permissions.reset(perm_token) so no early exception leaves recursion
state mutated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@autogpt_platform/backend/backend/blocks/autopilot.py`:
- Around line 280-339: Move the call to
_merge_inherited_permissions(permissions) so that both
_check_recursion(max_recursion_depth) and _merge_inherited_permissions(...)
happen inside the same try block, ensuring their ContextVar tokens (tokens and
perm_token) are always reset in the finally; specifically, call tokens =
_check_recursion(...) and then effective_permissions, perm_token =
_merge_inherited_permissions(...) after entering the try, keep the rest of the
logic (building effective_prompt, await collect_copilot_response, building
tool_calls/usage, and returning) inside that try, and in the finally call
_reset_recursion(tokens) and if perm_token is not None:
_inherited_permissions.reset(perm_token) so no early exception leaves recursion
state mutated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f5b9895d-f3b8-4d4c-8e93-5fcca4b8c32d

📥 Commits

Reviewing files that changed from the base of the PR and between 1a4d14e and 0b45a19.

📒 Files selected for processing (3)
  • autogpt_platform/backend/backend/blocks/autopilot.py
  • autogpt_platform/backend/backend/copilot/permissions.py
  • docs/integrations/block-integrations/misc.md
📜 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: Seer Code Review
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Check PR Status
  • GitHub Check: end-to-end tests
  • GitHub Check: type-check (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: conflicts
🧰 Additional context used
📓 Path-based instructions (8)
docs/integrations/**/*.md

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/integrations/**/*.md: Provide a technical explanation of how the block functions in the 'How It Works' section, including 1-2 paragraphs describing processing logic, validation, error handling, or edge cases, with code examples in backticks when helpful
Provide exactly 3 practical use cases in the 'Use Case' section, formatted with bold headings followed by short one-sentence descriptions

Files:

  • docs/integrations/block-integrations/misc.md
docs/**/*.md

📄 CodeRabbit inference engine (docs/CLAUDE.md)

docs/**/*.md: Keep documentation descriptions concise and action-oriented, focusing on practical, real-world scenarios
Use consistent terminology with other blocks and avoid overly technical jargon unless necessary in documentation

Files:

  • docs/integrations/block-integrations/misc.md
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

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
autogpt_platform/backend/**/*.{py,txt}

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use poetry run prefix for all Python commands, including testing, linting, formatting, and migrations

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
autogpt_platform/backend/backend/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
autogpt_platform/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.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

Files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
autogpt_platform/backend/backend/blocks/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/backend/blocks/*.py: When creating new blocks, inherit from the Block base class and define input/output schemas using BlockSchema
Implement blocks with an async run method and generate unique block IDs using uuid.uuid4()
When working with files in blocks, use store_media_file() from backend.util.file with appropriate return_format parameter: for_local_processing for local tools, for_external_api for external APIs, for_block_output for block outputs
Always use for_block_output format in store_media_file() for block outputs unless there is a specific reason not to
Never hardcode workspace checks when using store_media_file() - let for_block_output handle context adaptation automatically
When adding new blocks, analyze block interfaces to ensure inputs and outputs tie well together for productive graph-based editor connections

Files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
🧠 Learnings (21)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:10.126Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — OpenAPI/codegen
Learning: Ensuring a field is required in generated TS types needs two sides: (1) no default value on the Pydantic field, and (2) the OpenAPI model's "required" array must list it. For MCPToolInfo, making input_schema required in OpenAPI and removing Field(default_factory=dict) in the backend prevents optional typing drift.
📚 Learning: 2026-03-08T23:28:21.675Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12334
File: docs/integrations/block-integrations/github/repo.md:11-40
Timestamp: 2026-03-08T23:28:21.675Z
Learning: In Significant-Gravitas/AutoGPT, new GitHub block documentation stubs in `docs/integrations/block-integrations/github/` are auto-generated by a docs script with placeholder text (`_Add technical explanation here._` / `_Add practical use case examples here._`) inside `<!-- MANUAL: how_it_works

Applied to files:

  • docs/integrations/block-integrations/misc.md
📚 Learning: 2026-03-10T08:39:22.025Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-16T17:00:02.827Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-17T10:57:10.126Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:10.126Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-10T08:38:33.249Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-02-27T15:59:00.370Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — OpenAPI/codegen
Learning: Ensuring a field is required in generated TS types needs two sides: (1) no default value on the Pydantic field, and (2) the OpenAPI model's "required" array must list it. For MCPToolInfo, making input_schema required in OpenAPI and removing Field(default_factory=dict) in the backend prevents optional typing drift.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/**/data/*.py : For changes touching `data/*.py`, validate user ID checks or explain why not needed

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.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/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-04T08:04:35.881Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12273
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:216-220
Timestamp: 2026-03-04T08:04:35.881Z
Learning: In the AutoGPT Copilot backend, ensure that SVG images are not treated as vision image types by excluding 'image/svg+xml' from INLINEABLE_MIME_TYPES and MULTIMODAL_TYPES in tool_adapter.py; the Claude API supports PNG, JPEG, GIF, and WebP for vision. SVGs (XML text) should be handled via the text path instead, not the vision path.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions.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/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.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/copilot/permissions.py
  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-10T08:38:36.655Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:349-370
Timestamp: 2026-03-10T08:38:36.655Z
Learning: In the AutoGPT CoPilot HITL (Human-In-The-Loop) flow (`autogpt_platform/backend/backend/copilot/tools/run_block.py`), the review card presented to users sets `editable: false`, meaning reviewers cannot modify the input payload. Therefore, credentials resolved before `is_block_exec_need_review()` remain valid and do not need to be recomputed after the review step — the original `input_data` is unchanged through the review lifecycle.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-15T15:30:09.706Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:149-185
Timestamp: 2026-03-15T15:30:09.706Z
Learning: In autogpt_platform/backend/backend/copilot/tools/helpers.py, within execute_block, when InsufficientBalanceError occurs after post-execution credit charging (concurrent balance drain after pre-check passed), this is treated as a non-fatal billing leak: log at ERROR level with structured JSON fields `{"billing_leak": True, "user_id": ..., "cost": ...}` for monitoring/alerting, then return BlockOutputResponse normally. Discarding the output would worsen UX since the block already executed with potential side effects. Reuse the credit_model obtained during the pre-execution balance check (guarded by `if cost > 0 and credit_model:`) for the post-execution charge; do not perform a second get_user_credit_model call.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-15T16:52:15.463Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12426
File: autogpt_platform/backend/backend/copilot/sdk/service.py:0-0
Timestamp: 2026-03-15T16:52:15.463Z
Learning: In Significant-Gravitas/AutoGPT (copilot backend), GitHub tokens (GH_TOKEN / GITHUB_TOKEN) for the `gh` CLI are injected lazily per-command in `autogpt_platform/backend/backend/copilot/tools/bash_exec._execute_on_e2b()` by calling `integration_creds.get_integration_env_vars(user_id)`, not on the global SDK subprocess environment in `sdk/service.py`. This scopes credentials to individual E2B sandbox command invocations and prevents token leakage into tool output streams or uploaded transcripts.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 Learning: 2026-03-12T14:42:40.552Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/rate_limit.py:141-170
Timestamp: 2026-03-12T14:42:40.552Z
Learning: In Significant-Gravitas/AutoGPT, `check_rate_limit` in `autogpt_platform/backend/backend/copilot/rate_limit.py` is intentionally a "pre-turn soft check" (not a hard atomic reservation). Because LLM token counts are unknown before generation completes, a strict check-and-reserve is impractical. The TOCTOU race (two concurrent turns both passing the pre-check and both committing via `record_token_usage`) is an accepted trade-off. If stricter enforcement is ever needed, the approach is a Lua script doing GET+INCRBY atomically in Redis.

Applied to files:

  • autogpt_platform/backend/backend/blocks/autopilot.py
📚 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/autopilot.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/autopilot.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/autopilot.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/autopilot.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/autopilot.py
🔇 Additional comments (2)
autogpt_platform/backend/backend/copilot/permissions.py (1)

180-201: merged_with_parent() keeps the permission ceiling monotonic.

Intersecting effective tool sets while delegating block checks through _parent is a clean way to preserve the “sub-agents can only get stricter” rule without flattening the original block filters.

docs/integrations/block-integrations/misc.md (1)

59-62: The new input rows make the filter semantics explicit.

Spelling out both the allow-list/deny-list behavior and the accepted block identifier formats should make these advanced controls much easier to discover and use correctly.

Comment thread autogpt_platform/backend/backend/copilot/permissions_test.py
Comment thread autogpt_platform/backend/backend/copilot/tools/run_block.py

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

🧹 Nitpick comments (3)
autogpt_platform/backend/backend/copilot/permissions_test.py (2)

330-332: Consider removing the empty setup_method.

The empty setup_method with just pass serves no purpose and can be removed for cleaner code.

♻️ Proposed fix
 class TestApplyToolPermissions:
-    def setup_method(self):
-        # Patch get_copilot_tool_names and get_sdk_disallowed_tools
-        pass
-
     def test_empty_permissions_returns_base_unchanged(self, mocker):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/copilot/permissions_test.py` around lines
330 - 332, Remove the no-op setup_method defined in permissions_test.py (the
empty def setup_method(self): pass) since it adds no behavior; delete the entire
method definition from the test class and run tests to verify nothing depended
on it (no additional changes to get_copilot_tool_names/get_sdk_disallowed_tools
patching are required).

334-354: The conditional patch path may be fragile.

The conditional logic checking hasattr(apply_tool_permissions, "__wrapped__") to determine the patch target is unusual. If apply_tool_permissions is decorated (e.g., with @functools.wraps), the patch target changes. This could lead to test brittleness if the decoration changes.

Consider documenting why this conditional is needed or simplifying to a consistent patch target.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/copilot/permissions_test.py` around lines
334 - 354, The test's conditional patch path around apply_tool_permissions is
fragile; update test_empty_permissions_returns_base_unchanged to patch the
consistent module-level symbol
"backend.copilot.permissions.apply_tool_permissions" (rather than checking for
__wrapped__) so the mock target doesn't change if the function is decorated, and
adjust any other mocker.patch calls in the test to reference the stable
module-level names (e.g., apply_tool_permissions, get_sdk_disallowed_tools,
TOOL_REGISTRY) to keep the test deterministic.
autogpt_platform/backend/backend/copilot/tools/run_block_test.py (1)

165-200: Consider strengthening the success assertion.

The test verifies that permission-allowed blocks pass the guard, but the assertion at lines 198-200 only checks that if the response is an ErrorResponse, it doesn't contain "not permitted". This could pass even if the block fails for unrelated reasons.

Consider adding a positive assertion to confirm the expected response type (e.g., BlockDetailsResponse or BlockOutputResponse) when the block passes all guards, similar to test_non_excluded_block_passes_guard below.

♻️ Suggested improvement
         # Must NOT be blocked by permissions
-        if isinstance(response, ErrorResponse):
-            assert "not permitted" not in response.message
+        assert not isinstance(response, ErrorResponse) or "not permitted" not in response.message
+        # Optionally, add a stronger assertion for expected success path:
+        # assert isinstance(response, (BlockDetailsResponse, BlockOutputResponse))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/copilot/tools/run_block_test.py` around
lines 165 - 200, The test test_allowed_by_permissions_passes_guard currently
only asserts the absence of "not permitted" in an ErrorResponse, which can miss
unrelated failures; update the assertion after calling RunBlockTool._execute to
positively assert the successful response type (e.g., assert that response is an
instance of BlockDetailsResponse or BlockOutputResponse) or otherwise assert
that response is not an ErrorResponse, using the concrete response classes used
by RunBlockTool._execute to confirm the block actually passed the guard and
executed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@autogpt_platform/backend/backend/copilot/permissions_test.py`:
- Around line 330-332: Remove the no-op setup_method defined in
permissions_test.py (the empty def setup_method(self): pass) since it adds no
behavior; delete the entire method definition from the test class and run tests
to verify nothing depended on it (no additional changes to
get_copilot_tool_names/get_sdk_disallowed_tools patching are required).
- Around line 334-354: The test's conditional patch path around
apply_tool_permissions is fragile; update
test_empty_permissions_returns_base_unchanged to patch the consistent
module-level symbol "backend.copilot.permissions.apply_tool_permissions" (rather
than checking for __wrapped__) so the mock target doesn't change if the function
is decorated, and adjust any other mocker.patch calls in the test to reference
the stable module-level names (e.g., apply_tool_permissions,
get_sdk_disallowed_tools, TOOL_REGISTRY) to keep the test deterministic.

In `@autogpt_platform/backend/backend/copilot/tools/run_block_test.py`:
- Around line 165-200: The test test_allowed_by_permissions_passes_guard
currently only asserts the absence of "not permitted" in an ErrorResponse, which
can miss unrelated failures; update the assertion after calling
RunBlockTool._execute to positively assert the successful response type (e.g.,
assert that response is an instance of BlockDetailsResponse or
BlockOutputResponse) or otherwise assert that response is not an ErrorResponse,
using the concrete response classes used by RunBlockTool._execute to confirm the
block actually passed the guard and executed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ec6f8e59-910b-4ef3-a409-9b8f6a24c159

📥 Commits

Reviewing files that changed from the base of the PR and between 0b45a19 and 4250b6e.

📒 Files selected for processing (2)
  • autogpt_platform/backend/backend/copilot/permissions_test.py
  • autogpt_platform/backend/backend/copilot/tools/run_block_test.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). (13)
  • GitHub Check: check API types
  • GitHub Check: Seer Code Review
  • GitHub Check: end-to-end tests
  • GitHub Check: Check PR Status
  • GitHub Check: test (3.11)
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: type-check (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: check-docs-sync
🧰 Additional context used
📓 Path-based instructions (6)
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

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
autogpt_platform/backend/**/*.{py,txt}

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use poetry run prefix for all Python commands, including testing, linting, formatting, and migrations

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/**/*_test.py: Always review snapshot changes with git diff before committing when updating snapshots with poetry run pytest --snapshot-update
Use pytest with snapshot testing for API responses in test files
Colocate test files with source files using the *_test.py naming convention

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
autogpt_platform/backend/backend/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
autogpt_platform/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
autogpt_platform/backend/**/*test*.py

📄 CodeRabbit inference engine (AGENTS.md)

Run poetry run test for backend testing (runs pytest with docker based postgres + prisma)

Files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
🧠 Learnings (19)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/blocks/**/*.py : Write tests alongside block implementation when adding new blocks in backend

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-03-16T17:00:02.827Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12439
File: autogpt_platform/backend/backend/blocks/autogpt_copilot.py:0-0
Timestamp: 2026-03-16T17:00:02.827Z
Learning: In autogpt_platform/backend/backend/blocks/autogpt_copilot.py, the recursion guard uses two module-level ContextVars: `_copilot_recursion_depth` (tracks current nesting depth) and `_copilot_recursion_limit` (stores the chain-wide ceiling). On the first invocation, `_copilot_recursion_limit` is set to `max_recursion_depth`; nested calls use `min(inherited_limit, max_recursion_depth)`, so they can only lower the cap, never raise it. The entry/exit logic is extracted into module-level helper functions. This is the approved pattern for preventing runaway sub-agent recursion in AutogptCopilotBlock (PR `#12439`, commits 348e9f8e2 and 3b70f61b1).

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-03-10T08:38:33.249Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/tools/run_block.py:297-300
Timestamp: 2026-03-10T08:38:33.249Z
Learning: In autogpt_platform/backend/backend/copilot/tools/run_block.py, the auto-approval key for sensitive block HITL review uses graph_exec_id (copilot-session-{session_id}) + node_id (copilot-node-{block_id}). This is intentional: approving a block type within a CoPilot session auto-approves all future invocations of that same block type within the same session, mirroring how auto-approve works in normal graph execution. The user explicitly opts into this session-scoped behavior via an auto-approve toggle. Without the toggle (default), each individual invocation requires its own approval.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/blocks/**/*.py : Implement 'run' method with proper error handling in backend blocks

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
📚 Learning: 2026-03-10T08:39:22.025Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/**/test/**/*.py : Use snapshot testing with '--snapshot-update' flag in backend tests when output changes; always review with 'git diff'

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : Always review snapshot changes with `git diff` before committing when updating snapshots with `poetry run pytest --snapshot-update`

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-03-16T16:32:29.430Z
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:29.430Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, the Block base class `execute()` method in `backend/blocks/_base.py` already wraps `run()` in a try/except that converts uncaught exceptions into `BlockExecutionError`/`BlockUnknownError`. Therefore, explicit try/except in individual block `run()` methods is redundant and not the established pattern (e.g., Gmail, Slack, Todoist blocks omit it). Exception: blocks like attachment blocks that need to distinguish between success and error yield paths within the generator use explicit try/except for branching control, not for the framework's error routing.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
📚 Learning: 2026-03-16T16:30:30.764Z
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:30.764Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, explicit try/except in the `run()` method is NOT required for standard error handling. The block framework's `_execute()` method in `_base.py` catches unhandled exceptions and re-raises them as `BlockExecutionError` or `BlockUnknownError`. Additionally, when a block yields `("error", message)`, `_execute()` immediately raises `BlockExecutionError` — so the `error` output port never propagates downstream. Explicit try/except is only needed when partial output must be controlled (e.g., attachment blocks that must skip yielding `content_base64` on failure).

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
📚 Learning: 2026-03-19T15:16:37.702Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12483
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:81-103
Timestamp: 2026-03-19T15:16:37.702Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/helpers.py`, `execute_block()` calls `block.execute()` directly (NOT `block._execute()`). Because of this, a real block CAN yield `("error", "some message")` alongside other output pins, and all outputs are collected. A non-empty `error` pin does NOT mean the block run failed from the caller's perspective — callers see all outputs. Only `[SIMULATOR ERROR ...]` (the dry-run sentinel, distinct from a simulated block logic failure) should map to `ErrorResponse`. Treating any non-empty `error` pin as `ErrorResponse` in dry-run would diverge from real `block.execute()` semantics.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.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/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-03-04T08:04:35.881Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12273
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:216-220
Timestamp: 2026-03-04T08:04:35.881Z
Learning: In the AutoGPT Copilot backend, ensure that SVG images are not treated as vision image types by excluding 'image/svg+xml' from INLINEABLE_MIME_TYPES and MULTIMODAL_TYPES in tool_adapter.py; the Claude API supports PNG, JPEG, GIF, and WebP for vision. SVGs (XML text) should be handled via the text path instead, not the vision path.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-03-04T12:19:39.243Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12279
File: autogpt_platform/backend/backend/copilot/tools/base.py:184-188
Timestamp: 2026-03-04T12:19:39.243Z
Learning: In autogpt_platform/backend/backend/copilot/tools/, ensure that anonymous users always pass user_id=None to tool execution methods. The anon_ prefix (e.g., anon_123) is used only for PostHog/analytics distinct_id and must not be used as an actual user_id. Use a simple truthiness check on user_id (e.g., if user_id: ... else: ... or a dedicated is_authenticated flag) to distinguish anonymous from authenticated users, and review all tool execution call sites within this directory to prevent accidentally forwarding an anon_ user_id to tools.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/run_block_test.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/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.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/copilot/tools/run_block_test.py
  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/**/data/*.py : For changes touching `data/*.py`, validate user ID checks or explain why not needed

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-02-04T16:50:20.508Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:20.508Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : Colocate test files with source files using the `*_test.py` naming convention

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
📚 Learning: 2026-03-17T10:57:10.126Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:10.126Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.

Applied to files:

  • autogpt_platform/backend/backend/copilot/permissions_test.py
🔇 Additional comments (11)
autogpt_platform/backend/backend/copilot/permissions_test.py (10)

1-15: LGTM!

Clean imports with proper organization. The test file is correctly colocated with the source file following the *_test.py naming convention as per coding guidelines.


22-59: LGTM!

Comprehensive tests for _block_matches covering all identifier matching semantics: full UUID, partial UUID (8-char prefix), and name matching, all with case-insensitivity. The disambiguation test at lines 55-59 is particularly valuable for documenting the expected behavior when an 8-hex string could ambiguously be either a partial UUID or a block name.


72-103: LGTM!

Well-structured tests for effective_allowed_tools covering both blacklist and whitelist modes, including the important edge case where an empty whitelist allows all tools (lines 77-80). Good coverage of unknown tool handling in both modes.


115-168: LGTM!

Excellent coverage of is_block_allowed including the critical parent-child permission inheritance tests (lines 144-168). The tests correctly verify that parent restrictions propagate down the chain and that both parent and child must allow a block for it to be permitted. The grandparent propagation test at lines 162-168 is valuable for ensuring multi-level inheritance works correctly.


176-221: LGTM!

Critical tests for merged_with_parent verifying the security invariant that child permissions cannot expand parent capabilities. The test at lines 195-205 is particularly important for ensuring sub-agents cannot escalate privileges. Good coverage of how merged permissions are stored internally.


229-242: LGTM!

Good coverage of is_empty including the edge case where having a parent with restrictions makes the permissions non-empty (lines 239-242).


250-267: LGTM!

Comprehensive tests for synchronous validate_tool_names covering registry tools, SDK builtins, invalid tools, mixed inputs, and empty lists. The assertion at line 264 correctly verifies that valid tools don't appear in the error list.


275-321: LGTM!

Well-structured async tests for validate_block_identifiers with consistent mocking of get_blocks. Good coverage of full UUID, partial UUID, and name-based identifier resolution.


415-470: LGTM! — Addresses past review concern.

These two tests (test_read_tool_always_included_even_when_blacklisted and test_read_tool_always_included_with_narrow_whitelist) verify the critical invariant that mcp__copilot__Read is always preserved in the allowed tools list for SDK internals, even when explicitly blacklisted or omitted from a whitelist. This addresses the past review concern about missing coverage for this behavior.


478-495: LGTM!

Good sanity check tests verifying that expected SDK builtin tools are present in SDK_BUILTIN_TOOL_NAMES and that all_known_tool_names() correctly combines registry tools with builtins.

autogpt_platform/backend/backend/copilot/tools/run_block_test.py (1)

135-163: LGTM!

Well-structured test for the permission denial path. Good use of try/finally to ensure the contextvar is properly reset regardless of test outcome. The test correctly verifies that a block blacklisted by CopilotPermissions returns an ErrorResponse with "not permitted" in the message.

@majdyz

majdyz commented Mar 19, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Fixed in 586ea04: moved _merge_inherited_permissions() inside the try block with perm_token = None initialised before it, so _reset_recursion() always runs even if the merge step throws.

@majdyz

majdyz commented Mar 19, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Fixed in 586ea04: removed the no-op setup_method from TestApplyToolPermissions and replaced the fragile __wrapped__ conditional with a direct get_copilot_tool_names patch target.

@majdyz

majdyz commented Mar 19, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Fixed in 586ea04: expanded the AutoPilot "How it works" section to explain tool/block validation at run time, SDK-level enforcement, and parent→child permission inheritance for sub-agent patterns.

Comment thread autogpt_platform/backend/backend/copilot/context.py

@majdyz majdyz left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 Automated review pass — PR #12482 (AutoPilotBlock tool/block permissions)

Summary

CI is fully green (all 26 checks pass). All previously raised inline threads are resolved.

Findings

No new issues found. The implementation is correct:

  1. Contextvar hygiene_merge_inherited_permissions returns a reset token; execute_copilot resets in finally. Prevents permission leakage between sequential autopilot calls.
  2. Read tool always includedapply_tool_permissions unconditionally adds mcp__copilot__Read so the SDK's large-output tool is never blocked by permissions.
  3. Inheritance tighteningmerged_with_parent intersects effective-allowed sets so children can only narrow, never widen, the parent's permissions.
  4. Block permission gaterun_block._execute reads get_current_permissions() and returns ErrorResponse before execution when a block is denied.
  5. Validation before session creation — permissions are validated before create_session, so invalid inputs fail fast without orphaned sessions.
  6. Empty-tools-list semanticseffective_allowed_tools returns the full universe when tools=[] regardless of tools_exclude (allow-all default).

Verdict: LGTM

majdyz added 11 commits March 24, 2026 08:26
- Replace hardcoded "read_file" with _READ_TOOL_NAME from tool_adapter so
  the SDK Read tool is correctly preserved when permissions are applied
- Update AutoPilotBlock.Input.tools description to include the complete
  set of platform tools and SDK built-ins (was missing 13 tools)
- Regenerate block docs
- Test that mcp__copilot__Read is always preserved in allowed_tools even
  when Read is explicitly blacklisted or absent from a whitelist
- Test that run_block returns ErrorResponse when CopilotPermissions deny
  the block, and passes guard when block is explicitly allowed
…y, clean up test nits

- Move `_merge_inherited_permissions()` call inside the `try` block so
  `_reset_recursion()` is always called even if the merge step throws.
- Remove the no-op `setup_method` from `TestApplyToolPermissions`.
- Replace fragile `__wrapped__` conditional patch path with a direct
  `get_copilot_tool_names` patch target.
- Expand the AutoPilot "How it works" docs section to describe the new
  tool/block permission filtering, validation, enforcement, and
  parent→child inheritance for sub-agents.
- Materialize block name map before loop in validate_block_identifiers
  to avoid N*M block instantiations
- Remove dead validate_tool_names call (Pydantic ToolName Literal
  validates at model construction time)
- Add cross-reference comments between PLATFORM_TOOL_NAMES and ToolName
  Literal declarations
…p-level

- Make ToolName Literal the single source of truth; derive PLATFORM_TOOL_NAMES
  and SDK_BUILTIN_TOOL_NAMES from it instead of maintaining duplicate lists
- Move internal imports to top-level where safe (collect.py, service.py, autopilot.py)
- Keep circular-import-prone imports (create_chat_session, collect_copilot_response)
  as local imports with explanatory comments
- Add unit tests guarding PLATFORM_TOOL_NAMES == TOOL_REGISTRY keys
Blocks denied by CopilotPermissions are now filtered out of find_block
search results and UUID lookups, so the AI never discovers them.
This reduces unnecessary back-and-forth where the AI would find a block
via search, attempt to run it, and get a permission error.
Move imports from inside test method bodies to the top of the file
for consistency with project conventions. Lazy imports in non-test
code for circular dependency avoidance are left unchanged.
…sion filtering

In E2B mode, SDK built-in file tools (Read, Write, Edit, Glob, Grep)
are replaced by MCP equivalents (read_file, write_file, ...). When a
user whitelists "Read", the E2B read_file tool must also be included
in the permitted set, and vice versa for blacklisting.
@majdyz
majdyz force-pushed the feat/copilot-permissions branch from 1db24df to a1572ae Compare March 24, 2026 01:27
Use a single assert expression instead of conditional check so the test
cannot silently pass when the block fails for unrelated reasons.
@majdyz

majdyz commented Mar 24, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Addressed remaining review feedback from coderabbitai in 3a83caa:

  • run_block_test.py: Strengthened the assertion in test_allowed_by_permissions_passes_guard — replaced the conditional if isinstance(...) check with a single assert expression so the test cannot silently pass when the block fails for unrelated reasons.

  • permissions_test.py empty setup_method: Already removed in a prior commit.

  • permissions_test.py conditional patch path: Already simplified in a prior commit (direct module-level patching).

  • docs/misc.md: Permission filtering explanation and complete tools list already present.

  • permissions.py read_file hardcode: Already uses _READ_TOOL_NAME constant.

  • autopilot.py _merge_inherited_permissions try/finally: Already moved inside try block with perm_token = None initialization.

Comment thread autogpt_platform/backend/backend/blocks/autopilot.py
Comment thread autogpt_platform/backend/backend/blocks/autopilot.py
Comment thread autogpt_platform/backend/backend/blocks/autopilot.py
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban Mar 24, 2026
@majdyz
majdyz added this pull request to the merge queue Mar 24, 2026
Merged via the queue into dev with commit ee5382a Mar 24, 2026
27 checks passed
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Mar 24, 2026
@majdyz
majdyz deleted the feat/copilot-permissions branch March 24, 2026 08:04
majdyz added a commit that referenced this pull request Mar 24, 2026
Integrate block-level permission checking from #12482 into
the refactored run_block that uses prepare_block_for_execution helper.
Bentlybro pushed a commit that referenced this pull request Apr 4, 2026
#12507)

## Summary
- Adds `/pr-test` skill for automated E2E testing of PRs using docker
compose, agent-browser, and API calls
- Covers full environment setup (copy .env, configure copilot auth,
ARM64 Docker fix)
- Includes browser UI testing, direct API testing, screenshot capture,
and test report generation
- Has `--fix` mode for auto-fixing bugs found during testing (similar to
`/pr-address`)
- **Screenshot uploads use GitHub Git API** (blobs → tree → commit →
ref) — no local git operations, safe for worktrees
- **Subscription mode improvements:**
- Extract subscription auth logic to `sdk/subscription.py` — uses SDK's
bundled CLI binary instead of requiring `npm install -g
@anthropic-ai/claude-code`
- Auto-provision `~/.claude/.credentials.json` from
`CLAUDE_CODE_OAUTH_TOKEN` env var on container startup — no `claude
login` needed in Docker
- Add `scripts/refresh_claude_token.sh` — cross-platform helper
(macOS/Linux/Windows) to extract OAuth tokens from host and update
`backend/.env`

## Test plan
- [x] Validated skill on multiple PRs (#12482, #12483, #12499, #12500,
#12501, #12440, #12472) — all test scenarios passed
- [x] Confirmed screenshot upload via GitHub Git API renders correctly
on all 7 PRs
- [x] Verified subscription mode E2E in Docker:
`refresh_claude_token.sh` → `docker compose up` → copilot chat responds
correctly with no API keys (pure OAuth subscription)
- [x] Verified auto-provisioning of credentials file inside container
from `CLAUDE_CODE_OAUTH_TOKEN` env var
- [x] Confirmed bundled CLI detection
(`claude_agent_sdk._bundled/claude`) works without system-installed
`claude`
- [x] `poetry run pytest backend/copilot/sdk/service_test.py` — 24/24
tests pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation platform/backend AutoGPT Platform - Back end platform/blocks size/xl

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

2 participants