Skip to content

[Fix] Keep conversation commands on the active preset lane#825

Merged
dingyi222666 merged 1 commit intov1-devfrom
fix/conversation-system
Apr 12, 2026
Merged

[Fix] Keep conversation commands on the active preset lane#825
dingyi222666 merged 1 commit intov1-devfrom
fix/conversation-system

Conversation

@dingyi222666
Copy link
Copy Markdown
Member

This pr keeps conversation management commands aligned with the active preset lane, fixes numeric target resolution to follow the visible conversation list, and only includes archived conversations when commands explicitly request them.

New Features

  • Added --preset support to chatluna.list.
  • Added --archived and --all options to restore, export, compress, and delete conversation commands.

Bug fixes

  • Fixed switch, list, rollback, and stop_chat so they resolve the active conversation from the current preset lane.
  • Fixed numeric conversation targets so they resolve by the visible list order instead of raw sequence values.
  • Fixed conversation target completion so archived conversations stay hidden unless a command opts in.

Other Changes

  • Updated English and Chinese locale entries for the new conversation command options.
  • Added regression tests for conversation resolution, target completion, rollback fallback, and stop fallback.

Keep explicit conversation commands aligned with the active preset lane so switch, list, rollback, and stop operate on the same conversation set users see. Resolve numeric conversation targets through visible list order and let management commands opt into archived conversations when needed.

Tests: not run (not requested)
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 12, 2026

总体概览

该PR对对话管理系统进行了重构,核心改进包括:添加预设车道(preset lane)支持到多个命令中;更新中间件的对话解析逻辑以支持预设选项和存档过滤;简化数字目标解析流程,改为基于显示序列而非存储序列;扩展completeConversationTarget函数签名以支持灵活的存档过滤控制;并增加综合测试覆盖预设车道和存档对话的行为验证。

变更清单

内聚组 / 文件 摘要
命令行参数扩展
packages/core/src/commands/conversation.ts
chatluna.switchchatluna.list添加预设选项;为chatluna.restorechatluna.exportchatluna.compresschatluna.delete添加存档(-a)和全部(--all)选项;更新completeConversationTarget调用传参以支持新的预设和存档处理。
对话路由中间件
packages/core/src/middlewares/conversation/resolve_conversation.ts, packages/core/src/middlewares/conversation/request_conversation.ts
调整useRoutePresetLane判断逻辑,从依赖context.command改为基于预设选项和对话目标的显式检查,改进隐式与显式对话选择的区分。
聊天执行中间件
packages/core/src/middlewares/chat/rollback_chat.ts, packages/core/src/middlewares/chat/stop_chat.ts
引入hasTarget标志优化条件分支;更新getCurrentConversation调用方式,显式传递预设车道选项对象,改进对活跃对话的解析。
对话管理系统中间件
packages/core/src/middlewares/system/conversation_manage.ts
支持预设车道在对话切换和列表中的处理;更改缓存键生成逻辑以纳入includeArchived状态;优化目标解析时的存档过滤传参从硬编码true改为条件判断。
对话服务
packages/core/src/services/conversation.ts
移除useDisplaySeq决策分支,简化数字目标解析为统一基于显示序列的方式,不再在全局范围使用存储序列号。
对话目标补全工具
packages/core/src/utils/conversation.ts
扩展函数签名添加resolveIncludeArchived参数;重构数字目标映射逻辑,从返回原始数字改为映射到规范的对话ID;改进对话过滤和建议的控制流。
测试套件
packages/core/tests/conversation-resolve.spec.ts, packages/core/tests/conversation-service.spec.ts, packages/core/tests/conversation-target.spec.ts, packages/core/tests/rollback-chat.spec.ts
新增121行对话解析中间件测试;更新约10行对话服务约束记录;扩展99行对话目标补全测试验证显示序列映射;添加274行预设车道和停止聊天中间件测试。

时间序列图

sequenceDiagram
    participant User as 用户
    participant Cmd as 命令层<br/>(conversation.ts)
    participant Mgr as 对话管理中间件<br/>(conversation_manage)
    participant Resolve as 路由解析中间件<br/>(resolve_conversation)
    participant Service as 对话服务<br/>(conversation.ts)
    participant Utils as 工具函数<br/>(completeConversationTarget)

    User->>Cmd: 执行带预设选项的命令
    activate Cmd
    Cmd->>Cmd: 提取presetLane选项
    Cmd->>Utils: 调用completeConversationTarget(含presetLane)
    activate Utils
    Utils->>Service: 调用resolveCommandConversation
    activate Service
    Service->>Service: 基于displaySeq映射数字目标
    Service-->>Utils: 返回规范对话ID
    deactivate Service
    Utils-->>Cmd: 返回完成的对话目标
    deactivate Utils
    Cmd->>Mgr: 传递presetLane和includeArchived
    deactivate Cmd
    activate Mgr
    Mgr->>Mgr: 根据presetLane调整缓存键<br/>(active vs all)
    Mgr->>Resolve: 触发对话解析
    deactivate Mgr
    activate Resolve
    Resolve->>Resolve: 判断useRoutePresetLane<br/>(基于显式选择)
    Resolve-->>Cmd: 返回解析结果
    deactivate Resolve
Loading

代码审查工作量评估

🎯 4 (复杂) | ⏱️ ~45 分钟

可能相关的PR

诗篇

🐰 车道分明有条序,
存档对话显序号,
预设流转如兔跃,
映射规范识归处,
中间件层层递进妙~

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: keeping conversation commands aligned with the active preset lane, which is the core focus of this comprehensive PR.
Description check ✅ Passed The description is well-organized and directly related to the changeset, clearly explaining new features, bug fixes, and test additions that match the implementation changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/conversation-system

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances conversation management by adding preset, archived, and all options to various commands and refactoring conversation resolution logic across several middlewares. Key changes include updating completeConversationTarget to resolve numeric display sequences to canonical IDs and ensuring that fallback logic for current conversations only triggers when no explicit target is provided. Feedback was provided regarding the stop_chat middleware to ensure its fallback behavior is consistent with rollback_chat, preventing accidental stops when an invalid target is specified.

Comment thread packages/core/src/middlewares/chat/stop_chat.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/src/middlewares/chat/stop_chat.ts (1)

42-66: ⚠️ Potential issue | 🟠 Major

仅在未显式指定目标时才回退到当前会话。

这里 conversation == null 就会回退到当前活动会话;如果用户已经传了 conversationIdtargetConversation,但解析失败,这个分支会误停掉当前会话,而不是返回“目标不存在”。同一 PR 里的 rollback_chat 已经用 !hasTarget 避免了这个问题,这里也应保持一致。

💡 建议修改
-            if (conversation == null) {
+            if (conversation == null && !hasTarget) {
                 conversation = (
                     await ctx.chatluna.conversation.getCurrentConversation(
                         session,
                         {
                             presetLane: context.options.presetLane,
                             useRoutePresetLane:
                                 context.options.presetLane == null
                         }
                     )
                 ).conversation
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/middlewares/chat/stop_chat.ts` around lines 42 - 66, The
current fallback to the active conversation runs whenever conversation == null,
which wrongly triggers even if the user explicitly provided a target that failed
to resolve; introduce a hasTarget boolean (e.g., based on
context.options.conversationId or context.options.targetConversation) and change
the logic so the getCurrentConversation/resolveCommandConversation fallback only
runs when !hasTarget; if hasTarget and the resolved conversation is null,
return/propagate a "target not found" error instead of falling back. Target
symbols: conversation variable,
ctx.chatluna.conversation.getCurrentConversation,
ctx.chatluna.conversation.resolveCommandConversation, and
context.options.presetLane / context.options.allPresetLanes.
🧹 Nitpick comments (2)
packages/core/src/middlewares/system/conversation_manage.ts (1)

290-298: includeArchived || undefined 模式可以简化

includeArchived: includeArchived || undefinedfalse 转换为 undefined。根据 getTarget 方法的默认参数 includeArchived = falseresolveTargetConversation!options.includeArchived 的判断逻辑,undefinedfalse 的行为是相同的。

可以考虑直接传递 includeArchived 布尔值,简化代码:

-                    includeArchived: includeArchived || undefined,
+                    includeArchived,

这个模式在多处使用(archive、restore、export、delete、compress),如果简化可以保持一致性。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/middlewares/system/conversation_manage.ts` around lines 290
- 298, 当前在 conversation_manage 中通过 includeArchived: includeArchived || undefined
将 false 转换为 undefined,冗余且与 getTarget 的默认参数和 resolveTargetConversation 中对
!options.includeArchived 的判断等价;请在 ctx.chatluna.conversation.deleteConversation
调用(以及其它类似处:archive、restore、export、delete、compress 分支)直接传递布尔值 includeArchived 而不是
includeArchived || undefined,并确保相关调用(例如 resolveTargetConversation /
getTarget)仍按布尔值处理以保持行为不变。
packages/core/src/commands/conversation.ts (1)

92-96: list 命令的 -P 选项与其他命令不一致

chatluna.list 使用大写 -P 作为 preset 选项的短选项,而其他命令(如 switchcurrentarchive 等)都使用小写 -p。这是因为 -p 已被 page 选项占用。

这种不一致可能会让用户困惑。建议在文档或帮助信息中明确说明这一点,或者考虑将 page 选项改为其他短选项(如 --page 仅使用长选项)以保持 -p 用于 preset 的一致性。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/commands/conversation.ts` around lines 92 - 96, The preset
short flag is inconsistent: in conversation.ts the list command registers
.option('page', '-p <page:number>') and .option('preset', '-P <preset:string>')
so preset uses -P while other commands (switch/current/archive) use -p; change
the flags to be consistent by removing the short '-p' from the page option (use
only the long option 'page' / '--page') and reassign the lowercase '-p' to the
preset option (i.e., make .option('preset', '-p <preset:string>')) or
alternatively document the exception in the help text; update the option
definitions in the list command (page and preset) accordingly so they match the
short-option convention used by switch/current/archive.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/tests/conversation-resolve.spec.ts`:
- Around line 91-100: The mock middleware builder currently returned only an
after() method which can cause runtime errors if code calls .before(); update
the mock returned object in the middleware arrow (where run is set from fn) to
also implement a before() method that returns this, matching the pattern used in
rollback-chat.spec.ts; ensure the signature and chaining behavior mirror after()
so any request_conversation middleware calling .before() will work without
error.

---

Outside diff comments:
In `@packages/core/src/middlewares/chat/stop_chat.ts`:
- Around line 42-66: The current fallback to the active conversation runs
whenever conversation == null, which wrongly triggers even if the user
explicitly provided a target that failed to resolve; introduce a hasTarget
boolean (e.g., based on context.options.conversationId or
context.options.targetConversation) and change the logic so the
getCurrentConversation/resolveCommandConversation fallback only runs when
!hasTarget; if hasTarget and the resolved conversation is null, return/propagate
a "target not found" error instead of falling back. Target symbols: conversation
variable, ctx.chatluna.conversation.getCurrentConversation,
ctx.chatluna.conversation.resolveCommandConversation, and
context.options.presetLane / context.options.allPresetLanes.

---

Nitpick comments:
In `@packages/core/src/commands/conversation.ts`:
- Around line 92-96: The preset short flag is inconsistent: in conversation.ts
the list command registers .option('page', '-p <page:number>') and
.option('preset', '-P <preset:string>') so preset uses -P while other commands
(switch/current/archive) use -p; change the flags to be consistent by removing
the short '-p' from the page option (use only the long option 'page' / '--page')
and reassign the lowercase '-p' to the preset option (i.e., make
.option('preset', '-p <preset:string>')) or alternatively document the exception
in the help text; update the option definitions in the list command (page and
preset) accordingly so they match the short-option convention used by
switch/current/archive.

In `@packages/core/src/middlewares/system/conversation_manage.ts`:
- Around line 290-298: 当前在 conversation_manage 中通过 includeArchived:
includeArchived || undefined 将 false 转换为 undefined,冗余且与 getTarget 的默认参数和
resolveTargetConversation 中对 !options.includeArchived 的判断等价;请在
ctx.chatluna.conversation.deleteConversation
调用(以及其它类似处:archive、restore、export、delete、compress 分支)直接传递布尔值 includeArchived 而不是
includeArchived || undefined,并确保相关调用(例如 resolveTargetConversation /
getTarget)仍按布尔值处理以保持行为不变。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8369ff07-8c4f-47ea-a7ce-554c06c0e9f1

📥 Commits

Reviewing files that changed from the base of the PR and between 99609e2 and ba52a01.

⛔ Files ignored due to path filters (2)
  • packages/core/src/locales/en-US.yml is excluded by !**/*.yml
  • packages/core/src/locales/zh-CN.yml is excluded by !**/*.yml
📒 Files selected for processing (12)
  • packages/core/src/commands/conversation.ts
  • packages/core/src/middlewares/chat/rollback_chat.ts
  • packages/core/src/middlewares/chat/stop_chat.ts
  • packages/core/src/middlewares/conversation/request_conversation.ts
  • packages/core/src/middlewares/conversation/resolve_conversation.ts
  • packages/core/src/middlewares/system/conversation_manage.ts
  • packages/core/src/services/conversation.ts
  • packages/core/src/utils/conversation.ts
  • packages/core/tests/conversation-resolve.spec.ts
  • packages/core/tests/conversation-service.spec.ts
  • packages/core/tests/conversation-target.spec.ts
  • packages/core/tests/rollback-chat.spec.ts

Comment thread packages/core/tests/conversation-resolve.spec.ts
@dingyi222666 dingyi222666 merged commit e384c18 into v1-dev Apr 12, 2026
4 of 5 checks passed
@dingyi222666 dingyi222666 deleted the fix/conversation-system branch April 12, 2026 13:50
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.

1 participant