From add5db67480b1b8744b01c3d4aed836226381267 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 10 Apr 2026 00:01:50 +0800 Subject: [PATCH] feat: add workspace extra prompt handling in message processing --- astrbot/core/astr_main_agent.py | 48 ++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/astrbot/core/astr_main_agent.py b/astrbot/core/astr_main_agent.py index 4a9e2637d..bf8bd12b5 100644 --- a/astrbot/core/astr_main_agent.py +++ b/astrbot/core/astr_main_agent.py @@ -9,6 +9,7 @@ import platform import zoneinfo from collections.abc import Coroutine from dataclasses import dataclass, field +from pathlib import Path from astrbot.core import logger from astrbot.core.agent.handoff import HandoffTool @@ -64,6 +65,7 @@ from astrbot.core.tools.computer_tools import ( RollbackSkillReleaseTool, RunBrowserSkillTool, SyncSkillReleaseTool, + _normalize_umo_for_workspace, ) from astrbot.core.tools.cron_tools import ( CreateActiveCronTool, @@ -301,6 +303,44 @@ def _apply_prompt_prefix(req: ProviderRequest, cfg: dict) -> None: req.prompt = f"{prefix}{req.prompt}" +def _get_workspace_path_for_umo(umo: str) -> Path: + normalized_umo = _normalize_umo_for_workspace(umo) + return Path(get_astrbot_workspaces_path()) / normalized_umo + + +def _apply_workspace_extra_prompt( + event: AstrMessageEvent, + req: ProviderRequest, +) -> None: + extra_prompt_path = _get_workspace_path_for_umo(event.unified_msg_origin) / ( + "EXTRA_PROMPT.md" + ) + if not extra_prompt_path.is_file(): + return + + try: + extra_prompt = extra_prompt_path.read_text(encoding="utf-8").strip() + except Exception as exc: # noqa: BLE001 + logger.warning( + "Failed to read workspace extra prompt for umo=%s from %s: %s", + event.unified_msg_origin, + extra_prompt_path, + exc, + ) + return + + if not extra_prompt: + return + + req.system_prompt = ( + f"{req.system_prompt or ''}\n" + "[Workspace Extra Prompt]\n" + "The following instructions are loaded from the current workspace " + "`EXTRA_PROMPT.md` file.\n" + f"{extra_prompt}\n" + ) + + def _apply_local_env_tools(req: ProviderRequest, plugin_context: Context) -> None: if req.func_tool is None: req.func_tool = ToolSet() @@ -781,6 +821,7 @@ async def _decorate_llm_request( if tz is None: tz = plugin_context.get_config().get("timezone") _append_system_reminders(event, req, cfg, tz) + _apply_workspace_extra_prompt(event, req) def _modalities_fix(provider: Provider, req: ProviderRequest) -> None: @@ -1404,14 +1445,9 @@ async def build_main_agent( ) if config.computer_use_runtime == "local": - from astrbot.core.tools.computer_tools.fs import ( - _normalize_umo_for_workspace, - ) - - normalized_umo = _normalize_umo_for_workspace(event.unified_msg_origin) tool_prompt += ( f"\nCurrent workspace you can use: " - f"`{os.path.join(get_astrbot_workspaces_path(), normalized_umo)}`\n" + f"`{_get_workspace_path_for_umo(event.unified_msg_origin)}`\n" "Unless the user explicitly specifies a different directory, " "perform all file-related operations in this workspace.\n" )