Skip to content

fix(frontend/copilot): fail a send at reset the server didn't set, bound the draft cache, ease far-off polling - #15591

Open
ntindle wants to merge 1 commit into
devfrom
claude/secrt-2959-send-at-reset-tidy-ups
Open

ntindle wants to merge 1 commit into
devfrom
claude/secrt-2959-send-at-reset-tidy-ups

Conversation

@ntindle

@ntindle ntindle commented Oct 16, 2026

Copy link
Copy Markdown
Member

Fixes SECRT-2959 (part of SECRT-2958, the usage-limits stack's follow-ups).

Why / What / How

Why: three things the review bot flagged on #15403, all in Send at reset:

  1. useScheduledSend.schedule returned quietly when the schedule call answered anything but 200. The API client throws on error statuses, so this only ran on another 2xx, which the endpoint never sends; but if it ever ran, the composer had already cleared the message, so it was gone without a word.
  2. useChatDraft's in-memory written map kept every draft the tab ever saw and was read before session storage, so it could also shadow storage that had been cleared since.
  3. useAtResetJobs read the at-reset list every minute for as long as a send waited, days if need be.

What:

  1. That answer now fails like any other error, so the message goes back to the composer (or, for a send no composer holds, back into the chat's draft) with the usual toast.
  2. The map only keeps a draft while browser storage refuses it, and drops it once storage takes a later write.
  3. A turn more than an hour away is read every 15 minutes; within the hour it's read every minute and on the moment it's due, as before. Changes made in the tab update the list directly, and React Query reads it again on focus once it's stale (60 s), so the chip still catches changes made elsewhere when the user comes back.

How: the dead branch throws an Error with no message, which describeSendFailure turns into "Your message is back in the composer. Try again." Nothing else changes. SECRT-2969 asks how CI could catch this kind of dead branch across the frontend (there are 238 status === 200 checks on generated responses).

Changes 🏗️

  • SendAtReset/useScheduledSend.ts: a non-200 answer to the schedule call fails instead of returning.
  • ChatInput/useChatDraft.ts: written holds only drafts storage refused.
  • SendAtReset/useAtResetJobs.ts: 15-minute reads for a turn more than an hour away.
  • Tests: useScheduledSend.test.tsx, chatDraft.test.tsx, useAtResetJobs.test.tsx; each new test fails on dev's code.

Agents and large language models used

  • Claude Code with Claude Opus 5.5

Checklist 📋

For code changes:

  • I have clearly listed my changes in the PR description
  • I have made a test plan
  • I have tested my changes according to the test plan:
    • A schedule call answered with 202 rejects, and scheduleQuietly puts the message back in the draft (fails on dev: the message is lost)
    • A draft storage holds isn't kept in memory: clearing storage clears it (fails on dev)
    • A turn three hours away is read again at 15 minutes, not at 10 (fails on dev: read every minute); the existing due-time test still passes
    • Send at reset, ChatInput, ChatContainer, rate-limit dialog, Paused card and out-of-budget suites: 417 tests in 38 files pass under TZ=UTC
    • prettier, eslint and tsc --noEmit clean

For configuration changes:

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

🤖 Generated with Claude Code

…und the draft cache, ease far-off polling

From the review bot's passes over #15403:
- useScheduledSend.schedule returned quietly on a non-200 answer. The API
  client throws on error statuses, so only another 2xx got there, but the
  composer had already cleared the message, so it was lost without a word.
  It fails like any other error now, and the message goes back.
- useChatDraft's in-memory copy kept every draft for the tab's life and was
  read before session storage; it now holds only drafts storage refused.
- useAtResetJobs read the list every minute however far off the turn was;
  a turn more than an hour away is read every 15 minutes.

Fixes SECRT-2959.

Co-authored-by: Claude Opus 5.5 (Claude Code) <noreply@anthropic.com>
@ntindle
ntindle requested a review from a team as a code owner October 16, 2026 09:23
@ntindle
ntindle requested review from 0ubbe and Abhi1992002 and removed request for a team October 16, 2026 09:23
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Oct 16, 2026
@github-actions github-actions Bot added platform/frontend AutoGPT Platform - Front end cla: pending CLA not yet signed by all contributors labels Oct 16, 2026
@ntindle

ntindle commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

/review

@autogpt-pr-reviewer

autogpt-pr-reviewer Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

🤖 Review of 1eec668 posted: #15591 (review)

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fc7464ff-6340-4c80-84e9-3b935fbd0591
📥 Commits

Reviewing files that changed from the base of the PR and between 9849b32 and 1eec668.

📒 Files selected for processing: 6
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/chatDraft.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/useChatDraft.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useAtResetJobs.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useScheduledSend.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout: 10
  • GitHub Check: integration_test (shard 1/4)
  • GitHub Check: integration_test (shard 2/4)
  • GitHub Check: integration_test (shard 3/4)
  • GitHub Check: integration_test (shard 4/4)
  • GitHub Check: check API types
  • GitHub Check: end-to-end tests (smoke)
  • GitHub Check: Check PR Status
  • GitHub Check: end-to-end tests (journeys)
  • GitHub Check: Analyze (python)
  • GitHub Check: conflicts
🧰 Additional context used
📚 Code guidelines: 2
autogpt_platform/frontend/AGENTS.md — unknown
AGENTS.md — unknown
📓 Path-based instructions: 4
Source excerpt: After making **any** code changes in the frontend, you MUST run the following commands **in order** before reporting work as done, creating commits, or opening PRs: Source excerpt: After making **any** code changes in the fr...

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

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/chatDraft.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useAtResetJobs.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/useChatDraft.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useScheduledSend.ts
Source excerpt: See `/frontend/CONTRIBUTING.md` for complete patterns.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/chatDraft.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useAtResetJobs.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/useChatDraft.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useScheduledSend.ts
Source excerpt: Format frontend code using `pnpm format`.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/chatDraft.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useAtResetJobs.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/useChatDraft.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useScheduledSend.ts
Source excerpt: Format Python code with `poetry run format`.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/chatDraft.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useAtResetJobs.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/useChatDraft.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useScheduledSend.ts
🔇 Additional comments: 6
autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts: 1

45-47: LGTM!

Also applies to: 53-56

autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useAtResetJobs.test.tsx: 1

73-98: LGTM!

autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useScheduledSend.ts: 1

52-55: LGTM!

autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx: 1

169-194: LGTM!

autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/useChatDraft.ts: 1

5-6: LGTM!

Also applies to: 23-23, 26-26

autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/chatDraft.test.tsx: 1

200-215: LGTM!

Walkthrough

The changes update chat draft storage fallback behavior, adjust scheduled-job polling intervals, and treat scheduling responses other than status 200 as failures. Tests cover the draft fallback, polling interval, and retained composer draft.

Changes

Chat draft storage

Layer / File(s) Summary
Draft storage fallback
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/useChatDraft.ts, autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/__tests__/chatDraft.test.tsx
writeDraft updates session storage before updating the fallback map. It removes the map entry after a successful write or removal and stores the value if storage throws. A test checks that a later successful write does not leave a stale in-memory draft.

Scheduled-send behavior

Layer / File(s) Summary
Scheduled-job polling interval
autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts, autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useAtResetJobs.test.tsx
When the nearest job is more than an hour away, refetchEvery uses a maximum interval of 15 minutes. The test checks for a second read after 15 minutes.
Scheduling response handling
autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useScheduledSend.ts, autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx
A scheduling response other than status 200 now causes schedule to throw. A test checks that scheduleQuietly leaves the submitted message in the composer draft.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 1eec6

No actionable issue remains in the reviewed changes; the PR is ready to merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the three main changes: handling failed send-at-reset scheduling, limiting draft caching, and reducing polling for distant jobs.
Description check Passed The description directly explains the motivation, implementation, tests, and validation for all changes in the pull request.
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

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

Capy found no issues.

Open in Capy

@github-actions github-actions Bot added cla: signed CLA signed by all contributors and removed cla: pending CLA not yet signed by all contributors labels Oct 16, 2026
@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 86.86%. Comparing base (9849b32) to head (1eec668).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #15591      +/-   ##
==========================================
- Coverage   86.87%   86.86%   -0.01%     
==========================================
  Files        4947     4947              
  Lines      378328   378329       +1     
  Branches    33657    33659       +2     
==========================================
- Hits       328656   328650       -6     
- Misses      44196    44204       +8     
+ Partials     5476     5475       -1     
Flag Coverage Δ
platform-frontend 71.60% <85.71%> (+<0.01%) ⬆️
platform-frontend-e2e 29.54% <0.00%> (+0.06%) ⬆️

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

Components Coverage Δ
Platform Backend 90.25% <ø> (ø)
Platform Frontend 72.91% <85.71%> (-0.02%) ⬇️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Verdict: Approved — No findings require changes before approval; this review counts as an approval.

Three well-scoped copilot bug fixes (fail a non-200 schedule answer, bound the in-memory draft cache, ease far-off at-reset polling) each traced correctly through callers and helpers and each backed by a regression test that fails on dev. No blockers, no security/auth/data-exposure impact, no copy-policy issues.

Risk level: low | Human review: not required | Duration: 297s | Reviewed: 1eec668c

Findings: 🔴 0 blockers | 🟠 0 should fix | 🟡 2 nice to have | 🔵 0 nits

Optional advice — does not block approval

🟡 Nice to Have

  • 🔵 autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/__tests__/useScheduledSend.test.tsx:193 Optionally assert the failure toast copy in the non-200 schedule test — The test confirms the draft is repopulated on a non-200 answer but does not assert the recovery toast copy from describeSendFailure; a regression dropping the toast would pass here.
    Suggestion: Optionally spy on toastSendFailure and assert the 'Your message is back in the composer' message. Non-blocking — the toast path is covered elsewhere.
  • 🔵 autogpt_platform/frontend/src/app/(platform)/copilot/components/SendAtReset/useAtResetJobs.ts:55 Consider tiering the polling ceiling beyond a day — A day-out turn still polls ~96x/day under the fixed 15-min ceiling. Advisory only; the change is already a large reduction over the prior per-minute cadence.
    Suggestion: If it ever matters, scale the ceiling with untilDue for far-future turns.

GitHub CI on reviewed head: success

Validation and specialist details

Specialist Reports

Specialist Status Summary
security ✅ PASS Well-scoped client-side copilot fix (fail a non-200 schedule, bound the draft cache, ease far-off polling) with no security, auth, or data-exposure impact and no concrete defects.
architect ✅ PASS Tight, well-scoped fix of three Send-at-reset issues (silent dead branch, stale draft cache, far-off polling cadence) with matching regression tests; no concrete defects found.
performance ✅ PASS A clean set of three copilot fixes that reduce polling load for far-off scheduled sends, bound a previously unbounded in-memory draft cache, and harden an unreachable error branch — all net-positive for performance and memory with no blocking defects.
testing ✅ PASS Three focused copilot fixes each backed by a genuine regression test that fails on dev; assertions are meaningful and no defects found.
quality ✅ PASS A clean, well-tested three-part fix (fail the dead reset branch, bound the draft cache, ease far-off polling) with no concrete defects found.
product ✅ PASS Three well-scoped copilot fixes (fail-on-non-200 schedule, bounded draft cache, eased far-off polling) all trace correctly through their callers and are covered by tests that fail on dev; no defects or copy issues found.
discussion ✅ PASS No failing required checks on head 1eec668 (all pending, mergeable) and no open human-reviewer requests in the discussion snapshot.
ui-reviewer (local) ✅ PASS Three correctly-implemented, well-tested copilot bug fixes (fail-on-non-200 schedule, bounded draft cache, eased far-off polling) with no reachable defect and no human-signoff path touched.
ui-reviewer (hosted) ✅ PASS Three correct, well-tested copilot hook fixes (fail-on-non-200 schedule, bounded draft cache, eased far-off polling); backend/client contract confirms 200 is the only success status, and all 19 targeted tests pass.

@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban Oct 16, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: signed CLA signed by all contributors platform/frontend AutoGPT Platform - Front end size/m

Projects

Status: 👍🏼 Mergeable
Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant