Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions astrbot/core/astr_main_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,38 @@ def _get_compress_provider(
return provider


def _apply_global_context_info(event: AstrMessageEvent, req: ProviderRequest) -> None:
"""Add platform and session information to user prompt when in global unified context mode."""
from astrbot.core.config.default import (
GLOBAL_UNIFIED_CONTEXT_UMO,
ORIGINAL_UMO_KEY,
)

if event.unified_msg_origin != GLOBAL_UNIFIED_CONTEXT_UMO:
return

# Get original UMO from extras
original_umo = event.get_extra(ORIGINAL_UMO_KEY)
if not original_umo:
return

# Parse the original UMO to extract platform, message type, and session info
try:
parts = original_umo.split(":", 2)
if len(parts) != 3:
logger.warning(
f"Original UMO format is invalid (expected 3 parts): {original_umo}"
)
return

platform_id, message_type, session_id = parts
context_info = f"[Context: Platform={platform_id}, Type={message_type}, Session={session_id}]"
# Prepend context info to the user prompt
req.prompt = f"{context_info} {req.prompt or ''}"
except Exception as e:
logger.warning(f"Failed to parse original UMO for global context: {e}")


async def build_main_agent(
*,
event: AstrMessageEvent,
Expand Down Expand Up @@ -888,6 +920,9 @@ async def build_main_agent(
if isinstance(req.contexts, str):
req.contexts = json.loads(req.contexts)

# Apply global context information if enabled
_apply_global_context_info(event, req)

if config.file_extract_enabled:
try:
await _apply_file_extract(event, req, config)
Expand Down
11 changes: 10 additions & 1 deletion astrbot/core/astr_main_agent_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ class SendMessageToUserTool(FunctionTool[AstrAgentContext]):
"required": ["type"],
},
},
"session": {
"type": "string",
"description": "Target session ID in format 'platform:type:session_id'. If not specified, sends to the current session.",
},
},
"required": ["messages"],
}
Expand Down Expand Up @@ -253,7 +257,12 @@ async def _resolve_path_from_sandbox(
async def call(
self, context: ContextWrapper[AstrAgentContext], **kwargs
) -> ToolExecResult:
session = kwargs.get("session") or context.context.event.unified_msg_origin
# In global context mode, default to original UMO if session not specified
from astrbot.core.config.default import ORIGINAL_UMO_KEY

original_umo = context.context.event.get_extra(ORIGINAL_UMO_KEY)
default_session = original_umo or context.context.event.unified_msg_origin
session = kwargs.get("session") or default_session
messages = kwargs.get("messages")

if not isinstance(messages, list) or not messages:
Expand Down
6 changes: 6 additions & 0 deletions astrbot/core/config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@
"lark",
]

# Constant UMO for global unified context mode
GLOBAL_UNIFIED_CONTEXT_UMO = "global::global"
# Key for storing original UMO in event extras when global context mode is enabled
ORIGINAL_UMO_KEY = "original_umo"

# 默认配置
DEFAULT_CONFIG = {
"config_version": 2,
"platform_settings": {
"unique_session": False,
"global_unified_context_mode": False,
"rate_limit": {
"time": 60,
"count": 30,
Expand Down
10 changes: 10 additions & 0 deletions astrbot/core/pipeline/respond/stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ async def process(
f"Prepare to send - {event.get_sender_name()}/{event.get_sender_id()}: {event._outline_chain(result.chain)}",
)

# Restore original UMO before sending if in global context mode
from astrbot.core.config.default import ORIGINAL_UMO_KEY

original_umo = event.get_extra(ORIGINAL_UMO_KEY)
if original_umo:
logger.debug(
f"Restoring original UMO before sending: {event.unified_msg_origin} -> {original_umo}"
)
event.unified_msg_origin = original_umo

if result.result_content_type == ResultContentType.STREAMING_RESULT:
if result.async_stream is None:
logger.warning("async_stream 为空,跳过发送。")
Expand Down
18 changes: 18 additions & 0 deletions astrbot/core/pipeline/waking_check/stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,29 @@ async def initialize(self, ctx: PipelineContext) -> None:
)
platform_settings = self.ctx.astrbot_config.get("platform_settings", {})
self.unique_session = platform_settings.get("unique_session", False)
self.global_unified_context_mode = platform_settings.get(
"global_unified_context_mode", False
)

async def process(
self,
event: AstrMessageEvent,
) -> None | AsyncGenerator[None, None]:
# apply global unified context mode
if self.global_unified_context_mode:
from astrbot.core.config.default import (
GLOBAL_UNIFIED_CONTEXT_UMO,
ORIGINAL_UMO_KEY,
)

original_umo = event.unified_msg_origin
event.unified_msg_origin = GLOBAL_UNIFIED_CONTEXT_UMO
# Store original UMO for reference in later stages
event.set_extra(ORIGINAL_UMO_KEY, original_umo)
logger.debug(
f"Global unified context mode enabled. Changed UMO from {original_umo} to {GLOBAL_UNIFIED_CONTEXT_UMO}"
)

# apply unique session
if self.unique_session and event.message_obj.type == MessageType.GROUP_MESSAGE:
sid = build_unique_session_id(event)
Expand Down
6 changes: 3 additions & 3 deletions dashboard/src/theme/DarkTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ const PurpleThemeDark: ThemeTypes = {
name: 'PurpleThemeDark',
dark: true,
variables: {
'border-color': '#1677ff',
'border-color': '#3c96ca',
'carousel-control-size': 10
},
colors: {
primary: '#1677ff',
secondary: '#722ed1',
primary: '#3c96ca',
secondary: '#2288b7',
info: '#03c9d7',
success: '#52c41a',
accent: '#FFAB91',
Expand Down