Skip to content

feat: ask the harness to title a session - #40

Merged
dviejokfs merged 7 commits into
mainfrom
feat/harness-session-titles
Oct 12, 2026
Merged

dviejokfs merged 7 commits into
mainfrom
feat/harness-session-titles

Conversation

@dviejokfs

@dviejokfs dviejokfs commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

Lets a caller ask the harness to title a new session, the way the harness's own client does.

  • TurnRequest::request_session_title: the user's own description of the task (normally the first prompt, without injected context). Keep setting it until a title arrives.
  • TurnEvent::SessionTitle and TurnResult::session_title: the title, trimmed and de-duplicated.
  • Carried over the protocol (ProtocolTurnInput::request_session_title) and never logged.

Per harness:

  • Claude Code: generate_session_title, asked after the turn's first frame.
  • Codex app-server: replays the TUI's hidden, ephemeral, read-only title thread on the turn's own connection, with every tool disabled and one fallback model attempt.
  • OpenCode serve: titles through its session API.

Generation runs alongside the turn and never delays or fails it. A turn that ends first simply reports no title.

Why

Temps Fleet's uncommitted src/agents/runtime_sdk.rs change uses SdkTurnEvent::SessionTitle and request_session_title. Fleet's pin (dafba07) doesn't have them, so Fleet can't commit that change until this merges and the pin moves.

Verification

cargo fmt --check, cargo clippy --locked --all-targets --all-features -- -D warnings and cargo test --all-features --lib (442 passed) are clean locally. CI runs a newer clippy than my local toolchain, so its first run may report lints I could not reproduce.

🤖 Generated with Claude Code

dviejokfs and others added 3 commits October 12, 2026 20:53
Add TurnRequest::request_session_title, TurnEvent::SessionTitle and
TurnResult::session_title so a caller can have the harness title a new
session the way its own client does. Claude Code answers
generate_session_title, the Codex app-server replays its TUI's hidden title
thread, and opencode serve titles through its session API. Generation runs
alongside the turn and never delays or fails it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@dviejokfs
dviejokfs marked this pull request as ready for review October 12, 2026 19:14
@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; all previous findings are addressed.

Summary

This PR lets callers ask the harness for a session title and receive it through SessionTitle.

  • Callers can ask supported harnesses to title new sessions.
  • Codex titles new sessions on a separate hidden thread.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Caller requests a title] --> B[User turn starts]
  B --> C[Harness title work runs alongside turn]
  C --> D{Title arrives first?}
  D -->|Yes| E[Report SessionTitle]
  D -->|No| F[Finish turn without a title]
  C --> G[Offer optional provider writes]
  G --> H{Writer accepts bytes?}
  H -->|None| I[Drop optional frame]
  H -->|Some| J[Keep unfinished bytes]
  J --> K[Send remainder before later frames]
Loading

Reviews (5) · Last reviewed commit: "fix(runtime): keep the unsent rest of a ..." · Reviewed by Greptile

Comment thread src/providers/codex_app_server.rs
Comment thread src/providers/codex_app_server.rs
dviejokfs and others added 3 commits October 12, 2026 21:26
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A nested `mcp_servers` object in thread/start replaces a server's whole
definition. Codex refuses that ("invalid transport") for a server only a
`--config` override on the app-server defines, as an application like Fleet
launches it, so the hidden title thread never started and no title arrived.
Dotted `mcp_servers.<name>.enabled` keys merge instead. Names that cannot be
written unquoted keep the table form.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…den threads

A completed turn could fail with ProcessIo when the title's
thread/unsubscribe (or Claude's title request) was written to a stdin the
provider had already closed, and a blocked write delayed completion because
both runtime paths awaited every write before checking the terminal frame.

AdapterOutput gains optional_writes: frames the runtime offers to stdin
once, drops if it would block, and whose failure it ignores. Every title
frame of the Codex flow and Claude's generate_session_title use it. A frame
the writer began to accept is finished first so the stream stays framed.

A hidden thread whose thread/start was answered after its turn ended
(including on a retained connection between turns) never got
thread/unsubscribe and stayed loaded. The answer to a title thread/start is
now recognized by its request id: the turn parser unsubscribes any such
thread no live flow awaits, and AgentAdapter::idle_frame_writes lets the
idle supervisor do the same for replies read between turns.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Comment thread src/runtime.rs Outdated
An optional frame the provider's stdin accepted only in part was abandoned
after a timeout, leaving a fragment without its newline that the next
required write (a request or an approval reply) was glued onto.

The runtime now wraps every provider stdin in a FrameWriter. A frame it
accepted in part keeps its unsent remainder, and the remainder goes out
before any later write, required or optional. An optional write still never
waits: it is offered once and dropped if nothing is accepted.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@dviejokfs
dviejokfs merged commit 95f2038 into main Oct 12, 2026
7 checks passed
dviejokfs added a commit that referenced this pull request Oct 12, 2026
Resolves the CHANGELOG overlap with the session title PR (#40).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant