Skip to content

fix: 修复创建新对话时 persona 继承丢失问题#7046

Closed
idiotsj wants to merge 1 commit intoAstrBotDevs:masterfrom
idiotsj:fix/persona-inheritance-minimal
Closed

fix: 修复创建新对话时 persona 继承丢失问题#7046
idiotsj wants to merge 1 commit intoAstrBotDevs:masterfrom
idiotsj:fix/persona-inheritance-minimal

Conversation

@idiotsj
Copy link
Copy Markdown
Contributor

@idiotsj idiotsj commented Mar 27, 2026

Fixes #7045

Modifications / 改动点

  • 修复 ConversationManager.new_conversation() 在未显式传入 persona_id 时不会继承当前对话人格的问题

  • 将显式“无人格”标记 [%None] 统一归一化为 None,避免该标记被继续继承到新对话

  • 新增 astrbot/core/persona_utils.py,统一管理 PERSONA_NONE_MARKER 和 persona 归一化逻辑

  • 替换 persona 相关命令和管理器中的硬编码 marker 判断,避免后续值漂移

  • 新增聚焦单测,覆盖以下场景:

    • 新对话继承当前 persona
    • [%None] 不会被继承
    • 显式传入的 persona_id 优先级高于自动继承
  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

验证步骤:

  1. 在当前对话执行 /persona psychologist
  2. 触发一个未显式传入 persona_id 的新建对话路径
  3. 验证新对话能够继承 psychologist
  4. 执行 /persona unset
  5. 再次创建新对话
  6. 验证新对话中保存的是 None,而不是继续保留 [%None]

已执行的聚焦回归测试:

uv run pytest tests/unit/test_conversation_mgr.py tests/unit/test_astr_main_agent.py::TestGetSessionConv tests/unit/test_astr_main_agent.py::TestEnsurePersonaAndSkills -q
.............
13 passed, 3 warnings in 1.58s

Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”

  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。

  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码.

Summary by Sourcery

Fix conversation persona handling so new conversations correctly inherit or clear persona settings and centralize the explicit no-persona marker logic.

Bug Fixes:

  • Ensure new conversations inherit the current conversation's persona when no persona_id is explicitly provided.
  • Prevent the explicit no-persona marker from being propagated to new conversations by normalizing it to None.
  • Treat the explicit no-persona marker as no persona when resolving or displaying the current persona.

Enhancements:

  • Introduce a shared persona_utils module to centralize the no-persona marker constant and persona normalization logic.
  • Refactor persona-related commands and managers to use the centralized marker and normalization helpers instead of hardcoded checks.

Tests:

  • Add focused unit tests covering persona inheritance, non-inheritance of the no-persona marker, explicit persona_id precedence, and current persona resolution behavior.

@auto-assign auto-assign bot requested review from LIghtJUNction and anka-afk March 27, 2026 10:27
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend feature:persona The bug / feature is about astrbot AI persona system (system prompt) labels Mar 27, 2026
@idiotsj idiotsj closed this Mar 27, 2026
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 centralizes persona marker handling by introducing a persona_utils module and implements persona inheritance for new conversations in the ConversationManager. When a new conversation is initiated without a specific persona ID, the system now attempts to inherit and normalize the persona from the current active conversation. A review comment identifies a potential performance improvement to eliminate redundant database queries that occur when both the caller and the new_conversation method attempt to resolve the persona ID independently.

Comment on lines +102 to +107
if persona_id is None:
curr_cid = await self.get_curr_conversation_id(unified_msg_origin)
if curr_cid:
curr_conv = await self.db.get_conversation_by_id(cid=curr_cid)
if curr_conv:
persona_id = normalize_persona_id(curr_conv.persona_id)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

这段代码正确地实现了在创建新对话时继承当前人格的逻辑。

然而,我注意到这可能会导致一些调用路径(例如 conversation.py 中的 new_conv)出现效率问题。new_conv 会先调用 _get_current_persona_id 来解析当前的人格,然后将结果传给 new_conversation。如果当前人格是 [%None]_get_current_persona_id 会返回 None,然后 new_conversation 会因为 persona_id is None 而再次执行几乎相同的逻辑来解析当前人格,这导致了重复的数据库查询。

虽然这不影响功能的正确性,但为了提高性能和代码的简洁性,建议在未来的重构中,让调用方(如 new_conv)直接调用 new_conversation() 而不传递 persona_id,完全依赖此处的继承逻辑。

由于相关调用方的代码不在此次变更范围内,这可以作为一个后续的改进点。

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • Since you introduced is_persona_none_marker and normalize_persona_id, consider using them consistently everywhere you compare against PERSONA_NONE_MARKER (e.g., in persona_mgr.resolve_selected_persona) to avoid duplicating marker-specific logic.
  • is_persona_none_marker is currently not used anywhere in the diff; either replace direct PERSONA_NONE_MARKER equality checks with this helper or drop the function to keep the helper module minimal.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Since you introduced `is_persona_none_marker` and `normalize_persona_id`, consider using them consistently everywhere you compare against `PERSONA_NONE_MARKER` (e.g., in `persona_mgr.resolve_selected_persona`) to avoid duplicating marker-specific logic.
- `is_persona_none_marker` is currently not used anywhere in the diff; either replace direct `PERSONA_NONE_MARKER` equality checks with this helper or drop the function to keep the helper module minimal.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@idiotsj idiotsj reopened this Mar 27, 2026
@idiotsj idiotsj force-pushed the fix/persona-inheritance-minimal branch from d69380a to a0186b5 Compare March 27, 2026 10:46
@idiotsj
Copy link
Copy Markdown
Contributor Author

idiotsj commented Mar 27, 2026

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In ConversationManager.new_conversation, normalize_persona_id is used but there’s no corresponding import shown in the diff; double-check that astrbot.core.persona_utils.normalize_persona_id is imported in conversation_mgr.py to avoid runtime errors.
  • The new behavior in new_conversation treats persona_id=None as “inherit from current conversation,” which changes semantics for callers that previously passed None to explicitly mean no persona; consider either normalizing an explicit PERSONA_NONE_MARKER to None before persisting, or adding an explicit flag/constant to request a non-inherited, persona-less conversation to keep the API behavior unambiguous.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ConversationManager.new_conversation`, `normalize_persona_id` is used but there’s no corresponding import shown in the diff; double-check that `astrbot.core.persona_utils.normalize_persona_id` is imported in `conversation_mgr.py` to avoid runtime errors.
- The new behavior in `new_conversation` treats `persona_id=None` as “inherit from current conversation,” which changes semantics for callers that previously passed `None` to explicitly mean no persona; consider either normalizing an explicit `PERSONA_NONE_MARKER` to `None` before persisting, or adding an explicit flag/constant to request a non-inherited, persona-less conversation to keep the API behavior unambiguous.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@idiotsj
Copy link
Copy Markdown
Contributor Author

idiotsj commented Mar 27, 2026

修完了,不再扩展了……如果要改逻辑另算吧

@Soulter Soulter force-pushed the master branch 2 times, most recently from faf411f to 0068960 Compare April 19, 2026 09:50
@idiotsj
Copy link
Copy Markdown
Contributor Author

idiotsj commented Apr 20, 2026

刚看了看好像修复了,关了

@idiotsj idiotsj closed this Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend feature:persona The bug / feature is about astrbot AI persona system (system prompt) size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 创建新对话时 persona 继承丢失

1 participant