You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I searched existing issues and did not find a duplicate.
I am describing a concrete problem or use case, not just a vague idea.
Area
apps/server
Problem or use case
When an agent is launched inline (synchronously, i.e. run_in_background: false), the parent turn blocks on that tool call until the child finishes. There is no way to move it to the background after the fact. If the child turns out to be long-running, the only options are to wait or to interrupt, which throws away the work.
The Claude SDK already models this: task_updated carries an is_backgrounded patch. T3 ingests the flag but does nothing with it, and never sends the corresponding control request:
apps/server/src/provider/Layers/ClaudeAdapter.ts:3267 maps patch.is_backgrounded onto the task.updated event
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts:663 persists it into the activity payload
Nothing in packages/client-runtime, apps/web, or apps/mobile reads isBackgrounded, so it is stored and dropped. On the outbound side the only task-lifecycle control we send is Query.stopTask (ClaudeAdapter.ts:253, used on interrupt at :4413) — there is no background request path and no UI affordance for it.
Proposed solution
Two halves:
Outbound control — add a background-task control request alongside stopTask in the Claude adapter, plumbed through the same runtime command path that interrupt uses.
Surface state — render isBackgrounded in the Agents panel (a "Backgrounded" state on the agent row) and expose a "Move to background" action on a running inline agent. Once backgrounded, the parent's tool call resolves with a moved-to-background result and the completion notification arrives later, exactly as it does for agents launched with run_in_background: true.
Why this matters
Inline agents are the default for anything whose result you need before continuing, but you often only discover a task is slow after it starts. Today a misjudged inline launch costs you the whole turn: you either sit blocked or interrupt and lose the child's progress. Backgrounding turns that into a recoverable decision and gets control back to the user without discarding work.
Smallest useful scope
Just the outbound control plus a minimal Agents-panel action on running agents — no state persistence changes needed, since isBackgrounded already round-trips through ingestion. Even without any new UI badge, being able to trigger the background request and have the parent turn resolve would solve the blocking problem.
Alternatives considered
Interrupting and relaunching with run_in_background: true — loses all of the child's in-flight work.
Always launching agents backgrounded — defeats the purpose when the result is genuinely needed inline, and makes the model wait on notifications it could have had synchronously.
Race between the background request and the child completing on its own — the control request may land after task_notification, so the handler needs to no-op cleanly on an already-finished task (stopTask has the same acknowledgement-only semantics today, see the comment at ClaudeAdapter.ts:4436).
This discussion was converted from issue #5824 on August 15, 2026 09:50.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Before submitting
Area
apps/server
Problem or use case
When an agent is launched inline (synchronously, i.e.
run_in_background: false), the parent turn blocks on that tool call until the child finishes. There is no way to move it to the background after the fact. If the child turns out to be long-running, the only options are to wait or to interrupt, which throws away the work.The Claude SDK already models this:
task_updatedcarries anis_backgroundedpatch. T3 ingests the flag but does nothing with it, and never sends the corresponding control request:apps/server/src/provider/Layers/ClaudeAdapter.ts:3267mapspatch.is_backgroundedonto thetask.updatedeventpackages/contracts/src/providerRuntime.ts:633typesisBackgroundedapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts:663persists it into the activity payloadNothing in
packages/client-runtime,apps/web, orapps/mobilereadsisBackgrounded, so it is stored and dropped. On the outbound side the only task-lifecycle control we send isQuery.stopTask(ClaudeAdapter.ts:253, used on interrupt at:4413) — there is no background request path and no UI affordance for it.Proposed solution
Two halves:
stopTaskin the Claude adapter, plumbed through the same runtime command path that interrupt uses.isBackgroundedin the Agents panel (a "Backgrounded" state on the agent row) and expose a "Move to background" action on a running inline agent. Once backgrounded, the parent's tool call resolves with a moved-to-background result and the completion notification arrives later, exactly as it does for agents launched withrun_in_background: true.Why this matters
Inline agents are the default for anything whose result you need before continuing, but you often only discover a task is slow after it starts. Today a misjudged inline launch costs you the whole turn: you either sit blocked or interrupt and lose the child's progress. Backgrounding turns that into a recoverable decision and gets control back to the user without discarding work.
Smallest useful scope
Just the outbound control plus a minimal Agents-panel action on running agents — no state persistence changes needed, since
isBackgroundedalready round-trips through ingestion. Even without any new UI badge, being able to trigger the background request and have the parent turn resolve would solve the blocking problem.Alternatives considered
run_in_background: true— loses all of the child's in-flight work.Risks or tradeoffs
task_notification, so the handler needs to no-op cleanly on an already-finished task (stopTaskhas the same acknowledgement-only semantics today, see the comment atClaudeAdapter.ts:4436).Examples or references
Related: #1297 (background/kill long-running processes), #4198 (reaper kills in-flight background work), #5218 / #5529 (Agents panel visibility and lifecycle).
Contribution
All reactions