Skip to content

馃珎 fix: Keep Legacy Background Results Until Durable - #16405

Merged
danny-avila merged 1 commit into
devfrom
lia/background-shutdown-followup
Sep 27, 2026
Merged

danny-avila merged 1 commit into
devfrom
lia/background-shutdown-followup

Conversation

@lia-by-librechat

Copy link
Copy Markdown
Contributor

Summary

After #16365, a background completion admitted by an older producer can have an automatic delivery but no independent persistResult writer. Its parent-message projection is then the only durable result. Shutdown currently releases the task's handle when the tool finishes, before that projection commits; a flush can also count a false receipt as success. A non-cooperative tool can therefore lose its result while shutdown reports a clean drain. Separately, an unsuccessful write leaves an unconfirmed shutdown handle reachable even after the registry expires or evicts the task.

Keep these pre-admitted tasks tracked until their projection is confirmed. When shutdown interrupts a still-running task without a receipt writer, project one terminal interruption through the existing result path. A late tool settlement cannot overwrite it. If neither a receipt nor a projection is confirmed, report the drain as unsettled rather than successful. Release and warn about unconfirmed handles when their task is evicted, so a run of failed writes cannot retain an unbounded set of dead tasks.

How it works

pre-admitted background task
  independent receipt succeeds  -> release shutdown handle
  no receipt, projection succeeds -> release shutdown handle
  projection still pending       -> wait through the shutdown budget
  both paths fail                -> report unconfirmed result
  still running at flush         -> store one interruption via receipt or legacy projection
  later task eviction            -> drop orphaned handle and log an unconfirmed result

The original delivery identity, caller authorization, claim rules and configurable shutdown grace are unchanged. The one-result guard also prevents a tool that ignores its abort from rewriting a forced interruption later in the same process.

Type of change

  • Bug fix

Testing

Tested environments/configuration: Node 24, local Jest with the receipt-capable and legacy pre-admitted completion adapters; no external model or database required for the focused tests.

Automated tests:

  • handlers.shutdown.spec.ts: legacy projection pending through flush, failed projection, an uncooperative legacy task whose interruption is projected, failed interruption projection, and late success after the forced result. Existing receipt, fallback, code harvest, cancellation and admission cases remain covered.
  • background.shutdown.spec.ts: task expiry and capacity-pressure eviction cannot leave an unconfirmed shutdown handle retained. Existing drain and ordering cases remain covered.
  • Focused Jest: background.shutdown.spec.ts, background.spec.ts, handlers.shutdown.spec.ts, handlers.background.spec.ts, triggers/service.delivery.spec.ts, app/shutdown.spec.ts.
  • npx tsc --noEmit in packages/api; npm run sort-imports -- <changed paths> and npm run static-checks -- --against origin/dev.

Screenshots / recordings

No new user-facing UI. The forced legacy result uses the existing shutdown interruption message.

Risk / compatibility

A poll-only task with no pre-admitted durable delivery remains process-local and cannot be recovered after restart. A non-cooperative external action can keep running after LibreChat exits; its forced interruption does not prove the external side effect did not happen. The existing shutdown deadline and grace continue to bound these attempts. There are no schema, configuration or API changes.

Checklist

  • I reviewed my own changes
  • Relevant tests have been added or updated
  • Existing relevant tests pass
  • The change does not introduce new warnings or errors
  • User-facing or complex behavior is documented where necessary
  • Required dependency changes have been merged/published
  • Required documentation PR: N/A

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Review handoff for exact remote head a9ebc331bce489877d50b088270586d31768b9f9: follow-up to merged #16365. Legacy pre-admitted completions now remain tracked until their only durable projection completes; a forced interruption projects once when no receipt writer exists, failed writes stay unconfirmed, and evicted tasks release their shutdown handles. Local focused Jest (285 passing), API tsc --noEmit, and static checks passed against merged dev. Maintainer review is welcome for this exact head.

@danny-avila
danny-avila merged commit 9ffcd28 into dev Sep 27, 2026
28 checks passed
@danny-avila
danny-avila deleted the lia/background-shutdown-followup branch September 27, 2026 01:59
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.

2 participants