Skip to content

ci: cut Actions spend across PR/push triggers - #12955

Closed
Swiftyos wants to merge 6 commits into
devfrom
swiftyos/optomise-ci-costs
Closed

ci: cut Actions spend across PR/push triggers#12955
Swiftyos wants to merge 6 commits into
devfrom
swiftyos/optomise-ci-costs

Conversation

@Swiftyos

Copy link
Copy Markdown
Contributor

Summary

  • classic-python-checks: scoped path filters to classic/**.py (was repo-wide **.py) so unrelated changes don't trigger the workflow.
  • platform-backend: dropped the 3.11 / 3.12 / 3.13 pyright + pytest matrix down to 3.13 (the prod runtime), removing 2/3 of the per-PR runs.
  • platform-fullstack: added a preflight-e2e gate that waits for backend + frontend CI on the same SHA and skips the big-boi E2E job if upstream failed or didn't run for that SHA.
  • repo-pr-label: only fans out on push to master now (was master / dev / release-*) since master holds the bulk of open PRs.
  • repo-workflow-checker: switched from pull_request polling to workflow_run, evaluates once per upstream completion, and posts a single Check PR Status check-run for branch protection.
  • check_actions_status.py: rewritten around the workflow_run model (paginated check-runs, brief settle retry, no 30s polling loop).
  • wait_for_upstream.py: new helper that gates the E2E job on named upstream workflow runs by head SHA.

Test plan

  • Verify Check PR Status posts on this PR's head SHA after the upstream workflows complete and is required by branch protection.
  • Confirm preflight-e2e resolves to proceed=true once backend + frontend CI succeed, and that the big-boi e2e_test job runs.
  • Force a backend CI failure on a draft PR and confirm e2e_test is skipped.
  • Touch a non-classic file and confirm Classic - Python checks does not trigger.
  • Push to dev / a release-* branch and confirm repo-pr-label no longer fan-outs (only master should trigger it).
  • Confirm backend pyright + pytest now runs on 3.13 only.

🤖 Generated with Claude Code

- classic-python-checks: scope path filters to classic/**.py instead of repo-wide **.py so unrelated changes don't trigger the workflow.
- platform-backend: drop the 3.11/3.12/3.13 pyright + pytest matrix down to 3.13 (the prod runtime), removing 2/3 of the per-PR runs.
- platform-fullstack: add a preflight-e2e gate that waits for backend + frontend CI on the same SHA and skips the big-boi E2E job if upstream failed or didn't run.
- repo-pr-label: only fan out on push to master (was master/dev/release-*) since master holds the bulk of open PRs.
- repo-workflow-checker: switch from pull_request polling to workflow_run, evaluate once per upstream completion, and post a single "Check PR Status" check-run for branch protection.
- check_actions_status.py: rewrite around the workflow_run model (paginated check-runs, brief settle retry, no polling loop).
- wait_for_upstream.py: new helper that gates the E2E job on named upstream workflow runs by head SHA.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Swiftyos
Swiftyos requested review from a team as code owners April 30, 2026 10:37
@Swiftyos
Swiftyos requested review from Bentlybro and kcze and removed request for a team April 30, 2026 10:37
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Apr 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

Automatically setting the base branch to dev.

@github-actions
github-actions Bot changed the base branch from master to dev April 30, 2026 10:38
@github-actions github-actions Bot added platform/frontend AutoGPT Platform - Front end platform/backend AutoGPT Platform - Back end labels Apr 30, 2026
@coderabbitai

coderabbitai Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1138df71-3c14-442c-a91e-1c0397024ced

📥 Commits

Reviewing files that changed from the base of the PR and between 494a916 and 0a7b8df.

📒 Files selected for processing (1)
  • .github/workflows/scripts/wait_for_upstream.py
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: check API types
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Analyze (python)
  • GitHub Check: Wait for upstream CI
  • GitHub Check: type-check
  • GitHub Check: test
  • GitHub Check: Check PR Status
🧰 Additional context used
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Use the template in `.github/PULL_REQUEST_TEMPLATE.md` for pull requests, rely on pre-commit checks for linting and formatting, fill out the Changes section and checklist, use conventional commit titles with scope, keep out-of-scope changes under 20% of the PR, ensure PR descriptions are complete, and use linear ticket branch structure
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-28T03:31:29.696Z
Learning: In Significant-Gravitas/AutoGPT PR `#12933` (`fix/stripe-checkout-link-auth-loop`), the initial approach of pinning `payment_method_types=["card"]` in `top_up_intent` and `create_subscription_checkout` (in `autogpt_platform/backend/backend/data/credit.py`) was reverted in commit `584b43a71` as it patched a symptom. The true root cause was in `update_subscription_tier()` in `v1.py`: a `current_tier_price_id is not None` guard was gating admin-granted DB-tier flips and short-circuiting them when the BUSINESS tier was pruned from the price-id LaunchDarkly flag. Do NOT flag `payment_method_types` absence in these checkout helpers as a Stripe Link bypass issue; the fix lives in the subscription tier update guard logic.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-25T02:53:53.964Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py` (PR `#12918`, commit 6576bf561):
- `_flush_unresolved_tool_calls` was renamed to `flush_unresolved_tool_calls` (public); all call sites updated, `# noqa: SLF001` suppressor removed.
- `_flush_orphan_tool_uses_to_session` and `_InterruptedAttempt.finalize` both return `list[StreamBaseResponse]`; the post-loop caller yields those events directly to avoid double-flush and skipped UI cleanup events.
- The three former post-loop blocks (partial restore + redundant re-flush + two separate `yield StreamError` sites) are collapsed into a single block driven by `_classify_final_failure` returning a `_FinalFailure(display_msg, code, retryable)` dataclass, so history marker and SSE yield share one source of truth.
Do NOT flag double-flush risk or mismatched history/SSE marker as issues in the post-loop section of `stream_chat_completion_sdk`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12701
File: .claude/skills/orchestrate/scripts/verify-complete.sh:120-121
Timestamp: 2026-04-07T18:08:03.548Z
Learning: In Significant-Gravitas/AutoGPT, verify-complete.sh (`.claude/skills/orchestrate/scripts/verify-complete.sh`) uses `commits[-1].committedDate` (not `updatedAt`) to identify stale CHANGES_REQUESTED reviews. This is intentional: `updatedAt` changes on any PR activity (bot comments, label changes, description edits), which would falsely classify a reviewer's CHANGES_REQUESTED as stale — a silent false negative. The `committedDate` edge case (commit created locally before a review but pushed after) only causes a false positive (unnecessary re-brief), which is the safer failure mode. Do not suggest switching to `updatedAt` for this comparison.
📚 Learning: 2026-04-13T13:11:00.401Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/EmptySession/EmptySession.tsx:41-42
Timestamp: 2026-04-13T13:11:00.401Z
Learning: In Significant-Gravitas/AutoGPT `autogpt_platform/frontend`, unconditional React Query hook calls (e.g. `usePulseChips()` in `EmptySession.tsx`) are intentional when the underlying data is expected to be cached from prior page visits. The team considers the fetch cost acceptable in these cases and does not require `enabled` gating purely for feature-flag-disabled paths. Do not flag unconditional query hooks as wasteful when caching makes the cost negligible.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-03-24T02:05:08.144Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/CopilotPage.tsx:0-0
Timestamp: 2026-03-24T02:05:08.144Z
Learning: In `Significant-Gravitas/AutoGPT` (autogpt_platform frontend), when gating logic on a React Query result being available (e.g., `useGetV2GetCopilotUsage`), prefer destructuring `isSuccess` (e.g., `const { data, isSuccess: hasUsage } = useQuery(...)`) over checking `!isLoading`. `isLoading` can be `false` in error/idle states where `data` is still `undefined`, while `isSuccess` guarantees the query completed successfully and `data` is populated. This pattern was established in `CopilotPage.tsx` (PR `#12526`, commit e9dfd1f76).

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-22T05:57:38.198Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12879
File: autogpt_platform/backend/backend/copilot/baseline/service.py:0-0
Timestamp: 2026-04-22T05:57:38.198Z
Learning: In `autogpt_platform/backend/backend/copilot/baseline/service.py`, the approved pattern for `_run_task_subagent` (PR `#12879`, commit 187f0a5) uses a nested `try/except Exception` inside an outer `try/finally`. The outer `finally` block resets `_TASK_DEPTH_VAR` (via `_TASK_DEPTH_VAR.reset(token)`) AND calls `_absorb_inner_usage(parent_state, inner_state)` unconditionally, so both the depth ContextVar and usage roll-up are guaranteed on all exit paths including `CancelledError`/`KeyboardInterrupt`/`SystemExit`. The inner `except Exception` catches and converts failures into a `TaskResponse` error payload that is returned as `StreamToolOutputAvailable`. Do NOT flag missing ContextVar reset or usage roll-up on BaseException paths in this function.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-14T06:34:02.835Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12774
File: autogpt_platform/backend/backend/copilot/tools/e2b_sandbox.py:0-0
Timestamp: 2026-04-14T06:34:02.835Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/e2b_sandbox.py`, the `asyncio.wait_for()` retry loop around `AsyncSandbox.create()` (introduced in PR `#12774`) can leak up to `_SANDBOX_CREATE_MAX_RETRIES - 1` (≤2) orphaned E2B sandboxes per hang incident because `wait_for` cancels only the client-side wait while E2B may complete server-side provisioning. With the default `on_timeout="pause"` lifecycle, leaked orphaned sandboxes are **paused** (not killed) when their original `end_at` is reached and persist indefinitely until explicitly killed — there is NO automatic E2B project-level cleanup. Operators must manage these manually or via their own cleanup jobs. The sandbox_id is not accessible from the timed-out coroutine, so recovery via `AsyncSandbox.connect(sandbox_id)` is not possible at timeout. This is an intentionally accepted trade-off; a proper fix is deferred to a follow-up PR. Do NOT flag the retry loop as a blocking issue.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-07T18:08:03.548Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12701
File: .claude/skills/orchestrate/scripts/verify-complete.sh:120-121
Timestamp: 2026-04-07T18:08:03.548Z
Learning: In Significant-Gravitas/AutoGPT, verify-complete.sh (`.claude/skills/orchestrate/scripts/verify-complete.sh`) uses `commits[-1].committedDate` (not `updatedAt`) to identify stale CHANGES_REQUESTED reviews. This is intentional: `updatedAt` changes on any PR activity (bot comments, label changes, description edits), which would falsely classify a reviewer's CHANGES_REQUESTED as stale — a silent false negative. The `committedDate` edge case (commit created locally before a review but pushed after) only causes a false positive (unnecessary re-brief), which is the safer failure mode. Do not suggest switching to `updatedAt` for this comparison.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-25T02:53:53.964Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-25T02:53:53.964Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py` (PR `#12918`, commit 6576bf561):
- `_flush_unresolved_tool_calls` was renamed to `flush_unresolved_tool_calls` (public); all call sites updated, `# noqa: SLF001` suppressor removed.
- `_flush_orphan_tool_uses_to_session` and `_InterruptedAttempt.finalize` both return `list[StreamBaseResponse]`; the post-loop caller yields those events directly to avoid double-flush and skipped UI cleanup events.
- The three former post-loop blocks (partial restore + redundant re-flush + two separate `yield StreamError` sites) are collapsed into a single block driven by `_classify_final_failure` returning a `_FinalFailure(display_msg, code, retryable)` dataclass, so history marker and SSE yield share one source of truth.
Do NOT flag double-flush risk or mismatched history/SSE marker as issues in the post-loop section of `stream_chat_completion_sdk`.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-23T00:07:27.130Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.130Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py`, background tasks that persist cost or emit Langfuse backfill (e.g. the cost-reconcile task) must be anchored to `_background_tasks` using `_background_tasks.add(task)` and `task.add_done_callback(_background_tasks.discard)`, mirroring the existing pattern at lines 3063 / 4232 / 4256. This prevents the asyncio task from being garbage-collected before persistence or Langfuse emission completes. Do NOT flag the absence of this anchoring as acceptable in this file. Established in PR `#12889` commit 5ce3d0388.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-23T01:26:38.272Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T01:26:38.272Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py`, `langfuse_trace_id = get_client().get_current_trace_id()` must be captured under the `if _lf_span is not None:` guard (before `_lf_span` is torn down), NOT under `if _otel_ctx is not None:`. The `_otel_ctx` guard is too narrow: if `propagate_attributes().__enter__()` raises, `_otel_ctx` is never assigned, and placing the trace-id capture there would silently orphan the `openrouter-cost-reconcile` event from its parent span. Established in PR `#12889` commit d243bf6c9.

Applied to files:

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

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-15T02:06:40.213Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/util/workspace.py:198-221
Timestamp: 2026-04-15T02:06:40.213Z
Learning: In `autogpt_platform/backend/backend/util/workspace.py`, the TOCTOU gap between the `get_workspace_total_size()` pre-check and the subsequent storage write + DB insert in `WorkspaceManager.write_file()` is an accepted trade-off. Reasons: (1) the workspace is single-user-scoped, so a true race requires precise concurrent timing from the same user; (2) the REST upload route (`autogpt_platform/backend/backend/api/features/workspace/routes.py`) already has a post-write quota check with soft-delete rollback as a safety net for that path; (3) adding the same rollback inside `write_file()` would couple the manager to HTTP semantics. The pre-write check catches the overwhelming majority of cases. Do NOT flag this as a blocking TOCTOU issue.

Applied to files:

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

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-15T13:44:34.273Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12797
File: autogpt_platform/backend/backend/copilot/sdk/service.py:1991-2021
Timestamp: 2026-04-15T13:44:34.273Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py` (`_run_stream_attempt`), the pre-create block (PR `#12797`) intentionally does NOT call `state.transcript_builder.append_assistant(...)` when inserting the empty assistant placeholder into `ctx.session.messages`. The transcript is left ending at the `tool_result` entry (N entries) while `message_count` metadata is N+1. This mismatch is benign and deliberate: on the next `--resume`, the SDK sees the transcript ending at `tool_result` and correctly regenerates the assistant response. Pre-appending the assistant turn to the transcript would suppress regeneration while leaving `session.messages[-1].content = ""` permanently (worse outcome). On the gap-fallback path, `transcript_msg_count (N+1) >= msg_count-1 (N)` means no gap is injected for the empty placeholder, which is correct because injecting an empty assistant message as context would mislead the SDK. Do NOT flag this transcript/message_count discrepancy as a bug.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-13T13:17:00.049Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/hooks/useAgentStatus.ts:65-79
Timestamp: 2026-04-13T13:17:00.049Z
Learning: In Significant-Gravitas/AutoGPT, `useGetV1ListAllExecutions` (`autogpt_platform/frontend/src/app/api/__generated__/endpoints/graphs/graphs`) returns executions in reverse-chronological order (most recent first). Therefore, using `.find()` on the result to pick the first matching failure/completion is intentional and already returns the most recent match. Do not suggest sorting the executions array before `.find()` as it adds overhead with no practical benefit given the API ordering guarantee. This pattern is used in `useAgentStatus.ts` and `useLibraryFleetSummary.ts` (PR `#12764`).

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-03-23T06:36:25.447Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/frontend/src/app/(platform)/library/components/LibraryImportWorkflowDialog/useLibraryImportWorkflowDialog.ts:0-0
Timestamp: 2026-03-23T06:36:25.447Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, the `LibraryImportWorkflowDialog` (previously `LibraryImportCompetitorDialog`) and its associated generated API hook (`usePostV2ImportACompetitorWorkflowN8nMakeComZapier` / `usePostV2ImportAWorkflowFromAnotherToolN8nMakeComZapier`) were removed in a subsequent refactor. Workflow import from external platforms (n8n, Make.com, Zapier) now uses a server action `fetchWorkflowFromUrl` instead of direct API calls or generated orval hooks. Do not expect or flag missing generated hook usage for workflow import in `autogpt_platform/frontend/src/app/(platform)/library/components/LibraryImportWorkflowDialog/`.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
🔇 Additional comments (3)
.github/workflows/scripts/wait_for_upstream.py (3)

67-81: Rerun tie-break logic looks correct.

Using (run_number, run_attempt) to select latest per workflow correctly avoids stale-attempt selection on reruns.


115-127: Transient GitHub API failure handling is robust.

Catching requests.RequestException and retrying until deadline is the right behavior for flaky API/network conditions.


160-170: Missing-upstream handling now enforces the fail-closed gate.

Blocking (proceed=false) when required workflows are still missing after grace matches the preflight cost-control intent.


Walkthrough

Adds a preflight gating job and polling script to block E2E until upstream CI runs for the same commit are acceptable, pins backend CI to Python 3.13 (removing python-version matrix), and tightens workflow trigger path/branch filters and paths-ignore globs across workflows. (33 words)

Changes

Cohort / File(s) Summary
Backend CI & Classic Python checks
.github/workflows/platform-backend-ci.yml, .github/workflows/classic-python-checks.yml
Pin backend CI to Python 3.13 (remove matrix), update Poetry cache keys and Pyright invocation; narrow classic workflow path globs for Python file triggers.
Workflow triggers & labels
.github/workflows/repo-pr-label.yml, .github/workflows/classic-python-checks.yml
Restrict branch triggers (e.g., push -> dev), and change paths-ignore to exclude classic/forge/tests/vcr_cassettes/**.
E2E preflight gate & script
.github/workflows/platform-fullstack-ci.yml, .github/workflows/scripts/wait_for_upstream.py
Add preflight-e2e job that polls upstream workflow runs for the commit and emits proceed; make e2e_test depend on preflight-e2e and run only when proceed == 'true'.

Sequence Diagram

sequenceDiagram
    actor GH as GitHub Actions
    participant Preflight as preflight-e2e Job / script
    participant API as GitHub REST API
    participant Upstream as Upstream CI Workflows
    participant E2E as e2e_test Job

    GH->>Preflight: start preflight-e2e (job)
    Preflight->>API: list workflow runs for HEAD_SHA (paginated)
    API->>Upstream: return runs (status, conclusion)
    API-->>Preflight: latest runs per workflow
    alt Any upstream failed
        Preflight->>GH: set output `proceed=false`
        GH->>E2E: skip e2e_test (if condition fails)
    else All upstream complete (success/neutral/skipped)
        Preflight->>GH: set output `proceed=true`
        GH->>E2E: run e2e_test
        E2E->>E2E: execute E2E steps
    else Timeout / API error
        Preflight->>GH: set `proceed=false`, exit non‑zero
        GH->>E2E: skip e2e_test
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

platform/backend

Suggested reviewers

  • Bentlybro
  • kcze

Poem

🐰 I hopped through CI with a tiny tweak,
Pinned Python steps and guarded the e2e peak.
I polled the upstream, patient and spry,
If green, I cheer — if not, I sigh.
Hop on, pipelines — let's pass and fly!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 'ci: cut Actions spend across PR/push triggers' directly describes the main objective of reducing GitHub Actions spending by restricting workflow triggers, which aligns with the changeset.
Description check ✅ Passed The description provides a clear summary of all major changes across multiple workflows and scripts, directly corresponding to the modifications in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch swiftyos/optomise-ci-costs

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Apr 30, 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.

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


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

@github-actions github-actions Bot removed platform/frontend AutoGPT Platform - Front end platform/backend AutoGPT Platform - Back end labels Apr 30, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ec53c5dd7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/scripts/check_actions_status.py Outdated
Comment thread .github/workflows/scripts/wait_for_upstream.py Outdated
@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.56%. Comparing base (b966194) to head (0a7b8df).
⚠️ Report is 235 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #12955      +/-   ##
==========================================
+ Coverage   69.52%   69.56%   +0.03%     
==========================================
  Files        2105     2115      +10     
  Lines      157113   157577     +464     
  Branches    16200    16233      +33     
==========================================
+ Hits       109236   109614     +378     
- Misses      44666    44740      +74     
- Partials     3211     3223      +12     
Flag Coverage Δ
platform-backend 78.59% <ø> (+0.04%) ⬆️

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

Components Coverage Δ
Platform Backend 78.59% <95.65%> (+0.04%) ⬆️
Platform Frontend 37.19% <88.15%> (+0.04%) ⬆️
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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/scripts/wait_for_upstream.py (1)

75-76: ⚡ Quick win

Make latest-run selection deterministic beyond run_number

At Line 75, using only run_number can select the wrong candidate in edge cases (re-runs / mixed run contexts on same SHA). Prefer a stronger ordering key (e.g., created_at + id, optionally run_attempt) when deciding the latest run per workflow name.

Proposed patch
-        if prev is None or run["run_number"] > prev["run_number"]:
+        prev_key = (
+            prev.get("run_number", -1),
+            prev.get("run_attempt", -1),
+            prev.get("id", -1),
+        ) if prev else (-1, -1, -1)
+        run_key = (
+            run.get("run_number", -1),
+            run.get("run_attempt", -1),
+            run.get("id", -1),
+        )
+        if prev is None or run_key > prev_key:
             by_name[name] = run
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/scripts/wait_for_upstream.py around lines 75 - 76, The
current selection logic that updates by_name[name] using only run["run_number"]
is non-deterministic for reruns; change the comparison to use a deterministic
composite key (e.g., (run["created_at"], run.get("run_attempt",
run["run_number"]), run["id"]) or similar) so the newest run is chosen
unambiguously. In the block that currently checks if prev is None or
run["run_number"] > prev["run_number"], compute comparable tuples for both run
and prev (referencing variables run, prev, by_name, name) and replace the
numeric comparison with tuple comparison to pick the latest run
deterministically. Ensure created_at is parsed/used consistently (string ISO
timestamps compare lexicographically) and include run["id"] as a final
tiebreaker.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/scripts/wait_for_upstream.py:
- Around line 112-113: fetch_runs call can throw transient requests errors and
currently aborts preflight; modify the polling loop around fetch_runs(env,
headers) so it catches requests.RequestException (or whichever requests
exception type is used), log the error via the existing logger, sleep briefly,
and continue retrying until the MAX_WAIT_SECONDS deadline is reached before
giving up; keep using latest_per_workflow(...) only when fetch_runs succeeds and
ensure the catch uses the same env/headers context so intermittent HTTP/timeouts
don't terminate the job prematurely.

---

Nitpick comments:
In @.github/workflows/scripts/wait_for_upstream.py:
- Around line 75-76: The current selection logic that updates by_name[name]
using only run["run_number"] is non-deterministic for reruns; change the
comparison to use a deterministic composite key (e.g., (run["created_at"],
run.get("run_attempt", run["run_number"]), run["id"]) or similar) so the newest
run is chosen unambiguously. In the block that currently checks if prev is None
or run["run_number"] > prev["run_number"], compute comparable tuples for both
run and prev (referencing variables run, prev, by_name, name) and replace the
numeric comparison with tuple comparison to pick the latest run
deterministically. Ensure created_at is parsed/used consistently (string ISO
timestamps compare lexicographically) and include run["id"] as a final
tiebreaker.
🪄 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: 336a5890-3da6-4c88-b176-40ace938259b

📥 Commits

Reviewing files that changed from the base of the PR and between ffed9da and 184e53d.

📒 Files selected for processing (1)
  • .github/workflows/scripts/wait_for_upstream.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: check API types
  • GitHub Check: Wait for upstream CI
  • GitHub Check: test
  • GitHub Check: type-check
  • GitHub Check: Check PR Status
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Use the template in `.github/PULL_REQUEST_TEMPLATE.md` for pull requests, rely on pre-commit checks for linting and formatting, fill out the Changes section and checklist, use conventional commit titles with scope, keep out-of-scope changes under 20% of the PR, ensure PR descriptions are complete, and use linear ticket branch structure
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:57.501Z
Learning: Split PRs by concern — each PR should have a single clear purpose (e.g., separate PRs for 'usage tracking' and 'credit charging' even if related)
📚 Learning: 2026-04-13T13:11:00.401Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/EmptySession/EmptySession.tsx:41-42
Timestamp: 2026-04-13T13:11:00.401Z
Learning: In Significant-Gravitas/AutoGPT `autogpt_platform/frontend`, unconditional React Query hook calls (e.g. `usePulseChips()` in `EmptySession.tsx`) are intentional when the underlying data is expected to be cached from prior page visits. The team considers the fetch cost acceptable in these cases and does not require `enabled` gating purely for feature-flag-disabled paths. Do not flag unconditional query hooks as wasteful when caching makes the cost negligible.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-03-24T02:05:08.144Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/CopilotPage.tsx:0-0
Timestamp: 2026-03-24T02:05:08.144Z
Learning: In `Significant-Gravitas/AutoGPT` (autogpt_platform frontend), when gating logic on a React Query result being available (e.g., `useGetV2GetCopilotUsage`), prefer destructuring `isSuccess` (e.g., `const { data, isSuccess: hasUsage } = useQuery(...)`) over checking `!isLoading`. `isLoading` can be `false` in error/idle states where `data` is still `undefined`, while `isSuccess` guarantees the query completed successfully and `data` is populated. This pattern was established in `CopilotPage.tsx` (PR `#12526`, commit e9dfd1f76).

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py

Comment thread .github/workflows/scripts/wait_for_upstream.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In @.github/workflows/scripts/wait_for_upstream.py:
- Around line 143-164: The current logic in the block using variables missing,
grace_deadline and MISSING_GRACE_SECONDS treats "still missing after grace" as a
pass and calls write_output("proceed", "true"); change this so that if missing
is non-empty after the grace deadline (and in_progress is false) we treat the
upstream as not triggered and do not proceed: call write_output("proceed",
"false") (and update the printed message to reflect a skip/fail decision)
instead of returning success; keep the existing behavior of proceeding only when
the required workflows are present (i.e., when missing is empty) and still log
by_name.keys() when proceeding.
- Around line 67-76: The function latest_per_workflow selects the latest run
using only run_number; change the comparison in latest_per_workflow to consider
both run_number and run_attempt (compare the tuple (run["run_number"],
run.get("run_attempt", 0)) against the stored run's tuple) so that when
run_number is equal the higher run_attempt (more recent attempt) wins; update
the assignment to store the entire run as before and ensure you handle missing
run_attempt by defaulting to 0.
🪄 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: c520e2c1-006e-4f05-9ef1-710219a35ed8

📥 Commits

Reviewing files that changed from the base of the PR and between 184e53d and 494a916.

📒 Files selected for processing (1)
  • .github/workflows/scripts/wait_for_upstream.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: check API types
  • GitHub Check: test
  • GitHub Check: type-check
  • GitHub Check: Wait for upstream CI
  • GitHub Check: Check PR Status
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (13)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-28T03:31:29.696Z
Learning: In Significant-Gravitas/AutoGPT PR `#12933` (`fix/stripe-checkout-link-auth-loop`), the initial approach of pinning `payment_method_types=["card"]` in `top_up_intent` and `create_subscription_checkout` (in `autogpt_platform/backend/backend/data/credit.py`) was reverted in commit `584b43a71` as it patched a symptom. The true root cause was in `update_subscription_tier()` in `v1.py`: a `current_tier_price_id is not None` guard was gating admin-granted DB-tier flips and short-circuiting them when the BUSINESS tier was pruned from the price-id LaunchDarkly flag. Do NOT flag `payment_method_types` absence in these checkout helpers as a Stripe Link bypass issue; the fix lives in the subscription tier update guard logic.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-25T02:53:53.964Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py` (PR `#12918`, commit 6576bf561):
- `_flush_unresolved_tool_calls` was renamed to `flush_unresolved_tool_calls` (public); all call sites updated, `# noqa: SLF001` suppressor removed.
- `_flush_orphan_tool_uses_to_session` and `_InterruptedAttempt.finalize` both return `list[StreamBaseResponse]`; the post-loop caller yields those events directly to avoid double-flush and skipped UI cleanup events.
- The three former post-loop blocks (partial restore + redundant re-flush + two separate `yield StreamError` sites) are collapsed into a single block driven by `_classify_final_failure` returning a `_FinalFailure(display_msg, code, retryable)` dataclass, so history marker and SSE yield share one source of truth.
Do NOT flag double-flush risk or mismatched history/SSE marker as issues in the post-loop section of `stream_chat_completion_sdk`.
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Use the template in `.github/PULL_REQUEST_TEMPLATE.md` for pull requests, rely on pre-commit checks for linting and formatting, fill out the Changes section and checklist, use conventional commit titles with scope, keep out-of-scope changes under 20% of the PR, ensure PR descriptions are complete, and use linear ticket branch structure
📚 Learning: 2026-04-13T13:11:00.401Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/EmptySession/EmptySession.tsx:41-42
Timestamp: 2026-04-13T13:11:00.401Z
Learning: In Significant-Gravitas/AutoGPT `autogpt_platform/frontend`, unconditional React Query hook calls (e.g. `usePulseChips()` in `EmptySession.tsx`) are intentional when the underlying data is expected to be cached from prior page visits. The team considers the fetch cost acceptable in these cases and does not require `enabled` gating purely for feature-flag-disabled paths. Do not flag unconditional query hooks as wasteful when caching makes the cost negligible.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-03-24T02:05:08.144Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/CopilotPage.tsx:0-0
Timestamp: 2026-03-24T02:05:08.144Z
Learning: In `Significant-Gravitas/AutoGPT` (autogpt_platform frontend), when gating logic on a React Query result being available (e.g., `useGetV2GetCopilotUsage`), prefer destructuring `isSuccess` (e.g., `const { data, isSuccess: hasUsage } = useQuery(...)`) over checking `!isLoading`. `isLoading` can be `false` in error/idle states where `data` is still `undefined`, while `isSuccess` guarantees the query completed successfully and `data` is populated. This pattern was established in `CopilotPage.tsx` (PR `#12526`, commit e9dfd1f76).

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-22T05:57:38.198Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12879
File: autogpt_platform/backend/backend/copilot/baseline/service.py:0-0
Timestamp: 2026-04-22T05:57:38.198Z
Learning: In `autogpt_platform/backend/backend/copilot/baseline/service.py`, the approved pattern for `_run_task_subagent` (PR `#12879`, commit 187f0a5) uses a nested `try/except Exception` inside an outer `try/finally`. The outer `finally` block resets `_TASK_DEPTH_VAR` (via `_TASK_DEPTH_VAR.reset(token)`) AND calls `_absorb_inner_usage(parent_state, inner_state)` unconditionally, so both the depth ContextVar and usage roll-up are guaranteed on all exit paths including `CancelledError`/`KeyboardInterrupt`/`SystemExit`. The inner `except Exception` catches and converts failures into a `TaskResponse` error payload that is returned as `StreamToolOutputAvailable`. Do NOT flag missing ContextVar reset or usage roll-up on BaseException paths in this function.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-14T06:34:02.835Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12774
File: autogpt_platform/backend/backend/copilot/tools/e2b_sandbox.py:0-0
Timestamp: 2026-04-14T06:34:02.835Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/e2b_sandbox.py`, the `asyncio.wait_for()` retry loop around `AsyncSandbox.create()` (introduced in PR `#12774`) can leak up to `_SANDBOX_CREATE_MAX_RETRIES - 1` (≤2) orphaned E2B sandboxes per hang incident because `wait_for` cancels only the client-side wait while E2B may complete server-side provisioning. With the default `on_timeout="pause"` lifecycle, leaked orphaned sandboxes are **paused** (not killed) when their original `end_at` is reached and persist indefinitely until explicitly killed — there is NO automatic E2B project-level cleanup. Operators must manage these manually or via their own cleanup jobs. The sandbox_id is not accessible from the timed-out coroutine, so recovery via `AsyncSandbox.connect(sandbox_id)` is not possible at timeout. This is an intentionally accepted trade-off; a proper fix is deferred to a follow-up PR. Do NOT flag the retry loop as a blocking issue.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-03-16T16:30:20.657Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/threads.py:80-102
Timestamp: 2026-03-16T16:30:20.657Z
Learning: In autogpt_platform/backend/backend/blocks/agent_mail/ (and other blocks under autogpt_platform/backend/backend/blocks/), the block executor framework (backend/executor/manager.py lines ~708-733) automatically catches all uncaught exceptions from a block's `run()` method and emits them on the `"error"` output. Explicit try/except blocks within `run()` are therefore not required for standard error propagation — they are only needed when partial output behaviour must be controlled (e.g., preventing some outputs from being yielded on failure, as in attachment blocks). This is the standard pattern across the codebase.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-23T00:07:27.130Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.130Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py`, background tasks that persist cost or emit Langfuse backfill (e.g. the cost-reconcile task) must be anchored to `_background_tasks` using `_background_tasks.add(task)` and `task.add_done_callback(_background_tasks.discard)`, mirroring the existing pattern at lines 3063 / 4232 / 4256. This prevents the asyncio task from being garbage-collected before persistence or Langfuse emission completes. Do NOT flag the absence of this anchoring as acceptable in this file. Established in PR `#12889` commit 5ce3d0388.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-07T18:08:03.548Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12701
File: .claude/skills/orchestrate/scripts/verify-complete.sh:120-121
Timestamp: 2026-04-07T18:08:03.548Z
Learning: In Significant-Gravitas/AutoGPT, verify-complete.sh (`.claude/skills/orchestrate/scripts/verify-complete.sh`) uses `commits[-1].committedDate` (not `updatedAt`) to identify stale CHANGES_REQUESTED reviews. This is intentional: `updatedAt` changes on any PR activity (bot comments, label changes, description edits), which would falsely classify a reviewer's CHANGES_REQUESTED as stale — a silent false negative. The `committedDate` edge case (commit created locally before a review but pushed after) only causes a false positive (unnecessary re-brief), which is the safer failure mode. Do not suggest switching to `updatedAt` for this comparison.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-03-16T16:30:30.764Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:30:30.764Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, explicit try/except in the `run()` method is NOT required for standard error handling. The block framework's `_execute()` method in `_base.py` catches unhandled exceptions and re-raises them as `BlockExecutionError` or `BlockUnknownError`. Additionally, when a block yields `("error", message)`, `_execute()` immediately raises `BlockExecutionError` — so the `error` output port never propagates downstream. Explicit try/except is only needed when partial output must be controlled (e.g., attachment blocks that must skip yielding `content_base64` on failure).

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-03-16T16:32:29.430Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:32:29.430Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, the Block base class `execute()` method in `backend/blocks/_base.py` already wraps `run()` in a try/except that converts uncaught exceptions into `BlockExecutionError`/`BlockUnknownError`. Therefore, explicit try/except in individual block `run()` methods is redundant and not the established pattern (e.g., Gmail, Slack, Todoist blocks omit it). Exception: blocks like attachment blocks that need to distinguish between success and error yield paths within the generator use explicit try/except for branching control, not for the framework's error routing.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-25T02:53:53.964Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-25T02:53:53.964Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py` (PR `#12918`, commit 6576bf561):
- `_flush_unresolved_tool_calls` was renamed to `flush_unresolved_tool_calls` (public); all call sites updated, `# noqa: SLF001` suppressor removed.
- `_flush_orphan_tool_uses_to_session` and `_InterruptedAttempt.finalize` both return `list[StreamBaseResponse]`; the post-loop caller yields those events directly to avoid double-flush and skipped UI cleanup events.
- The three former post-loop blocks (partial restore + redundant re-flush + two separate `yield StreamError` sites) are collapsed into a single block driven by `_classify_final_failure` returning a `_FinalFailure(display_msg, code, retryable)` dataclass, so history marker and SSE yield share one source of truth.
Do NOT flag double-flush risk or mismatched history/SSE marker as issues in the post-loop section of `stream_chat_completion_sdk`.

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py
📚 Learning: 2026-04-15T02:06:40.213Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/util/workspace.py:198-221
Timestamp: 2026-04-15T02:06:40.213Z
Learning: In `autogpt_platform/backend/backend/util/workspace.py`, the TOCTOU gap between the `get_workspace_total_size()` pre-check and the subsequent storage write + DB insert in `WorkspaceManager.write_file()` is an accepted trade-off. Reasons: (1) the workspace is single-user-scoped, so a true race requires precise concurrent timing from the same user; (2) the REST upload route (`autogpt_platform/backend/backend/api/features/workspace/routes.py`) already has a post-write quota check with soft-delete rollback as a safety net for that path; (3) adding the same rollback inside `write_file()` would couple the manager to HTTP semantics. The pre-write check catches the overwhelming majority of cases. Do NOT flag this as a blocking TOCTOU issue.

Applied to files:

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

Applied to files:

  • .github/workflows/scripts/wait_for_upstream.py

Comment thread .github/workflows/scripts/wait_for_upstream.py
Comment thread .github/workflows/scripts/wait_for_upstream.py
Treat workflows still missing after the grace period as not-triggered
(proceed=false) so slow webhooks or path-filtered upstreams cannot let
the expensive E2E job through. Tie-break latest_per_workflow on
(run_number, run_attempt) so the most recent attempt wins.

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

@ntindle ntindle left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

discard everything not e2e full stack related

@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 🚧 Needs work in AutoGPT development kanban Apr 30, 2026
Comment on lines -8 to -10
- 'classic/original_autogpt/**'
- 'classic/forge/**'
- 'classic/direct_benchmark/**'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

let's keep these rather than classic/**.py;

Comment on lines -71 to -74
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please put this back, it doesn't save us anything and costs cross-version coverage

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

same below

@github-actions github-actions Bot added the conflicts Automatically applied to PRs with merge conflicts label May 6, 2026
@github-actions

github-actions Bot commented May 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.

@CLAassistant

CLAassistant commented May 11, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@Pwuts

Pwuts commented Jul 22, 2026

Copy link
Copy Markdown
Member

seems we don't really need this anymore, CI spend has been within bounds the past period

@Pwuts Pwuts closed this Jul 22, 2026
@github-project-automation github-project-automation Bot moved this to Done in Frontend Jul 22, 2026
@github-project-automation github-project-automation Bot moved this from 🚧 Needs work to ✅ Done in AutoGPT development kanban Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conflicts Automatically applied to PRs with merge conflicts size/l

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants