You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a new ACP agent chat is created, the chat shows a placeholder name like Agent 5f3a9c1b — the literal string Agent plus a slice of the random agent/session id. This comes from the deriveTitle() fallback:
A freshly created session has title: null and no messages yet (src/renderer/stores/acp-store.ts:103, :798), so the Chats history list renders Agent <random>. This is noisy and meaningless to the user — it looks like a bug, and multiple new chats are hard to tell apart.
Separately, ACP already defines a first-class mechanism for agent-generated session titles, but Termul currently throws those titles away. The session_info_update notification (agent → client) is dropped in the Rust client:
// src-tauri/src/acp/client.rs:296-303// SessionInfoUpdate and any future (non_exhaustive) variants have no// dedicated P0 event; ignore them — but log so a silently-dropped// update can be diagnosed instead of vanishing.ref other => {log::debug!("[acp] agent {agent_id} sent an unhandled session/update variant: {other:?}");}
So even when an ACP agent auto-generates a nice session title after the first prompt (e.g. "Implement user authentication"), the renderer never sees it and the chat keeps its placeholder / first-message-slice name.
Proposed Solution
Two coordinated changes:
1. Friendly placeholder for not-yet-started chats
Replace the Agent <random> fallback with an incrementing Untitled Chat N label (e.g. Untitled Chat 1, Untitled Chat 2, …). The number comes from a monotonic counter so concurrent new chats stay distinguishable.
2. Rename on chat start using the ACP session title
Wire the ACP session_info_update notification end-to-end so a started chat is renamed to the agent-provided session name, with a graceful fallback chain:
agent-pushed title (session_info_update) → first user message (existing deriveTitle behavior) → Untitled Chat N
Per the ACP spec, SessionInfo.title is "Human-readable title for the session. May be auto-generated from the first prompt," and agents send session_info_update "after the first meaningful exchange to auto-generate a title" — exactly the "rename when the chat starts" behavior requested here.
Implementation outline:
Rust (src-tauri/src/acp/)
Add EVENT_SESSION_INFO_UPDATE (acp:session_info_update) in events.rs and a SessionInfoUpdateEvent { agent_id, session_id, title } struct.
In client.rs::emit_session_update, handle SessionUpdate::SessionInfoUpdate and emit the new event instead of letting it fall into the debug-log catch-all.
Renderer API (src/renderer/lib/acp-api.ts)
Add sessionInfoUpdate: 'acp:session_info_update' to ACP_EVENTS (~line 312) and export a SessionInfoUpdateEvent type.
Store (src/renderer/stores/acp-store.ts)
Add _onSessionInfoUpdate reducer that sets session.title from the agent title and re-persists the session index entry; subscribe it in initAcpEventListeners.
Introduce the Untitled Chat N counter and use it as the placeholder.
Keep deriving from the first user message only — already the current behavior once a message exists, but it does nothing for the pre-prompt placeholder and ignores the richer agent-generated titles ACP already provides.
session/setTitle (client → agent), spec PR #1199 — enables user-initiated rename pushed back to the agent. It's not in Termul's vendored SDK yet (only session_info_update is stabilized — see src-tauri/vendor/agent-client-protocol/CHANGELOG.md:102), so it's out of scope here but a natural follow-up for manual rename.
Success Criteria
A newly created ACP chat shows Untitled Chat N (not Agent <random>) in the Chats history list and tab.
After the chat starts, if the agent sends session_info_update, the chat is renamed to the ACP session title in real time and the new title persists across app restarts.
If the agent never pushes a title, the chat still falls back to the first-user-message derivation, then to Untitled Chat N.
Will you contribute an implementation?
Yes — I plan to open a pull request.
Problem or Opportunity
When a new ACP agent chat is created, the chat shows a placeholder name like
Agent 5f3a9c1b— the literal stringAgentplus a slice of the random agent/session id. This comes from thederiveTitle()fallback:A freshly created session has
title: nulland no messages yet (src/renderer/stores/acp-store.ts:103,:798), so the Chats history list rendersAgent <random>. This is noisy and meaningless to the user — it looks like a bug, and multiple new chats are hard to tell apart.Separately, ACP already defines a first-class mechanism for agent-generated session titles, but Termul currently throws those titles away. The
session_info_updatenotification (agent → client) is dropped in the Rust client:So even when an ACP agent auto-generates a nice session title after the first prompt (e.g. "Implement user authentication"), the renderer never sees it and the chat keeps its placeholder / first-message-slice name.
Proposed Solution
Two coordinated changes:
1. Friendly placeholder for not-yet-started chats
Replace the
Agent <random>fallback with an incrementingUntitled Chat Nlabel (e.g.Untitled Chat 1,Untitled Chat 2, …). The number comes from a monotonic counter so concurrent new chats stay distinguishable.2. Rename on chat start using the ACP session title
Wire the ACP
session_info_updatenotification end-to-end so a started chat is renamed to the agent-provided session name, with a graceful fallback chain:agent-pushed title (session_info_update)→first user message (existing deriveTitle behavior)→Untitled Chat NPer the ACP spec,
SessionInfo.titleis "Human-readable title for the session. May be auto-generated from the first prompt," and agents sendsession_info_update"after the first meaningful exchange to auto-generate a title" — exactly the "rename when the chat starts" behavior requested here.Implementation outline:
src-tauri/src/acp/)EVENT_SESSION_INFO_UPDATE(acp:session_info_update) inevents.rsand aSessionInfoUpdateEvent { agent_id, session_id, title }struct.client.rs::emit_session_update, handleSessionUpdate::SessionInfoUpdateand emit the new event instead of letting it fall into the debug-log catch-all.src/renderer/lib/acp-api.ts)sessionInfoUpdate: 'acp:session_info_update'toACP_EVENTS(~line 312) and export aSessionInfoUpdateEventtype.src/renderer/stores/acp-store.ts)_onSessionInfoUpdatereducer that setssession.titlefrom the agent title and re-persists the session index entry; subscribe it ininitAcpEventListeners.Untitled Chat Ncounter and use it as the placeholder.src/renderer/lib/acp-history-persistence.ts)deriveTitle()fallback toUntitled Chat N.Alternatives Considered
session/setTitle(client → agent), spec PR #1199 — enables user-initiated rename pushed back to the agent. It's not in Termul's vendored SDK yet (onlysession_info_updateis stabilized — seesrc-tauri/vendor/agent-client-protocol/CHANGELOG.md:102), so it's out of scope here but a natural follow-up for manual rename.Success Criteria
Untitled Chat N(notAgent <random>) in the Chats history list and tab.session_info_update, the chat is renamed to the ACP session title in real time and the new title persists across app restarts.Untitled Chat N.session_info_updatenotifications are no longer silently dropped (resolves item fix: resolve test failures, typecheck errors, and improve Settings UI #2 of ACP: Cleanup dead code, dropped protocol messages, and stale comments #363).deriveTitlefallback, the_onSessionInfoUpdatereducer, and the Rust event emission.Additional Context
ACP references
session_info_updatenotification): https://agentclientprotocol.com/protocol/session-listsession/setTitle(future, client→agent): Add session/setTitle method agentclientprotocol/agent-client-protocol#1199Code references
src/renderer/lib/acp-history-persistence.ts:49-55—deriveTitle()placeholdersrc-tauri/src/acp/client.rs:296-303— droppedSessionInfoUpdatesrc/renderer/stores/acp-store.ts:103,:476,:798— sessiontitlelifecyclesrc/renderer/lib/acp-api.ts:312—ACP_EVENTSsrc-tauri/src/acp/events.rs:20-47—acp:*event constantssrc/renderer/components/chat/AgentBadge.tsx:33,src/renderer/components/workspace/WorkspaceTabBar.tsx:649— label surfacesRelated: Complements #363 (item #2 calls out the dropped
SessionInfoUpdate); this issue is the "implement it properly" counterpart.