Skip to content

fix(acp): recover stale foreground turn on replace - #2679

Open
rinseaid wants to merge 3 commits into
getpaseo:mainfrom
rinseaid:codex/recover-stale-acp-turn
Open

fix(acp): recover stale foreground turn on replace#2679
rinseaid wants to merge 3 commits into
getpaseo:mainfrom
rinseaid:codex/recover-stale-acp-turn

Conversation

@rinseaid

Copy link
Copy Markdown

Problem

If a provider acknowledges cancellation but never emits a terminal turn event, Paseo force-cancels its manager-side run after the timeout. The provider session can still retain its foreground turn. The next replacement prompt then fails with A foreground turn is already active.

Fix

After that forced cancellation path, reload the agent session before starting the replacement prompt. Reloading resumes the persisted provider session while retaining the Paseo agent, timeline, labels, and workspace. Normal cancellations keep their existing result shape and do not reload.

Regression coverage

The test models a provider that accepts cancellation, omits the terminal event, and rejects another foreground turn. It verifies that Paseo closes the stale session, resumes a replacement session, and completes the queued replacement prompt.

Validation

  • npx vitest run src/server/agent/agent-manager.test.ts
  • npm run typecheck --workspace=@getpaseo/server
  • npm run lint -- packages/server/src/server/agent/agent-manager.ts packages/server/src/server/agent/agent-manager.test.ts
  • npm run format:check:files -- packages/server/src/server/agent/agent-manager.ts packages/server/src/server/agent/agent-manager.test.ts

Fixes #1936

Comment thread packages/server/src/server/agent/agent-manager.ts
@greptile-apps

greptile-apps Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR recovers replacement prompts after forced cancellation leaves a provider-side foreground turn active.

  • Marks timeout-driven cancellation settlements as forced.
  • Reloads the provider session before starting a replacement prompt only after forced cancellation.
  • Makes reload registration transactional enough to retain the existing live and durable agent when replacement registration fails.
  • Adds regression coverage for stale foreground sessions and failed recovery registration.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the current rollback preserves the existing agent and durable session record when recovery registration fails, addressing both previously reported failure paths.

Important Files Changed

Filename Overview
packages/server/src/server/agent/agent-manager.ts Adds forced-cancellation signaling, reloads stale provider sessions before replacement, and restores the existing agent if replacement registration fails.
packages/server/src/server/agent/agent-manager.test.ts Covers stale foreground-turn recovery and verifies that registration failure retains both the live agent and its original durable session record.

Sequence Diagram

sequenceDiagram
  participant C as Client
  participant M as AgentManager
  participant Old as Stale provider session
  participant New as Resumed provider session
  C->>M: replaceAgentRun(prompt)
  M->>Old: interrupt()
  Old--xM: No terminal turn event
  M->>M: Force-settle cancellation
  M->>New: resumeSession(handle)
  M->>M: Register replacement session
  M->>Old: close()
  M->>New: startTurn(prompt)
  New-->>M: turn_completed
  M-->>C: Replacement stream completes
Loading

Reviews (3): Last reviewed commit: "fix(acp): keep prior snapshot on reload ..." | Re-trigger Greptile

Comment thread packages/server/src/server/agent/agent-manager.ts Outdated
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.

Hermes ACP follow-up can fail with “A foreground turn is already active” and leave confusing agent state

1 participant