[AI-1398] Capture Cursor ACP native session title (daemon)#331
Conversation
cursor-agent's ACP stream auto-titles the session via a
`session_info_update` sessionUpdate carrying `{title}`. The daemon dropped
it as AcpUpdateKind.Unknown, so hosted-Cursor agents showed their random
8-char id as the session title.
Reduce() now maps `session_info_update` to a new AcpUpdateKind.SessionInfo
carrying the title; AcpEventTranslator emits a SessionTitle envelope (new
AcpEventKind, mirrored to the server contract) when a non-blank title is
present. The server half consumes this to update the displayed prompt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR Summary by QodoCapture ACP session_info_update titles as SessionTitle events in daemon
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo
1.
|
realtonyyoung
left a comment
There was a problem hiding this comment.
Summary: 1 actionable finding: keep standalone session-title updates from splitting chunk aggregation.
| ToolIsError: update.ToolIsError, | ||
| TimestampIso: timestampIso); | ||
|
|
||
| case AcpUpdateKind.SessionInfo: |
There was a problem hiding this comment.
[P2] Preserve the open chunk run across SessionInfo
AggregateUpdate routes this new kind through its default branch, which calls FlushOpenRunLocked() before invoking this translator. Therefore a session_info_update that arrives between two agent_message_chunk (or thought-chunk) frames splits one contiguous run into two AssistantText/AssistantThinking envelopes. Since this title is standalone metadata and must not perturb chunk aggregation, handle SessionInfo separately in AggregateUpdate so it emits the title without closing _openRunKind, and add an interleaving runtime test (chunk → session info → chunk).
AggregateUpdate sent the new SessionInfo kind through its default branch, which calls FlushOpenRunLocked() before translating — so a session_info_update interleaved between two message/thought chunks split one contiguous assistant run into two transcript envelopes. Session-title metadata is not transcript content and must not perturb chunk aggregation: SessionInfo now emits its envelope standalone, leaving the open run untouched, so the surrounding chunks still coalesce into one AssistantText/AssistantThinking envelope. Adds a chunk → session_info → chunk regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
NO FINDINGS |
- GetStringOrNull now guards ValueKind == String before calling GetString(), which throws on a non-string JSON value (number/object/array). A schema-drift session_info_update with a wrong-typed title would otherwise bubble an exception up and make the read loop skip the entire notification frame; a wrong-typed field is now treated as absent (Title=null). Benefits every field the reducer reads (toolCallId/kind/status/title). - Drop the Linear-issue-numbered doc filename from a test XML comment (repo source-comment hygiene). Adds a non-string-title reduce regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
NO FINDINGS |
Problem
When dogfooding a hosted Cursor agent, the session title always showed as a random 8-char hex id.
cursor-agent acpauto-titles its session and emits asession_info_updatesessionUpdate carrying{title}(e.g.{"sessionUpdate":"session_info_update","title":"Shell Reporter"}), but the daemon dropped it asAcpUpdateKind.Unknown, so the title never reached the server.Change (daemon half)
AcpHostedAgentRuntime.Reduce()mapssession_info_update→ a newAcpUpdateKind.SessionInfocarrying the title on a newAcpSessionUpdate.Titlefield.AcpEventTranslator.Translate()emits aSessionTitleenvelope (newAcpEventKind, string valuesession_title) when a non-blank title is present; a title-less info update is dropped.AcpEventKind.SessionTitleto the daemon-local Core contract, mirrored to the server-sideCapacitor.Server.Core.Acp.AcpEventKind(kcap-server companion PR).Tests
AcpHostedAgentRuntimeTests—session_info_updatereduces toSessionInfowith the captured title.AcpEventTranslatorTests—SessionInfo+ title →SessionTitleenvelope; blank/null/whitespace title → null.AcpEventEnvelopeWireCompatTests— locks thesession_titlewire value.FakeAcpAgent.BuildSessionInfoUpdatehelper (probe-confirmed shape).Full CLI unit suite green (3349/3351, 2 gated live E2E skipped).
Companion PR
kcap-server #1123: applies the
SessionTitleenvelope to the hosted-agent UI (durable title event + live agent-card prompt sync). Safe to merge in either order — an unknown kind is ignored by whichever side is behind.