Skip to content

fix(chat): retry released queue inputs - #2137

Merged
zerob13 merged 4 commits into
devfrom
fix/issue-2112-pending-input-retry
Aug 11, 2026
Merged

fix(chat): retry released queue inputs#2137
zerob13 merged 4 commits into
devfrom
fix/issue-2112-pending-input-retry

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add a durable retry_required state for Queue inputs released after a pre-user-fact failure or transcript rollback.
  • Expose an explicit per-item Retry action in the pending input lane.
  • Preserve FIFO ordering, restart-held Queue behavior, ACP compatibility, and edit-as-retry behavior.
  • Add regression coverage across persistence, runtime admission, routes, restart recovery, ACP, and renderer behavior.

Closes #2112.

Root Cause

PR #2023 centralized pending input claim, release, and single-flight draining in PendingInputPump.

When a claimed Queue input failed before its user fact was committed, or after the fact was rolled back, it was released to the FIFO head as an ordinary pending row. The pump intentionally did not replay that row automatically, but the renderer could not distinguish it from a normal draft and exposed no explicit recovery action.

PR #2129 added restart recovery and Resume Queue behavior, which made the issue more visible, but did not introduce the original defect.

Changes

  • Add retry_required to PendingSessionInputState.
  • Transition failed DeepChat Queue settlements from claimed to retry_required.
  • Keep intentional Queue-to-Steer mutation and restart repair releases as ordinary pending.
  • Keep retry-required rows in FIFO ordering and capacity accounting while excluding them from automatic dispatch.
  • Add a typed, session-gated sessions.retryPendingQueueInput route.
  • Validate session ownership, retry state, and FIFO-head position inside the persistence transaction.
  • Return separate accepted and started results so an accepted retry delayed by a runtime gate is not reported as a failure.
  • Preserve retry acceptance when event publication or the first immediate drain fails after persistence.
  • Keep ACP pending-input semantics unchanged.
  • Preserve attachmentFallbackPolicy when editing a Queue item.
  • Add localized Retry labels and descriptions for all supported locales.

No database migration is required because the pending input state column is unconstrained text.

UI

Before

┌──────────────────────── Queue ────────────────────────┐
│ Failed message                              [Steer][×] │
└───────────────────────────────────────────────────────┘

The failed item remained at the Queue head without explaining why the Queue was blocked or how to continue it.

After

┌──────────────────────── Queue ────────────────────────┐
│ Failed message   This message wasn't sent             │
│                  [Retry required]          [Retry][×]  │
└───────────────────────────────────────────────────────┘

Retry-required rows cannot be reordered or converted to Steer. They can be retried, edited and retried, or removed.

Safety and Compatibility

  • Later Queue items cannot bypass a retry-required FIFO head, including through the question-follow-up fast path.
  • Duplicate Retry requests produce at most one state transition and turn.
  • Restart-held Queue rows retain the existing Resume Queue contract.
  • A retry-required head prevents a restart-held tail from being resumed out of order.
  • ACP continues releasing failed Queue claims to ordinary pending.
  • Retry diagnostics do not include message content, attachment paths, or payload data.
  • Publication and immediate-drain failures after a successful state transition remain recoverable.

Validation

  • pnpm run format
  • pnpm run i18n
  • pnpm run lint
  • pnpm run typecheck:node
  • pnpm run typecheck:web
  • Main pending-input, route, session, backend, and ACP tests — 210 passed
  • Renderer pending-input tests — 29 passed
  • DeepChat harness failure and rollback boundaries — 4 passed

Twelve native SQLite tests were skipped by the repository harness because the locally installed native module ABI does not match the Node ABI used by Vitest. Equivalent store, FIFO, retry, and restart contracts passed in the non-native suites.

Summary by CodeRabbit

  • New Features

    • Added explicit retry handling for queued messages that cannot proceed automatically.
    • Retry-required items remain at the queue head until manually retried.
    • Added Retry actions with loading, failure, and recovery feedback.
    • Editing a retry-required message now retries it safely.
    • Added localized retry messaging across supported languages.
  • Bug Fixes

    • Improved restart and queue-resume behavior for interrupted messages.
    • Prevented duplicate retries and preserved queued message settings during edits.
    • Prevented later queued messages from bypassing items requiring retry.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b835ea89-e1d8-4f3d-a69d-79fb92e9c38e

📥 Commits

Reviewing files that changed from the base of the PR and between e665348 and f91b35a.

📒 Files selected for processing (12)
  • docs/issues/pending-input-explicit-retry/spec.md
  • src/main/agent/deepchat/runtime/pendingInputAdmissionCoordinator.ts
  • src/main/data/schemaCatalog.ts
  • src/main/session/data/pendingInputStore.ts
  • src/main/session/data/pendingInputs.ts
  • src/main/session/data/tables/deepchatPendingInputs.ts
  • test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts
  • test/main/agent/deepchat/runtime/pendingInputAdmissionCoordinator.test.ts
  • test/main/orchestration/liveDelegationMigration.test.ts
  • test/main/session/data/pendingInputStore.test.ts
  • test/main/session/data/pendingInputs.test.ts
  • test/main/session/data/tables/deepchatPendingInputsTable.test.ts
💤 Files with no reviewable changes (1)
  • src/main/agent/deepchat/runtime/pendingInputAdmissionCoordinator.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/main/session/data/pendingInputs.test.ts
  • src/main/session/data/pendingInputs.ts
  • test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts

📝 Walkthrough

Walkthrough

The PR adds durable retry_required handling for released DeepChat Queue inputs. It preserves FIFO blocking, adds explicit retry APIs from the renderer to the runtime, supports restart recovery, and exposes localized retry controls.

Changes

Explicit Queue Input Retry

Layer / File(s) Summary
Durable retry state and transitions
docs/issues/..., src/main/session/data/*, src/main/data/schemaCatalog.ts, src/shared/types/agent-interface.d.ts, test/main/session/data/*, test/main/orchestration/liveDelegationMigration.test.ts
Queue inputs can enter retry_required, remain at the queue head, survive restart, and transition once back to pending. Editing, reordering, persistence, migration, and rollback rules handle this state.
Pump rollback and explicit retry admission
src/main/agent/deepchat/runtime/*, src/main/agent/deepchat/harness/deepChatAgentHarness.ts, test/main/agent/deepchat/runtime/*, test/main/agent/deepchat/harness/*
Claim settlement separates mutation releases from retry releases. Explicit retries validate state and queue ownership before persistence and draining.
Session and route retry API
src/main/agent/manager/*, src/main/app/composition.ts, src/main/session/*, src/shared/contracts/routes/*, src/renderer/api/SessionClient.ts, test/main/agent/manager/*, test/main/session/turn.test.ts, test/main/routes/dispatcher.test.ts
The retry operation is exposed through runtime contracts, session handles, the session gate, the route catalog, and the renderer client.
Renderer retry controls and localization
src/renderer/src/components/chat/PendingInputLane.vue, src/renderer/src/features/chat-page/*, src/renderer/src/stores/ui/pendingInput.ts, src/renderer/src/i18n/*, test/renderer/*
The renderer displays retry-required status, disables conflicting queue actions, prevents concurrent retries, refreshes queue state, starts a plan turn when applicable, and adds translations.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: zerob13

Sequence Diagram(s)

sequenceDiagram
  participant PendingInputLane
  participant PendingInputStore
  participant SessionClient
  participant SessionTurn
  participant PendingInputAdmissionCoordinator
  participant SessionPendingInputStore

  PendingInputLane->>PendingInputStore: retryQueueInput(sessionId, itemId)
  PendingInputStore->>SessionClient: retryPendingQueueInput(sessionId, itemId)
  SessionClient->>SessionTurn: invoke retry route
  SessionTurn->>PendingInputAdmissionCoordinator: retryPendingQueueInput(sessionId, itemId)
  PendingInputAdmissionCoordinator->>SessionPendingInputStore: retryReleasedQueueInput(itemId)
  PendingInputAdmissionCoordinator->>PendingInputAdmissionCoordinator: drain or schedule queue
  PendingInputStore->>PendingInputLane: refresh item and clear retrying state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: retrying released chat queue inputs.
Linked Issues check ✅ Passed The implementation satisfies [#2112] with durable retry_required state, explicit retry UI, FIFO protection, idempotent admission, compatibility handling, and regression tests.
Out of Scope Changes check ✅ Passed The production, schema, renderer, localization, documentation, and test changes directly support durable released-queue retry behavior.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-2112-pending-input-retry

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@src/renderer/src/i18n/ru-RU/chat.json`:
- Line 77: Update the retryRequired translation in the Russian chat localization
to use “Требуется повторная попытка,” clearly indicating that the unsent queue
message must be retried.

In `@test/renderer/stores/pendingInputStore.test.ts`:
- Line 97: Remove the duplicate const retry declaration in the affected test
scope, keeping the single existing createDeferred<{ accepted: boolean; started:
boolean }>() declaration and all references to retry unchanged.
🪄 Autofix

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d28fb894-de3d-44e5-b52b-d2ae20846b5e

📥 Commits

Reviewing files that changed from the base of the PR and between 4d02c92 and 60d189b.

📒 Files selected for processing (53)
  • docs/issues/pending-input-explicit-retry/spec.md
  • src/main/agent/deepchat/harness/deepChatAgentHarness.ts
  • src/main/agent/deepchat/runtime/pendingInputAdmissionCoordinator.ts
  • src/main/agent/deepchat/runtime/pendingInputContracts.ts
  • src/main/agent/deepchat/runtime/pendingInputPump.ts
  • src/main/agent/manager/deepChatAgentBackend.ts
  • src/main/agent/manager/sessionHandles.ts
  • src/main/app/composition.ts
  • src/main/session/contracts.ts
  • src/main/session/data/pendingInputStore.ts
  • src/main/session/data/pendingInputs.ts
  • src/main/session/routes.ts
  • src/main/session/turn.ts
  • src/renderer/api/SessionClient.ts
  • src/renderer/src/components/chat/PendingInputLane.vue
  • src/renderer/src/features/chat-page/ChatPage.vue
  • src/renderer/src/features/chat-page/composables/usePendingInputActions.ts
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/stores/ui/pendingInput.ts
  • src/shared/contracts/routes.ts
  • src/shared/contracts/routes/sessions.routes.ts
  • src/shared/types/agent-interface.d.ts
  • test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts
  • test/main/agent/deepchat/runtime/pendingInputAdmissionCoordinator.test.ts
  • test/main/agent/deepchat/runtime/pendingInputPump.test.ts
  • test/main/agent/manager/deepChatAgentBackend.test.ts
  • test/main/routes/dispatcher.test.ts
  • test/main/session/data/pendingInputStore.test.ts
  • test/main/session/data/pendingInputs.test.ts
  • test/main/session/data/tables/deepchatPendingInputsTable.test.ts
  • test/main/session/turn.test.ts
  • test/renderer/components/PendingInputLane.test.ts
  • test/renderer/features/chat-page/composables/usePendingInputActions.test.ts
  • test/renderer/stores/pendingInputStore.test.ts

Comment thread src/renderer/src/i18n/ru-RU/chat.json Outdated
Comment thread test/renderer/stores/pendingInputStore.test.ts

Copilot AI 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.

Pull request overview

Adds durable, explicit retry handling for failed Queue inputs while preserving FIFO, restart, ACP, and attachment behavior.

Changes:

  • Introduces retry_required persistence and retry routing.
  • Adds localized retry UI and edit-as-retry support.
  • Expands regression coverage across runtime, persistence, routes, and renderer.

Reviewed changes

Copilot reviewed 52 out of 53 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/renderer/stores/pendingInputStore.test.ts Tests retry deduplication and deferred acceptance.
test/renderer/features/chat-page/composables/usePendingInputActions.test.ts Tests retry actions and payload preservation.
test/renderer/components/PendingInputLane.test.ts Tests retry-required lane controls.
test/main/session/turn.test.ts Tests gated retry delegation and ACP rejection.
test/main/session/data/tables/deepchatPendingInputsTable.test.ts Tests native persistence and FIFO blocking.
test/main/session/data/pendingInputStore.test.ts Tests retry transitions and ordering constraints.
test/main/session/data/pendingInputs.test.ts Tests ownership and restart recovery.
test/main/routes/dispatcher.test.ts Tests retry route dispatch.
test/main/agent/manager/deepChatAgentBackend.test.ts Tests backend retry delegation.
test/main/agent/deepchat/runtime/pendingInputPump.test.ts Tests release, FIFO, and restart behavior.
test/main/agent/deepchat/runtime/pendingInputAdmissionCoordinator.test.ts Tests retry admission and failure recovery.
test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts Updates end-to-end failure-state expectations.
src/shared/types/agent-interface.d.ts Adds the retry_required state.
src/shared/contracts/routes/sessions.routes.ts Defines the typed retry route.
src/shared/contracts/routes.ts Registers the retry route.
src/renderer/src/stores/ui/pendingInput.ts Manages retry state and requests.
src/renderer/src/i18n/zh-TW/chat.json Adds Traditional Chinese retry copy.
src/renderer/src/i18n/zh-HK/chat.json Adds Hong Kong Chinese retry copy.
src/renderer/src/i18n/zh-CN/chat.json Adds Simplified Chinese retry copy.
src/renderer/src/i18n/vi-VN/chat.json Adds Vietnamese retry copy.
src/renderer/src/i18n/tr-TR/chat.json Adds Turkish retry copy.
src/renderer/src/i18n/ru-RU/chat.json Adds Russian retry copy.
src/renderer/src/i18n/pt-BR/chat.json Adds Brazilian Portuguese retry copy.
src/renderer/src/i18n/pl-PL/chat.json Adds Polish retry copy.
src/renderer/src/i18n/ms-MY/chat.json Adds Malay retry copy.
src/renderer/src/i18n/ko-KR/chat.json Adds Korean retry copy.
src/renderer/src/i18n/ja-JP/chat.json Adds Japanese retry copy.
src/renderer/src/i18n/it-IT/chat.json Adds Italian retry copy.
src/renderer/src/i18n/id-ID/chat.json Adds Indonesian retry copy.
src/renderer/src/i18n/he-IL/chat.json Adds Hebrew retry copy.
src/renderer/src/i18n/fr-FR/chat.json Adds French retry copy.
src/renderer/src/i18n/fa-IR/chat.json Adds Persian retry copy.
src/renderer/src/i18n/es-ES/chat.json Adds Spanish retry copy.
src/renderer/src/i18n/en-US/chat.json Adds English retry copy.
src/renderer/src/i18n/de-DE/chat.json Adds German retry copy.
src/renderer/src/i18n/da-DK/chat.json Adds Danish retry copy.
src/renderer/src/features/chat-page/composables/usePendingInputActions.ts Implements renderer retry handling.
src/renderer/src/features/chat-page/ChatPage.vue Connects retry state and events.
src/renderer/src/components/chat/PendingInputLane.vue Displays retry status and controls.
src/renderer/api/SessionClient.ts Exposes the retry client method.
src/main/session/turn.ts Gates retry through session operations.
src/main/session/routes.ts Handles the retry route.
src/main/session/data/pendingInputStore.ts Persists retry state and transitions.
src/main/session/data/pendingInputs.ts Coordinates retry ownership and recovery.
src/main/session/contracts.ts Extends session retry contracts.
src/main/app/composition.ts Wires retry into runtime composition.
src/main/agent/manager/sessionHandles.ts Extends the DeepChat control facet.
src/main/agent/manager/deepChatAgentBackend.ts Delegates backend retries.
src/main/agent/deepchat/runtime/pendingInputPump.ts Enforces retry-aware release and draining.
src/main/agent/deepchat/runtime/pendingInputContracts.ts Adds mutation-specific release disposition.
src/main/agent/deepchat/runtime/pendingInputAdmissionCoordinator.ts Implements retry admission and scheduling.
src/main/agent/deepchat/harness/deepChatAgentHarness.ts Exposes runtime retry operations.
docs/issues/pending-input-explicit-retry/spec.md Documents the design and validation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/main/session/data/pendingInputStore.ts Outdated

@zerob13 zerob13 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Two actionable state-machine issues remain. The first is reproduced by a failing regression on the current head; the second combines two already-supported paths that are only tested separately.

Comment thread src/main/session/data/pendingInputStore.ts Outdated
Comment thread src/main/session/data/pendingInputStore.ts Outdated

@zerob13 zerob13 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One additional persisted-data compatibility issue:

Comment thread docs/issues/pending-input-explicit-retry/spec.md Outdated
@zerob13
zerob13 merged commit 099e4e0 into dev Aug 11, 2026
12 checks passed
@zhangmo8
zhangmo8 deleted the fix/issue-2112-pending-input-retry branch August 11, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] Expose explicit retry for released queued inputs

3 participants