Skip to content

feat(platform): set up webhook triggers from AutoPilot#13298

Draft
Pwuts wants to merge 19 commits into
devfrom
pwuts/open-3152-autopilot-doesnt-know-how-to-help-user-set-up-webhook
Draft

feat(platform): set up webhook triggers from AutoPilot#13298
Pwuts wants to merge 19 commits into
devfrom
pwuts/open-3152-autopilot-doesnt-know-how-to-help-user-set-up-webhook

Conversation

@Pwuts

@Pwuts Pwuts commented Jun 4, 2026

Copy link
Copy Markdown
Member

Why / What / How

Why: Resolves OPEN-3152. AutoPilot (the copilot) couldn't help users set up webhook-triggered agents — it had no way to create a triggered preset, collect the trigger's config, choose which account the webhook registers under, or hand back the ingress URL. In practice it invented incorrect steps (wrong host platform.agpt.co instead of backend.agpt.co, a nonexistent Builder side-panel) or tried to "configure" the trigger by editing the agent graph.

What: AutoPilot can now set up a webhook trigger end-to-end, with the full inline chat UI: discover the agent, collect the trigger block's config conversationally, pick the registration account explicitly, create the preset, and return the exact ingress URL. Plus guardrails that keep it on the trigger-setup path (rather than editing the graph or trying to "run" a triggered agent), and a small dev CLI for inspecting copilot chat sessions (used to validate all of the above).

How:

  • Shared trigger setup: setup_triggered_preset() backs both POST /presets/setup-trigger and the setup_agent_webhook_trigger tool; it's exposed as a DatabaseManager RPC and reached from the copilot worker via a triggers_db() accessor (the worker has no connected Prisma client).
  • Config from the user, not guesses: when the trigger block needs config (e.g. GitHub repo + events), the tool returns trigger_config_required with the schema so the LLM asks the user instead of inventing values.
  • Explicit credentials: the trigger node's own credential (the account the webhook registers under) is surfaced in the inline setup card for an explicit choice and carried back verbatim — never auto-picked. Other agent-body credentials mirror run_agent (auto-matched, shown only when missing). The card also tells the user the account connects right there, so the LLM doesn't fire a duplicate connect_integration.
  • Discovery without reading the graph: find_library_agent returns each agent's trigger_setup_info (provider + config schema), so AutoPilot recognizes/configures triggers without fetching and reverse-engineering the full graph. This required loading graph nodes in the listing — list_library_agents gains an opt-in include_nodes flag (the main library page stays fast and unchanged).
  • Guardrails: edit_agent rejects edits that change a trigger node's config fields (those belong on the per-trigger preset, not the agent's global graph); run_agent detects webhook-trigger agents (which can't be run/scheduled directly) and points to setup_agent_webhook_trigger, rendered as an informational card (no stale "set up" button after setup already succeeded).
  • RPC-safe errors: webhook managers raise WebhookRegistrationError so the failure reason survives the RPC boundary into the copilot worker.

Changes 🏗️

Backend

  • New setup_agent_webhook_trigger tool: trigger_config_required config collection, explicit credential selection via the setup card, preset creation, and the manual-setup ingress URL.
  • list_agent_triggers returns webhook_url + provider (via the RPC-safe library_db accessor).
  • find_library_agent surfaces trigger_info; list_library_agents gains an opt-in include_nodes flag.
  • edit_agent guard against in-graph trigger-config edits; run_agent redirect for webhook-trigger agents.
  • WebhookRegistrationError raised consistently across webhook managers (github / slant3d / telegram / airtable / exa, plus a base-class wrapper).
  • Agent-building guide documents the flow.
  • ResponseType.trigger_config_required + AgentInfo.trigger_info (regenerated openapi.json).

Frontend

  • SetupTrigger tool UI: credentials setup card (explicit account selection, carried back to the tool), trigger_config_required prompt, and a success card with the ingress URL + copy.
  • AgentDetailsCard shows an informational card (no action button) for webhook-trigger agents redirected from run_agent, so nothing goes stale after setup succeeds.
  • Trigger setup / connect_integration cards exempt from CollapsedToolGroup so they persist.

DX

  • poetry run cli chat view <id> [range] / chat list to inspect copilot chat sessions (--full / --json; suppresses INFO log noise). Also fixes a pre-existing cli.py vs cli/ packaging clash that left poetry run cli broken.

Checklist 📋

For code changes:

  • I have clearly listed my changes in the PR description
  • I have made a test plan
  • I have tested my changes according to the test plan:
    • Backend unit: setup_agent_webhook_trigger_test.py, list_agent_triggers_test.py, agent_search_test.py, find_library_agent_test.py, edit_agent_test.py, run_agent_test.py (webhook redirect), tool_schema_test.py (schema char budget), cli/render_test.py.
    • Frontend unit: SetupTrigger (credentials card + config-required + success URL), AgentDetailsCard (webhook agent → informational card, no button).
    • Manual E2E (maintainer, live CoPilot sessions): GitHub provider webhook — discover → collect repo/events → explicit GitHub-account card → preset created; verified no duplicate connect_integration card. Generic webhook (TypeForm) — preset created and correct backend.agpt.co/.../ingress URL returned; verified the run-redirect card no longer shows a stale "Set up trigger" button.

For configuration changes:

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

N/A — no configuration changes.

AutoPilot could not help users set up webhook-triggered agents: it had no
tool to create a triggered preset and no way to retrieve the webhook ingress
URL, so it invented incorrect steps (wrong host, nonexistent Builder panel).

- add the `setup_agent_webhook_trigger` copilot tool: creates a triggered
  preset and returns the exact ingress URL for manual webhooks; requires
  explicit credential selection for provider webhooks (never auto-picks the
  account a webhook is registered under)
- expose `webhook_url` (+ provider) on `list_agent_triggers`
- extract `setup_triggered_preset()` shared by the setup-trigger route and the
  tool; expose it as a DatabaseManager RPC endpoint (reached via a new
  `triggers_db()` accessor) since the copilot worker has no connected Prisma
- document the webhook-trigger flow in the agent-building guide

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Pwuts Pwuts requested a review from a team as a code owner June 4, 2026 16:35
@Pwuts Pwuts requested review from 0ubbe and kcze and removed request for a team June 4, 2026 16:35
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Jun 4, 2026
@Pwuts

Pwuts commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot added platform/frontend AutoGPT Platform - Front end platform/backend AutoGPT Platform - Back end labels Jun 4, 2026
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9e80a81c-cbbe-4edb-8940-fe5c890ae79d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Centralizes webhook-triggered preset creation into a new helper, exposes it via the presets API and RPC, surfaces webhook metadata in copilot tools and listings, standardizes provider webhook error handling, adds a conversational copilot tool for trigger setup with credential flows, updates validator/docs/UI, and adds tests across backend and frontend.

Changes

Webhook-triggered agent preset setup

Layer / File(s) Summary
Core webhook preset creation and database wiring
autogpt_platform/backend/backend/api/features/library/triggers.py, autogpt_platform/backend/backend/api/features/library/routes/presets.py, autogpt_platform/backend/backend/data/db_accessors.py, autogpt_platform/backend/backend/data/db_manager.py
Adds setup_triggered_preset to centralize graph validation, webhook node verification, credential merging, webhook provisioning, and preset creation. /presets/setup-trigger delegates to this helper; DB accessor and manager expose it for RPC and async clients.
Copilot webhook setup tool and tests
autogpt_platform/backend/backend/copilot/tools/setup_agent_webhook_trigger.py, .../setup_agent_webhook_trigger_test.py, autogpt_platform/backend/backend/copilot/tools/__init__.py, autogpt_platform/backend/backend/copilot/tools/tool_schema_test.py
Implements SetupAgentWebhookTriggerTool with credential-resolution/card flows, structured responses (trigger_setup, trigger_config_required), registration into TOOL_REGISTRY, and end-to-end tests for manual/provider flows and failure cases. Tool-schema budget bumped.
Trigger listing, models, and agent search
autogpt_platform/backend/backend/copilot/tools/list_agent_triggers.py, autogpt_platform/backend/backend/copilot/tools/models.py, autogpt_platform/backend/backend/copilot/tools/list_agent_triggers_test.py, autogpt_platform/backend/backend/copilot/tools/agent_search.py
AgentTriggerInfo and AgentInfo gain webhook metadata fields (webhook_url, provider, trigger_info), listing tool reads webhook objects from presets and tests assert webhook URLs are exposed. Library search requests node data to populate trigger metadata and appends setup guidance when triggers exist.
Webhook provider error handling and exceptions
autogpt_platform/backend/backend/integrations/webhooks/_base.py, autogpt_platform/backend/backend/integrations/webhooks/github.py, autogpt_platform/backend/backend/integrations/webhooks/*.py, autogpt_platform/backend/backend/util/exceptions.py, autogpt_platform/backend/backend/blocks/*/_webhook.py
Adds WebhookRegistrationError, wraps provider _register_webhook calls to normalize errors, maps GitHub HTTP statuses to domain errors, and standardizes error messaging/handling across Exa/Slant3D/Airtable/Telegram.
Validator, SDK guide, OpenAPI and tests
autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py, autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py, autogpt_platform/backend/backend/copilot/sdk/agent_generation_guide.md, autogpt_platform/frontend/src/app/api/openapi.json
Validator accepts webhook trigger blocks as a valid start mechanism, unit tests added, SDK guide documents trigger setup and inspection, and OpenAPI gains trigger_info and new response types.
Edit/run-agent guards and tests
autogpt_platform/backend/backend/copilot/tools/edit_agent.py, .../edit_agent_test.py, autogpt_platform/backend/backend/copilot/tools/run_agent.py, .../run_agent_test.py
Prevents changing trigger-config fields via graph edits (points users to setup tool) and redirects run/schedule attempts for webhook-trigger agents to the setup flow; tests cover guards and redirection behavior.
CLI additions and render tests
autogpt_platform/backend/backend/cli/*, autogpt_platform/backend/backend/cli/render_test.py
Adds a chat CLI with view/list, a main CLI with start/stop/gen-key commands, and tests for CLI rendering helpers used by transcript outputs.
Frontend copilot SetupTrigger UI and helpers
autogpt_platform/frontend/src/app/.../SetupTrigger/*, SetupRequirementsCard/*, MessagePartRenderer.tsx, tests
Adds a SetupTriggerTool React component, type-guards/parsers/helpers for tool outputs, SetupRequirementsCard trigger mode and message builder, message-part wiring, and UI/tests to render setup requirements, success (with webhook URL copy), and config-required flows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Swiftyos
  • 0ubbe

Poem

🐰 A rabbit hops with joyful cheer,

"Webhooks now awake and near!
Presets set with careful art,
Credentials picked—each plays its part.
Tests pass, docs shine bright and clear." 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(platform): set up webhook triggers from AutoPilot' clearly summarizes the main change—enabling AutoPilot to set up webhook-triggered agents end-to-end.
Description check ✅ Passed The PR description comprehensively relates to the changeset, explaining the motivation (OPEN-3152), the solution (webhook trigger setup tool and infrastructure), and the implementation details across backend, frontend, and DX layers.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pwuts/open-3152-autopilot-doesnt-know-how-to-help-user-set-up-webhook

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.

@autogpt-pr-reviewer

Copy link
Copy Markdown

Queued a review for PR #13298 at 90bdfad.

@github-actions

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


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

@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.55285% with 171 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.14%. Comparing base (3370237) to head (f3eddbc).
⚠️ Report is 1 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #13298      +/-   ##
==========================================
+ Coverage   72.95%   73.14%   +0.19%     
==========================================
  Files        2373     2386      +13     
  Lines      177395   178432    +1037     
  Branches    17936    18041     +105     
==========================================
+ Hits       129419   130521    +1102     
+ Misses      44152    44056      -96     
- Partials     3824     3855      +31     
Flag Coverage Δ
platform-backend 80.85% <83.56%> (+0.09%) ⬆️
platform-frontend 41.41% <97.61%> (+0.67%) ⬆️
platform-frontend-e2e 30.90% <0.00%> (-0.64%) ⬇️

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

Components Coverage Δ
Platform Backend 80.85% <83.56%> (+0.09%) ⬆️
Platform Frontend 45.85% <96.47%> (+0.52%) ⬆️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@autogpt-pr-reviewer autogpt-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📋 Automated Review — PR #13298

PR #13298 — feat(backend/copilot): add setup_agent_webhook_trigger tool
Author: Pwuts | Files: 13

🎯 Verdict: REQUEST_CHANGES

PR Description Quality

✅ Has Why + What + How — Clear description of the problem (AutoPilot inventing wrong webhook URLs), the solution (new copilot tool + shared extraction), and implementation approach (RPC exposure, explicit credential selection).

What This PR Does

AutoPilot (the AI copilot) was fabricating incorrect webhook ingress URLs when users asked it to set up webhook triggers for their agents. This PR adds a setup_agent_webhook_trigger copilot tool that properly creates webhook presets and returns the real ingress URL. It extracts the webhook-preset logic from the existing REST route into a shared setup_triggered_preset() function used by both the route and the new tool, exposes it via RPC, and adds a deliberate two-step credential flow that never auto-picks accounts.

Specialist Findings

🛡️ Security ✅ — Auth scoping is correct throughout: all graph/library lookups include user_id, credentials require explicit user choice (never auto-picked), and the requires_auth = True guard is properly enforced.

  • 🟡 trigger_config is an unvalidated dict[str, Any] passed to setup_triggered_preset() (setup_agent_webhook_trigger.py:219), adding a second unvalidated entry point alongside the HTTP route. Downstream validation in setup_webhook_for_block likely catches issues, but schema validation at the tool boundary would be stronger.

🏗️ Architecture ✅ — Clean extract-and-delegate refactor. setup_triggered_preset() is a proper shared function, the RPC exposure via triggers_db() follows the exact db_accessors.py pattern, and the tool structure matches sibling tools.

  • 🟠 After refactoring, the setup_trigger route (presets.py:158) no longer catches exceptions explicitly. The old code raised HTTPException(410) for missing graphs and HTTPException(400) for invalid input. Now NotFoundError and InvalidInputError propagate to global handlers — if NotFoundError maps to 404 (common default) instead of 410, this is a silent API-breaking change. (Flagged by: architect, testing — 2)

Performance ✅ — No hot-path concerns. One minor optimization opportunity: get_or_create_library_agent() is called (setup_agent_webhook_trigger.py:194) before checking whether credentials are still needed, wasting a DB call (and potential write) when the response is TriggerCredentialsRequiredResponse.

  • 🟡 Double graph fetch (_resolve_graph + setup_triggered_preset) is documented as intentional for RPC compatibility. Adds ~50-200ms per call; acceptable for interactive copilot use.

🧪 Testing ⚠️ — The copilot tool tests are well-structured and cover the critical "never auto-pick credentials" invariant. However, the extracted setup_triggered_preset() function — the shared core logic now used by both the REST route and the copilot tool — has zero direct unit tests. The copilot tool tests mock it away entirely, so regressions in the core webhook-setup logic would go undetected.

  • 🔴 No unit tests for setup_triggered_preset() in triggers.py — 3 error paths and 1 success path untested directly.
  • 🟠 No test verifying the route refactor preserves HTTP status codes (old: explicit HTTPException(410/400), new: domain exceptions via global handlers). (Flagged by: architect, testing — 2)
  • 🟠 list_agent_triggers_test.py has no test for preset.webhook = None, leaving the p.webhook.url if p.webhook else None guard (list_agent_triggers.py:169) unverified.

📖 Quality ✅ — Clean, well-documented code. Good docstrings, consistent patterns, clear helper method separation (_resolve_graph, _resolve_credentials, _build_success_response).

  • 🔵 Non-deterministic next(iter(field_info.provider)) on a frozenset (setup_agent_webhook_trigger.py:280) — use sorted() for deterministic output.
  • 🔵 Minor duplication: p.webhook.url if p.webhook else None / p.webhook.provider if p.webhook else None in list_agent_triggers.py:169-170.

📦 Product ✅ — Directly solves the reported user problem. The explicit credential selection design is correct, the "never reconstruct the URL" messaging is strong, and the guide documentation is thorough.

  • 🟡 No duplicate-prevention guard — calling the tool twice creates duplicate presets. Guide tells the LLM to check first, but this isn't enforced. Pre-existing behavior from the REST route.

📬 Discussion ⚠️ — No human reviews submitted. CI fails on all 3 Python versions because PLATFORM_TOOL_NAMES Literal is missing the new tool name. E2E failure is an infra flake (Docker 504).

  • 🔴 setup_agent_webhook_trigger must be added to PLATFORM_TOOL_NAMES in permissions.pyautopilot_permissions_test and permissions_test fail across Python 3.11/3.12/3.13. (Flagged by: discussion, CI — 2)
  • 🟠 Merge conflict with PR #12206 in copilot/tools/__init__.py (~148 lines overlap). Needs coordination.

🔎 QA ✅ — OpenAPI spec updated with both new ResponseType values, copilot recognizes the tool, REST endpoint works with refactored logic, 178 unit tests pass, negative cases (unauthenticated access, non-existent graph) return proper errors. Full E2E webhook creation couldn't be tested due to missing webhook-trigger agents and LLM keys in the sandbox.

🔴 Blockers

  1. PLATFORM_TOOL_NAMES Literal not updated (backend/copilot/permissions.py) — CI fails on all Python versions. Add "setup_agent_webhook_trigger" to the PLATFORM_TOOL_NAMES Literal type. (Flagged by: discussion, CI — 2)
  2. No unit tests for setup_triggered_preset() (backend/api/features/library/triggers.py:24) — This is the shared core logic used by both the REST route and the new copilot tool. It has 3 error branches and 1 success path with zero direct tests. The copilot tool tests mock it away entirely. Add a triggers_test.py covering: graph not found → NotFoundError, no webhook node → InvalidInputError, webhook rejection → InvalidInputError, happy path → returns preset with webhook. (Flagged by: testing)

🟠 Should Fix

  1. Route error mapping regression risk (presets.py:158) — The old route explicitly raised HTTPException(410) / HTTPException(400). After refactoring, NotFoundError and InvalidInputError propagate to global handlers. Verify global handlers map NotFoundError → 410 (not 404), or add an explicit try/except in the route. Add a route-level test asserting the status codes. (Flagged by: architect, testing — 2)
  2. Missing webhook=None test (list_agent_triggers_test.py:29) — _make_webhook_preset() uses MagicMock() which auto-creates preset.webhook. Add a test with preset.webhook = None to verify the None-guard at list_agent_triggers.py:169. (Flagged by: testing)
  3. Wasted DB call when credentials required (setup_agent_webhook_trigger.py:194) — get_or_create_library_agent() is called before checking if credentials are still needed (line 196). Move it after the if required: early-return. (Flagged by: performance)
  4. Merge conflict with #12206 (copilot/tools/__init__.py) — Coordinate merge order with the overlapping PR. (Flagged by: discussion)

🟡 Nice to Have

  1. Extract response models (setup_agent_webhook_trigger.py:34-77) — File is 361 lines, slightly over the ~300 line guideline. Moving CredentialChoice, RequiredTriggerCredential, etc. to models.py would bring it under budget. (architect, quality)
  2. Duplicate-prevention guard (setup_agent_webhook_trigger.py:213) — Check for existing active presets before creating new ones, rather than relying on LLM compliance with guide instructions. (security, product, architect)
  3. Deterministic provider selection (setup_agent_webhook_trigger.py:280) — Use sorted(field_info.provider)[0] instead of next(iter(...)) on a frozenset. (quality)

🔵 Nits

  1. Minor duplication (list_agent_triggers.py:169-170) — Extract wh = p.webhook to avoid repeating the None-check.
  2. Variable shadows function name (db_accessors.py:56) — Local triggers_db shadows the enclosing function. Matches existing pattern but is a mild smell.

QA Screenshots

Screenshot Description
Copilot page Copilot page loads and recognizes the new tool ✅

Human Review Needed

YES — This is a multi-layer refactor (REST route → shared function → RPC → copilot tool) touching auth-adjacent code (credentials handling, webhook registration), with 13 files changed and a new RPC endpoint. The error mapping regression risk in the route refactor and the credential flow design warrant human review from a second maintainer.

Risk Assessment

Merge risk: MEDIUM | Rollback: EASY

CI is currently broken (fixable with a one-line Literal update), and the route refactor has an unverified error-mapping change. The merge conflict with #12206 adds coordination overhead. Rollback is easy — no migrations, no schema changes, feature is additive.

CI Status

❌ 4/6 checks failed — Backend lint ✅, Frontend lint ✅, Frontend typecheck ❌ (pre-existing), Backend tests ❌ (missing PLATFORM_TOOL_NAMES entry), Frontend tests ❌ (pre-existing), Frontend build ❌ (pre-existing). 2 failures are PR-related (backend tests due to missing tool name registration).



UI Testing — Variant Results

✅ local: All testable scenarios pass: OpenAPI updated, copilot recognizes tool, REST endpoint works with refactored shared logic, 178 unit tests pass, negative cases return proper errors.

✅ hosted: All 178 unit tests pass, API negative tests confirm proper error handling, OpenAPI updated correctly; copilot E2E blocked by missing LLM API keys in test env (environment limitation, not code issue).

@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 🚧 Needs work in AutoGPT development kanban Jun 4, 2026
Pwuts and others added 2 commits June 4, 2026 21:44
The copilot AgentValidator required every agent to have at least one input
block, so building a webhook-triggered agent forced an extra user-facing
input node onto it — itself invalid, since a triggered agent is started by an
external event and takes no user input.

validate_io_blocks now satisfies the input requirement with EITHER at least
one input block OR a webhook trigger block (uiType "Webhook" / "Webhook
(manual)"). The output-block requirement is unchanged. The agent-building
guide is updated to tell the model to use an input block or a trigger block,
never both.

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

Webhook registration failures now raise WebhookRegistrationError (defined in backend.util.exceptions) instead of provider-specific HTTP/Runtime/ValueError types, so the reason survives reconstruction across the DatabaseManager RPC boundary (e.g. when the copilot worker sets up a trigger). The base _create_webhook wraps any non-WebhookRegistrationError from a provider's _register_webhook as a safety net.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pwuts and others added 2 commits June 5, 2026 16:53
… in chat

Adds the SetupTrigger tool UI: renders the credentials setup card (explicit account selection for the trigger, carried back to the tool), the trigger_config_required prompt, and a success card with the manual webhook ingress URL + copy. Dispatches it from MessagePartRenderer and exempts it (and connect_integration) from CollapsedToolGroup so the cards persist. AgentDetailsCard now shows an informational message (no action button) for webhook-trigger agents redirected from run_agent, so nothing goes stale after setup succeeds. Includes the regenerated openapi.json (ResponseType.trigger_config_required, AgentInfo.trigger_info).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…in webhook trigger setup

setup_agent_webhook_trigger now: (1) returns trigger_config_required so the LLM collects the trigger block's config (e.g. GitHub repo/events) from the user instead of guessing; (2) surfaces the trigger node's own credential for explicit account selection in the setup card (never auto-picked), while other agent credentials mirror run_agent; (3) tells the user the account connects in that card so the LLM does not fire a duplicate connect_integration. list_agent_triggers exposes each webhook's ingress URL + provider via the RPC-safe library_db accessor. Expose setup_triggered_preset/list_presets/list_trigger_agents on DatabaseManager. models: ResponseType.trigger_config_required + AgentInfo.trigger_info.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@autogpt_platform/backend/backend/integrations/webhooks/_base.py`:
- Around line 214-223: The except block around the call to _register_webhook
currently wraps every exception into WebhookRegistrationError, hiding provider
domain errors (e.g., provider-raised
ValueError/NotFoundError/NotAuthorizedError). Change the handler so that after
checking for WebhookRegistrationError it re-raises provider domain ValueError
instances (or their subclasses) unchanged (i.e., if isinstance(e, ValueError):
raise) and only wrap other unexpected exceptions into WebhookRegistrationError;
keep the original exception as the __cause__ when wrapping. This targets the
try/except around _register_webhook and ensures callers that branch on provider
ValueError types still receive them.

In `@autogpt_platform/backend/backend/integrations/webhooks/github.py`:
- Around line 125-136: The new GitHub 401/403 branch raises NotAuthorizedError
but the webhook setup handler (setup_agent_webhook_trigger.py) only catches
NotFoundError and InvalidInputError, so NotAuthorizedError will escape and
bypass trigger_setup_failed; update the handler to also catch NotAuthorizedError
(or map it to the same failure flow) so that when GitHubRepoWebhook.create
raises NotAuthorizedError the code invokes trigger_setup_failed and returns the
same user-facing failure path as for NotFoundError/InvalidInputError.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b578b9f9-a14e-4f3e-9ecb-79dc0146a871

📥 Commits

Reviewing files that changed from the base of the PR and between 90bdfad and 4fd934d.

📒 Files selected for processing (10)
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/sdk/agent_generation_guide.md
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/integrations/webhooks/telegram.py
  • autogpt_platform/backend/backend/util/exceptions.py
✅ Files skipped from review due to trivial changes (2)
  • autogpt_platform/backend/backend/integrations/webhooks/telegram.py
  • autogpt_platform/backend/backend/copilot/sdk/agent_generation_guide.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: integration_test
  • GitHub Check: lint
  • GitHub Check: check API types
  • GitHub Check: end-to-end tests
  • GitHub Check: Check PR Status
  • GitHub Check: type-check (3.13)
  • GitHub Check: Analyze (python)
  • GitHub Check: test (3.13)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
🧰 Additional context used
📓 Path-based instructions (4)
autogpt_platform/backend/**/*.py

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

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

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

Files:

  • autogpt_platform/backend/backend/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/util/exceptions.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/util/exceptions.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
autogpt_platform/backend/backend/blocks/**/*.py

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

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

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

Files:

  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
autogpt_platform/backend/**/*_test.py

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

autogpt_platform/backend/**/*_test.py: Use pytest with snapshot testing for API responses
Colocate test files with source files using *_test.py naming convention
Mock at boundaries — mock where the symbol is used, not where it's defined; after refactoring, update mock targets to match new module paths
Use AsyncMock from unittest.mock for async functions in tests
When writing tests, use Test-Driven Development (TDD): write failing tests marked with @pytest.mark.xfail before implementation, then remove the marker once the implementation is complete
When creating snapshots in tests, use poetry run pytest path/to/test.py --snapshot-update; always review snapshot changes with git diff before committing

Files:

  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
🧠 Learnings (29)
📓 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: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12740
File: autogpt_platform/frontend/src/app/api/openapi.json:0-0
Timestamp: 2026-04-13T14:19:19.341Z
Learning: Repo: Significant-Gravitas/AutoGPT — autogpt_platform
When adding new CoPilot tool response models (e.g., ScheduleListResponse, ScheduleDeletedResponse), update backend/api/features/chat/routes.py to include them in the ToolResponseUnion so the frontend’s autogenerated openapi.json dummy export (/api/chat/schema/tool-responses) exposes them for codegen. Do not hand-edit frontend/src/app/api/openapi.json.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12879
File: autogpt_platform/frontend/src/app/api/openapi.json:14576-14577
Timestamp: 2026-04-22T05:58:31.684Z
Learning: Repo: Significant-Gravitas/AutoGPT — autogpt_platform
Process convention: When adding new CoPilot tool response models and updating ToolResponseUnion in backend/api/features/chat/routes.py, regenerate the frontend OpenAPI schema via `poetry run export-api-schema` (do not hand-edit autogpt_platform/frontend/src/app/api/openapi.json).
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/frontend/src/app/api/openapi.json:11897-11900
Timestamp: 2026-03-04T23:58:18.476Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12284`
Backend/frontend OpenAPI codegen convention: In backend/api/features/store/model.py, the StoreSubmission and StoreSubmissionAdminView models define submitted_at: datetime | None, changes_summary: str | None, and instructions: str | None with no default. This is intentional to produce “required but nullable” fields in OpenAPI (properties appear in required[] and use anyOf [type, null]). This matches Prisma’s submittedAt DateTime? and changesSummary String?. Do not flag this as a required/nullable mismatch.
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12536
File: autogpt_platform/frontend/src/app/api/openapi.json:5770-5790
Timestamp: 2026-03-24T21:25:15.983Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12536`
File: autogpt_platform/frontend/src/app/api/openapi.json
Learning: The OpenAPI spec file is auto-generated; per established convention, endpoints generally declare only 200/201, 401, and 422 responses. Do not suggest adding explicit 403/404 response entries for single operations unless planning a repo-wide spec update. Prefer clarifying such behaviors in endpoint descriptions/docstrings instead of altering response maps.
📚 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/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/util/exceptions.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.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/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/util/exceptions.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.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/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/util/exceptions.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

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

Applied to files:

  • autogpt_platform/backend/backend/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/util/exceptions.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
📚 Learning: 2026-05-23T05:29:43.085Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13200
File: autogpt_platform/backend/backend/executor/scheduler.py:590-593
Timestamp: 2026-05-23T05:29:43.085Z
Learning: When reviewing Python code that uses Pydantic discriminated/tagged unions (e.g., `Annotated[Union[...], Field(discriminator="kind")]`), recognize that using `isinstance(x, SomeVariantInfo)` to narrow the union is an intentional and correct runtime guard and should also enable static type narrowing in tools like Pyright. Do not recommend replacing such `isinstance`-based narrowing with `cast(...)` when the check already proves the variant at runtime.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • autogpt_platform/backend/backend/integrations/webhooks/slant3d.py
  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/util/exceptions.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
📚 Learning: 2026-05-26T14:24:34.866Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 13217
File: autogpt_platform/backend/backend/api/features/search/service.py:137-137
Timestamp: 2026-05-26T14:24:34.866Z
Learning: In the Significant-Gravitas/AutoGPT backend, treat `user_id` (an opaque UUID used only for correlation/tracing) as non-PII. Do not flag direct logging of `user_id` in `logger.warning`/`logger.info` statements as a PII exposure issue, as the established convention is to log `user_id` for tracing while reserving PII for fields like email or display name.

Applied to files:

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

Applied to files:

  • autogpt_platform/backend/backend/blocks/airtable/_webhook.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.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/airtable/_webhook.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.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/airtable/_webhook.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.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/airtable/_webhook.py
  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
📚 Learning: 2026-05-17T06:58:54.665Z
Learnt from: kcze
Repo: Significant-Gravitas/AutoGPT PR: 13135
File: autogpt_platform/backend/backend/blocks/generic_webhook/_webhook.py:0-0
Timestamp: 2026-05-17T06:58:54.665Z
Learning: In `autogpt_platform/backend/backend/blocks/generic_webhook/_webhook.py`, when `GenericWebhooksManager._configured_secret()` finds multiple distinct `secret_token` values across attached `triggered_nodes` and `triggered_presets`, the intended behavior is to log a warning (not fail closed / raise HTTP 403). This is because a webhook is scoped per `(user_id, graph_id)`, so multiple `GenericWebhookTriggerBlock` instances in the same graph share one webhook endpoint and may legitimately have different tokens configured by the user. Failing closed would lock users out of their own webhook, which is worse UX than logging the conflict. The first token found wins.

Applied to files:

  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
📚 Learning: 2026-06-03T14:22:14.714Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12206
File: autogpt_platform/backend/backend/api/external/v2/runs.py:130-145
Timestamp: 2026-06-03T14:22:14.714Z
Learning: In Significant-Gravitas/AutoGPT (autogpt_platform), `add_exception_handlers(app)` from `autogpt_platform/backend/backend/api/utils/exceptions.py` is registered on every API app instance, including `v2_app`. It automatically maps `NotFoundError` and `PrismaRecordNotFoundError` to HTTP 404. Therefore, v2 external API route handlers (e.g., in `autogpt_platform/backend/backend/api/external/v2/runs.py`) do NOT need explicit try/except blocks to catch `NotFoundError` from downstream helpers like `execution_utils.stop_graph_execution`; the top-level handler translates those to 404 without leaking a 500. Do NOT flag missing per-endpoint NotFoundError handling as a bug in v2 external API routes.

Applied to files:

  • autogpt_platform/backend/backend/integrations/webhooks/_base.py
  • autogpt_platform/backend/backend/integrations/webhooks/github.py
📚 Learning: 2025-11-03T17:41:48.242Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 11185
File: autogpt_platform/backend/backend/blocks/exa/webhook_blocks.py:133-161
Timestamp: 2025-11-03T17:41:48.242Z
Learning: The ExaWebsetWebhookBlock in autogpt_platform/backend/backend/blocks/exa/webhook_blocks.py is currently disabled (disabled=True in __init__) and not active in production.

Applied to files:

  • autogpt_platform/backend/backend/blocks/exa/_webhook.py
📚 Learning: 2026-04-30T14:10:26.644Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12960
File: autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/__tests__/helpers.test.ts:3-3
Timestamp: 2026-04-30T14:10:26.644Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/__tests__/helpers.test.ts`, the import path change from `./helpers` to `../helpers` was purely a file relocation into a `__tests__/` subdirectory — the helper module's contract did not change. `buildInputSchema({})` correctly returns `null` (empty properties check), `extractDefaults` correctly falls back to `examples[0]`, and `isFormValid(schema, formData)` has the correct argument order. Do not flag these assertions as mismatched after the path adjustment.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_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/tools/agent_generator/validator_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/agent_generator/validator_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/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
📚 Learning: 2026-04-01T04:17:41.600Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12632
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-01T04:17:41.600Z
Learning: When reviewing AutoGPT Copilot tool implementations, accept that `readOnlyHint=True` (provided via `ToolAnnotations`) may be applied unconditionally to *all* tools—even tools that have side effects (e.g., `bash_exec`, `write_workspace_file`, or other write/save operations). Do **not** flag these tools for having `readOnlyHint=True`; this is intentional to enable fully-parallel dispatch by the Anthropic SDK/CLI and has been E2E validated. Only flag `readOnlyHint` issues if they conflict with the established `ToolAnnotations` behavior (e.g., missing/incorrect propagation relative to the intended annotation mechanism).

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.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/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
📚 Learning: 2026-03-31T14:22:26.566Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12622
File: autogpt_platform/backend/backend/copilot/tools/agent_search.py:223-236
Timestamp: 2026-03-31T14:22:26.566Z
Learning: In files under autogpt_platform/backend/backend/copilot/tools/, ensure agent graph enrichment uses the typed Pydantic model `backend.data.graph.Graph` for `AgentInfo.graph` (i.e., `Graph | None`), not `dict[str, Any]`. When enriching with graph data (e.g., `_enrich_agents_with_graph`), prefer calling `graph_db().get_graph(graph_id, version=None, user_id=user_id)` directly to retrieve the typed `Graph` object rather than routing through JSON conversions like `get_agent_as_json()` / `graph_to_json()`.

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py
  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.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 : Inherit from 'Block' base class with input/output schemas when adding new blocks in backend

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
📚 Learning: 2026-04-08T17:26:12.102Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/CLAUDE.md:0-0
Timestamp: 2026-04-08T17:26:12.102Z
Learning: Agents must validate inputs before processing

Applied to files:

  • autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py
🔇 Additional comments (2)
autogpt_platform/backend/backend/copilot/tools/agent_generator/validator.py (1)

8-8: LGTM!

Also applies to: 24-26, 663-694, 696-756

autogpt_platform/backend/backend/copilot/tools/agent_generator/validator_test.py (1)

586-649: LGTM!

Comment thread autogpt_platform/backend/backend/integrations/webhooks/_base.py
Comment thread autogpt_platform/backend/backend/integrations/webhooks/github.py
Pwuts and others added 3 commits June 5, 2026 16:56
…gent

find_library_agent returns each agent's trigger_setup_info (provider + config_schema) so AutoPilot configures webhook triggers without fetching/parsing the full graph, and its response steers to setup_agent_webhook_trigger. list_library_agents gains an include_nodes flag (default False keeps the main library page fast); the copilot search opts in, since has_external_trigger / trigger_setup_info are False/None without graph nodes loaded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
edit_agent rejects edits that change a webhook trigger node's config fields (e.g. repo/events) — those belong on a per-trigger preset via setup_agent_webhook_trigger, not the agent's global graph — with an actionable error. run_agent detects webhook-trigger agents (which can't be run/scheduled directly) and returns the agent details pointing to setup_agent_webhook_trigger instead of attempting execution.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Pwuts Pwuts changed the title feat(backend/copilot): add setup_agent_webhook_trigger tool feat(platform): set up webhook triggers from AutoPilot Jun 5, 2026
@Pwuts Pwuts marked this pull request as draft June 5, 2026 15:23

@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: 5

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/cli/chat.py (1)

1-305: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Move local imports to module top level.

Lines 13, 42, 44-45, 95-98, 138, 158, 184, 212, 242, 265, 294 import standard library and application modules locally within functions and helpers. Per coding guidelines, use top-level imports only—local imports are reserved for heavy optional dependencies like openpyxl.

Move these imports to the top of the file:

  • asyncio (lines 42, 95)
  • json (lines 212, 242, 294)
  • re (line 265)
  • logging (line 13 — already correctly placed at function scope for one-time setup; can stay)
  • click (line 138 — used for exception; should be top-level)
  • prisma.models (lines 44, 97, 158, 184)
  • prisma.types (line 98)
  • backend.data.db (lines 46, 100)
♻️ Refactor to use top-level imports
+import asyncio
+import json
+import re
+
 import click
+import prisma.models
+import prisma.types
+
+from backend.data.db import connect, disconnect


 `@click.group`()
 def chat():
     """
     Group for CoPilot chat inspection commands
     """
     # Suppress INFO/DEBUG logs (Prisma connection chatter, service-client
     # setup) so they don't interleave with the rendered transcript. Use
     # logging.disable so it can't be undone by configure_logging() running
     # later during connect().
     import logging

     logging.disable(logging.INFO)

Then remove the local import lines from within functions.

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

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@autogpt_platform/backend/backend/cli/chat.py` around lines 1 - 305, The file
contains many local imports; move these to module top-level: asyncio, json, re,
click, prisma.models, prisma.types, and from backend.data.db import connect,
disconnect (leave logging.disable call in chat() as-is). Remove the
corresponding in-function local import statements found in chat_view (asyncio,
prisma.models, backend.data.db), chat_list (asyncio, prisma.models,
prisma.types, backend.data.db), and helper functions (_render_session,
_render_message, _assistant_lines, _tool_lines, _strip_context_blocks,
_render_session_json) so their references use the top-level imports; keep
behavior and names unchanged (functions: chat_view, chat_list, _render_session,
_render_message, _assistant_lines, _tool_lines, _user_lines,
_strip_context_blocks, _render_session_json).
🧹 Nitpick comments (5)
autogpt_platform/backend/backend/cli/main.py (2)

69-86: 💤 Low value

Consider removing PID file after process termination.

Lines 79-83 remove the PID file before terminating the process. If termination fails or raises an exception, the PID file is already gone, making it harder to retry. Consider moving os.remove(get_pid_path()) to after the termination logic or into a finally block.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@autogpt_platform/backend/backend/cli/main.py` around lines 69 - 86, The PID
file is removed before attempting to terminate the process in stop(), which can
leave no record if termination fails; update stop() to only remove the PID file
after the termination logic succeeds or always remove it in a finally block:
locate stop(), get_pid(), get_pid_path(), psutil.Process(...) and the loop over
process.children(...). Move the os.remove(get_pid_path()) call so it runs after
calling child.terminate() and process.terminate(), or wrap the termination code
in try/finally and call os.remove(get_pid_path()) from the finally to ensure the
PID file is cleaned up reliably only after attempting termination.

40-45: ⚡ Quick win

Document why os._exit(0) is used instead of sys.exit(0).

Line 45 uses os._exit(0), which bypasses Python cleanup (finally blocks, atexit handlers, etc.). If this is intentional to avoid interfering with the backgrounded child process, add a comment explaining the reasoning.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@autogpt_platform/backend/backend/cli/main.py` around lines 40 - 45, The code
calls os._exit(0) after starting the background server (MainApp().start) and
writing the PID (write_pid); add an inline comment just above the os._exit(0)
call that documents why os._exit is intentionally used instead of sys.exit (it
immediately terminates the parent process without running Python cleanup
handlers, finally blocks, or atexit hooks) and state that this avoids running
cleanup code that could interfere with or hang the background child process and
double-shutdowns; keep write_pid(pid) before the exit and do not change the exit
status—just add the explanatory comment referencing MainApp.start and write_pid
to make the intent explicit.
autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/__tests__/AgentDetailsCard.test.tsx (1)

15-18: 💤 Low value

Consider removing redundant cleanup() call.

Per the learnings, testing-library/react cleanup is handled globally via src/tests/integrations/vitest.setup.tsx. The cleanup() call on line 16 may be redundant. The onSend.mockReset() on line 17 should remain to reset the mock between tests.

Based on learnings: "In the AutoGPT frontend, testing-library/react cleanup is already handled globally after each test via src/tests/integrations/vitest.setup.tsx. Therefore, for integration test files under __tests__/, do NOT add redundant afterEach(() => cleanup())."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/__tests__/AgentDetailsCard.test.tsx
around lines 15 - 18, Remove the redundant cleanup() call from the afterEach
block and keep only the mock reset call: replace the current afterEach(() => {
cleanup(); onSend.mockReset(); }) with an afterEach that calls
onSend.mockReset() so that testing-library/react's global cleanup (from
vitest.setup.tsx) is not duplicated; locate the afterEach in the
AgentDetailsCard.test.tsx file and update the block that references cleanup()
and onSend.mockReset().
autogpt_platform/frontend/src/app/(platform)/copilot/tools/SetupTrigger/__tests__/SetupTrigger.test.tsx (1)

23-29: 💤 Low value

Consider removing redundant cleanup() call.

The cleanup() call on line 24 may be redundant since cleanup is handled globally. The useConnectedProvidersStore.setState() call (lines 25-28) should remain as it resets state specific to this test suite.

Based on learnings: "In the AutoGPT frontend, testing-library/react cleanup is already handled globally after each test via src/tests/integrations/vitest.setup.tsx."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/tools/SetupTrigger/__tests__/SetupTrigger.test.tsx
around lines 23 - 29, Remove the redundant cleanup() call from the afterEach
block and keep the state reset for useConnectedProvidersStore; specifically,
edit the afterEach to only call useConnectedProvidersStore.setState({ connected:
new Set(), autoDismissedKeys: new Set() }) because testing-library/react cleanup
is already handled globally and the explicit cleanup() is unnecessary.
autogpt_platform/frontend/src/app/(platform)/copilot/tools/SetupTrigger/SetupTrigger.tsx (1)

106-111: ⚡ Quick win

Add cleanup for setTimeout to prevent memory leak.

If the component unmounts during the 2-second delay, the timeout will still fire and attempt to call setCopied, which can cause a React warning or memory leak. Store the timeout ID and clear it in a cleanup function.

🧹 Proposed fix to add cleanup
  function handleCopy() {
    if (!output.webhook_url) return;
    navigator.clipboard.writeText(output.webhook_url);
    setCopied(true);
-   setTimeout(() => setCopied(false), 2000);
+   const timeoutId = setTimeout(() => setCopied(false), 2000);
+   return () => clearTimeout(timeoutId);
  }

Or wrap in a useEffect if you want to ensure cleanup runs:

+ import { useEffect } from "react";
+
  function handleCopy() {
    if (!output.webhook_url) return;
    navigator.clipboard.writeText(output.webhook_url);
    setCopied(true);
  }

+ useEffect(() => {
+   if (!copied) return;
+   const timeoutId = setTimeout(() => setCopied(false), 2000);
+   return () => clearTimeout(timeoutId);
+ }, [copied]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/tools/SetupTrigger/SetupTrigger.tsx
around lines 106 - 111, handleCopy currently starts a 2s setTimeout to reset
setCopied without clearing it, which can fire after unmount and cause warnings;
change handleCopy to save the timeout ID (e.g., via a ref) when calling
setTimeout and then clear that timeout in a cleanup (useEffect return) to avoid
leaks. Ensure you still check output.webhook_url and call
navigator.clipboard.writeText, but store the timer id and call
clearTimeout(timerId) in the component cleanup so setCopied is not invoked after
unmount.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@autogpt_platform/backend/backend/cli/main.py`:
- Around line 55-67: get_pid() currently creates parent directories
(os.makedirs) even though it's a read-only accessor; remove the directory
creation call from get_pid() so it only reads the PID file (use get_pid_path()
and open/read + int conversion as-is), and ensure the complementary write_pid()
(or wherever the PID is written) is responsible for creating the parent
directory (call os.makedirs(file_path.parent, exist_ok=True) inside write_pid()
before opening/writing the file).
- Around line 69-86: The stop() command calls psutil.Process(int(pid)) without
handling a missing PID; wrap the psutil.Process(...) lookup and subsequent
termination calls in a try/except that catches psutil.NoSuchProcess (and
optionally psutil.AccessDenied) to handle already-exited PIDs gracefully, remove
the PID file only when appropriate using get_pid_path(), and log/print a clear
message when the process does not exist; ensure you still attempt to remove the
PID file if it’s stale and that process.children(recursive=True) and
process.terminate() are only called when the Process object was successfully
obtained.

In `@autogpt_platform/backend/backend/copilot/tools/agent_search_test.py`:
- Around line 181-184: The local import of GraphTriggerInfo inside the helper
method _github_trigger_info should be moved to the module top-level: remove the
inner "from backend.data.graph import GraphTriggerInfo" from
_github_trigger_info and add a top-level import "from backend.data.graph import
GraphTriggerInfo" at the top of the test module so the helper uses the
module-scoped symbol.

In `@autogpt_platform/backend/backend/copilot/tools/models.py`:
- Around line 170-179: Replace the untyped dict field trigger_info with a proper
Pydantic model: define a TriggerInfo (or similarly named) subclass of
pydantic.BaseModel with the documented attributes (e.g., provider: str,
config_schema: dict[str, Any] or a more specific model if appropriate,
credentials_input_name: str | None) and any field descriptions/validators
needed, then change the field declaration from trigger_info: dict[str, Any] |
None = Field(...) to trigger_info: TriggerInfo | None = Field(...). Update any
imports and usages that construct or access trigger_info to use the new model.

In
`@autogpt_platform/backend/backend/copilot/tools/setup_agent_webhook_trigger_test.py`:
- Around line 55-60: The helper _github_meta currently uses inline "# type:
ignore" comments for the provider and type fields when constructing a
CredentialsMetaInput; remove those suppressors and instead construct the object
via a proper typed conversion (e.g., build a typed dict/Mapping with
provider="github" and type="api_key" and pass it through CredentialsMetaInput's
validated constructor or parsing method) so the returned CredentialsMetaInput is
created with correct types and no linter ignores; update the _github_meta
signature and body accordingly to return a fully typed CredentialsMetaInput
without using "# type: ignore".

---

Outside diff comments:
In `@autogpt_platform/backend/backend/cli/chat.py`:
- Around line 1-305: The file contains many local imports; move these to module
top-level: asyncio, json, re, click, prisma.models, prisma.types, and from
backend.data.db import connect, disconnect (leave logging.disable call in chat()
as-is). Remove the corresponding in-function local import statements found in
chat_view (asyncio, prisma.models, backend.data.db), chat_list (asyncio,
prisma.models, prisma.types, backend.data.db), and helper functions
(_render_session, _render_message, _assistant_lines, _tool_lines,
_strip_context_blocks, _render_session_json) so their references use the
top-level imports; keep behavior and names unchanged (functions: chat_view,
chat_list, _render_session, _render_message, _assistant_lines, _tool_lines,
_user_lines, _strip_context_blocks, _render_session_json).

---

Nitpick comments:
In `@autogpt_platform/backend/backend/cli/main.py`:
- Around line 69-86: The PID file is removed before attempting to terminate the
process in stop(), which can leave no record if termination fails; update stop()
to only remove the PID file after the termination logic succeeds or always
remove it in a finally block: locate stop(), get_pid(), get_pid_path(),
psutil.Process(...) and the loop over process.children(...). Move the
os.remove(get_pid_path()) call so it runs after calling child.terminate() and
process.terminate(), or wrap the termination code in try/finally and call
os.remove(get_pid_path()) from the finally to ensure the PID file is cleaned up
reliably only after attempting termination.
- Around line 40-45: The code calls os._exit(0) after starting the background
server (MainApp().start) and writing the PID (write_pid); add an inline comment
just above the os._exit(0) call that documents why os._exit is intentionally
used instead of sys.exit (it immediately terminates the parent process without
running Python cleanup handlers, finally blocks, or atexit hooks) and state that
this avoids running cleanup code that could interfere with or hang the
background child process and double-shutdowns; keep write_pid(pid) before the
exit and do not change the exit status—just add the explanatory comment
referencing MainApp.start and write_pid to make the intent explicit.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/__tests__/AgentDetailsCard.test.tsx:
- Around line 15-18: Remove the redundant cleanup() call from the afterEach
block and keep only the mock reset call: replace the current afterEach(() => {
cleanup(); onSend.mockReset(); }) with an afterEach that calls
onSend.mockReset() so that testing-library/react's global cleanup (from
vitest.setup.tsx) is not duplicated; locate the afterEach in the
AgentDetailsCard.test.tsx file and update the block that references cleanup()
and onSend.mockReset().

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/tools/SetupTrigger/__tests__/SetupTrigger.test.tsx:
- Around line 23-29: Remove the redundant cleanup() call from the afterEach
block and keep the state reset for useConnectedProvidersStore; specifically,
edit the afterEach to only call useConnectedProvidersStore.setState({ connected:
new Set(), autoDismissedKeys: new Set() }) because testing-library/react cleanup
is already handled globally and the explicit cleanup() is unnecessary.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/tools/SetupTrigger/SetupTrigger.tsx:
- Around line 106-111: handleCopy currently starts a 2s setTimeout to reset
setCopied without clearing it, which can fire after unmount and cause warnings;
change handleCopy to save the timeout ID (e.g., via a ref) when calling
setTimeout and then clear that timeout in a cleanup (useEffect return) to avoid
leaks. Ensure you still check output.webhook_url and call
navigator.clipboard.writeText, but store the timer id and call
clearTimeout(timerId) in the component cleanup so setCopied is not invoked after
unmount.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b968c59c-f38c-4dd2-b7a4-a3a977381523

📥 Commits

Reviewing files that changed from the base of the PR and between 4fd934d and 44cf17a.

📒 Files selected for processing (32)
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/routes/presets.py
  • autogpt_platform/backend/backend/cli/__init__.py
  • autogpt_platform/backend/backend/cli/chat.py
  • autogpt_platform/backend/backend/cli/main.py
  • autogpt_platform/backend/backend/cli/render_test.py
  • autogpt_platform/backend/backend/cli/test.py
  • autogpt_platform/backend/backend/copilot/sdk/agent_generation_guide.md
  • autogpt_platform/backend/backend/copilot/tools/agent_search.py
  • autogpt_platform/backend/backend/copilot/tools/agent_search_test.py
  • autogpt_platform/backend/backend/copilot/tools/edit_agent.py
  • autogpt_platform/backend/backend/copilot/tools/edit_agent_test.py
  • autogpt_platform/backend/backend/copilot/tools/find_library_agent_test.py
  • autogpt_platform/backend/backend/copilot/tools/list_agent_triggers.py
  • autogpt_platform/backend/backend/copilot/tools/list_agent_triggers_test.py
  • autogpt_platform/backend/backend/copilot/tools/models.py
  • autogpt_platform/backend/backend/copilot/tools/run_agent.py
  • autogpt_platform/backend/backend/copilot/tools/run_agent_test.py
  • autogpt_platform/backend/backend/copilot/tools/setup_agent_webhook_trigger.py
  • autogpt_platform/backend/backend/copilot/tools/setup_agent_webhook_trigger_test.py
  • autogpt_platform/backend/backend/data/db_manager.py
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/MessagePartRenderer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/helpers.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SetupRequirementsCard/SetupRequirementsCard.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SetupRequirementsCard/helpers.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/AgentDetailsCard.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/__tests__/AgentDetailsCard.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/helpers.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/SetupTrigger/SetupTrigger.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/SetupTrigger/__tests__/SetupTrigger.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/SetupTrigger/helpers.tsx
  • autogpt_platform/frontend/src/app/api/openapi.json
✅ Files skipped from review due to trivial changes (2)
  • autogpt_platform/backend/backend/copilot/tools/find_library_agent_test.py
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/helpers.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • autogpt_platform/backend/backend/copilot/tools/list_agent_triggers.py
  • autogpt_platform/backend/backend/api/features/library/routes/presets.py
  • autogpt_platform/backend/backend/data/db_manager.py
  • autogpt_platform/backend/backend/copilot/tools/list_agent_triggers_test.py
  • autogpt_platform/backend/backend/copilot/sdk/agent_generation_guide.md

Comment thread autogpt_platform/backend/backend/cli/main.py
Comment thread autogpt_platform/backend/backend/cli/main.py
Comment thread autogpt_platform/backend/backend/copilot/tools/agent_search_test.py Outdated
Comment thread autogpt_platform/backend/backend/copilot/tools/models.py Outdated
@Pwuts

Pwuts commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

/review

@autogpt-pr-reviewer

Copy link
Copy Markdown

Queued a review for PR #13298 at 44cf17a.

Pwuts and others added 2 commits June 5, 2026 18:39
…ions

The tool was added to TOOL_REGISTRY but not to the ToolName Literal / PLATFORM_TOOL_NAMES in permissions.py, so the registry-sync assertions in permissions_test.py and autopilot_permissions_test.py failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-run test mocks

The webhook-redirect guard in run_agent reads graph.has_external_trigger; these mocks left it an unset (truthy) MagicMock, so the redirect fired and short-circuited execution (KeyError: 'dry_run', add_graph_execution not called). Non-webhook agents have has_external_trigger=False.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@autogpt-pr-reviewer autogpt-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📋 Automated Review — PR #13298

PR #13298 — feat(platform): set up webhook triggers from AutoPilot
Author: Pwuts | Files: 45

🎯 Verdict: REQUEST_CHANGES

PR Description Quality

✅ Has Why + What + How — PR describes the full copilot webhook trigger setup flow, lists all new tools and guardrails, and explains the credential selection UX.

What This PR Does

Adds an end-to-end webhook trigger setup flow to the AutoPilot copilot: a new setup_agent_webhook_trigger tool discovers the agent's trigger block, collects config conversationally, lets the user pick a registration account via a credential card, creates the preset, and returns the ingress URL. Supporting changes include shared business logic extraction (setup_triggered_preset), guardrails preventing run_agent/edit_agent from silently mishandling webhook agents, trigger discovery in find_library_agent, a CLI for inspecting copilot chat sessions, and new Airtable/Exa webhook block support.

Specialist Findings

🛡️ Security ✅ — Auth checks are consistent across all new tools (user_id null checks, access control via get_graph). No SQL injection, no hardcoded secrets. Credential validation in _resolve_selection is sound.

  • 🟡 trigger_config values are not validated against the block's config schema at the triggers.py:58 layer — only presence is checked. Defense-in-depth improvement.
  • 🟡 Error messages in triggers.py:74, airtable/_webhook.py:130, exa/_webhook.py:109 may leak raw third-party API responses to users.

🏗️ Architecture ✅ — Clean extraction of shared logic into setup_triggered_preset, proper RPC accessor pattern via triggers_db(), effective guardrails in edit_agent against trigger-config mutation, and correct webhook error boundary with WebhookRegistrationError.

  • 🟠 Error handling inconsistency: _resolve_graph uses if not library_agent guard (setup_agent_webhook_trigger.py:257) while list_agent_triggers.py:117 catches NotFoundError — one path may be dead code.
  • 🟠 Dual error path (InvalidInputError from None-return vs WebhookRegistrationError from webhook manager) is correct but undocumented — future maintainers will be confused.

Performance ✅ — No critical perf issues. Three efficiency concerns, all bounded:

  • 🟡 Double graph fetch: _resolve_graph loads the full graph, then setup_triggered_preset loads it again (setup_agent_webhook_trigger.py:210triggers.py:50). One extra DB round-trip per trigger setup.
  • 🟡 include_nodes=True in copilot search (agent_search.py:153) loads full node trees for up to 50 agents. Bounded by pagination but worth monitoring.
  • 🔵 N+1 query in CLI chat_list (chat.py:118) — dev-only tool, default limit 20.

🧪 Testing ⚠️setup_agent_webhook_trigger has strong multi-path coverage. edit_agent trigger guard, validator, and CLI render tests are solid. However:

  • 🔴 setup_triggered_preset() (triggers.py:24) — the shared core logic — has zero unit tests. The route delegates to it; the copilot tool mocks it out. Three error branches and a success path are completely untested in isolation. (Flagged by: testing, discussion — 2)
  • 🟠 WebhookRegistrationError — added in this PR for RPC-safe error propagation — is never exercised in any test (setup_agent_webhook_trigger_test.py:219). (Flagged by: testing — 1)
  • 🟠 list_agent_triggers_test.py has only 2 tests (auth + one happy path). The "agent" trigger kind, empty results, NotFoundError path (line 121), and asyncio.gather concurrency are all untested. (Flagged by: testing — 1)
  • 🟠 library_agent_id resolution path (setup_agent_webhook_trigger.py:253-264) and builder_graph_id fallback (lines 242-251) have zero test coverage. (Flagged by: testing — 1)
  • 🟡 Frontend AgentDetailsCard.test.tsx — no regression test for non-webhook agents to ensure buttons still render normally.

📖 Quality ⚠️ — Code is well-organized and readable. Naming follows conventions. Docstrings are excellent on new public functions.

  • 🔴 Exception handling gap in presets.py:168: After refactoring to setup_triggered_preset, the route only catches WebhookRegistrationError. But the shared function raises NotFoundError and InvalidInputError — these now bubble as unhandled 500 errors instead of proper 4xx responses. The previous route returned HTTP 410 for missing graphs; this is a silent API contract break. (Flagged by: quality, discussion, architect — 3)
  • 🟡 Dead imports in presets.py:14-15: get_webhook_manager and setup_webhook_for_block are no longer used after the refactor.

📦 Product ✅ — Feature delivers on all claims. Explicit credential selection, config collection without guessing, and stale-CTA prevention are well-designed.

  • 🟡 AgentDetailsCard.tsx:60 — webhook-trigger agent card tells the user it can't be run but offers no visible forward instruction (the hint goes only to the LLM).
  • 🟡 navigator.clipboard.writeText in SetupTrigger.tsx:109 has no try/catch — may silently fail in non-HTTPS contexts.

📬 Discussion ⚠️ — Zero human reviews. 7 bot inline comments with zero author responses.

  • 🟠 NotAuthorizedError from github.py:136 (401/403 GitHub responses) is not caught by setup_agent_webhook_trigger.py, which only handles InvalidInputError and WebhookRegistrationError. A GitHub account without repo-admin rights produces an unhandled exception. (Flagged by: discussion — 1)
  • 🟠 _base.py:223 broad except ValueError wraps all provider errors into WebhookRegistrationError, hiding domain-specific NotFoundError/NotAuthorizedError. (Flagged by: discussion — 1)

🔎 QA ✅ — All endpoint validations pass: auth enforcement returns 401, invalid graph IDs return clear errors, copilot correctly reasons about webhook triggers and guides users through setup. Frontend loads without errors. OpenAPI schema includes new trigger_config_required, trigger_setup, trigger_info types.

🔴 Blockers

  1. Missing exception handlers in presets.py route after refactor (presets.py:155-172) — setup_triggered_preset() raises NotFoundError (graph gone → should be 410) and InvalidInputError (no webhook node, setup failed → should be 400), but the route only catches WebhookRegistrationError. These exceptions now produce 500 Internal Server Errors, silently breaking the existing API contract (previously returned 410 for missing graphs). (Flagged by: quality, discussion, architect — 3)

  2. setup_triggered_preset() has zero unit tests (triggers.py:24) — This is the extracted shared core logic used by both the REST route and copilot tool. It has three error branches (NotFoundError, two InvalidInputError) and a success path involving credential merging, webhook setup, and preset creation — none are directly tested. The copilot tool tests mock this function entirely; the route test delegates to it. Regressions in this function would go completely undetected. (Flagged by: testing, discussion — 2)

🟠 Should Fix

  1. NotAuthorizedError escapes webhook trigger setup (github.py:136setup_agent_webhook_trigger.py:219) — A GitHub 401/403 raises NotAuthorizedError, which is neither InvalidInputError nor WebhookRegistrationError. The tool's error handler doesn't catch it, producing an unhandled exception. Either catch it in the tool or ensure _base.py's wrapper converts it. (Flagged by: discussion — 1)

  2. WebhookRegistrationError never exercised in tests (setup_agent_webhook_trigger_test.py) — This error type was added specifically in this PR for RPC-safe error propagation and is caught on line 219, but no test triggers it. Add a test where setup_mock.side_effect = WebhookRegistrationError(...). (Flagged by: testing — 1)

  3. list_agent_triggers test coverage is skeletal (list_agent_triggers_test.py) — Only 2 tests: auth check and one webhook happy path. The "agent" trigger kind, empty results, and NotFoundError path (line 121) are all untested. (Flagged by: testing — 1)

  4. library_agent_id and builder_graph_id resolution paths untested (setup_agent_webhook_trigger.py:242-264) — All tests use graph_id= directly. The library-agent lookup and session-metadata fallback are completely uncovered. (Flagged by: testing — 1)

  5. Broad except ValueError hides domain exceptions (_base.py:223) — The webhook manager wrapper catches all ValueError subclasses and wraps them as WebhookRegistrationError, hiding NotFoundError/NotAuthorizedError from callers that branch on those types. Let domain-specific exceptions propagate before the generic catch. (Flagged by: discussion — 1)

🟡 Nice to Have

  1. Validate trigger_config values against block schema (triggers.py:58) — Currently only checks presence via _is_filled, not types/constraints. Defense-in-depth improvement. (security)
  2. Sanitize error messages (triggers.py:74, airtable/_webhook.py:130, exa/_webhook.py:109) — Raw third-party API responses could leak internal details. Log full errors server-side, return generic messages. (security)
  3. Eliminate double graph fetch (setup_agent_webhook_trigger.py:210) — Pass already-loaded graph to setup_triggered_preset() via optional parameter. Saves one DB round-trip per trigger setup. (performance)
  4. Frontend AgentDetailsCard regression test — Add a test for non-webhook agents to ensure action buttons still render. (testing)
  5. Add ARIA live region for copy confirmation (SetupTrigger.tsx:108) — Screen reader users get no feedback when URL is copied. (product)
  6. Split LLM-facing and user-facing messages (setup_agent_webhook_trigger.py:297, 439) — trigger_config_required and success messages contain tool-calling instructions that read oddly if rendered to users. (product)

🔵 Nits

  1. Dead imports (presets.py:14-15) — get_webhook_manager and setup_webhook_for_block are unused after the refactor.
  2. Magic number (chat.py:280) — Truncation length 500 should be a named constant.
  3. Redundant inner import (chat.py:138) — import click is already at top level.
  4. Untyped CLI render functions (chat.py:157,183,207,293) — Type hints would improve maintainability.
  5. _patches dead parameter (setup_agent_webhook_trigger_test.py:99) — missing parameter is accepted but never applied to any mock.

QA Screenshots

Screenshot Description
Copilot page authenticated Copilot chat UI loads correctly with new webhook trigger support ✅

Human Review Needed

YES — Large refactor (45 files), new RPC boundary for webhook triggers, API contract change in presets.py route, credential handling, and zero human reviews to date.

Risk Assessment

Merge risk: MEDIUM | Rollback: EASY (feature-additive, no DB migrations)

CI Status

❌ 2/6 checks pass, 4 failing: typecheck (pnpm types), backend tests (poetry run test), frontend tests (pnpm test:unit), frontend build (pnpm build). Additionally, check-docs-sync failing on GitHub and 5 checks still pending (backend tests 3.11/3.12/3.13, E2E, PR status).



UI Testing — Variant Results

✅ local: All endpoint validations, auth checks, copilot webhook guidance, and frontend rendering pass; no regressions detected

⚠️ hosted: API endpoints are properly guarded with auth/validation/error handling, but full happy path could not be verified due to subscription gate and lack of seeded webhook-trigger agents

  • medium: setup_trigger catches WebhookRegistrationError but the shared setup_triggered_preset function raises InvalidInputError for graph-not-found and no-webhook-node cases. The route handler does not catch InvalidInputError, so those will surface as 500s instead of 400/410.
  • low: NotFoundError is raised for missing graph but the route handler in presets.py only catches WebhookRegistrationError — NotFoundError will bubble up as an unhandled 500.

Comment thread autogpt_platform/backend/backend/api/features/library/triggers.py
Comment thread autogpt_platform/backend/backend/api/features/library/triggers.py
Comment thread autogpt_platform/backend/backend/blocks/airtable/_webhook.py
Comment thread autogpt_platform/backend/backend/blocks/exa/_webhook.py
Comment thread autogpt_platform/backend/backend/copilot/tools/models.py
Comment thread autogpt_platform/backend/backend/api/features/library/triggers.py
Pwuts and others added 3 commits June 6, 2026 10:21
setup_agent_webhook_trigger now catches NotFoundError from setup_triggered_preset, whose graph re-fetch (it fetches by id to run as an RPC endpoint) can find the graph deleted/inaccessible between the tool's resolve and preset creation. Returns the clean trigger_setup_failed message instead of the generic fallback. Provider registration failures remain WebhookRegistrationError (wrapped in _base by design) and are already caught.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CLI: drop makedirs from read-only get_pid(); handle psutil.NoSuchProcess in stop(); hoist logging/click imports to module scope; name the truncation length constant. Tests: move GraphTriggerInfo import to module scope; build CredentialsMetaInput with ProviderName.GITHUB instead of suppressing the type with # type: ignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
navigator.clipboard.writeText can reject in non-secure/unsupported contexts; wrap it in try/catch so the copy button no-ops gracefully (the URL stays visible for manual copy) instead of throwing an unhandled rejection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the conflicts Automatically applied to PRs with merge conflicts label Jun 6, 2026
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

…lot-doesnt-know-how-to-help-user-set-up-webhook
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly.

@github-actions github-actions Bot removed the conflicts Automatically applied to PRs with merge conflicts label Jun 8, 2026
Pwuts and others added 2 commits June 8, 2026 14:15
…as GraphTriggerInfo

trigger_info had a defined schema (provider, config_schema, credentials_input_name) but was typed dict[str, Any]; type it as GraphTriggerInfo so the OpenAPI/generated client expose a proper model. run_agent and find_library_agent pass the GraphTriggerInfo instance through instead of model_dump()-ing it. Regenerates openapi.json (AgentInfo/AgentDetails trigger_info -> ref GraphTriggerInfo).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-setup failure paths

_resolve_graph uses try/except NotFoundError for the library_agent lookup (get_library_agent raises NotFoundError, it doesn't return None). Adds tests covering the tool's failure paths: WebhookRegistrationError (provider refusal) and NotFoundError (graph deleted between resolve and preset creation) both surface a clean trigger_setup_failed message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jun 8, 2026
Pwuts and others added 2 commits June 8, 2026 15:25
Direct unit test for setup_triggered_preset (happy + NotFoundError + no-webhook-node + webhook-rejected), setup_agent_webhook_trigger library_agent_id resolution (found + NotFoundError), and a list_agent_triggers 'agent'-kind test. Lifts backend patch coverage past 80% and closes the corresponding review threads.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… for patch coverage

Adds/extends Vitest unit tests for the webhook-trigger frontend: SetupTrigger (all output branches + copy button + helpers), RunAgent helpers (trigger_info accordion/animation branches), MessagePartRenderer dispatch (incl. tool-setup_agent_webhook_trigger), SetupRequirementsCard trigger-mode credential carry-back, AgentDetailsCard run paths, and ChatMessagesContainer helpers. Lifts platform-frontend patch coverage well past the 70% target (changed files now 97-100%).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 platform/frontend AutoGPT Platform - Front end size/xl

Projects

Status: 🚧 Needs work
Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant