Skip to content

feat: subagent prompt-cache affinity TTL #1307

Description

@tobwen

Pre-flight checklist

  • I searched existing issues and discussions for similar proposals.
  • This is a concrete proposal, not an open-ended question.

Problem / motivation

OpenCode identifies short-lived child work (subagents) with the x-parent-session-id request header, but codex-lb currently retains their prompt-cache mapping under the same long-lived settings used by parent sessions. A subagent bridge session inherits the parent's PROMPT_CACHE affinity with a 3600s idle TTL, holding an account stream lease for up to one hour after the subagent finishes.

With enough concurrent subagents, the account stream cap is exhausted:

Account stream capacity is exhausted; per-account limit is 8.

Additionally, internal_unanchored_parallel fork bridge sessions (created when multiple requests share one session header) inherit the parent's PROMPT_CACHE idle TTL and hold stream leases long after the fork completes.

Proposed change

Add a persisted dashboard setting http_responses_session_bridge_subagent_prompt_cache_ttl_seconds, defaulting to NULL (No Cache).

  • NULL or 0: subagent bridge sessions and stream leases are released immediately when the response stream ends. No PROMPT_CACHE sticky mapping is created for the subagent.
  • Positive value: the subagent's bridge session, stream lease, and PROMPT_CACHE mapping are retained for that many seconds, then released via a delayed background close task.

Subagent sessions are detected via x-parent-session-id, x-openai-subagent, or x-codex-parent-thread-id headers.

internal_unanchored_parallel fork bridge sessions are closed immediately when their response stream ends, releasing the stream lease. The parent session's bridge and sticky mapping remain available.

Sticky mappings persist an is_subagent marker so the cleanup scheduler can apply the subagent TTL independently from parent mappings. The scheduler interval is capped at 30 seconds so that subagent mappings with short TTLs are cleaned promptly.

The dashboard displays "Prompt cache, Subagent" for subagent entries and "Prompt cache" for parent entries.

A Routing Settings control labelled "Subagent prompt-cache affinity TTL" is added with validation and immediate settings API persistence. Empty means No Cache.

Area

  • Proxy / upstream routing
  • Dashboard UI

Additional context

codex-lb already distinguishes internal_unanchored_parallel forks at creation time via _http_bridge_unanchored_parallel_fork_key in helpers.py. The fork key differs from the canonical key, but the resulting bridge session inherits the parent's affinity kind, giving it the PROMPT_CACHE idle TTL (default 3600s) instead of the base bridge idle TTL (default 120s).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions