Skip to content

fix(history): show the provider's real session title, not the first prompt - #72

Merged
Germey merged 1 commit into
mainfrom
fix/claude-history-ai-title
Jul 28, 2026
Merged

fix(history): show the provider's real session title, not the first prompt#72
Germey merged 1 commit into
mainfrom
fix/claude-history-ai-title

Conversation

@acedatacloud-dev

Copy link
Copy Markdown
Member

问题

历史会话抽屉里显示的名字,和用户在 Claude Code 里看到的 session 名字对不上。

原因:三个 provider 都会给会话起名,但代码只读了两个。

Provider 官方标题来源 修复前
Codex ~/.codex/session_index.jsonlthread_name 列表用了,但详情页没用(两者打架)
Copilot <session>/workspace.yamlname
Claude transcript 里的 ai-title 记录 完全没读,退化成截断首条 prompt

Claude Code 每个会话都会写若干条 {"type":"ai-title","aiTitle":"…"},随对话推进不断精炼(最后一条为准)。history.py 从头到尾没认这个记录类型。

实测对照:

修复前(首条 prompt) 修复后(Claude Code 真实名字)
有个痛点,定时任务触发之后。。运行中的时… 定时任务运行时无法打开会话
这里如果指定了 connector 账号,也显示出… 显示指定的 connector 账号
你这个 x skill 是不是有问题啊。。为啥… 移除 x skill 的账号限制

改动

  1. Claude 读 ai-title,列表与详情一致;空标题不覆盖已有标题(后写的空值不清空好标题)。
  2. Codex 列表/详情统一_codex_read 此前仅在标题为空时才查索引,导致抽屉显示 thread_name、点开却显示首条 prompt。
  3. provider 自报标题统一 sanitise:抽出 _provider_title()isinstance 守卫 + _clean_title),四个取值点全部接上。Codex/Copilot 此前用的是裸值——本机 48 条索引里 11 条超 80 字符,最长一条是 120 字符的提示词脚手架泄漏。
  4. 一个坏文件不再拖垮整个列表_summaries 原先只吞 OSError,任一 transcript 抛别的异常会让所有会话消失。改为吞 Exception 并记日志(KeyboardInterrupt 仍会传播)。

前端无需改动,HistoryDrawer.vue 只是渲染 item.title

验证

真实数据(本机 855 个 transcript):125 个 Codex 会话中超长/非 str 标题 0 个,列表与详情标题全部一致;Claude 侧抽样标题即 CLI 自己的名字。

测试:history 27/27 通过(净增 6 个)。全量 531 passed / 22 failed,干净 origin/main 基线为 525 / 22 —— 失败集完全一致(channels/portal 网络超时 + version 元数据,与本改动无关)。ruff check 通过。

变异测试 14 个变异体全部被杀,含:四个 sanitise 点各一、_provider_title 的两半守卫、Claude ai-title 的 last-wins 与 blank-non-clobber、_claude_read 覆盖、Codex 详情优先级、except OSError 回退、日志行、logger 命名空间。

🤖 对抗评审

Codex 额度耗尽(You've hit your usage limit),回落到 Claude general-purpose subagent。3 轮收敛,共 8 条 RISK,全部修复或申辩,无一遗漏。

第 1 轮 — 5 条:isinstance 守卫无测试覆盖(可被静默删除);一个坏文件炸掉整个列表;blank-clobber 语义未测;_clean_titleaiTitle 形同虚设;Codex 列表/详情标题不一致(评审员用合成 fixture 实证:list 返回 thread_name、read 返回首条 prompt)。全部修复。

第 2 轮 — 3 条,其中第一条是我在第 1 轮修复中引入的:把 Codex thread_name 提升为权威值时没走 _clean_title,泄漏面从列表扩大到详情(评审员在真实 session_index.jsonl 里找到 120 字符的提示词脚手架);非 str thread_name 会把裸 dict 送进前端 title: stringexcept Exception 让会话静默消失且无日志。全部修复 → 抽出 _provider_title

第 3 轮 — 1 条,又是我上一轮修复引入的:日志 logger 用了 logging.getLogger(__name__)coding_bridge.history,下划线),而守护进程只配置 coding-bridge(连字符)根 logger 且 propagate=False——我加的日志既进不了 agent.log 也进不了 CLS,恰好废掉了它自己的诊断目的。评审员同时指出旧测试用 caplog 挂在真根 logger 上,对错命名空间无差别(改成正确名字仍 27/27 绿)。

已端到端复现(调 logs.setup() 后触发跳过,agent.log 为空、"sid-bad" in contentFalse),改用 coding-bridge.history 并把测试重写为真实跑 logs.setup() 断言落盘。写完发现全量套件下该测试会挂——别的测试先装了 handler,setup() 幂等跳过建文件,log_path 指向不存在的文件;已改为借还 handler。变异验证:错误命名空间现在会被测试杀掉(此前不会)。

申辩 1 条并被采纳_claude_summary 里的 continue 删掉后变异体存活。我主张这是行为等价(下一行即 kind in ("user","assistant") 守卫),不该也无法被测试区分;评审员独立复现后确认「your rebuttal is correct」——同时验证 _claude_read 里的同名 continue 删掉被杀,二者不对称是对的。

🤖 Generated with Claude Code

…rompt

Claude transcripts carry the CLI's own session name in `ai-title` records
(re-emitted as it gets refined). We ignored them and fell back to truncating
the first user prompt, so the browser's history list disagreed with what the
user sees in Claude Code — e.g. "有个痛点,定时任务触发之后。。运行中的时…"
instead of "定时任务运行时无法打开会话".

Codex had a related split: the list used `thread_name` but the opened session
header fell back to the first prompt, so the two disagreed. Both now prefer the
provider's own title consistently.

Provider-written titles are third-party data, so route all three through
`_provider_title` — Codex/Copilot previously used theirs raw, and 11 of 48 real
`session_index.jsonl` entries here exceed the 80-char cap (the longest is 120
chars of leaked prompt scaffolding).

Also stop one unreadable transcript from failing the whole listing — these
files are written by third-party CLIs, so `_summaries` now skips on any
exception rather than only OSError, logging the skip so a vanished session
stays diagnosable.
@Germey
Germey merged commit 3642c0d into main Jul 28, 2026
3 checks passed
@Germey
Germey deleted the fix/claude-history-ai-title branch July 28, 2026 06:03
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