[Fix] stabilize conversation resolution flow#828
Conversation
Use a single resolution path across chat and conversation middlewares so explicit targets, preset lanes, and archived lookups behave consistently. This restores target suggestions and keeps command routing stable for direct ids and active-lane commands.
Keep middleware and conversation management on the resolved conversation object instead of duplicating conversation ids in chain options. This tightens target resolution, typed error handling, and archived-target matching so command routing stays consistent after the resolution refactor.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 29 minutes and 35 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
Walkthrough统一对话解析为单一的 Changes
Sequence Diagram(s)sequenceDiagram
participant Cmd as Command (用户/CLI)
participant Chain as Middleware Chain
participant ConvSvc as Conversation Service
participant Store as Conversation Store/DB
Cmd->>Chain: 发起命令/消息(含 options.targetConversation)
Chain->>Chain: resolve_conversation 读取 options.targetConversation / options.conversation
Chain->>ConvSvc: resolveConversation(session, ResolveConversationOptions)
ConvSvc->>Store: 查询/匹配会话 (id/seq/title/archived)
Store-->>ConvSvc: 返回 conversation / ambiguous / not found
ConvSvc-->>Chain: 返回 ConversationResolution (mode, conversationId, conversation, constraint...)
Chain->>Chain: transform_chat_message 使用 context.options.conversation 和消息进行转换
Chain->>Chain: 继续后续中间件(message_delay / handlers)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request refactors the conversation resolution logic by introducing a unified resolveConversation method, replacing legacy methods and simplifying command option parsing. Middlewares and commands are updated to use this centralized flow, which supports multiple resolution modes and improves error handling. Feedback highlights a type discrepancy where the conversation option is typed as ConversationResolution but sometimes used as a partial object, suggesting stricter typing or a partial type definition to improve safety.
Run the repository lint autofixes on the conversation resolution changes. This keeps formatting and import ordering aligned with the project rules without changing behavior.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (7)
packages/core/src/services/types.ts (1)
3-14: 导入排序问题静态分析提示
ConstraintRecord应按字母顺序排列。建议修复以保持代码风格一致性。🔧 建议的导入排序
import { ACLRecord, ArchiveRecord, BindingRecord, + ConstraintRecord, ConversationResolution, ConversationResolveMode, - ConstraintRecord, ConversationRecord, MessageRecord, MetaRecord, ResolveConversationOptions } from './conversation_types'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/services/types.ts` around lines 3 - 14, Reorder the named imports in the import statement so they are alphabetized to satisfy the linter; specifically place ConstraintRecord in its correct alphabetical position among ACLRecord, ArchiveRecord, BindingRecord, ConversationRecord, ConversationResolution, ConversationResolveMode, MessageRecord, MetaRecord, and ResolveConversationOptions (ensure the entire import list is sorted and keep the import from './conversation_types' intact).packages/core/src/middlewares/chat/chat_time_limit_save.ts (1)
23-25: 访问模式可以简化根据
ConversationResolution类型定义,conversationId字段已经是string | null,其值在resolveConversation中被设置为resolved.conversation?.id ?? null。因此context.options.conversation?.conversation?.id的回退是冗余的。可以简化为:
- const conversationId = - context.options.conversation?.conversationId ?? - context.options.conversation?.conversation?.id + const conversationId = context.options.conversation?.conversationId不过当前写法也是安全的,可以作为可选优化。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/middlewares/chat/chat_time_limit_save.ts` around lines 23 - 25, The conversationId resolution is redundant: use the ConversationResolution field directly instead of falling back to context.options.conversation?.conversation?.id; update the assignment of conversationId (the variable in chat_time_limit_save.ts) to read from context.options.conversation?.conversationId (or default to null) and remove the extra fallback expression so the code becomes simpler and relies on the resolved conversationId provided by resolveConversation.packages/core/src/middlewares/system/conversation_manage.ts (1)
705-712: 格式问题需要修复。静态分析工具指出此处存在 prettier 格式问题。建议调整缩进以符合项目格式规范。
🔧 建议修复
const current = - await ctx.chatluna.conversation.updateManagedConstraint(session, { - routeMode - }) + await ctx.chatluna.conversation.updateManagedConstraint( + session, + { routeMode } + )🤖 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 705 - 712, 该段代码因缩进/格式不符合 prettier 导致静态检查失败;请调整 updateManagedConstraint 调用及接续赋值表达式的换行与缩进使其符合项目格式规范:定位到 conversation.updateManagedConstraint 和 conversation.resolveConstraint 使用的表达式(变量 current 和 nextRouteMode),将三元表达式与 await 对齐、适当拆行并确保对象字面量 { routeMode } 与后续链式调用缩进一致,保存并运行 prettier/项目格式化验证通过后提交。packages/core/src/middlewares/chat/rollback_chat.ts (2)
20-25: 考虑内联getTargetConversation函数。根据编码规范,函数体为 1-5 行的函数应在调用处内联。该函数仅在一处使用(第 36 行),可直接内联以减少抽象层。
♻️ 建议修复
-function getTargetConversation(context: ChainMiddlewareContext) { - return ( - context.options.conversation_manage?.targetConversation ?? - context.options.targetConversation - ) -} - // 在第 36 行直接内联: - const targetConversation = getTargetConversation(context) + const targetConversation = + context.options.conversation_manage?.targetConversation ?? + context.options.targetConversationBased on learnings: "Do NOT create extra functions for short logic; if a function body would be 1-5 lines, inline it at the call site instead"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/middlewares/chat/rollback_chat.ts` around lines 20 - 25, The helper function getTargetConversation is a 1-5 line helper that is only used once; inline its logic at the call site instead of keeping a separate function. Replace the call to getTargetConversation(context) with the inline expression context.options.conversation_manage?.targetConversation ?? context.options.targetConversation (preserving the same nullish/coalescing behavior), and remove the getTargetConversation function declaration (the function and its reference to ChainMiddlewareContext can be deleted).
9-12: 按字母顺序排列导入成员。静态分析工具指出
ConversationResolution应按字母顺序排在MessageRecord之后。🔧 建议修复
import { - MessageRecord, - type ConversationResolution + type ConversationResolution, + MessageRecord } from '../../services/conversation_types'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/middlewares/chat/rollback_chat.ts` around lines 9 - 12, 在 rollback_chat.ts 的导入列表中按字母顺序调整导入成员,把 MessageRecord 和 ConversationResolution 的顺序互换以满足静态分析要求;具体在 import {...} from '../../services/conversation_types' 语句中确保 ConversationResolution 位于 MessageRecord 之后(调整 "MessageRecord" 和 "ConversationResolution" 的顺序),保存并让 linter 通过。packages/core/src/services/conversation.ts (2)
525-527: 格式问题建议修复。静态分析指出此处存在 prettier 格式问题,建议调整换行。
🔧 建议修复
conversation = - matchTargetConversation(target, normalized, conversations, entries) ?? - null + matchTargetConversation( + target, + normalized, + conversations, + entries + ) ?? null🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/services/conversation.ts` around lines 525 - 527, Prettier reports a formatting issue on the assignment to the variable conversation; reformat the statement using the matchTargetConversation call so it conforms to project prettier rules (e.g., place the whole assignment on one line or wrap the call with parentheses and break lines consistently). Update the expression involving matchTargetConversation(target, normalized, conversations, entries) and the nullish coalescing (?? null) so the assignment to conversation is properly indented and line-broken according to the code style.
38-52: 按字母顺序排列导入成员。静态分析指出
ConstraintPermission(第 39 行)应按字母顺序排列。🔧 建议修复
import { ACLRecord, applyPresetLane, ArchiveRecord, BindingRecord, computeBaseBindingKey, ConversationResolution, - ConstraintPermission, ConstraintRecord, + ConstraintPermission, ConversationCompressionRecord,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/services/conversation.ts` around lines 38 - 52, Imports from './conversation_types' are not alphabetized; specifically move ConstraintPermission so the import list is sorted alphabetically; update the import statement that includes ConversationResolution, ConstraintPermission, ConstraintRecord, ConversationCompressionRecord, ConversationListEntry, ConversationRecord, ConversationResolutionError, getBaseBindingKey, getPresetLane, MessageRecord, ResolveConversationOptions, ResolvedConstraint, ResolvedConversationContext, RouteMode to be in strict alphabetical order (use the symbol names as sorting keys) so ConstraintPermission appears in its correct alphabetic position among the imported identifiers.
🤖 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/src/commands/conversation.ts`:
- Around line 53-56: The property assignment for
conversation_manage.targetConversation uses a multi-line expression that breaks
Prettier; change it to a single-line property assignment (e.g.,
conversation_manage: { targetConversation: conversation?.trim() || undefined })
and apply the same single-line fix to the other occurrences (same pattern under
archive/restore/export/compress/delete and the blocks referenced at the other
locations) so all targetConversation assignments use the compact single-line
form to satisfy the formatter.
In `@packages/core/src/middlewares/chat/stop_chat.ts`:
- Around line 25-42: The code currently skips an ACL re-check by reusing current
when it appears resolved; always re-run conversation resolution with permission:
'manage' to enforce the intended ACL check instead of allowing the early-return
path. Replace the conditional that assigns resolved using current (the variable
named current and type ConversationResolution) with an unconditional await call
to ctx.chatluna.conversation.resolveConversation(session, { targetConversation,
presetLane: context.options.presetLane, allPresetLanes:
context.options.allPresetLanes, permission: 'manage', useRoutePresetLane:
context.options.presetLane == null && targetConversation == null, mode: 'target'
}) so getTargetConversation/context.options flow is preserved but the manage
permission is always enforced; remove the branch that bypasses
resolveConversation to prevent view-only sessions from being allowed to stop
conversations.
In `@packages/core/src/middlewares/conversation/resolve_conversation.ts`:
- Around line 30-44: The call to ctx.chatluna.conversation.resolveConversation
in resolve_conversation.ts is misformatted and breaks the linter; reflow the
await ctx.chatluna.conversation.resolveConversation(session, { ... }) invocation
and the subsequent if block to match the repository's Prettier style
(single-line or consistent object property alignment), ensuring consistent
indentation and line breaks for the parameters mode, conversationId,
targetConversation, presetLane, includeArchived, allPresetLanes, and
useRoutePresetLane; run Prettier/ESLint and adjust the surrounding if/return
block (the following if that checks the resolved value) so both the call and the
conditional follow the same formatting pattern used elsewhere in this file.
---
Nitpick comments:
In `@packages/core/src/middlewares/chat/chat_time_limit_save.ts`:
- Around line 23-25: The conversationId resolution is redundant: use the
ConversationResolution field directly instead of falling back to
context.options.conversation?.conversation?.id; update the assignment of
conversationId (the variable in chat_time_limit_save.ts) to read from
context.options.conversation?.conversationId (or default to null) and remove the
extra fallback expression so the code becomes simpler and relies on the resolved
conversationId provided by resolveConversation.
In `@packages/core/src/middlewares/chat/rollback_chat.ts`:
- Around line 20-25: The helper function getTargetConversation is a 1-5 line
helper that is only used once; inline its logic at the call site instead of
keeping a separate function. Replace the call to getTargetConversation(context)
with the inline expression
context.options.conversation_manage?.targetConversation ??
context.options.targetConversation (preserving the same nullish/coalescing
behavior), and remove the getTargetConversation function declaration (the
function and its reference to ChainMiddlewareContext can be deleted).
- Around line 9-12: 在 rollback_chat.ts 的导入列表中按字母顺序调整导入成员,把 MessageRecord 和
ConversationResolution 的顺序互换以满足静态分析要求;具体在 import {...} from
'../../services/conversation_types' 语句中确保 ConversationResolution 位于
MessageRecord 之后(调整 "MessageRecord" 和 "ConversationResolution" 的顺序),保存并让 linter
通过。
In `@packages/core/src/middlewares/system/conversation_manage.ts`:
- Around line 705-712: 该段代码因缩进/格式不符合 prettier 导致静态检查失败;请调整
updateManagedConstraint 调用及接续赋值表达式的换行与缩进使其符合项目格式规范:定位到
conversation.updateManagedConstraint 和 conversation.resolveConstraint 使用的表达式(变量
current 和 nextRouteMode),将三元表达式与 await 对齐、适当拆行并确保对象字面量 { routeMode }
与后续链式调用缩进一致,保存并运行 prettier/项目格式化验证通过后提交。
In `@packages/core/src/services/conversation.ts`:
- Around line 525-527: Prettier reports a formatting issue on the assignment to
the variable conversation; reformat the statement using the
matchTargetConversation call so it conforms to project prettier rules (e.g.,
place the whole assignment on one line or wrap the call with parentheses and
break lines consistently). Update the expression involving
matchTargetConversation(target, normalized, conversations, entries) and the
nullish coalescing (?? null) so the assignment to conversation is properly
indented and line-broken according to the code style.
- Around line 38-52: Imports from './conversation_types' are not alphabetized;
specifically move ConstraintPermission so the import list is sorted
alphabetically; update the import statement that includes
ConversationResolution, ConstraintPermission, ConstraintRecord,
ConversationCompressionRecord, ConversationListEntry, ConversationRecord,
ConversationResolutionError, getBaseBindingKey, getPresetLane, MessageRecord,
ResolveConversationOptions, ResolvedConstraint, ResolvedConversationContext,
RouteMode to be in strict alphabetical order (use the symbol names as sorting
keys) so ConstraintPermission appears in its correct alphabetic position among
the imported identifiers.
In `@packages/core/src/services/types.ts`:
- Around line 3-14: Reorder the named imports in the import statement so they
are alphabetized to satisfy the linter; specifically place ConstraintRecord in
its correct alphabetical position among ACLRecord, ArchiveRecord, BindingRecord,
ConversationRecord, ConversationResolution, ConversationResolveMode,
MessageRecord, MetaRecord, and ResolveConversationOptions (ensure the entire
import list is sorted and keep the import from './conversation_types' intact).
🪄 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: b28116a8-cce2-41b8-a136-a85dcf4c6f96
📒 Files selected for processing (22)
packages/core/src/chains/chain.tspackages/core/src/commands/chat.tspackages/core/src/commands/conversation.tspackages/core/src/middlewares/chat/chat_time_limit_check.tspackages/core/src/middlewares/chat/chat_time_limit_save.tspackages/core/src/middlewares/chat/message_delay.tspackages/core/src/middlewares/chat/read_chat_message.tspackages/core/src/middlewares/chat/rollback_chat.tspackages/core/src/middlewares/chat/stop_chat.tspackages/core/src/middlewares/conversation/request_conversation.tspackages/core/src/middlewares/conversation/resolve_conversation.tspackages/core/src/middlewares/model/resolve_model.tspackages/core/src/middlewares/system/conversation_manage.tspackages/core/src/services/conversation.tspackages/core/src/services/conversation_types.tspackages/core/src/services/types.tspackages/core/src/utils/conversation.tspackages/core/tests/conversation-resolve.spec.tspackages/core/tests/conversation-service.spec.tspackages/core/tests/conversation-target.spec.tspackages/core/tests/rollback-chat.spec.tspackages/extension-long-memory/src/utils/conversation.ts
💤 Files with no reviewable changes (1)
- packages/core/tests/conversation-target.spec.ts
Always resolve the stop-chat target from the command options instead of reusing the current resolved conversation state. This keeps stop requests pointed at the intended conversation after the conversation resolution refactor.
Run the repository lint autofix on stop_chat after the explicit target resolution change. This only updates formatting to match the project's ESLint and prettier rules.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Ignore non-preset files in the preset watcher and treat missing files on rename as removals instead of logging spurious errors. This keeps preset schema updates stable when preset files are deleted or unrelated files change.
There was a problem hiding this comment.
Actionable comments posted: 2
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/services/conversation.ts (1)
1499-1547:⚠️ Potential issue | 🔴 Critical这里把“当前路由约束”当成了“目标会话约束”。
options.conversationId != null时,下面真正被修改的会话是通过一次新的mode: 'target'解析拿到的,但后续assertManageAllowed、fixedModel/fixedPreset/fixedChatMode、lockConversation仍然读的是前面mode: 'context'的resolved.constraint。跨路由或跨 lane 更新时,这会按当前路由而不是目标会话所属路由执行限制,允许绕过目标路由的管理/固定项/锁定约束。这里应直接复用 target 解析结果里的constraint。🔒 参考改法
- const resolved = await this.resolveConversation(session, { + const currentResolved = await this.resolveConversation(session, { ...options, mode: 'context' }) - await assertManageAllowed(session, resolved.constraint) - - const conversation = - options.conversationId == null - ? ( - await this.resolveConversation(session, { - ...options, - mode: 'active' - }) - ).conversation - : ( - await this.resolveConversation(session, { - ...options, - permission: 'manage', - mode: 'target' - }) - ).conversation + await assertManageAllowed(session, currentResolved.constraint) + + const targetResolved = + options.conversationId == null + ? await this.resolveConversation(session, { + ...options, + mode: 'active' + }) + : await this.resolveConversation(session, { + ...options, + permission: 'manage', + mode: 'target' + }) + const conversation = targetResolved.conversation if (conversation == null) { throw new Error('Conversation not found.') } - const target = await this.getManagedConstraintByBindingKey( + await assertManageAllowed(session, targetResolved.constraint) + + const managed = await this.getManagedConstraintByBindingKey( conversation.bindingKey ) - if (target != null) { - await assertManageAllowed(session, target) + if (managed != null) { + await assertManageAllowed(session, managed) } for (const [key, fixedKey, label] of [ ['model', 'fixedModel', 'Model'], ['preset', 'fixedPreset', 'Preset'], ['chatMode', 'fixedChatMode', 'Chat mode'] ] as const) { - const fixed = target?.[fixedKey] ?? resolved.constraint[fixedKey] + const fixed = + managed?.[fixedKey] ?? + targetResolved.constraint[fixedKey] if (options[key] != null && fixed != null) { throw new Error(`${label} is fixed to ${fixed}.`) } } - if (target?.lockConversation ?? resolved.constraint.lockConversation) { + if ( + managed?.lockConversation ?? + targetResolved.constraint.lockConversation + ) { throw new Error('Conversation update is locked by constraint.') }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/services/conversation.ts` around lines 1499 - 1547, The code is using the initial context resolution (resolved.constraint) for permission/ fixed-value/lock checks even when a target conversation was resolved; change the logic to reuse the target resolution's constraint when present: after obtaining target via getManagedConstraintByBindingKey and the conversation from resolveConversation (with mode: 'target' when options.conversationId != null), call assertManageAllowed(session, target.constraint) instead of resolved.constraint when target exists, and for the fixedModel/fixedPreset/fixedChatMode checks and the lockConversation check read from target.constraint (falling back to resolved.constraint only if target is null). Update references to resolved.constraint in those checks to use target.constraint where applicable so constraints are enforced for the actual target conversation.
🤖 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/src/middlewares/chat/rollback_chat.ts`:
- Around line 35-52: 当前逻辑在遇到 context.options.conversation 满足 constraint 和
bindingKey 时直接复用上游对象 (current / ConversationResolution) 导致跳过本应以 permission:
'manage' 重新解析的流程,允许仅有查看权限的会话被回滚;应始终调用
ctx.chatluna.conversation.resolveConversation(session, {..., permission:
'manage', mode: 'target'}) 来重新解析目标会话(可将上游 conversation 的 conversationId
或相关标识作为输入),不要直接返回 context.options.conversation;在 getTargetConversation
使用到的分支中、以及处理 resolved 的变量(resolved)处改为强制走 resolveConversation,以确保使用 manage 权限校验。
In `@packages/core/src/services/types.ts`:
- Around line 141-144: Prettier flags the current multiline declaration of
ListConversationsOptions; fix it by reformatting the export of
ListConversationsOptions that uses Omit<ResolveConversationOptions, 'mode' |
'targetConversation' | 'permission'> to match the project's Prettier rules
(e.g., collapse into a single line or run the repo Prettier/formatter) so the
declaration for ListConversationsOptions/ResolveConversationOptions/Omit no
longer triggers prettier/prettier in CI.
---
Outside diff comments:
In `@packages/core/src/services/conversation.ts`:
- Around line 1499-1547: The code is using the initial context resolution
(resolved.constraint) for permission/ fixed-value/lock checks even when a target
conversation was resolved; change the logic to reuse the target resolution's
constraint when present: after obtaining target via
getManagedConstraintByBindingKey and the conversation from resolveConversation
(with mode: 'target' when options.conversationId != null), call
assertManageAllowed(session, target.constraint) instead of resolved.constraint
when target exists, and for the fixedModel/fixedPreset/fixedChatMode checks and
the lockConversation check read from target.constraint (falling back to
resolved.constraint only if target is null). Update references to
resolved.constraint in those checks to use target.constraint where applicable so
constraints are enforced for the actual target conversation.
🪄 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: 5fbb646b-370f-43c8-93b4-ca1a4ea2b129
📒 Files selected for processing (9)
packages/core/src/commands/conversation.tspackages/core/src/middlewares/chat/rollback_chat.tspackages/core/src/middlewares/chat/stop_chat.tspackages/core/src/middlewares/conversation/resolve_conversation.tspackages/core/src/middlewares/system/conversation_manage.tspackages/core/src/preset.tspackages/core/src/services/conversation.tspackages/core/src/services/conversation_types.tspackages/core/src/services/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/core/src/services/conversation_types.ts
Always resolve rollback commands through the conversation service using either the explicit target or the current conversation id. This keeps rollback requests pointed at the intended conversation after the conversation resolution refactor.
description: |-
This pr consolidates conversation resolution into a single flow and fixes follow-up regressions in command routing, target lookup, and middleware state propagation.
New Features
None.
Bug fixes
conversationIdstate across middlewaresOther Changes