Skip to content

fix: 修复 subagent 使用 default persona 时查找失败的问题#5672

Open
whatevertogo wants to merge 2 commits intoAstrBotDevs:masterfrom
whatevertogo:fix/subagent-persona-not-found
Open

fix: 修复 subagent 使用 default persona 时查找失败的问题#5672
whatevertogo wants to merge 2 commits intoAstrBotDevs:masterfrom
whatevertogo:fix/subagent-persona-not-found

Conversation

@whatevertogo
Copy link
Contributor

@whatevertogo whatevertogo commented Mar 2, 2026

Motivation / 动机

修复 subagent 配置中使用 persona_id: "default" 时无法正确解析的问题。此前,SubAgentOrchestrator 调用 get_persona() 查找 persona,但该方法不支持 "default" 这个特殊标识符,导致 subagent 回退到内联 prompt,丢失了 default persona 的配置(如 tools、begin_dialogs 等)。

Modifications / 改动点

  • 新增 PersonaManager.get_persona_v3_by_id() 方法,统一 v3 persona 查找逻辑

    • 支持 None/空字符串返回 None
    • 支持 "default" 映射到内存中的 DEFAULT_PERSONALITY
    • 其他值从 personas_v3 列表中按 name 查找
  • 修复 SubAgentOrchestrator.reload_from_config() 使用新方法解析 persona

  • 修复 HandoffTool.default_description() 参数 agent_name 未被使用的问题

  • 重构 _ensure_persona_and_skills() 复用 get_persona_v3_by_id() 简化代码

  • 新增 7 个测试用例覆盖修复场景

  • This is NOT a breaking change. / 这不是一个破坏性变更。

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

$ python -m pytest tests/unit/test_subagent_orchestrator.py tests/unit/test_astr_main_agent.py::TestEnsurePersonaAndSkills::test_subagent_dedupe_uses_default_persona_tools tests/test_dashboard.py::test_subagent_config_accepts_default_persona -v

tests/unit/test_subagent_orchestrator.py::test_reload_from_config_default_persona_is_resolved PASSED
tests/unit/test_subagent_orchestrator.py::test_reload_from_config_missing_persona_falls_back_to_inline_and_warns PASSED
tests/unit/test_subagent_orchestrator.py::test_reload_from_config_uses_processed_begin_dialogs_and_deepcopy PASSED
tests/unit/test_subagent_orchestrator.py::test_reload_from_config_tool_normalization[None-None] PASSED
tests/unit/test_subagent_orchestrator.py::test_reload_from_config_tool_normalization[raw_tools1-expected_tools2] PASSED
tests/unit/test_subagent_orchestrator.py::test_reload_from_config_tool_normalization[not-a-list-expected_tools2] PASSED
tests/unit/test_astr_main_agent.py::TestEnsurePersonaAndSkills::test_subagent_dedupe_uses_default_persona_tools PASSED
tests/test_dashboard.py::test_subagent_config_accepts_default_persona PASSED

======================== 8 passed, 4 warnings in 3.36s ========================

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了"验证步骤"和"运行截图"。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ 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.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

Summary by Sourcery

修复子代理(subagent)人格(persona)解析逻辑,以正确处理特殊的 "default" 人格标识符,并改进子代理配置行为。

Bug 修复:

  • 确保使用 persona_id "default" 的子代理能够正确解析并应用默认人格配置,而不是回退到内联提示(inline prompts)。
  • HandoffTool.default_description 中使用目标代理名称,使生成的交接描述能够引用正确的代理。

增强功能:

  • PersonaManager 中通过 get_persona_v3_by_id 实现 v3 人格查找的集中化,包括对内存中的 "default" 人格和基于名称查找的支持。
  • 更新 SubAgentOrchestrator,在加载子代理配置时使用处理后的 begin dialogs、深度拷贝人格对话定义,并规范化工具列表。
  • 优化主代理的人格/技能设置,以复用统一的 v3 人格查找逻辑用于子代理工具解析。

测试:

  • SubAgentOrchestrator.reload_from_config 添加单元测试,覆盖默认人格解析、缺失人格时的回退策略、begin_dialogs 深拷贝行为以及工具规范化的边界情况。
  • 扩展主代理测试,以验证子代理去重逻辑在尊重已解析的默认人格所提供的工具时的行为。
  • 添加一个仪表盘 API 测试,以确保子代理配置可以接受并持久化 persona_id "default"
Original summary in English

Summary by Sourcery

Fix subagent persona resolution to correctly handle the special "default" persona identifier and improve subagent configuration behavior.

Bug Fixes:

  • Ensure subagents using persona_id "default" correctly resolve and apply the default persona configuration instead of falling back to inline prompts.
  • Use the target agent name in HandoffTool.default_description so generated handoff descriptions reference the correct agent.

Enhancements:

  • Centralize v3 persona lookup in PersonaManager via get_persona_v3_by_id, including support for the "default" in-memory persona and name-based lookups.
  • Update SubAgentOrchestrator to use processed begin dialogs, deep-copy persona dialog definitions, and normalize tool lists when loading subagent config.
  • Refine main agent persona/skill setup to reuse unified v3 persona lookup for subagent tool resolution.

Tests:

  • Add unit tests for SubAgentOrchestrator reload_from_config covering default persona resolution, missing persona fallback, begin_dialogs deep-copy behavior, and tool normalization edge cases.
  • Extend main agent tests to verify subagent deduplication respects tools from the resolved default persona.
  • Add a dashboard API test to ensure subagent config accepts and persists persona_id "default".

…on logic

- Add PersonaManager.get_persona_v3_by_id() to centralize v3 persona resolution
- Handle 'default' persona_id mapping to DEFAULT_PERSONALITY in subagent orchestrator
- Fix HandoffTool.default_description using agent_name parameter correctly
- Add tests for default persona in subagent config and tool deduplication

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@auto-assign auto-assign bot requested review from Raven95676 and Soulter March 2, 2026 10:11
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 2, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在解决 subagent 在配置中使用 "default" persona 时查找失败的问题。通过引入一个统一的 persona 查找方法,并更新相关逻辑以正确处理 "default" 标识符,确保 subagent 能够正确加载默认 persona 的配置,从而避免回退到内联 prompt 导致功能缺失。

Highlights

  • 统一 Persona 查找逻辑: 新增 PersonaManager.get_persona_v3_by_id() 方法,统一了 v3 persona 的查找逻辑,支持处理 None/空字符串、"default" 标识符以及按名称查找。
  • 修复 SubAgent Persona 解析: 修复 SubAgentOrchestrator.reload_from_config() 方法,使其能够正确解析 subagent 配置中使用的 persona,包括 "default" persona,避免回退到内联 prompt。
  • 修复 HandoffTool 参数使用: 修复 HandoffTool.default_description() 方法中 agent_name 参数未被使用的问题。
  • 代码重构: 重构 _ensure_persona_and_skills() 函数,通过复用新的 get_persona_v3_by_id() 方法简化了代码。
  • 新增测试用例: 新增了 7 个测试用例,全面覆盖了本次修复和新功能的场景,确保了代码的健壮性。
Changelog
  • astrbot/core/agent/handoff.py
    • 修复了 default_description 方法中 agent_name 参数未被使用的问题。
  • astrbot/core/astr_main_agent.py
    • 更新了 _ensure_persona_and_skills 函数,以使用新的 get_persona_v3_by_id 方法来解析 persona。
  • astrbot/core/persona_mgr.py
    • 新增了 get_persona_v3_by_id 方法,用于统一 v3 persona 的查找逻辑,支持处理 None/空字符串、"default" 标识符以及按名称查找。
  • astrbot/core/subagent_orchestrator.py
    • 更新了 reload_from_config 方法,以使用新的 get_persona_v3_by_id 方法来解析 subagent 的 persona 配置。
    • 导入了 copy 模块和 TYPE_CHECKING 类型提示。
    • 调整了从 persona_data 中获取 instructionspublic_description 的逻辑,以使用 get("prompt")
  • tests/test_dashboard.py
    • 导入了 copy 模块。
    • 新增了 test_subagent_config_accepts_default_persona 测试用例,验证 subagent 配置能够接受 "default" persona。
  • tests/unit/test_astr_main_agent.py
    • mock_context 添加了 get_persona_v3_by_id 的 mock。
    • 新增了 test_subagent_dedupe_uses_default_persona_tools 测试用例,验证 subagent 在去重时使用了默认 persona 的工具。
  • tests/unit/test_subagent_orchestrator.py
    • 新增了测试文件,包含多个测试用例,验证 SubAgentOrchestrator 在加载配置时对 persona 的解析、默认 persona 的处理、缺失 persona 的回退机制以及工具的规范化。
Activity
  • 作者新增了 7 个测试用例,以确保修复的正确性和新功能的覆盖。
  • 所有新增及受影响的测试用例均已通过,验证了本次变更的有效性。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
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 - 我给出了一些整体性的反馈:

  • 新的 get_persona_v3_by_id 辅助函数的类型标注为返回 Personality,但在使用时却被当作 dict(例如 persona.get("tools"))来访问,这与现有的 personas_v3 结构不一致;建议更新返回类型和相关注解,使其反映实际的映射/dict 结构,或者考虑将底层数据封装在一个类似 Personality 的对象中。
  • 既然 get_persona_v3_by_id 现在是 v3 personas 的核心查找路径,那么在该方法内部对 persona_id 做规范化处理(例如 str(...).strip(),以及必要时做大小写归一化)可能会更安全,而不是依赖像 reload_from_config 这样的各个调用方来预清洗这个标识符。
给 AI 代理的提示
Please address the comments from this code review:

## Overall Comments
- The new `get_persona_v3_by_id` helper is annotated to return `Personality` but is used as a `dict` (e.g., `persona.get("tools")`), which is inconsistent with the existing `personas_v3` structure; consider updating the return type and related annotations to reflect the actual mapping/dict shape or wrapping the underlying data in a `Personality`-like object.
- Since `get_persona_v3_by_id` is now the central lookup path for v3 personas, it may be safer to normalize `persona_id` inside this method (e.g., `str(...).strip()` and possibly case normalization) rather than relying on individual callers like `reload_from_config` to pre-clean the identifier.

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈改进后续的评审。
Original comment in English

Hey - I've left some high level feedback:

  • The new get_persona_v3_by_id helper is annotated to return Personality but is used as a dict (e.g., persona.get("tools")), which is inconsistent with the existing personas_v3 structure; consider updating the return type and related annotations to reflect the actual mapping/dict shape or wrapping the underlying data in a Personality-like object.
  • Since get_persona_v3_by_id is now the central lookup path for v3 personas, it may be safer to normalize persona_id inside this method (e.g., str(...).strip() and possibly case normalization) rather than relying on individual callers like reload_from_config to pre-clean the identifier.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `get_persona_v3_by_id` helper is annotated to return `Personality` but is used as a `dict` (e.g., `persona.get("tools")`), which is inconsistent with the existing `personas_v3` structure; consider updating the return type and related annotations to reflect the actual mapping/dict shape or wrapping the underlying data in a `Personality`-like object.
- Since `get_persona_v3_by_id` is now the central lookup path for v3 personas, it may be safer to normalize `persona_id` inside this method (e.g., `str(...).strip()` and possibly case normalization) rather than relying on individual callers like `reload_from_config` to pre-clean the identifier.

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.

@dosubot dosubot bot added the feature:persona The bug / feature is about astrbot AI persona system (system prompt) label Mar 2, 2026
@dosubot
Copy link

dosubot bot commented Mar 2, 2026

Related Documentation

1 document(s) may need updating based on files changed in this PR:

AstrBotTeam's Space

pr4697的改动
View Suggested Changes
@@ -34,6 +34,23 @@
 
 #### 配置说明
 SubAgent 的定义与 Persona 配置一致,需在配置文件中指定 tools、skills、name、description 等。
+
+**Persona 引用(PR #5672)**
+
+子代理支持通过 `persona_id` 字段引用现有的 Persona 配置。[PR #5672](https://github.com/AstrBotDevs/AstrBot/pull/5672) 修复了子代理使用 `persona_id: "default"` 时的查找失败问题:
+
+- **`persona_id: "default"`**:现在可正确引用系统内置的 DEFAULT_PERSONALITY,包括其配置的所有工具、begin_dialogs 等设置
+- **自定义 Persona**:使用其他 `persona_id` 值(如自定义人格名称)时,系统会从 `personas_v3` 列表中按名称查找对应的人格配置
+- **空值或未配置**:如果 `persona_id` 为空或未配置,子代理将使用内联的 `system_prompt` 和工具配置
+
+修复前,子代理使用 `persona_id: "default"` 会因查找失败而回退到内联 prompt,丢失 default persona 的完整配置(如 tools、begin_dialogs 等)。修复后,系统新增 `PersonaManager.get_persona_v3_by_id()` 方法,统一了 persona 查找逻辑:
+- `None` 或空字符串返回 `None`
+- `"default"` 映射到内存中的 `DEFAULT_PERSONALITY`
+- 其他值从 `personas_v3` 列表中按 name 查找
+
+`SubAgentOrchestrator.reload_from_config()` 方法现在使用新的查找方法正确解析 persona 引用,确保子代理配置的正确性。
+
+**委派工具参数**
 
 transfer_to_* 工具现支持以下参数:
 - `input`:转交给子代理的任务输入(必填)

[Accept] [Decline]

Note: You must be authenticated to accept/decline updates.

How did I do? Any feedback?  Join Discord

Copy link
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

这次的 PR 成功修复了 subagent 使用 persona_id: "default" 时 persona 解析失败的问题。核心改动是引入了 PersonaManager.get_persona_v3_by_id 方法,它统一了 persona 的查找逻辑,正确地处理了 "default" 标识符,这是一个清晰且有效的重构。相关的模块如 SubAgentOrchestrator_ensure_persona_and_skills 也都正确地适配了此新方法。此外,PR 中包含了全面的单元测试和集成测试,很好地覆盖了修复的场景。代码质量很高,没有发现需要修改的问题。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@whatevertogo
Copy link
Contributor Author

#5669

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

1 participant