Skip to content

feat(core): configurable hardcoded injections and i18n sync#6544

Closed
Rail1bc wants to merge 11 commits intoAstrBotDevs:devfrom
Rail1bc:feat/configurable-hardcoded-injections-clean
Closed

feat(core): configurable hardcoded injections and i18n sync#6544
Rail1bc wants to merge 11 commits intoAstrBotDevs:devfrom
Rail1bc:feat/configurable-hardcoded-injections-clean

Conversation

@Rail1bc
Copy link
Copy Markdown
Contributor

@Rail1bc Rail1bc commented Mar 18, 2026

使一部分硬编码注入文案可配置

Modifications / 改动点

允许用户配置更多文案,这些文案一直以来在工作流程中起到重要作用,现在用户可以进一步定制它们。

  • 新增一系列文案配置,并放在了逻辑上相近的位置
  • 配置传递路径尽可能模仿原本的代码风格
  • 最终消费点都增加了错误回退,最坏情况下会导致配置失效,回退到默认文案
  • i18n: 添加中文、英文、俄文的配置元数据翻译
  • [√] This is NOT a breaking change. / 这不是一个破坏性变更。

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

  • 尚未进行完整系统的测试,这需要一段时间

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

Make various previously hardcoded agent system prompts and tool-usage messages configurable through provider settings, including context compression, tool calling, safety mode, local runtime, proactive background tasks, and cron jobs, with i18n metadata updates.

Enhancements:

  • Add provider-level configuration options for context summarization prompts, tool call guidance (including lazy-load, follow-up, and max-step messages), LLM safety mode system prompts, live mode behavior, and local runtime hints.
  • Extend proactive background task and cron job handling to use configurable templates for history wrapping, execution instructions, and summary notes with safe fallbacks if formatting fails.
  • Refine computer tool provider and tool provider context to accept local runtime configuration and generate customized local-mode system prompts.
  • Adjust the LLM context compressor and manager to support configurable user and acknowledgment prompts for injected conversation summaries.

Documentation:

  • Add i18n config metadata entries for new configurable prompt fields in English, Chinese, and Russian locales.

Tests:

  • Update main agent configuration unit test to reflect supported tool schema modes and ensure lazy_load mode is handled correctly.

@auto-assign auto-assign bot requested review from LIghtJUNction and anka-afk March 18, 2026 04:48
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Mar 18, 2026
@gemini-code-assist
Copy link
Copy Markdown
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!

This pull request significantly enhances the system's flexibility by externalizing numerous hardcoded prompt messages into configurable settings. The primary goal is to allow users to customize the agent's interactions, tool usage, and operational messages, thereby improving adaptability and user experience. The changes ensure that critical system messages, such as those related to context compression, tool invocation, and proactive agent tasks, can be easily modified, while also providing internationalization support for these new configuration options.

Highlights

  • Configurable Prompt Texts: Many previously hardcoded prompt messages, including those for context summarization, tool calls, safety mode, live mode, and background/cron tasks, have been made configurable.
  • Internationalization (i18n) Support: New configuration metadata for the configurable prompts has been added with translations for Chinese, English, and Russian, enhancing multi-language support.
  • Robust Fallback Mechanisms: Error handling and fallback to default prompt texts have been implemented for all new configurable messages, ensuring system stability even if custom configurations are invalid.
  • Enhanced Agent Customization: Users can now tailor the agent's communication style and behavior more precisely by adjusting various system and user prompts, offering greater flexibility in agent deployment and interaction.
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.

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.

@dosubot dosubot bot added the area:core The bug / feature is about astrbot's core, backend label Mar 18, 2026
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 found 3 issues, and left some high level feedback:

  • In _woke_main_agent (cron manager), the customized cron_task_summary_note_result path only assigns result_prompt but never appends it to summary_note, so for valid templates the LLM result is silently dropped; you likely want to summary_note += result_prompt after successful formatting as well.
  • In _wake_main_agent_for_background_result, the configurable background_task_summary_note currently formats with result=result (the raw tool result) and then later conditionally appends another result block; consider consistently using the LLM completion text (or a clearly chosen value) and avoiding double/inconsistent result fields in the final summary string.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_woke_main_agent` (cron manager), the customized `cron_task_summary_note_result` path only assigns `result_prompt` but never appends it to `summary_note`, so for valid templates the LLM result is silently dropped; you likely want to `summary_note += result_prompt` after successful formatting as well.
- In `_wake_main_agent_for_background_result`, the configurable `background_task_summary_note` currently formats with `result=result` (the raw tool result) and then later conditionally appends another result block; consider consistently using the LLM completion text (or a clearly chosen value) and avoiding double/inconsistent result fields in the final summary string.

## Individual Comments

### Comment 1
<location path="astrbot/core/astr_agent_tool_exec.py" line_range="638-640" />
<code_context>
-            f"Result: {task_meta.get('result') or result_text or 'no content'}"
-        )
+
+        background_task_summary_note = proactive_cfg.get("background_task_summary_note", "")
+        try:
+            summary_note = background_task_summary_note.format(
+                summary_name=summary_name,
+                task_id=task_id,
</code_context>
<issue_to_address>
**issue (bug_risk):** Undefined `result` variable when formatting `background_task_summary_note`.

In `_wake_main_agent_for_background_result`, `background_task_summary_note.format` is called with `result=result`, but `result` isn’t defined in this scope, so this will always raise a `NameError` instead of producing the summary. This argument should likely come from `task_meta.get('result')`, `result_text`, or `extras['background_task_result']['result']`, to match the logic used in the fallback path.
</issue_to_address>

### Comment 2
<location path="astrbot/core/astr_agent_tool_exec.py" line_range="572" />
<code_context>
             context_dump = req._print_friendly_context()
             req.contexts = []
-            req.system_prompt += CONVERSATION_HISTORY_INJECT_PREFIX + context_dump
+            history_wrap_prompt = proactive_cfg.get(
+                "background_history_wrap_prompt",
+                CONVERSATION_HISTORY_INJECT_PREFIX
</code_context>
<issue_to_address>
**issue (complexity):** Consider extracting a shared helper for safe template formatting to simplify `_wake_main_agent_for_background_result` and reduce repetitive error-handling code.

You can centralize the repeated “template + format + fallback” logic into a small helper without changing behavior and make `_wake_main_agent_for_background_result` much easier to scan.

For example, extract a utility like this near the function (or in a shared module):

```python
def _safe_format(
    template: str | None,
    default: str,
    *,
    use_default_when_falsy: bool = True,
    log_msg: str | None = None,
    **kwargs,
) -> str:
    # For most prompts, falsy config => use default
    if (not template) and use_default_when_falsy:
        template = default

    try:
        return template.format(**kwargs)
    except Exception:
        if log_msg:
            logger.error(log_msg, exc_info=True)
        # default can be plain text or a format string; both are safe
        return default.format(**kwargs)
```

Then the branches become linear and shorter:

```python
# history_wrap_prompt
history_wrap_prompt = proactive_cfg.get(
    "background_history_wrap_prompt",
    CONVERSATION_HISTORY_INJECT_PREFIX,
)
req.system_prompt += _safe_format(
    history_wrap_prompt,
    CONVERSATION_HISTORY_INJECT_PREFIX,
    log_msg="background_history_wrap_prompt format failed, falling back to default",
    context_dump=context_dump,
)

# background_execution_prompt
background_execution_prompt = proactive_cfg.get(
    "background_execution_prompt",
    BACKGROUND_TASK_RESULT_WOKE_SYSTEM_PROMPT,
)
req.system_prompt += _safe_format(
    background_execution_prompt,
    BACKGROUND_TASK_RESULT_WOKE_SYSTEM_PROMPT,
    log_msg="background_execution_prompt format failed, falling back to default",
    background_task_result=bg,
)

# summary_note (preserve current behavior: empty template => empty output)
background_task_summary_note = proactive_cfg.get("background_task_summary_note", "")
summary_note = _safe_format(
    background_task_summary_note,
    (
        f"[BackgroundTask] {summary_name} "
        f"(task_id={task_meta.get('task_id', task_id)}) finished. "
        f"Result: {task_meta.get('result') or result_text or 'no content'}"
    ),
    use_default_when_falsy=False,  # keep existing semantics
    log_msg="background_task_summary_note format failed, falling back to default",
    summary_name=summary_name,
    task_id=task_id,
    result=result,  # same as current code
)

# summary_note result (also preserve empty-template behavior)
background_task_summary_note_result = proactive_cfg.get(
    "background_task_summary_note_result",
    "",
)
if llm_resp and llm_resp.completion_text:
    result_suffix = _safe_format(
        background_task_summary_note_result,
        f"I finished the task, here is the result: {llm_resp.completion_text}",
        use_default_when_falsy=False,
        log_msg="background_task_summary_note_result format failed, falling back to default",
        result=llm_resp.completion_text,
    )
    summary_note += result_suffix
```

This keeps all existing semantics (including the “empty string template” behavior for the two summary prompts) while:

- Removing duplicated try/except + fallback branches.
- Making the main function shorter and easier to visually scan.
- Centralizing logging and error handling for prompt formatting.
</issue_to_address>

### Comment 3
<location path="astrbot/core/cron/manager.py" line_range="329" />
<code_context>
             req.contexts = []
-            req.system_prompt += (
-                CONVERSATION_HISTORY_INJECT_PREFIX + f"---\n{context_dump}\n---\n"
+            history_wrap_prompt = self.ctx.get_config().get(
+                "cron_history_wrap_prompt",
+                CONVERSATION_HISTORY_INJECT_PREFIX
</code_context>
<issue_to_address>
**issue (complexity):** Consider extracting a shared helper to safely format config-based prompts so all these cron-related templates follow one concise, reusable pattern instead of repeating similar try/except blocks.

You can reduce the ad‑hoc try/except + logging + fallback logic by introducing a small helper and standardizing how you build these prompts. That also makes it easier to see and test the high‑level behavior.

For example, inside this class (or a shared util), add:

```python
def _safe_format_from_config(
    self,
    key: str,
    default_template: str,
    fallback_template: str | None,
    error_msg: str,
    **kwargs,
) -> str:
    template = self.ctx.get_config().get(key, default_template)
    try:
        return template.format(**kwargs)
    except Exception:
        logger.error(error_msg, exc_info=True)
        tmpl = fallback_template or default_template
        return tmpl.format(**kwargs)
```

Then the current repeated blocks can be simplified and unified, e.g.:

```python
# history_wrap_prompt
if context:
    req.contexts = context
    context_dump = req._print_friendly_context()
    req.contexts = []
    req.system_prompt += self._safe_format_from_config(
        key="cron_history_wrap_prompt",
        default_template=CONVERSATION_HISTORY_INJECT_PREFIX,
        fallback_template=CONVERSATION_HISTORY_INJECT_PREFIX,
        error_msg="cron_history_wrap_prompt 文案格式化失败,已退回默认格式",
        context_dump=context_dump,
    )
```

```python
# cron_execution_prompt
cron_job_str = json.dumps(extras.get("cron_job", {}), ensure_ascii=False)
req.system_prompt += self._safe_format_from_config(
    key="cron_execution_prompt",
    default_template="",
    fallback_template=PROACTIVE_AGENT_CRON_WOKE_SYSTEM_PROMPT,
    error_msg="cron_execution_prompt 文案格式化失败,已退回默认格式",
    cron_job=cron_job_str,
)
```

```python
# cron_task_summary_note
cron_meta = extras.get("cron_job", {}) if extras else {}
summary_note = self._safe_format_from_config(
    key="cron_task_summary_note",
    default_template=(
        "[CronJob] {name_or_id}: {description} triggered at {started_at}, "
    ),
    fallback_template=(
        "[CronJob] {name_or_id}: {description} triggered at {started_at}, "
    ),
    error_msg="cron_task_summary_note 文案格式化失败,已退回默认格式",
    name_or_id=cron_meta.get("name") or cron_meta.get("id", "unknown"),
    description=cron_meta.get("description", ""),
    started_at=cron_meta.get("run_started_at", "unknown time"),
)
```

```python
# cron_task_summary_note_result
if llm_resp and llm_resp.role == "assistant":
    result_suffix = self._safe_format_from_config(
        key="cron_task_summary_note_result",
        default_template="I finished this job, here is the result: {result}",
        fallback_template="I finished this job, here is the result: {result}",
        error_msg="cron_task_summary_note_result 文案格式化失败,已退回默认格式",
        result=llm_resp.completion_text,
    )
    summary_note += result_suffix
```

This:

- Removes four separate try/except/log blocks while keeping all configurability and fallbacks intact.
- Standardizes the “configurable template with safe fallback” pattern in one place, which you can reuse in the background task handler.
- Simplifies the final `summary_note` assembly and avoids subtle issues where the formatted `result_prompt` is computed but not appended.
</issue_to_address>

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.

Comment thread astrbot/core/astr_agent_tool_exec.py Outdated
Comment on lines +638 to +640
background_task_summary_note = proactive_cfg.get("background_task_summary_note", "")
try:
summary_note = background_task_summary_note.format(
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.

issue (bug_risk): Undefined result variable when formatting background_task_summary_note.

In _wake_main_agent_for_background_result, background_task_summary_note.format is called with result=result, but result isn’t defined in this scope, so this will always raise a NameError instead of producing the summary. This argument should likely come from task_meta.get('result'), result_text, or extras['background_task_result']['result'], to match the logic used in the fallback path.

Comment thread astrbot/core/astr_agent_tool_exec.py Outdated
Comment thread astrbot/core/cron/manager.py Outdated
@dosubot
Copy link
Copy Markdown

dosubot bot commented Mar 18, 2026

Related Documentation

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

AstrBotTeam's Space

pr4697的改动
View Suggested Changes
@@ -1448,7 +1448,129 @@
 
 ---
 
-### 14. 其他优化
+### 14. 可配置文本提示词功能(PR #6544)
+
+#### 功能说明
+[PR #6544](https://github.com/AstrBotDevs/AstrBot/pull/6544) 新增了可配置文本提示词功能,使用户能够自定义 Agent 系统中的关键文本注入内容,提升系统的灵活性和可定制化程度。此前,这些提示词在代码中硬编码,用户无法根据实际需求进行调整。
+
+#### 核心可配置提示词
+
+PR #6544 引入了以下可配置文本提示词,涵盖上下文管理、工具调用、后台任务、定时任务、健康模式、Live 模式和本地执行等核心场景:
+
+##### 上下文管理
+- **`context_summary_user_prompt`**:上下文摘要用户文案,默认值为 `"Our previous history conversation summary: {summary_content}"`
+  - 应包含且仅包含一个 `{summary_content}` 占位符
+  - 如果为空或不符合要求则使用默认文案
+- **`context_summary_ack_prompt`**:上下文摘要确认文案,默认值为 `"Acknowledged the summary of our previous conversation history."`
+
+##### 工具调用
+- **`tool_call_prompt`**:工具调用提示词(`full` 模式),默认值为工具使用指南文本
+  - 指导 LLM 如何正确使用工具:不返回空响应、简要说明工具用途、遵循工具 schema、总结执行结果、保持对话风格一致
+- **`tool_call_lazy_load_mode_prompt`**:工具调用提示词(`lazy_load` 模式),默认值为分阶段工具使用指南
+  - 说明工具 schema 分两阶段提供(先名称和描述,再参数 schema),不要在看到完整 schema 前猜测参数
+- **`tool_call_requery_instruction_prompt`**:`lazy_load` 模式工具调用二阶段提示词,默认值为 `"You have decided to call tool(s): {tool_names}. Now call the tool(s) with required arguments using the tool schema, and follow the existing tool-use rules."`
+  - 应包含且仅包含一个 `{tool_names}` 占位符
+- **`tool_call_follow_up_notice_prompt`**:工具执行期间用户追问的提示文案,默认值为系统通知模板
+  - 应包含且仅包含一个 `{follow_up_lines}` 占位符
+  - 指导 LLM 优先处理追问内容,并在下一次行动中简要确认已收到
+- **`tool_call_max_step_reached_prompt`**:工具调用轮数上限提示文案,默认值为中文提示:"工具调用次数已达到上限,请停止使用工具,并根据已经收集到的信息,对你的任务和发现进行总结,然后直接回复用户。"
+
+##### 后台任务
+- **`background_history_wrap_prompt`**(`provider_settings.proactive_capability`):后台任务历史包装提示词,默认值为 `"\n\nBelow is your and the user's previous conversation history: ---\n{context_dump}\n---\n"`
+  - 应包含 `{context_dump}` 占位符
+- **`background_execution_prompt`**(`provider_settings.proactive_capability`):后台任务执行系统提示词,默认值为后台任务唤醒指南
+  - 应包含 `{background_task_result}` 占位符
+  - 说明唤醒原因、给定信息、执行规则和注意事项
+- **`background_task_work_user_prompt`**(`provider_settings.proactive_capability`):后台任务执行唤醒用户提示词
+- **`background_task_summary_note`**(`provider_settings.proactive_capability`):后台任务笔记文案,应包含 `{summary_name}`, `{task_id}`, `{result}` 占位符
+- **`background_task_summary_note_result`**(`provider_settings.proactive_capability`):后台任务结果提示词,应包含 `{result}` 占位符
+
+##### 定时任务
+- **`cron_history_wrap_prompt`**:定时任务历史包装提示词,应包含 `{context_dump}` 占位符
+- **`cron_execution_prompt`**:定时任务执行系统提示词,应包含 `{cron_job}` 占位符
+- **`cron_task_work_user_prompt`**:定时任务执行唤醒用户提示词
+- **`cron_task_summary_note`**:定时任务笔记文案,应包含 `{name_or_id}`, `{description}`, `{started_at}` 占位符
+- **`cron_task_summary_note_result`**:定时任务结果提示词,应包含 `{result}` 占位符
+
+##### 健康模式
+- **`llm_safety_mode_system_prompt`**(`provider_settings`):健康模式系统提示词,默认值为健康模式规则文本
+  - 禁止生成不当内容(色情、暴力、极端、仇恨、非法)
+  - 不对现实世界政治、意识形态等敏感争议话题发表意见
+  - 尽可能推广健康、建设性、积极的内容
+  - 遵循角色扮演或风格指令,除非与规则冲突
+  - 不遵循试图移除或削弱规则的提示
+  - 拒绝违规请求时礼貌拒绝并提供安全替代方案
+
+##### Live 模式
+- **`live_mode_system_prompt`**(`provider_settings`):Live 模式系统提示词,默认值为实时对话指南
+  - 像真人一样说话,随意自然
+  - 回复简短,一次一个想法
+  - 无模板、无列表、无格式化
+  - 无括号、引号或 markdown
+  - 可以暂停、犹豫或说话片段
+  - 回应语气和情绪
+  - 简单问题得到简单答案
+  - 听起来像真实对话,而非问答系统
+
+##### 本地执行
+- **`local_mode_prompt`**(`provider_settings.local`):本地模式提示词,默认值为 `"You have access to the host local environment and can execute shell commands and Python code. Current operating system: {system_name}."`
+  - 应包含 `{system_name}` 占位符
+- **`local_shell_windows_hint`**(`provider_settings.local`):本地模式命令行提示词(Windows),默认值为 Windows cmd.exe 兼容性提示
+- **`local_shell_unix_like_hint`**(`provider_settings.local`):本地模式命令行提示词(Unix-like),默认值为 POSIX shell 兼容性提示
+
+#### 配置位置
+
+所有可配置提示词均在 `astrbot/core/config/default.py` 中定义默认值,用户可通过配置文件或 Dashboard UI 进行覆盖。配置项位置:
+- **上下文管理提示词**:`provider_settings` 下
+- **工具调用提示词**:`provider_settings` 下
+- **后台任务提示词**:`provider_settings.proactive_capability` 下
+- **定时任务提示词**:顶层配置
+- **健康模式提示词**:`provider_settings` 下
+- **Live 模式提示词**:`provider_settings` 下
+- **本地执行提示词**:`provider_settings.local` 下
+
+#### 错误回退机制
+
+为确保系统稳定性,所有可配置提示词均实现了错误回退机制:
+- 如果用户配置的提示词格式无效(例如缺少必需的占位符),系统会自动回退到默认值
+- 如果提示词格式化(`format()` 调用)失败,系统会捕获异常并使用默认文案
+- 对于空白字符串或不符合要求的配置,系统会进行规范化处理并回退
+
+例如,`tool_call_requery_instruction_prompt` 必须包含且仅包含一个 `{tool_names}` 占位符,否则系统会使用默认提示词。
+
+#### 国际化支持
+
+PR #6544 已为所有新增配置项添加了中英俄三语的 i18n 翻译(`dashboard/src/i18n/locales/*/features/config-metadata.json`),确保国际用户能够在 Dashboard 中看到本地化的配置说明和提示文本。
+
+#### 用户收益
+
+此功能为用户提供以下优势:
+- **高度可定制化**:用户可根据实际场景调整 Agent 系统的关键提示词,优化 LLM 行为
+- **多语言适配**:用户可将默认的英文提示词替换为其他语言,提升非英语场景的表现
+- **上下文优化**:针对特定领域或用户群体优化提示词,提高对话质量
+- **调试友好**:通过修改提示词可快速测试不同的 LLM 引导策略,便于系统调优
+- **向后兼容**:所有配置项均有合理的默认值,升级后无需任何配置即可正常使用
+
+#### 使用示例
+
+假设用户希望将工具调用提示词改为中文,可在配置文件中添加:
+
+```yaml
+provider_settings:
+  tool_call_prompt: |
+    使用工具时:
+    永远不要返回空响应;
+    在调用工具前简要解释目的;
+    严格遵循工具 schema,不要编造参数;
+    执行后简要总结结果;
+    保持对话风格一致。
+```
+
+保存配置后,Agent 会在系统提示词中使用自定义的中文指南,而非默认的英文版本。
+
+---
+
+### 15. 其他优化
 - JWT 处理和错误处理机制增强,提升系统安全性和稳定性
 - UI 细节优化,提升用户体验
 - 日志与异常处理增强,便于问题追踪

[Accept] [Decline]

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

How did I do? Any feedback?  Join Discord

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

这次的改动非常好,将大量硬编码的文案提取为可配置项,大大提高了系统的灵活性和可定制性。代码整体结构清晰,并且为配置项增加了 i18n 支持,考虑得很周全。

我在代码中发现了一些可以改进的地方,主要集中在 astrbot/core/astr_agent_tool_exec.pyastrbot/core/cron/manager.py 中,包括一个潜在的 NameError bug 和一些可以重构以提高代码可读性和可维护性的重复代码。

请查看具体的 review comments。

Comment thread astrbot/core/astr_agent_tool_exec.py Outdated
Comment on lines +639 to +644
try:
summary_note = background_task_summary_note.format(
summary_name=summary_name,
task_id=task_id,
result=result,
)
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.

critical

这里存在一个 NameError bug。在 try 块中,background_task_summary_note.format() 使用了变量 result,但是 result 在这个作用域内尚未定义。它是在后面的 if llm_resp and llm_resp.completion_text: 块中才被定义的。

这会导致在 llm_resp 为空或没有 completion_text 时抛出 NameError 异常。

为了修复这个问题,你应该在 try 块之前定义 result。根据之前的代码逻辑,它应该是从 task_metaresult_text 中获取的。

        result_text = llm_resp.completion_text if llm_resp and llm_resp.completion_text else ""
        result_for_summary = task_meta.get('result') or result_text or 'no content'
        try:
            summary_note = background_task_summary_note.format(
                summary_name=summary_name,
                task_id=task_id,
                result=result_for_summary,
            )

Comment thread astrbot/core/cron/manager.py Outdated
Comment on lines +392 to +403
if llm_resp and llm_resp.role == "assistant":
summary_note += (
f"I finished this job, here is the result: {llm_resp.completion_text}"
result_prompt = self.ctx.get_config().get(
"cron_task_summary_note_result", ""
)
try:
result_prompt = result_prompt.format(result=llm_resp.completion_text)
except Exception:
logger.error(
"cron_task_summary_note_result 文案格式化失败,已退回默认格式",
exc_info=True,
)
summary_note += f"I finished this job, here is the result: {llm_resp.completion_text}"
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.

high

这里存在一个 bug。在 try 块中,result_prompt.format() 的结果被赋给了 result_prompt 自身,但之后这个变量没有被使用。而在 except 块中,是直接将硬编码的字符串追加到 summary_note

这导致了即使 cron_task_summary_note_result 配置项存在且格式化成功,它也不会被添加到最终的 summary_note 中。

为了修复这个问题,try 块中应该将格式化后的字符串追加到 summary_note

Suggested change
if llm_resp and llm_resp.role == "assistant":
summary_note += (
f"I finished this job, here is the result: {llm_resp.completion_text}"
result_prompt = self.ctx.get_config().get(
"cron_task_summary_note_result", ""
)
try:
result_prompt = result_prompt.format(result=llm_resp.completion_text)
except Exception:
logger.error(
"cron_task_summary_note_result 文案格式化失败,已退回默认格式",
exc_info=True,
)
summary_note += f"I finished this job, here is the result: {llm_resp.completion_text}"
if llm_resp and llm_resp.role == "assistant":
result_prompt_template = self.ctx.get_config().get(
"cron_task_summary_note_result", ""
)
try:
result_text = result_prompt_template.format(result=llm_resp.completion_text)
summary_note += result_text
except Exception:
logger.error(
"cron_task_summary_note_result 文案格式化失败,已退回默认格式",
exc_info=True,
)
summary_note += f"I finished this job, here is the result: {llm_resp.completion_text}"

Comment thread astrbot/core/astr_agent_tool_exec.py Outdated
Comment on lines +572 to +615
history_wrap_prompt = proactive_cfg.get(
"background_history_wrap_prompt",
CONVERSATION_HISTORY_INJECT_PREFIX
)
if history_wrap_prompt:
try:
req.system_prompt += history_wrap_prompt.format(
context_dump=context_dump
)
except Exception:
logger.error(
"background_history_wrap_prompt 格式化失败,回退到默认模板",
exc_info=True,
)
req.system_prompt += CONVERSATION_HISTORY_INJECT_PREFIX.format(
context_dump=context_dump
)
else:
req.system_prompt += CONVERSATION_HISTORY_INJECT_PREFIX.format(
context_dump=context_dump
)

bg = json.dumps(extras["background_task_result"], ensure_ascii=False)
req.system_prompt += BACKGROUND_TASK_RESULT_WOKE_SYSTEM_PROMPT.format(
background_task_result=bg
background_execution_prompt = proactive_cfg.get(
"background_execution_prompt",
BACKGROUND_TASK_RESULT_WOKE_SYSTEM_PROMPT
)
if background_execution_prompt:
try:
req.system_prompt += background_execution_prompt.format(
background_task_result=bg
)
except Exception:
logger.error(
"background_execution_prompt 格式化失败,回退到默认模板",
exc_info=True,
)
req.system_prompt += BACKGROUND_TASK_RESULT_WOKE_SYSTEM_PROMPT.format(
background_task_result=bg
)
else:
req.system_prompt += BACKGROUND_TASK_RESULT_WOKE_SYSTEM_PROMPT.format(
background_task_result=bg
)
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

这里的 try-except 格式化文案逻辑在 history_wrap_promptbackground_execution_prompt 中是重复的。类似的逻辑也出现在 astrbot/core/cron/manager.py 中。

为了提高代码的可维护性并减少重复,建议将这个逻辑提取到一个辅助函数中。例如:

def _format_prompt_with_fallback(
    prompt_template: str | None,
    default_template: str,
    logger,
    log_message: str,
    **kwargs,
) -> str:
    """Helper to format a prompt with a fallback to a default template."""
    template_to_use = prompt_template or default_template
    try:
        return template_to_use.format(**kwargs)
    except Exception:
        logger.error(log_message, exc_info=True)
        return default_template.format(**kwargs)

# 使用示例:
# req.system_prompt += _format_prompt_with_fallback(
#     proactive_cfg.get("background_history_wrap_prompt"),
#     CONVERSATION_HISTORY_INJECT_PREFIX,
#     logger,
#     "background_history_wrap_prompt 格式化失败,回退到默认模板",
#     context_dump=context_dump,
# )

这样可以使代码更简洁,也更容易维护。

@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Mar 18, 2026
@Rail1bc
Copy link
Copy Markdown
Contributor Author

Rail1bc commented Mar 18, 2026

这个历史太糟糕了,我将重新整理后提交一个新的pr

@Rail1bc Rail1bc closed this Mar 18, 2026
@Rail1bc Rail1bc deleted the feat/configurable-hardcoded-injections-clean branch March 18, 2026 09:08
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 size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants