feat: auto-generate concise thread titles on first turn - #579
Open
angri450 wants to merge 1 commit into
Open
Conversation
Replace the full-first-message-as-title behavior with an async one-shot model call (<=6 words, 30s budget, no tools) that never blocks the turn. Fall back to a truncated first line on failure, timeout, or upstream rate limit. set_title_if_null is idempotent, so a title that did not finish is retried on the next turn. - title_gen.py: httpx call to the first usable provider model + sanitizer (wrapping quotes / trailing periods / 80-char cap, mirrors openresearch) - processor.py: _touch_thread_after_turn spawns the async generation with the turn's agent_id; call sites pass agent_id - tests: sanitizer/fallback/prompt unit tests - CHANGELOG: [Unreleased] entry
There was a problem hiding this comment.
🟡 Changes recommended
当前实现存在会把“仅空白首条消息”写成空字符串标题并阻断后续重试的风险,且标题长度上限与实际落库裁剪规则不一致需要对齐。
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
该 PR 旨在改进 Recents/线程列表的可读性:不再把“首条用户消息全文”直接落库为线程标题,而是在首轮 turn 结束后异步调用一个廉价 chat 模型生成 ≤6 词的简洁标题,并在失败/超时时回落到“首行截断”,从而避免长标题污染侧边栏显示。
Changes:
- 新增
title_gen.py:通过 httpx 直连 OpenAI 兼容chat.completions生成标题,并提供 sanitize / fallback 逻辑。 - 在
GlobalProcessor._touch_thread_after_turn中改为首轮异步 fire-and-forget 生成标题,不阻塞 turn 主流程。 - 新增单测覆盖 sanitize/fallback/prompt 关键行为,并在 CHANGELOG 记录该特性。
File summaries
| File | Description |
|---|---|
| tests/unit/agents/test_title_gen.py | 为标题 sanitize / fallback / prompt 提供单元测试用例 |
| src/octop/infra/gateway/process/processor.py | 首轮 turn 后异步触发标题生成并回落,避免阻塞响应 |
| src/octop/infra/agents/title_gen.py | 实现 one-shot 标题生成、清洗与回退逻辑 |
| CHANGELOG.md | 在 Unreleased 中记录自动生成简洁会话标题的新增特性 |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
1182
to
+1185
| self._thread_registry.touch_last_active(thread_id) | ||
| if title_source: | ||
| self._thread_registry.set_title_if_null(thread_id, title_source) | ||
| if not title_source: | ||
| return | ||
| try: |
Comment on lines
+23
to
+29
| #: Input cap fed to the model (a title only needs the opening intent). | ||
| _TITLE_INPUT_CAP = 2000 | ||
| #: Longest title we store (sidebar truncates past this anyway). | ||
| _TITLE_MAX_CHARS = 80 | ||
| #: One-shot budget — generous for a cold provider, short enough that a wedged | ||
| #: call does not linger (the fallback title is already acceptable). | ||
| _TITLE_TIMEOUT_SECONDS = 30 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
Octop 当前用首条用户消息全文当线程标题(set_title_if_null(thread_id, msg.text))——Recents 里显示一长段,难以辨认。吸收 openresearch-cli 的 one-shot 标题分级设计(title.rs:cheap 模型 30s 超时、≤6 词、sanitize),改为模型生成简洁标题。
改动
octop/infra/agents/title_gen.py(新):httpx 直发首个可用 provider(OpenAI 兼容 chat.completions,30s 超时、60 max_tokens、temperature 0.3)+_sanitize_title(引号包裹/尾句号剥两次/80 字符上限,照 openresearch title.rs)+_fallback_title(首行截断)processor.py _touch_thread_after_turn:首轮(标题为 NULL)异步 fire-and-forget 生成——不阻塞 turn;失败/超时/上游限流回落截断首行;set_title_if_null幂等,未完成下次 turn 重试agent_id(生成用首个可用 provider 模型,标题不绑 agent)tests/unit/agents/test_title_gen.py(sanitize/fallback/prompt 6 用例)设计要点
测试计划