feat(proxy): subagent prompt-cache TTL and session lifecycle - #1309
feat(proxy): subagent prompt-cache TTL and session lifecycle#1309tobwen wants to merge 3 commits into
Conversation
c18c81c to
beb1807
Compare
|
Maintainer decision: direction approved — header-based subagent detection (
Ping me once it's rebased and reviewed and I'll take it from there. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: beb18073f8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
beb1807 to
80e994b
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80e994bea7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 21bad215db
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
f55ca31 to
ce237e4
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce237e416d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ce237e4 to
a2b3716
Compare
ee12b05 to
4f9a321
Compare
4f9a321 to
de1d932
Compare
Add subagent prompt-cache affinity TTL setting with NULL default (No Cache). Subagent sessions are detected via x-parent-session-id header. - NULL/0 TTL: bridge session and stream lease released immediately after stream end; no sticky mapping created - Positive TTL: bridge session retained for configured duration, then closed; sticky mapping created and cleaned after TTL Unanchored parallel forks (internal_unanchored_parallel) are closed immediately after stream end, releasing their stream lease. This prevents parallel fork sessions from consuming stream capacity for the parent prompt-cache idle TTL (3600s). The is_subagent flag propagates from header detection through account selection to sticky session persistence. The cleanup scheduler respects subagent TTL independently from parent sessions. Includes dashboard settings control, frontend display, Alembic migrations, and OpenSpec specifications.
de1d932 to
e148598
Compare
e148598 to
4cce15b
Compare
|
Still want this for #1307 — the header-based subagent detection and immediate close of internal_unanchored_parallel fork sessions were already approved in direction (see the maintainer note above). The branch is now CONFLICTING against current main (head 4cce15b). Please rebase onto current main; note this PR carries the db migration label, so keep the Alembic revision chained off main's current head when you rebase. Merge gates will run right after. |
|
Timing note from triage: this is feature-class, so per the release policy it's queued behind the v1.23.0 stable cut (#1472) regardless of rebase state — no need to chase the current conflicts yet, since main will move again when the cut lands. Once #1472 merges, please rebase onto that main (heads-up: the conflict surface today spans |
|
This pull request has been automatically marked as stale because it has had no activity for 7 days. It will be closed in 23 more days unless there is new activity. If this is still relevant, please:
Thanks for the contribution 🙏 |
|
Post-#1703 status: the thread-identity affinity work has now merged (35bbb00), and it deliberately moves away from subagent-marker inference — the |
|
Closing after maintainer review: the detection mechanism here (x-parent-session-id / x-openai-subagent header inference + an is_subagent sticky-sessions column) is now structurally superseded — #1703 (merged 08-15) derives a versioned internal thread key from Codex's own (process session, thread-id) identity contract and explicitly rejects marker-based subagent inference, and #1747's idle-session sweep addresses the original lease-hogging complaint from #1307. A rebase would be a ground-up redesign rather than a mechanical update, as predicted back on 07-30. What this PR still uniquely proposed — a configurable subagent cache-affinity TTL and deterministic close of fork sessions at stream end (vs sweep-based reclaim) — remains a valid feature direction, but it would now be keyed on #1703's thread identity. #1307 stays open to track that; if the sweep turns out to be sufficient in practice we'll close it too. Thanks for the design groundwork — the TTL/lifecycle framing shaped how we evaluated #1703. |
Summary
Adds a subagent prompt-cache affinity TTL setting (default
NULL/ No Cache) that controls how long subagent bridge sessions retain their stream lease andPROMPT_CACHEsticky mapping after the response stream ends. Also closesinternal_unanchored_parallelfork bridge sessions immediately after stream completion, preventing them from holding stream leases for the parent's 3600s idle TTL.Type of change
fix:- bug fix (no behavior change beyond the bug)feat:- new user-facing feature or capabilityrefactor:- internal refactor (no behavior change, no API change)docs:- documentation onlychore:/ci:/build:- tooling, CI, packagingtest:- test-only changeLinked issue: Closes #1307
OpenSpec
Change directory:
openspec/changes/add-subagent-prompt-cache-ttl/Changes
Subagent detection and TTL
x-parent-session-id,x-openai-subagent, orx-codex-parent-thread-idheaders in_get_or_create_http_bridge_sessionhttp_responses_session_bridge_subagent_prompt_cache_ttl_secondsdashboard setting (nullable Integer, defaultNULL)NULLor0: suppress sticky key and mapping for subagents; bridge session and stream lease released immediately after stream endPROMPT_CACHEmapping retained for the configured TTL, then released via delayed background close taskFork close
internal_unanchored_parallelfork sessions are closed immediately when their response stream ends, releasing the stream leaseSticky session persistence
is_subagentcolumn tosticky_sessionstable (Alembic migration)is_subagentflag propagates from header detection through account selection to sticky session persistenceDashboard
Alternatives considered
is_forkflag with a separate fork idle TTL. Discarded because OpenCode sends tool calls as ordinary conversation requests, not as distinguishable forks. Theis_forkflag could not reliably identify the target sessions.x-openai-subagentheader as the sole detection signal. Discarded because OpenCode does not send this header.x-parent-session-idis the actual header OpenCode sends for subagent requests.GET/DELETE /api/http-bridge-sessions) with a dashboard table. Discarded to keep scope minimal. The fork close and subagent TTL already release stream leases promptly.Test plan
330 passed, ruff clean, OpenSpec 42/42.
Screenshots / output (optional)
Checklist
<type>(<scope>)?: <subject>).uv run ruff checkanduv run ruff format --checkon changed files.openspec validate --specspasses and/opsx:verifyis clean.