Skip to content

feat(copilot): standard/advanced model toggle with Opus rate-limit multiplier#12786

Merged
majdyz merged 16 commits into
devfrom
feat/copilot-model-targeting-flag
Apr 15, 2026
Merged

feat(copilot): standard/advanced model toggle with Opus rate-limit multiplier#12786
majdyz merged 16 commits into
devfrom
feat/copilot-model-targeting-flag

Conversation

@majdyz
Copy link
Copy Markdown
Contributor

@majdyz majdyz commented Apr 15, 2026

Why

Users have different task complexity needs. Sonnet is fast and cheap for most queries; Opus is more capable for hard reasoning tasks. Exposing this as a simple toggle gives users control without requiring infrastructure complexity.

Opus costs 5× more than Sonnet per Anthropic pricing ($15/$75 vs $3/$15 per M tokens). Rather than adding a separate entitlement gate, the rate-limit multiplier (5×) ensures Opus turns deplete the daily/weekly quota proportionally faster — users self-limit via their existing budget.

What

  • Standard/Advanced model toggle in the chat input toolbar (sky-blue star icon, label only when active — matches the simulation DryRunToggleButton pattern but visually distinct)
  • CopilotLlmModel = Literal["standard", "advanced"] — model-agnostic tier names (not tied to Anthropic model names)
  • Backend model resolution: "advanced"claude-opus-4-6, "standard"config.model (currently Sonnet)
  • Rate-limit multiplier: Opus turns count as 5× in Redis token counters (daily + weekly limits). Does not affect PlatformCostLog or cost_usd — those use real API-reported values
  • localStorage persistence via Key.COPILOT_MODEL so preference survives page refresh
  • claude_agent_max_budget_usd reduced from $15 to $10

How

Backend

  • CopilotLlmModel type added to config.py, imported in routes/executor/service
  • stream_chat_completion_sdk accepts model: CopilotLlmModel | None
  • Model tier resolved early in the SDK path; _normalize_model_name strips the OpenRouter provider prefix
  • model_cost_multiplier (1.0 or 5.0) computed from final resolved model name, passed to persist_and_record_usagerecord_token_usage (Redis only)
  • No separate LD flag needed — rate limit is the gate

Frontend

  • ModelToggleButton component: sky-blue, star icon, "Advanced" label when active
  • copilotModel state in useCopilotUIStore with localStorage hydration
  • copilotModelRef pattern in useCopilotStream (avoids recreating DefaultChatTransport)
  • Toggle gated behind showModeToggle && !isStreaming in ChatInput

Checklist

  • Tests added/updated (ModelToggleButton.test.tsx, service_helpers_test.py, token_tracking_test.py)
  • Rate-limit multiplier only affects Redis counters, not cost tracking
  • No new LD flag needed

majdyz added 3 commits April 15, 2026 11:46
Adds `Flag.COPILOT_MODEL` (string flag) and a `_resolve_user_model_override`
helper that fetches the flag value per-request and overrides the SDK model
for that user's turn.

- `feature_flag.py`: add `Flag.COPILOT_MODEL = "copilot-model"` and
  `_env_flag_override_string` for local dev/test string overrides
- `service.py`: after `_resolve_sdk_model()`, await user override and replace
  `sdk_model` if LD returns a non-empty string for the user
- Tests: 12 new tests for `_env_flag_override_string` and
  `_resolve_user_model_override` (all passing)

Local dev: set `FORCE_FLAG_COPILOT_MODEL=anthropic/claude-opus-4-6` (or
`NEXT_PUBLIC_FORCE_FLAG_COPILOT_MODEL`) to route all users to Opus without
touching LaunchDarkly.
… user_id to log, add LD flag key test

Self-review fixes:
- `env_flag_string_override`: remove leading underscore — function is part
  of the public API surface (used across modules), private prefix was wrong
- `_resolve_user_model_override`: include truncated user_id in the override
  log line for easier correlation in prod logs
- Add test asserting get_feature_flag_value is called with the correct flag
  key ("copilot-model") and user_id
…ltiplier

Add a per-request model tier toggle to CoPilot. Users can switch between
Standard (Sonnet) and Advanced (Opus) from the chat input toolbar.
Opus turns consume rate-limit quota 5× faster (matching Anthropic pricing),
so no separate entitlement gate is needed — usage self-limits via the budget.

- Add CopilotLlmModel = Literal["standard", "advanced"] type
- ModelToggleButton (sky-blue, star icon, label only when active)
- localStorage persistence via Key.COPILOT_MODEL
- Backend: model tier passed in request body, resolved to actual model name
- Rate-limit multiplier 5.0 for Opus in record_token_usage (Redis only,
  does not affect PlatformCostLog or cost_usd — those use real API values)
- Reduce claude_agent_max_budget_usd default from $15 to $10
@majdyz majdyz requested a review from a team as a code owner April 15, 2026 05:30
@majdyz majdyz requested review from Bentlybro and Swiftyos and removed request for a team April 15, 2026 05:30
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Apr 15, 2026
@github-actions github-actions Bot added platform/frontend AutoGPT Platform - Front end platform/backend AutoGPT Platform - Back end size/l labels Apr 15, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 15, 2026

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds an optional per-request Copilot LLM model-tier ("standard" | "advanced") end-to-end: frontend toggle and persisted store state, API/schema change, server-side resolution (env > LD > request > config), threading model into enqueue/processor/stream, and applying a model_cost_multiplier into usage persistence and rate limiting.

Changes

Cohort / File(s) Summary
Backend API & Execution
autogpt_platform/backend/backend/api/features/chat/routes.py, autogpt_platform/backend/backend/copilot/executor/utils.py, autogpt_platform/backend/backend/copilot/executor/processor.py
Added optional model to StreamChatRequest; threaded model into enqueue_copilot_turn / CoPilotExecutionEntry and passed into stream invocation.
Backend Config & Feature Flags
autogpt_platform/backend/backend/copilot/config.py, autogpt_platform/backend/backend/util/feature_flag.py
Added CopilotLlmModel = Literal["standard","advanced"], new Flag.COPILOT_MODEL, env_flag_string_override() helper; lowered claude_agent_max_budget_usd default 15.0→10.0.
Backend SDK / Service Logic
autogpt_platform/backend/backend/copilot/sdk/service.py
Added per-user/env/request model resolution helpers, _resolve_model_and_multiplier, new model parameter on stream_chat_completion_sdk, and computed model_cost_multiplier used for SDK selection and usage recording.
Backend Token Tracking & Rate Limiting
autogpt_platform/backend/backend/copilot/token_tracking.py, autogpt_platform/backend/backend/copilot/rate_limit.py
Propagated model_cost_multiplier into persist/record paths; record_token_usage gains model_cost_multiplier (clamped ≥1.0), scales/rounds weighted token costs and logs multiplier.
Backend Tests
autogpt_platform/backend/backend/copilot/sdk/service_helpers_test.py, autogpt_platform/backend/backend/copilot/token_tracking_test.py, autogpt_platform/backend/backend/util/feature_flag_test.py, autogpt_platform/backend/backend/copilot/sdk/p0_guardrails_test.py
Added tests for model normalization and LD/env overrides; updated mocks/assertions for multiplier propagation and adjusted default-budget expectation.
Frontend Store & Persistence
autogpt_platform/frontend/src/app/(platform)/copilot/store.ts, autogpt_platform/frontend/src/services/storage/local-storage.ts
Added CopilotLlmModel type and copilotLlmModel state + setter persisted to Key.COPILOT_MODEL; renamed copilotModecopilotChatMode and updated reset/persistence behavior.
Frontend UI & Hooks
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx, autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/components/ModelToggleButton.tsx, autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts, autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotStream.ts
Added ModelToggleButton and toggle handler; wired copilotLlmModel through page/hook into outbound stream payload; updated hook API to accept copilotModel.
Frontend Tests
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/components/__tests__/ModelToggleButton.test.tsx, autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts, autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
Added tests for the model toggle component; updated store and ChatInput tests to use copilotChatMode, include copilotLlmModel, and verify setter interactions.
API Schema
autogpt_platform/frontend/src/app/api/openapi.json
Added model property to StreamChatRequest schema supporting "standard", "advanced", or null (server-side resolution).

Sequence Diagram(s)

sequenceDiagram
    participant User as Frontend/User
    participant UI as ChatInput UI
    participant Store as Copilot UI Store
    participant API as Backend API
    participant SDK as Copilot SDK/Service
    participant LD as LaunchDarkly
    participant Exec as Executor
    participant Tracker as Token Tracker

    User->>UI: toggle model
    UI->>Store: setCopilotLlmModel("advanced"|"standard")
    Store->>Store: persist Key.COPILOT_MODEL

    UI->>API: POST /stream-chat (model=<selected>|null)
    API->>SDK: stream_chat_completion_sdk(..., model=request.model)
    SDK->>LD: get_feature_flag_value(user_id, "copilot-model")
    LD-->>SDK: flag value or None
    SDK->>SDK: resolve final sdk_model and model_cost_multiplier (env > LD > request > config)
    SDK->>Exec: enqueue_copilot_turn(..., model=resolved_model)
    Exec->>Tracker: persist_and_record_usage(..., model_cost_multiplier)
    Tracker->>Tracker: apply multiplier (clamp ≥1.0), round, update counters
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Swiftyos
  • Bentlybro

"I hopped and flipped a little switch,
Advanced or standard—pick which!
From store to stream I carry the tune,
Tokens counted under moon,
Hop on, copilot—let's launch soon!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(copilot): standard/advanced model toggle with Opus rate-limit multiplier' directly and clearly describes the main changes in the changeset: a new standard/advanced model toggle feature and rate-limit multiplier for Opus.
Description check ✅ Passed The description provides detailed context on the feature's motivation (user control over model complexity), implementation approach (rate-limit multiplier instead of separate entitlement), and specific technical changes across frontend and backend components.

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

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 15, 2026

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

  • fix(copilot): prevent 524 timeout on chat deletion by deferring cleanup #12668 (Otto-AGPT · updated 11d ago)

    • .gitignore (1 conflict, ~4 lines)
    • autogpt_platform/backend/backend/api/features/admin/rate_limit_admin_routes.py (2 conflicts, ~32 lines)
    • autogpt_platform/backend/backend/api/features/admin/rate_limit_admin_routes_test.py (3 conflicts, ~60 lines)
    • autogpt_platform/backend/backend/api/features/chat/routes.py (5 conflicts, ~22 lines)
    • autogpt_platform/backend/backend/api/features/chat/routes_test.py (4 conflicts, ~151 lines)
    • autogpt_platform/backend/backend/blocks/ai_condition.py (1 conflict, ~6 lines)
    • autogpt_platform/backend/backend/blocks/ai_condition_test.py (3 conflicts, ~52 lines)
    • autogpt_platform/backend/backend/blocks/autopilot.py (1 conflict, ~6 lines)
    • autogpt_platform/backend/backend/blocks/orchestrator.py (9 conflicts, ~77 lines)
    • autogpt_platform/backend/backend/blocks/test/test_llm.py (1 conflict, ~295 lines)
    • autogpt_platform/backend/backend/copilot/baseline/service.py (12 conflicts, ~360 lines)
    • autogpt_platform/backend/backend/copilot/db.py (3 conflicts, ~89 lines)
    • autogpt_platform/backend/backend/copilot/model.py (2 conflicts, ~8 lines)
    • autogpt_platform/backend/backend/copilot/prompting.py (1 conflict, ~18 lines)
    • autogpt_platform/backend/backend/copilot/rate_limit.py (4 conflicts, ~16 lines)
    • autogpt_platform/backend/backend/copilot/rate_limit_test.py (3 conflicts, ~944 lines)
    • autogpt_platform/backend/backend/copilot/reset_usage_test.py (11 conflicts, ~92 lines)
    • autogpt_platform/backend/backend/copilot/sdk/agent_generation_guide.md (1 conflict, ~13 lines)
    • autogpt_platform/backend/backend/copilot/sdk/e2b_file_tools.py (5 conflicts, ~160 lines)
    • autogpt_platform/backend/backend/copilot/sdk/e2b_file_tools_test.py (3 conflicts, ~760 lines)
    • autogpt_platform/backend/backend/copilot/sdk/env.py (4 conflicts, ~139 lines)
    • autogpt_platform/backend/backend/copilot/sdk/env_test.py (10 conflicts, ~125 lines)
    • autogpt_platform/backend/backend/copilot/sdk/retry_scenarios_test.py (1 conflict, ~267 lines)
    • autogpt_platform/backend/backend/copilot/sdk/service.py (6 conflicts, ~244 lines)
    • autogpt_platform/backend/backend/copilot/sdk/service_test.py (2 conflicts, ~73 lines)
    • autogpt_platform/backend/backend/copilot/sdk/thinking_blocks_test.py (8 conflicts, ~53 lines)
    • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py (8 conflicts, ~316 lines)
    • autogpt_platform/backend/backend/copilot/sdk/tool_adapter_test.py (6 conflicts, ~254 lines)
    • autogpt_platform/backend/backend/copilot/sdk/transcript.py (1 conflict, ~1078 lines)
    • autogpt_platform/backend/backend/copilot/tools/ask_question.py (5 conflicts, ~175 lines)
    • autogpt_platform/backend/backend/copilot/tools/ask_question_test.py (3 conflicts, ~301 lines)
    • autogpt_platform/backend/backend/copilot/tools/find_block.py (2 conflicts, ~9 lines)
    • autogpt_platform/backend/backend/copilot/tools/run_agent.py (3 conflicts, ~16 lines)
    • autogpt_platform/backend/backend/copilot/tools/run_block.py (3 conflicts, ~21 lines)
    • autogpt_platform/backend/backend/copilot/tools/test_dry_run.py (4 conflicts, ~208 lines)
    • autogpt_platform/backend/backend/copilot/tools/workspace_files.py (1 conflict, ~4 lines)
    • autogpt_platform/backend/backend/executor/manager.py (1 conflict, ~18 lines)
    • autogpt_platform/backend/backend/executor/simulator_test.py (2 conflicts, ~43 lines)
    • autogpt_platform/backend/backend/util/service.py (1 conflict, ~21 lines)
    • autogpt_platform/backend/poetry.lock (1 conflict, ~5 lines)
    • autogpt_platform/backend/snapshots/get_rate_limit (1 conflict, ~4 lines)
    • autogpt_platform/backend/snapshots/reset_user_usage_daily_and_weekly (1 conflict, ~4 lines)
    • autogpt_platform/backend/snapshots/reset_user_usage_daily_only (1 conflict, ~4 lines)
    • autogpt_platform/frontend/AGENTS.md (3 conflicts, ~20 lines)
    • autogpt_platform/frontend/package.json (1 conflict, ~7 lines)
    • autogpt_platform/frontend/src/app/(no-navbar)/onboarding/components/ProgressBar.tsx (1 conflict, ~9 lines)
    • autogpt_platform/frontend/src/app/(no-navbar)/onboarding/components/SelectableCard.tsx (3 conflicts, ~17 lines)
    • autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/PainPointsStep.tsx (5 conflicts, ~43 lines)
    • autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/RoleStep.tsx (5 conflicts, ~88 lines)
    • autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/WelcomeStep.tsx (3 conflicts, ~46 lines)
    • autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/usePainPointsStep.ts (5 conflicts, ~48 lines)
    • autogpt_platform/frontend/src/app/(no-navbar)/onboarding/store.ts (2 conflicts, ~9 lines)
    • autogpt_platform/frontend/src/app/(platform)/admin/rate-limits/components/RateLimitDisplay.tsx (4 conflicts, ~84 lines)
    • autogpt_platform/frontend/src/app/(platform)/admin/rate-limits/components/RateLimitManager.tsx (1 conflict, ~4 lines)
    • autogpt_platform/frontend/src/app/(platform)/admin/rate-limits/components/useRateLimitManager.ts (9 conflicts, ~113 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/CopilotPage.tsx (4 conflicts, ~85 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (1 conflict, ~5 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/MessagePartRenderer.tsx (1 conflict, ~5 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/helpers.test.ts (2 conflicts, ~408 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/helpers.ts (1 conflict, ~23 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/helpers/convertChatSessionToUiMessages.ts (4 conflicts, ~22 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/store.ts (4 conflicts, ~100 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/useChatSession.ts (2 conflicts, ~11 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts (2 conflicts, ~9 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotStream.ts (1 conflict, ~14 lines)
    • autogpt_platform/frontend/src/app/api/openapi.json (1 conflict, ~7 lines)
    • autogpt_platform/frontend/src/playwright/utils/onboarding.ts (6 conflicts, ~59 lines)
    • autogpt_platform/frontend/src/services/feature-flags/use-get-flag.ts (2 conflicts, ~12 lines)
    • autogpt_platform/frontend/src/services/storage/local-storage.ts (1 conflict, ~9 lines)
    • autogpt_platform/frontend/src/tests/AGENTS.md (8 conflicts, ~68 lines)
    • autogpt_platform/frontend/src/tests/pages/login.page.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/signin.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/vitest.config.mts (1 conflict, ~4 lines)
    • codecov.yml (3 conflicts, ~61 lines)
    • docs/integrations/block-integrations/misc.md (1 conflict, ~5 lines)
  • feat(platform): add first-class org/workspace support — schema, auth, APIs, migration, frontend #12670 (ntindle · updated 12h ago)

    • .claude/skills/pr-address/SKILL.md (1 conflict, ~11 lines)
    • .github/workflows/platform-fullstack-ci.yml (1 conflict, ~11 lines)
    • autogpt_platform/backend/backend/api/features/chat/routes.py (1 conflict, ~8 lines)
    • autogpt_platform/backend/backend/api/features/chat/routes_test.py (2 conflicts, ~104 lines)
    • autogpt_platform/backend/backend/blocks/agent.py (1 conflict, ~5 lines)
    • autogpt_platform/backend/backend/blocks/orchestrator.py (2 conflicts, ~32 lines)
    • autogpt_platform/backend/backend/blocks/test/test_llm.py (1 conflict, ~295 lines)
    • autogpt_platform/backend/backend/copilot/baseline/service.py (8 conflicts, ~72 lines)
    • autogpt_platform/backend/backend/copilot/config.py (2 conflicts, ~19 lines)
    • autogpt_platform/backend/backend/copilot/db.py (2 conflicts, ~59 lines)
    • autogpt_platform/backend/backend/copilot/executor/processor.py (1 conflict, ~4 lines)
    • autogpt_platform/backend/backend/copilot/executor/utils.py (5 conflicts, ~43 lines)
    • autogpt_platform/backend/backend/copilot/sdk/e2b_file_tools.py (3 conflicts, ~149 lines)
    • autogpt_platform/backend/backend/copilot/sdk/e2b_file_tools_test.py (1 conflict, ~739 lines)
    • autogpt_platform/backend/backend/copilot/sdk/retry_scenarios_test.py (1 conflict, ~267 lines)
    • autogpt_platform/backend/backend/copilot/sdk/service.py (10 conflicts, ~277 lines)
    • autogpt_platform/backend/backend/copilot/sdk/service_test.py (2 conflicts, ~67 lines)
    • autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py (6 conflicts, ~130 lines)
    • autogpt_platform/backend/backend/copilot/sdk/tool_adapter_test.py (2 conflicts, ~222 lines)
    • autogpt_platform/backend/backend/copilot/tools/find_block.py (2 conflicts, ~9 lines)
    • autogpt_platform/backend/backend/copilot/tools/run_agent.py (3 conflicts, ~61 lines)
    • autogpt_platform/backend/backend/copilot/tools/run_block.py (4 conflicts, ~29 lines)
    • autogpt_platform/backend/backend/copilot/tools/test_dry_run.py (4 conflicts, ~277 lines)
    • autogpt_platform/backend/backend/executor/manager.py (1 conflict, ~8 lines)
    • autogpt_platform/backend/backend/util/service.py (1 conflict, ~21 lines)
    • autogpt_platform/backend/poetry.lock (1 conflict, ~5 lines)
    • autogpt_platform/frontend/package.json (1 conflict, ~7 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx (1 conflict, ~8 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx (4 conflicts, ~63 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/helpers.ts (1 conflict, ~5 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/store.ts (2 conflicts, ~13 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/useChatSession.ts (1 conflict, ~8 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts (2 conflicts, ~11 lines)
    • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotStream.ts (4 conflicts, ~19 lines)
    • autogpt_platform/frontend/src/app/api/mutators/custom-mutator.ts (1 conflict, ~31 lines)
    • autogpt_platform/frontend/src/app/api/openapi.json (25 conflicts, ~537 lines)
    • autogpt_platform/frontend/src/services/feature-flags/use-get-flag.ts (2 conflicts, ~8 lines)
    • autogpt_platform/frontend/src/services/storage/local-storage.ts (2 conflicts, ~9 lines)
    • autogpt_platform/frontend/src/tests/agent-activity.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/agent-dashboard.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/api-keys.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/build.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/library.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/marketplace-agent.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/marketplace-creator.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/marketplace.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/pages/login.page.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/profile-form.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/profile.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/publish-agent.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/settings.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/signin.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/signup.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/title.spec.ts (deleted here, modified there)
    • autogpt_platform/frontend/src/tests/util.spec.ts (deleted here, modified there)
    • docs/integrations/block-integrations/misc.md (1 conflict, ~5 lines)
  • feat(copilot): queue follow-up messages on busy sessions (UI + run_sub_session + AutoPilot block) #12737 (majdyz · updated 36m ago)

    • 📁 autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/
      • ChatInput.test.tsx (2 conflicts, ~163 lines)
  • fix(backend/copilot): idempotency guard + frontend dedup fix for duplicate messages #12788 (majdyz · updated 9m ago)

    • 📁 autogpt_platform/backend/backend/api/features/chat/
      • routes.py (1 conflict, ~31 lines)
  • feat(backend): MemoryEnvelope metadata model, scoped retrieval, and memory hardening #12765 (ntindle · updated 11m ago)

    • 📁 autogpt_platform/backend/backend/copilot/sdk/
      • service.py (1 conflict, ~8 lines)
  • feat(frontend): add Agent Briefing Panel #12764 (0ubbe · updated 3h ago)

    • 📁 autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/
      • ChatInput.tsx (1 conflict, ~6 lines)

🟡 Medium Risk — Some Line Overlap

These PRs have some overlapping changes:

  • [TMP] [TESTING] merge(preview): consolidated preview of 5 active PRs #12783 (majdyz · updated 3h ago)
    • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts: L42-49, L78-86
    • autogpt_platform/backend/backend/copilot/sdk/service_helpers_test.py: L20-26, L353-400
    • autogpt_platform/backend/backend/copilot/sdk/service.py: L56-62, L132-142, L674-679, L699-726, L2155-2160, L2165-2170, L2279-2284, L2333-2338, L2490-2496, L3175-3182
    • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx: L8-28, L107-112, L141-147, L149-155, L157-161, L187-189, L195-204, L230-263
    • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx: L13-19, L50-77, L84-99, L198-207, L222-235
    • autogpt_platform/backend/backend/api/features/chat/routes.py: L15-21, L139-144, L146-149, L891-902

🟢 Low Risk — File Overlap Only

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

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


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

Comment thread autogpt_platform/backend/backend/copilot/sdk/service.py
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 15, 2026

Codecov Report

❌ Patch coverage is 85.29412% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.63%. Comparing base (da18f37) to head (432202c).
⚠️ Report is 1 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #12786      +/-   ##
==========================================
- Coverage   64.64%   64.63%   -0.01%     
==========================================
  Files        1819     1820       +1     
  Lines      133985   134044      +59     
  Branches    14428    14433       +5     
==========================================
+ Hits        86615    86644      +29     
- Misses      44671    44696      +25     
- Partials     2699     2704       +5     
Flag Coverage Δ
platform-backend 75.46% <80.00%> (+<0.01%) ⬆️
platform-frontend 18.98% <85.18%> (+0.05%) ⬆️
platform-frontend-e2e 30.09% <21.42%> (-0.40%) ⬇️

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

Components Coverage Δ
Platform Backend 75.46% <80.00%> (+<0.01%) ⬆️
Platform Frontend 26.92% <92.85%> (-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.

majdyz added 2 commits April 15, 2026 12:36
…el name

- Rename store state: copilotMode → copilotChatMode, copilotModel → copilotLlmModel
  (matching the CopilotMode/CopilotLlmModel type names for consistency)
- Inline model_cost_multiplier into the advanced/standard/else branches
  (cleaner — no separate computation block after the if/else)
- Fix model name in PlatformCostLog: pass sdk_model instead of config.model
  so cost dashboard shows "claude-opus-4-6" when Opus is actually used
- Fix stale docstring: 'opus'/'sonnet' → 'advanced'/'standard'
…icant-Gravitas/AutoGPT into feat/copilot-model-targeting-flag
@github-actions github-actions Bot added size/xl and removed size/l labels Apr 15, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
autogpt_platform/backend/backend/copilot/sdk/service.py (1)

2556-2563: Consider extracting the cost multiplier constant to module level.

The multiplier logic is correct (5× aligns with Opus/Sonnet pricing ratio). However, _OPUS_COST_MULTIPLIER is defined inside the function body, which is inconsistent with other module-level constants like _MAX_STREAM_ATTEMPTS and _EMPTY_TOOL_CALL_LIMIT.

♻️ Suggested refactor

Move the constant to module level (e.g., near line 138 with other constants):

+# Cost multiplier for Opus model turns — Opus is ~5× more expensive than Sonnet
+# ($15/$75 vs $3/$15 per M tokens).  Applied to rate-limit counters so Opus
+# turns deplete quota proportionally faster.
+_OPUS_COST_MULTIPLIER = 5.0
+
 _EMPTY_TOOL_CALL_LIMIT = 5

Then at line 2560:

-        _OPUS_COST_MULTIPLIER = 5.0
         model_cost_multiplier = (
             _OPUS_COST_MULTIPLIER if sdk_model and "opus" in sdk_model else 1.0
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/copilot/sdk/service.py` around lines 2556 -
2563, Move the local constant _OPUS_COST_MULTIPLIER out of the function and
declare it at module level alongside other constants like _MAX_STREAM_ATTEMPTS
and _EMPTY_TOOL_CALL_LIMIT; then remove the in-function definition and keep the
existing computation that sets model_cost_multiplier = (_OPUS_COST_MULTIPLIER if
sdk_model and "opus" in sdk_model else 1.0) so behavior is unchanged. Ensure the
module-level _OPUS_COST_MULTIPLIER is named exactly the same and referenced by
the model_cost_multiplier expression (which uses sdk_model) so no other callers
need changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@autogpt_platform/backend/backend/copilot/sdk/service.py`:
- Around line 2556-2563: Move the local constant _OPUS_COST_MULTIPLIER out of
the function and declare it at module level alongside other constants like
_MAX_STREAM_ATTEMPTS and _EMPTY_TOOL_CALL_LIMIT; then remove the in-function
definition and keep the existing computation that sets model_cost_multiplier =
(_OPUS_COST_MULTIPLIER if sdk_model and "opus" in sdk_model else 1.0) so
behavior is unchanged. Ensure the module-level _OPUS_COST_MULTIPLIER is named
exactly the same and referenced by the model_cost_multiplier expression (which
uses sdk_model) so no other callers need changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c2ff2fd1-eb6b-4e89-a5cf-f16ac91ea6e9

📥 Commits

Reviewing files that changed from the base of the PR and between 55869d3 and dd2833d.

📒 Files selected for processing (18)
  • autogpt_platform/backend/backend/api/features/chat/routes.py
  • autogpt_platform/backend/backend/copilot/config.py
  • autogpt_platform/backend/backend/copilot/executor/processor.py
  • autogpt_platform/backend/backend/copilot/executor/utils.py
  • autogpt_platform/backend/backend/copilot/rate_limit.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/backend/backend/copilot/sdk/service_helpers_test.py
  • autogpt_platform/backend/backend/copilot/token_tracking.py
  • autogpt_platform/backend/backend/copilot/token_tracking_test.py
  • autogpt_platform/backend/backend/util/feature_flag.py
  • autogpt_platform/backend/backend/util/feature_flag_test.py
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/components/ModelToggleButton.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/components/__tests__/ModelToggleButton.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/store.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotStream.ts
  • autogpt_platform/frontend/src/services/storage/local-storage.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts (2)

183-203: Extend clearCopilotLocalData test to verify model-tier reset.

Line 193 checks copilotChatMode reset, but this flow now also resets copilotLlmModel. Adding this assertion will protect the new Standard/Advanced behavior from regressions.

Proposed patch
   it("resets state and clears localStorage keys", () => {
     useCopilotUIStore.getState().setCopilotChatMode("fast");
+    useCopilotUIStore.getState().setCopilotLlmModel("advanced");
     useCopilotUIStore.getState().setNotificationsEnabled(true);
     useCopilotUIStore.getState().toggleSound();
     useCopilotUIStore.getState().addCompletedSession("s1");

     useCopilotUIStore.getState().clearCopilotLocalData();

     const state = useCopilotUIStore.getState();
     expect(state.copilotChatMode).toBe("extended_thinking");
+    expect(state.copilotLlmModel).toBe("standard");
     expect(state.isNotificationsEnabled).toBe(false);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/frontend/src/app/`(platform)/copilot/__tests__/store.test.ts
around lines 183 - 203, The test for clearCopilotLocalData needs to assert that
the copilotLlmModel is reset to its default (to protect Standard/Advanced
regression); update the "clearCopilotLocalData" spec in store.test.ts to call
useCopilotUIStore.getState().clearCopilotLocalData() (already done) and add an
expectation on useCopilotUIStore.getState().copilotLlmModel (or the getter) to
equal the default model value (e.g., "standard" or whatever the store uses)
after the call, referencing the clearCopilotLocalData and copilotLlmModel
symbols.

15-26: Reset copilotLlmModel in beforeEach to keep tests isolated.

Line 17 currently resets only part of the store. Adding copilotLlmModel: "standard" here will prevent state leakage if a future test mutates model tier.

Proposed patch
   beforeEach(() => {
     window.localStorage.clear();
     useCopilotUIStore.setState({
       initialPrompt: null,
       sessionToDelete: null,
       isDrawerOpen: false,
       completedSessionIDs: new Set<string>(),
       isNotificationsEnabled: false,
       isSoundEnabled: true,
       showNotificationDialog: false,
       copilotChatMode: "extended_thinking",
+      copilotLlmModel: "standard",
     });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/frontend/src/app/`(platform)/copilot/__tests__/store.test.ts
around lines 15 - 26, The beforeEach setup in the test does not reset the
copilotLlmModel, which can cause cross-test state leakage; update the
useCopilotUIStore.setState invocation inside the beforeEach to include
copilotLlmModel: "standard" so the store is fully reset before each test (locate
the beforeEach block and the useCopilotUIStore.setState call in store.test.ts
and add the copilotLlmModel property to the state object).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@autogpt_platform/backend/backend/copilot/sdk/service.py`:
- Around line 2535-2560: The current per-request override sets
model_cost_multiplier based on the requested "model" value (e.g., in the branch
that handles model == "advanced" / "standard"), but that value is never
recomputed if sdk_model is later changed by the SDK fallback path; update the
logic so that after any fallback or final model resolution (i.e., anywhere
sdk_model may be reassigned after _normalize_model_name or fallback handling),
you recompute and persist both the effective model name and
model_cost_multiplier from the final sdk_model (use a check like "if sdk_model
and 'opus' in sdk_model then multiplier=5.0 else 1.0"), and ensure the persisted
"model" string reflects the final sdk_model rather than the original requested
override; modify the code paths that set sdk_model/model_cost_multiplier
(including the advanced/standard branches and the SDK fallback activation path)
to enforce this re-evaluation.
- Around line 3245-3247: The variables sdk_model and model_cost_multiplier must
be initialized before the try block to avoid UnboundLocalError when the early
return in the sdk_cwd exception handler skips their later assignments; add
default initializations (e.g., sdk_model: str | None = None and
model_cost_multiplier = 1.0) immediately before the try that contains the
sdk_cwd handling so the finally block (which uses sdk_model and
model_cost_multiplier) can always reference them safely.

---

Nitpick comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/__tests__/store.test.ts:
- Around line 183-203: The test for clearCopilotLocalData needs to assert that
the copilotLlmModel is reset to its default (to protect Standard/Advanced
regression); update the "clearCopilotLocalData" spec in store.test.ts to call
useCopilotUIStore.getState().clearCopilotLocalData() (already done) and add an
expectation on useCopilotUIStore.getState().copilotLlmModel (or the getter) to
equal the default model value (e.g., "standard" or whatever the store uses)
after the call, referencing the clearCopilotLocalData and copilotLlmModel
symbols.
- Around line 15-26: The beforeEach setup in the test does not reset the
copilotLlmModel, which can cause cross-test state leakage; update the
useCopilotUIStore.setState invocation inside the beforeEach to include
copilotLlmModel: "standard" so the store is fully reset before each test (locate
the beforeEach block and the useCopilotUIStore.setState call in store.test.ts
and add the copilotLlmModel property to the state object).
🪄 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: 0789cc68-4622-4b10-a797-133954bb80d2

📥 Commits

Reviewing files that changed from the base of the PR and between dd2833d and 2f8d9cc.

📒 Files selected for processing (6)
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/store.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/store.ts
📜 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: integration_test
  • GitHub Check: end-to-end tests
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (16)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}

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

autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development

Format frontend code using pnpm format

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/**/*.{tsx,ts}

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

autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/
'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/**/*.{ts,tsx}

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

autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend development

autogpt_platform/frontend/**/*.{ts,tsx}: Fully capitalize acronyms in symbols, e.g. graphID, useBackendAPI
Use function declarations (not arrow functions) for components and handlers
No dark: Tailwind classes — the design system handles dark mode
Use Next.js <Link> for internal navigation — never raw <a> tags
No any types unless the value genuinely can be anything
No linter suppressors (// @ts-ignore``, // eslint-disable) — fix the actual issue
Keep files under ~200 lines; extract sub-components or hooks into their own files when a file grows beyond this
Keep render functions and hooks under ~50 lines; extract named helpers or sub-components when they grow longer
Use generated API hooks from `@/app/api/generated/endpoints/` with pattern `use{Method}{Version}{OperationName}` and regenerate with `pnpm generate:api`
Do not use `useCallback` or `useMemo` unless asked to optimise a given function
Separate render logic (`.tsx`) from business logic (`use*.ts` hooks)
Use ErrorCard for render errors, toast for mutations, and Sentry for exceptions in the frontend

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

autogpt_platform/frontend/src/**/*.{ts,tsx}: Use generated API hooks from @/app/api/__generated__/endpoints/ following the pattern use{Method}{Version}{OperationName}, and regenerate with pnpm generate:api
Separate render logic from business logic using component.tsx + useComponent.ts + helpers.ts pattern, colocate state when possible and avoid creating large components, use sub-components in local /components folder
Use function declarations for components and handlers, use arrow functions only for callbacks
Do not use useCallback or useMemo unless asked to optimise a given function

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/**/*.{tsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
autogpt_platform/frontend/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Component props should use interface Props { ... } (not exported) unless the interface needs to be used outside the component

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
autogpt_platform/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never type with any, if no types available use unknown

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx}: Use Vitest + RTL + MSW for integration tests as the primary testing approach (~90%, page-level), use Playwright for E2E critical flows, and use Storybook for design system components
Run frontend integration tests with pnpm test:unit (Vitest + RTL + MSW)

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/src/app/(platform)/**/components/**/*.tsx

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

Put sub-components in local components/ folder

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
autogpt_platform/frontend/**/*.tsx

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

autogpt_platform/frontend/**/*.tsx: Component props should be type Props = { ... } (not exported) unless it needs to be used outside the component
Use design system components from src/components/ (atoms, molecules, organisms)
Never use src/components/__legacy__/*
Tailwind CSS only for styling, use design tokens, Phosphor Icons only

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
autogpt_platform/frontend/src/app/(platform)/**/__tests__/**/*.test.{ts,tsx}

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

Write integration tests in __tests__/ next to page.tsx using Vitest + RTL + MSW for new pages/features

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/src/**/__tests__/**/*.test.{ts,tsx}

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

Use Orval-generated MSW handlers from @/app/api/__generated__/endpoints/{tag}/{tag}.msw.ts for API mocking

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

No barrel files or index.ts re-exports in the frontend

Do not type hook returns, let Typescript infer as much as possible

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
autogpt_platform/frontend/src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Do not type hook returns, let Typescript infer as much as possible

Extract component logic into custom hooks grouped by concern, not by component. Each hook should represent a cohesive domain of functionality (e.g., useSearch, useFilters, usePagination) rather than bundling all state into one useComponentState hook. Put each hook in its own .ts file.

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
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/copilot/sdk/service.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
🧠 Learnings (32)
📓 Common learnings
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: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12566
File: autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts:968-974
Timestamp: 2026-03-26T00:32:06.673Z
Learning: In Significant-Gravitas/AutoGPT, the admin-facing methods in `autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts` (e.g., `addUserCredits`, `getUsersHistory`, `getUserRateLimit`, `resetUserRateLimit`) intentionally follow the legacy `BackendAPI` pattern with manually defined types in `autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts`. Migrating these admin endpoints to the generated OpenAPI hooks (`@/app/api/__generated__/endpoints/`) is a planned separate effort covering all admin endpoints together, not done piecemeal per PR. Do not flag individual admin type additions in `types.ts` as blocking issues.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/copilot/workflow_import/converter.py:0-0
Timestamp: 2026-03-17T10:57:12.953Z
Learning: In Significant-Gravitas/AutoGPT PR `#12440`, `autogpt_platform/backend/backend/copilot/workflow_import/converter.py` was fully rewritten (commit 732960e2d) to no longer make direct LLM/OpenAI API calls. The converter now builds a structured text prompt for AutoPilot/CoPilot instead. There is no `response.choices` access or any direct LLM client usage in this file. Do not flag `response.choices` access or LLM client initialization patterns as issues in this file.
Learnt from: 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: 12445
File: autogpt_platform/backend/backend/copilot/sdk/service.py:1071-1072
Timestamp: 2026-03-17T06:48:26.471Z
Learning: In Significant-Gravitas/AutoGPT (autogpt_platform), the AI SDK enforces `z.strictObject({type, errorText})` on SSE `StreamError` responses, so additional fields like `retryable: bool` cannot be added to `StreamError` or serialized via `to_sse()`. Instead, retry signaling for transient Anthropic API errors is done via the `COPILOT_RETRYABLE_ERROR_PREFIX` constant prepended to persisted session messages (in `ChatMessage.content`). The frontend detects retryable errors by checking `markerType === "retryable_error"` from `parseSpecialMarkers()` — no SSE schema changes and no string matching on error text. This pattern was established in PR `#12445`, commit 64d82797b.
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: classic/original_autogpt/CLAUDE.md:0-0
Timestamp: 2026-04-08T17:27:26.657Z
Learning: LLM model selection can be customized via environment variables: SMART_LLM, FAST_LLM, and TEMPERATURE. These are loaded during config initialization.
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: classic/forge/CLAUDE.md:0-0
Timestamp: 2026-04-08T17:27:07.646Z
Learning: Applies to classic/forge/**/forge/agent/**/*.py : Use MultiProvider to route LLM requests to correct provider based on model name (OpenAI, Anthropic, Groq)
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx:172-177
Timestamp: 2026-03-31T14:04:45.723Z
Learning: The Copilot frontend (autogpt_platform/frontend/src/app/(platform)/copilot/) does support dark mode. Dark mode Tailwind CSS variants (dark:*) are appropriate and intentional in copilot UI components to provide proper contrast in both light and dark themes. Do not flag dark: utilities in copilot components as incorrect.
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/src/tests/**/*.spec.ts : Import `test` and `expect` from `./coverage-fixture` instead of `playwright/test` in E2E tests to auto-collect V8 coverage per test for Codecov reporting

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:28:40.841Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:40.841Z
Learning: Applies to autogpt_platform/frontend/src/**/__tests__/**/*.test.{ts,tsx} : Use Orval-generated MSW handlers from `@/app/api/__generated__/endpoints/{tag}/{tag}.msw.ts` for API mocking

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:28:40.841Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:40.841Z
Learning: Applies to autogpt_platform/frontend/src/app/(platform)/**/__tests__/**/*.test.{ts,tsx} : Write integration tests in `__tests__/` next to `page.tsx` using Vitest + RTL + MSW for new pages/features

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/__tests__/main.test.tsx : Start integration tests at page level with a `main.test.tsx` file before splitting into smaller test files

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/*.test.{ts,tsx} : Place unit tests co-located with the file being tested: `Component.test.tsx` next to `Component.tsx`

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:27:45.740Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Applies to autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx} : Use Vitest + RTL + MSW for integration tests as the primary testing approach (~90%, page-level), use Playwright for E2E critical flows, and use Storybook for design system components

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:27:45.740Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Applies to autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx} : Run frontend integration tests with `pnpm test:unit` (Vitest + RTL + MSW)

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/__tests__/**/*.test.{ts,tsx} : Use `findBy...` methods in integration tests instead of `getBy...` methods to avoid flaky tests by waiting for elements to appear asynchronously

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-08T17:27:57.501Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:57.501Z
Learning: Applies to autogpt_platform/frontend/**/*.spec.{ts,tsx} : Create a failing test first using `.fixme` marker (Playwright) when fixing a bug or adding a feature, then implement the fix and remove the fixme marker

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/__tests__/**/*.test.{ts,tsx} : Place integration tests in a `__tests__` folder next to the component being tested

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-02-27T10:45:49.499Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunMCPTool/helpers.tsx:23-24
Timestamp: 2026-02-27T10:45:49.499Z
Learning: Prefer using generated OpenAPI types from '@/app/api/__generated__/' for payloads defined in openapi.json (e.g., MCPToolsDiscoveredResponse, MCPToolOutputResponse). Use inline TypeScript interfaces only for payloads that are SSE-stream-only and not exposed via OpenAPI. Apply this pattern to frontend tool components (e.g., RunMCPTool) and related areas where similar SSE/openapi-discrepancies occur; avoid re-implementing types when a generated type is available.

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
📚 Learning: 2026-03-24T02:05:04.672Z
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:04.672Z
Learning: When gating React component logic on a React Query result (e.g., hooks like `useQuery` / `useGetV2GetCopilotUsage`), prefer destructuring and checking `isSuccess` (or aliasing it to a meaningful boolean like `isSuccess: hasUsage`) instead of relying on `!isLoading`. Reason: `isLoading` can be `false` in error/idle states where `data` may still be `undefined`, while `isSuccess` indicates the query completed successfully and `data` is populated.

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
📚 Learning: 2026-03-24T02:23:31.305Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/RateLimitResetDialog/RateLimitResetDialog.tsx:0-0
Timestamp: 2026-03-24T02:23:31.305Z
Learning: In the Copilot platform UI code, follow the established Orval hook `onError` error-handling convention: first explicitly detect/handle `ApiError`, then read `error.response?.detail` (if present) as the primary message; if not available, fall back to `error.message`; and finally fall back to a generic string message. This convention should be used for generated Orval hooks even if the custom Orval mutator already maps details into `ApiError.message`, to keep consistency across hooks/components (e.g., `useCronSchedulerDialog.ts`, `useRunGraph.ts`, and rate-limit/reset flows).

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-03-31T14:04:42.444Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx:172-177
Timestamp: 2026-03-31T14:04:42.444Z
Learning: In the Copilot frontend components under autogpt_platform/frontend/src/app/(platform)/copilot/, Tailwind dark mode variants (e.g., `dark:*`) are intentional and should be allowed. Do not flag `dark:` utilities in these Copilot UI components as incorrect; they are used to ensure proper contrast and correct behavior in both light and dark themes.

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
📚 Learning: 2026-04-01T18:54:16.035Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 12633
File: autogpt_platform/frontend/src/app/(platform)/library/components/AgentFilterMenu/AgentFilterMenu.tsx:3-10
Timestamp: 2026-04-01T18:54:16.035Z
Learning: In the frontend, the legacy Select component at `@/components/__legacy__/ui/select` is an intentional, codebase-wide visual-consistency pattern. During code reviews, do not flag or block PRs merely for continuing to use this legacy Select. If a migration to the newer design-system Select is desired, bundle it into a single dedicated cleanup/migration PR that updates all Select usages together (e.g., avoid piecemeal replacements).

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-07T09:24:16.582Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12686
File: autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/__tests__/PainPointsStep.test.tsx:1-19
Timestamp: 2026-04-07T09:24:16.582Z
Learning: In Significant-Gravitas/AutoGPT’s `autogpt_platform/frontend` (Vite + `vitejs/plugin-react` with the automatic JSX transform), do not flag usages of React types/components (e.g., `React.ReactNode`) in `.ts`/`.tsx` files as missing `React` imports. Since the React namespace is made available by the project’s TS/Vite setup, an explicit `import React from 'react'` or `import type { ReactNode } ...` is not required; only treat it as missing if typechecking (e.g., `pnpm types`) would actually fail.

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-02T05:43:49.128Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12640
File: autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/WelcomeStep.tsx:13-13
Timestamp: 2026-04-02T05:43:49.128Z
Learning: Do not flag `import { Question } from "phosphor-icons/react"` as an invalid import. `Question` is a valid named export from `phosphor-icons/react` (as reflected in the package’s generated `.d.ts` files and re-exports via `dist/index.d.ts`), so it should be treated as a supported named export during code reviews.

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts
📚 Learning: 2026-04-13T13:11:07.445Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/components/SitrepItem/SitrepItem.tsx:143-145
Timestamp: 2026-04-13T13:11:07.445Z
Learning: In `autogpt_platform/frontend`, do not flag direct interpolation of `executionID` UUID strings into URL query parameters (e.g., `activeItem=${executionID}` in JSX/Next links). If the value is a UUID string matching `[0-9a-f-]`, it contains no reserved URL characters, so additional `encodeURIComponent` or Next.js object-based `href` encoding is unnecessary. Only treat it as an encoding issue if the query-param value is not guaranteed to be UUID-formatted (i.e., may include characters outside `[0-9a-f-]`).

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/*.stories.tsx : Place Storybook tests co-located with components: `Component.stories.tsx` next to `Component.tsx`

Applied to files:

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

Applied to files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
📚 Learning: 2026-04-13T14:19:19.341Z
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.

Applied to files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
📚 Learning: 2026-03-09T10:50:43.907Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-03-09T10:50:43.907Z
Learning: Repo: Significant-Gravitas/AutoGPT — File: autogpt_platform/backend/backend/blocks/llm.py
For xAI Grok models accessed via OpenRouter, the API returns `null` for `max_completion_tokens`. The convention in this codebase is to use the model's context window size as the `max_output_tokens` value in ModelMetadata. For example, Grok 3 uses 131072 (128k) and Grok 4 uses 262144 (256k). Do not flag these as incorrect max output token values.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • autogpt_platform/backend/backend/copilot/sdk/service.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/copilot/sdk/service.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/copilot/sdk/service.py
🔇 Additional comments (5)
autogpt_platform/frontend/src/app/(platform)/copilot/__tests__/store.test.ts (1)

157-180: copilotChatMode rename coverage looks correct.

The assertions and setter calls now match the updated store API and correctly preserve the non-persistence expectation for chat mode.

autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/ChatInput.test.tsx (2)

11-20: Store mock update is aligned with the new API surface.

Switching to copilotChatMode/setCopilotChatMode and including copilotLlmModel prevents drift from the updated Zustand store contract.


141-155: Toggle behavior assertions are correctly updated.

The click-path expectations now validate the renamed setter and the expected mode transitions.

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

682-701: Nice precedence order for override resolution.

Env override → LaunchDarkly → default is a clean sequence here, and the string guard keeps the untyped flag API from feeding non-string values into model resolution.


2180-2194: Good call keeping the request contract tier-based.

Accepting CopilotLlmModel here avoids leaking provider-specific model IDs into callers and keeps the transport contract stable if the backend mapping changes later.

Comment thread autogpt_platform/backend/backend/copilot/sdk/service.py Outdated
Comment thread autogpt_platform/backend/backend/copilot/sdk/service.py
majdyz added 2 commits April 15, 2026 13:09
…ant, UnboundLocalError guard, test coverage

- Extract _OPUS_COST_MULTIPLIER to module level alongside _MAX_STREAM_ATTEMPTS / _EMPTY_TOOL_CALL_LIMIT
- Extract _resolve_model_and_multiplier() helper to consolidate LD + request-tier model resolution
- Initialize sdk_model and model_cost_multiplier before the outer try block to prevent UnboundLocalError in finally when sdk_cwd setup returns early
- Add copilotLlmModel: "standard" to beforeEach store reset to prevent cross-test state leakage
- Assert copilotLlmModel resets to "standard" in clearCopilotLocalData test
@majdyz
Copy link
Copy Markdown
Contributor Author

majdyz commented Apr 15, 2026

🧪 E2E Test Report

E2E Test Report: PR #12786 — feat(copilot): standard/advanced model toggle

Date: 2026-04-15
Branch: feat/copilot-model-targeting-flag
Worktree: /Users/majdyz/Code/AutoGPT12

Environment

  • Docker services: all running (copilot_executor rebuilt with fixes)
  • Subscription mode: Claude OAuth token (CHAT_USE_CLAUDE_CODE_SUBSCRIPTION=true)
  • Feature flag override: NEXT_PUBLIC_FORCE_FLAG_CHAT_MODE_OPTION=true

Bugs Found & Fixed

Bug 1: UnboundLocalError: sdk_model (commit 88f20d8)

Root cause: Early return path (auth timeout) exited before sdk_model was assigned, but
the finally block referenced it. Fixed by initializing sdk_model = None before the try block.

Bug 2: standard model sent invalid model name (commit 3937d47)

Root cause: _resolve_model_and_multiplier used _normalize_model_name(config.model) for
standard, yielding "claude-sonnet-4" (invalid). In subscription mode, standard should be
None so the CLI uses the subscription default. Fixed by calling _resolve_sdk_model() instead.

Test Results

Scenario 1: Toggle button visible (flag enabled)

Steps: Navigate to /copilot with NEXT_PUBLIC_FORCE_FLAG_CHAT_MODE_OPTION=true
Expected: ModelToggleButton "Switch to Advanced model" appears in toolbar
Actual: Button visible ✓
Result: PASS

Scenario 2: Toggle button hidden when flag off

Steps: Unit tests in ChatInput.test.tsx cover this
Result: PASS (unit test)

Scenario 3: Standard state (default)

Steps: Open fresh copilot page
Expected: Button shows no "Advanced" label, aria-label = "Switch to Advanced model"
Actual: Confirmed in snapshot: button "Switch to Advanced model" [ref=e61]
Result: PASS
Screenshot: 03-standard-state-default.png

Scenario 4: Advanced state

Steps: Click "Switch to Advanced model"
Expected: Button shows "Advanced" label, toast fires
Actual: Button becomes "Switch to Standard model" with StaticText "Advanced", toast: "Switched to Advanced model"
Result: PASS
Screenshot: 04-advanced-state.png

Scenario 5: Toggle back to Standard

Steps: Click "Switch to Standard model"
Expected: Reverts to standard, no "Advanced" label
Actual: Confirmed ✓, toast: "Switched to Standard model"
Result: PASS
Screenshot: 05-standard-restored.png

Scenario 6: Hidden while streaming

Steps: Send a chat message, check for toggle during streaming
Expected: ModelToggleButton not rendered when isStreaming=true
Actual: Toggle count=0 while streaming confirmed
Result: PASS
Screenshot: 07-streaming-state.png

Scenario 7: Preference persists after reload

Steps: Set to Advanced, reload page
Expected: Still shows Advanced
Actual: After reload, button shows "Switch to Standard model" (Advanced active) ✓
Result: PASS
Screenshot: 06-persistence-after-reload.png

Scenario 8: model=standard in request body

Steps: POST /stream with {"model": "standard"}
Expected: Backend accepts, routes to subscription default
Actual: Response received, executor log: Per-request model override: standard (subscription-default)
Result: PASS

Scenario 9: model=advanced in request body

Steps: POST /stream with {"model": "advanced"}
Expected: Backend routes to claude-opus-4-6
Actual: Response received, executor log: Per-request model override: advanced (claude-opus-4-6)
Result: PASS

Scenario 10: model=null falls back to default

Steps: POST /stream with no model field
Expected: Uses server default (subscription default)
Actual: Response received correctly
Result: PASS

Scenario 11: Backend logs confirm model routing

Steps: Check executor logs after all API tests
Expected: Logs show "Per-request model override: advanced (claude-opus-4-6)"
Actual: Confirmed ✓
Result: PASS

Scenario 12: Chat with Standard model (browser)

Steps: Send "Say hi" via browser UI with standard model selected
Expected: Chat responds, executor uses subscription-default
Actual: Response: "Hi! I'm AutoPilot...", log: Per-request model override: standard (subscription-default)
Result: PASS
Screenshot: 08-chat-response.png

Summary

  • Total: 12 scenarios
  • Passed: 12
  • Failed: 0
  • Bugs found and fixed: 2
    1. UnboundLocalError on sdk_model in subscription mode auth timeout path
    2. standard model tier sent invalid model name instead of respecting subscription default

Screenshots

01-copilot-page.png
02-copilot-main.png
03-standard-state-default.png
04-advanced-state.png
05-standard-restored.png
06-persistence-after-reload.png
07-streaming-state.png
08-chat-response.png

majdyz added 3 commits April 15, 2026 13:47
…handler

Add describe block for ChatInput model toggle covering:
- render/hide based on feature flag
- standard→advanced and advanced→standard toggle calls
- hide when streaming
- toast notifications for both toggle directions

Also update store mock to use reactive mockCopilotLlmModel variable
and reset it in afterEach for test isolation.
Drop Flag.COPILOT_MODEL, env_flag_string_override, _resolve_user_model_override
and all associated tests — the UI toggle makes per-user LD targeting unnecessary.
Wire up Key.COPILOT_MODE the same way as Key.COPILOT_MODEL — read on init,
write on change, clear on clearCopilotLocalData.
@github-actions github-actions Bot added the conflicts Automatically applied to PRs with merge conflicts label Apr 15, 2026
@github-actions
Copy link
Copy Markdown
Contributor

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

majdyz added 2 commits April 15, 2026 14:59
- Keep both TestNormalizeModelName (model toggle) and TestTokenUsageNullSafety
  (merged from #12789) in service_helpers_test.py
- Add dedicated copilotLlmModel describe block: defaults, setter, localStorage
  persistence
- Assert clearCopilotLocalData also clears copilot-model localStorage key
@github-actions
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 Apr 15, 2026
…resetModules

The copilotChatMode and copilotLlmModel store fields are initialised from
localStorage via IIFEs that run once at module-load time. The existing tests
reset state with setState() which bypasses the initialiser, leaving the 'fast'
and 'advanced' branches uncovered for codecov patch.

Use vi.resetModules() + dynamic import to get a fresh store instance with
pre-populated localStorage, covering both initialiser branches.
Comment thread autogpt_platform/backend/backend/copilot/executor/utils.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform/backend AutoGPT Platform - Back end platform/frontend AutoGPT Platform - Front end size/l

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant