Skip to content

feat(server): T3CODE_PROVIDER_IDLE_TIMEOUT_MINUTES sets how long idle agents stay running - #37137

Closed
shayuc137 wants to merge 1 commit into
pingdotgg:mainfrom
shayuc137:feat/provider-idle-timeout-env
Closed

shayuc137 wants to merge 1 commit into
pingdotgg:mainfrom
shayuc137:feat/provider-idle-timeout-env

Conversation

@shayuc137

Copy link
Copy Markdown

Problem

T3 Code stops an agent's process 30 minutes after its thread goes idle (DEFAULT_IDLE_TIMEOUT_MS in ProviderSessionManager.ts) and resumes it on the next message. A host cannot change this. That breaks tools that run inside the provider process and need it to stay alive. For example, a Claude Code plugin can keep a long thread's prompt cache warm by sending a small forked request shortly before the one-hour subscription cache expires. Inside T3 Code, the process is gone after 30 minutes, so the keep-alive never runs. When the user comes back, the whole conversation is sent again uncached. For a thread with 200k+ tokens, that costs far more than the keep-alive would have.

Change

ProviderSessionManager.layerWithOptions already accepts idleTimeoutMs. Until now, only tests set it. The default layer now reads T3CODE_PROVIDER_IDLE_TIMEOUT_MINUTES from the host environment:

  • unset or blank: no change, still 30 minutes
  • a whole number of minutes from 1 to 1440: used as the idle timeout
  • anything else: logged as a warning and ignored, so the default applies

The background-service guide documents the variable next to the other service.env settings, including the memory cost of keeping idle processes alive.

Scope

This is a focused configuration option for an existing capability, the idle release of provider sessions, under CONTRIBUTING's configuration route. It does not change the default or add a workflow. It only exposes a parameter the layer already has. It is server-only, so clients need no changes.

The value applies to all providers. A per-provider-instance override could later follow the idleCompaction pattern (a global default that each provider can override) if maintainers want it. I left that out to keep this PR to one problem.

Verification

  • vp test run apps/server/src/orchestration-v2/ProviderSessionManager.test.ts: 72/72 pass, including a new case for parsing the variable: unset, blank, 90, 1440, and the rejected values 0, 1441, 1.5, -5, 30m, 1e3.
  • vp run check:changed: format, lint, knip, typecheck and tests all pass.
  • Runtime, with an isolated serve --base-dir <checkout>/.t3 and the Replay (dev) provider (command-output scenario):
    • T3CODE_PROVIDER_IDLE_TIMEOUT_MINUTES=1: the turn finished at 00:58:09 and the replay agent process exited at 00:59:09. The trace records ProviderSessionManager.releaseIfStillIdle at 00:59:09.
    • T3CODE_PROVIDER_IDLE_TIMEOUT_MINUTES=30m: startup logged WARN Ignoring T3CODE_PROVIDER_IDLE_TIMEOUT_MINUTES: expected whole minutes from 1 to 1440 { value: '30m' }. After a turn finished at 00:59:38, the agent process was still alive 130 seconds later, so the 30-minute default applied.
  • Not checked: the full 30-minute default, real paid providers, and desktop-managed local servers. Those read the same host environment, but I did not run them.

Written with Claude Opus 5.5 in Claude Code (running under T3 Code).

🤖 Generated with Claude Code

… agents stay running

Idle provider processes were always released after 30 minutes, which ends
keep-alive tools running inside the provider process (such as a prompt-cache
keep-warm plugin) before they can act. The default ProviderSessionManager layer
now reads the timeout from the host environment; unset keeps 30 minutes and
invalid values are logged and ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched Author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Nov 15, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at c55aa4f

Macroscope's review found this PR approvable — Adds a bounded, opt-in environment setting for idle agent lifetime while preserving the 30-minute default. Invalid settings fall back safely, and documentation explains the memory cost of longer lifetimes.

You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge

Copy link
Copy Markdown
Member

Thanks for this. #25624 makes the same change and is the one being kept.

#25624 already makes idle agent lifetime configurable through Settings on web, desktop, and mobile. It also applies changes to agents already waiting while idle and offers Never, so it covers the underlying need more completely.

Your bounded validation and explanation of the memory cost are useful. Keeping the configuration in the existing settings system gives hosts one place to control this behavior.

Closing as a duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched Author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants