[Bug]: /compact on ACP registry agents (e.g. Devin) fails at turn start — adapter never sets supportsCompaction#16663

opened26d agobySstilak12

Area: apps/server

Steps to reproduce

  1. Add an ACP registry agent that advertises a compact slash command via available_commands_update (e.g. Devin, acpRegistry_devin).
  2. Open a thread on that provider and send a message or two.
  3. Send /compact (or click Compact context in the context-window meter popover).

Expected behavior

The /compact command is forwarded to the agent and conversation compaction runs (Devin handles /compact natively over ACP and emits compaction_update notifications, which AcpRuntimeModel already maps to a "Compact context" tool-call row).

Actual behavior

The run fails immediately (~500ms) with:

Provider error — "The provider could not start this turn. Retry the turn; if it keeps failing, check the provider setup and server logs."

The provider event log shows initialize and session/load succeed, then the run fails — session/prompt is never sent:

101:00:46.541 initialize → succeeded
201:00:46.585 session/load → succeeded
301:00:47.079 run failed → ProviderAdapterTurnStartError

Impact

Minor bug or occasional failure — compaction is unreachable for every ACP-registry provider, and the UI actively offers a command that cannot succeed.

Root cause

Two capability signals disagree:

  1. Enablement (works): since #16021 ("feat(acp): support local provider commands"), available_commands_update is normalized into the provider snapshot's slashCommands. The web UI enables compact when snapshot.slashCommands.some(c => c.name === "compact") (providerSupportsManualCompaction in ContextWindowMeter.logic.ts). Devin advertises compact, so the UI offers it.

  2. Dispatch (broken): the orchestrator special-cases a message whose trimmed text is exactly /compact and routes it to session.compactThread(...) instead of session.startTurn(...). compactThread is only attached when the adapter flavor sets supportsCompaction: true. The Antigravity and Grok ACP flavors set it; AcpRegistryAdapterV2's flavor does not → the call hits compactThread?.() ?? fail(ProviderAdapterTurnStartError("This provider does not support context compaction.")) and the run dies before session/prompt.

Suggested fix

Set supportsCompaction: true on the acpRegistry flavor. The existing compactThread implementation just calls startTurn with message.text = "/compact", which is correct for any agent that advertises the command — and the UI already gates on advertised commands, so agents that don't advertise compact never get the affordance. (Optionally also gate on the captured slashCommands if you want the runtime side to be defensive too.)

Environment

  • T3 Code: 0.0.46-nightly.20261005.2702 (macOS arm64); still present on main
  • Agent: Devin 3000.11.3 via acpRegistry_devin (devin acp), which advertises 95 commands including compact
  • Verified devin acp accepts /compact via session/prompt directly (returns end_turn, emits compaction_update)

Workaround for users

Attaching any file to the message bypasses the compact dispatch (attachments.length === 0 check), so the prompt goes through session/prompt and the agent parses /compact itself.

Generated with Devin

Note

Grok responding on behalf of Julius.

Confirmed on current main (f8ed2a0). Clear eng bug: UI advertises Compact for ACP-registry agents that expose a compact slash command, but the adapter never opts into compaction, so the orchestrator fails the turn before session/prompt.

What main does

  1. UI enablement (works). providerSupportsManualCompaction is purely slash-command based:
ts
1// apps/web/src/components/chat/ContextWindowMeter.logic.ts
2return provider?.snapshot.slashCommands.some((command) => command.name === "compact") ?? false;

#16021 (merged) feeds available_commands_update into the provider snapshot’s slashCommands, so Devin (and any other registry agent that advertises compact) gets the Compact affordance.

  1. Dispatch (broken). Bare /compact (no attachments) is special-cased in RunExecutionService and routed to session.compactThread, not startTurn:
ts
1// apps/server/src/orchestration-v2/RunExecutionService.ts (~1376-1389)
2const compact =
3 input.message.attachments.length === 0 &&
4 input.message.text.trim().toLowerCase() === "/compact";
5const startTurn = compact
6 ? (input.session.compactThread?.(turnInput) ??
7 Effect.fail(
8 new ProviderAdapterTurnStartError({
9 /* ... */
10 cause: "This provider does not support context compaction.",
11 }),
12 ))
13 : input.session.startTurn(turnInput);

That matches the reported ProviderAdapterTurnStartError with no session/prompt.

  1. Adapter gap. AcpAdapterV2 only attaches compactThread when the flavor sets supportsCompaction: true (and that helper just rewrites the message to /compact and calls startTurn):
ts
1// apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.ts (~7393-7400)
2...(flavor.supportsCompaction === true
3 ? {
4 compactThread: (turnInput) =>
5 startTurn({
6 ...turnInput,
7 message: { ...turnInput.message, text: "/compact" },
8 }),
9 }
10 : {}),
  • Antigravity / Grok ACP flavors set supportsCompaction: true (AntigravityAdapterV2.ts ~225, GrokAdapterV2.ts ~255).
  • makeAcpRegistryAdapterV2 never sets it — the flavor only wires driver/capabilities/Devin+Mistral exceptions/runtimeCoordinator hooks (AcpRegistryAdapterV2.ts ~190-239). No supportsCompaction symbol in that file on main.

So any ACP-registry agent that advertises compact gets a button that cannot succeed. The attachment workaround in the report is real: non-empty attachments skips the compact special-case and goes through startTurn → session/prompt.

Related (not duplicates)

RefNotes
#16021 (merged)Added local ACP slash commands → UI enablement path.
#5412 (closed)Grok /compact + compaction feedback — different flavor, already sets the flag.
#11276 (closed)Devin via ACP — landed the provider, not this compaction gate.
#10164 / #10959 (open)Compaction notification / Claude status UX — unrelated to registry supportsCompaction.

Fix direction (no open fix PR found)

Agree with the reporter: set supportsCompaction: true on the acpRegistry flavor. Existing compactThread already forwards /compact via startTurn, which is what Devin expects over ACP. Optionally also gate runtime compact on the captured slashCommands for defense in depth. No open PR from stilak12 (or anyone else) targets this; issue has no comments / linked PRs yet.

Verdict: valid eng bug — ready to track / fix.

Another way users end up here: switching a thread back to an ACP registry agent (Factory Droid in my case) whose conversation is full fails with "Insufficient context allowance… Compact the target conversation". That error points the user to /compact, which this bug makes unavailable for registry agents, so the thread can't return to that provider. Details in #22636.

As #22205 shows, sending /compact as text only helps agents that actually implement it. Gating on the advertised compact command, as the UI already does, seems like the right signal.

Triage on Linux at main a12d6ed942: reproduction stopped at step 1. command -v devin returned no executable, and the available provider catalog has no configured ACP registry agent. No /compact turn was run, so this is not a reproduction or a claim that main is fixed. Verification needs an environment with an authenticated ACP registry agent that advertises compact, followed by both the text command and context-meter action. Checked 949 open issues; no earlier duplicate with this same surface and symptom was found.

Synced from GitHub

Note

Written by claude-opus-5-5 on behalf of Adam

GitHub Copilot over ACP has the same problem. It's another provider that could be used to reproduce this, since the last triage stopped for lack of a configured registry agent.

Version: 0.1.3-nightly.20261026.3726 (desktop) Provider: GitHub Copilot CLI ACP (gh copilot), via the ACP registry

Steps to reproduce

  1. Add GitHub Copilot as an ACP provider and open a thread.
  2. Send a normal prompt or two. They work.
  3. Click Compact context or send /compact.

Expected

T3 sends /compact to Copilot as plain session/prompt text. GitHub's ACP docs say Copilot supports this, and Copilot advertises compact in available_commands_update. The cached registry metadata lists it too, which is why the UI offers Compact.

Actual

The run fails with the generic "The provider could not start this turn" provider error. The failed run has no provider-turn ID, and there's no session/prompt for it. Later normal prompts on the same thread start and finish fine.

Cause (same as this issue)

Copilot goes through the registry flavor. On current main, that flavor still never sets supportsCompaction, so compactThread is missing (packages/provider-acp/src/server/adapter.ts). A bare /compact then fails in RunExecutionService with "This provider does not support context compaction." That happens before session/prompt is sent. The user-facing failure mapping hides that message, so the UI only shows the generic error.

#19572 changes the registry adapter, so it should fix Copilot as well. Copilot would also be a good real-world check for that PR, since it handles /compact natively.