Skip to content

feat: multi-session support and improved session naming#65

Merged
Zhang-Henry merged 5 commits intomainfrom
feat/multi-session-management
Mar 22, 2026
Merged

feat: multi-session support and improved session naming#65
Zhang-Henry merged 5 commits intomainfrom
feat/multi-session-management

Conversation

@davidliuk
Copy link
Copy Markdown
Collaborator

@davidliuk davidliuk commented Mar 21, 2026

This PR introduces support for multiple concurrent sessions and improves session naming logic.

Key Changes:

  • Multi-session support: Unblocked the WebSocket message loop by removing sequential await on chat commands. This allows users to switch between and interact with multiple sessions simultaneously.
  • Session safety: Added isSessionActive checks to prevent duplicate concurrent requests to the same session while allowing different sessions to run in parallel.
  • Improved session naming: Implemented a robust stripInternalContextPrefix utility to remove technical [Context: ...] markers from session titles and summaries.
  • Semantic summaries: Updated the session file parser to better extract meaningful names from the first user message, even when prepended with context metadata.
  • Fixed session reuse: Added logic to clear stale provider session IDs from sessionStorage when starting an explicit new session.

@davidliuk davidliuk requested a review from bbsngg March 21, 2026 16:49
@Zhang-Henry
Copy link
Copy Markdown
Collaborator

Code Review

Bug 1 — Claude SDK 双重错误消息

server/index.js 中 claude-command handler 的 .catch() 会发送 claude-error 给客户端。但 server/claude-sdk.jsqueryClaudeSDK 内部已有 catch 块发送 claude-error 后 re-throw。客户端会收到两条错误消息。

修复建议:去掉 index.js.catch() 里的 writer.send(只保留 console.error),或让 queryClaudeSDK 不 re-throw。

Bug 2 — sanitizePersistedGeminiContent 行为改变

server/gemini-cli.js 约第788行,sanitizePersistedGeminiContent 调用 stripInternalContextPrefix(content) 。旧的本地函数对空字符串返回 '',新的共享函数(server/utils/sessionFormatting.js)默认 returnDefaultOnEmpty=true,对纯 context 前缀返回 'New Session'

这意味着 Gemini 的聊天内容如果只有 [Context: ...] 前缀,会在响应中显示 "New Session"。

修复:调用处改为 stripInternalContextPrefix(content, false)

Bug 3 — 系统消息检测在 strip 之前执行

server/projects.jsparseJsonlSessions 中,isSystemMessage 检查(textContent.startsWith('<command-name>') 等)在 stripInternalContextPrefix 之前执行。如果消息以 [Context: ...] <command-name>... 开头,startsWith 返回 false,系统消息不会被过滤,会泄漏到 session name 中。

修复:先 strip 再检查 isSystemMessage,或在 isSystemMessage 检查中也处理 context 前缀的情况。

中等问题

  • TOCTOU 竞争isXSessionActive 检查和 session 注册(addSession)之间有多个 await,两条快速到达的消息可以同时通过检查
  • stripInternalContextPrefix 重复 4 次:服务端共享 util + 客户端 3 份(messageTransforms.tsMainContentTitle.tsxsidebar/utils/utils.ts),且客户端版本缺少 session-mode 语义回退
  • useChatComposerStateisExplicitNewSessionStart 只检查 routedSessionId(比旧的 isExplicitNewSession 更宽泛),当有 currentSessionId 但无路由 session 时可能过度清理 sessionStorage

@davidliuk
Copy link
Copy Markdown
Collaborator Author

Thanks @Zhang-Henry for your comprehensive review! I already fixed them with a new commit.

@davidliuk davidliuk force-pushed the feat/multi-session-management branch from f416f1b to 415f480 Compare March 22, 2026 00:06
…rn, both imports, stripInternalContextPrefix)
@Zhang-Henry Zhang-Henry merged commit 6260df3 into main Mar 22, 2026
1 check passed
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.

2 participants