fix:提及必回越过频率控制

This commit is contained in:
SengokuCola
2026-05-02 14:40:54 +08:00
parent 86d4e57cf0
commit f9328840d0
2 changed files with 43 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
from datetime import datetime from datetime import datetime
from types import SimpleNamespace from types import SimpleNamespace
import asyncio
import pytest import pytest
from src.core.tooling import ToolExecutionResult, ToolInvocation from src.core.tooling import ToolExecutionResult, ToolInvocation
@@ -8,6 +9,7 @@ from src.llm_models.payload_content.tool_option import ToolCall
from src.maisaka.chat_loop_service import ChatResponse, MaisakaChatLoopService from src.maisaka.chat_loop_service import ChatResponse, MaisakaChatLoopService
from src.maisaka.context_messages import AssistantMessage, TIMING_GATE_INVALID_TOOL_HINT_SOURCE from src.maisaka.context_messages import AssistantMessage, TIMING_GATE_INVALID_TOOL_HINT_SOURCE
from src.maisaka.reasoning_engine import MaisakaReasoningEngine from src.maisaka.reasoning_engine import MaisakaReasoningEngine
from src.maisaka.runtime import MaisakaHeartFlowChatting
def _build_chat_response(tool_calls: list[ToolCall]) -> ChatResponse: def _build_chat_response(tool_calls: list[ToolCall]) -> ChatResponse:
@@ -173,6 +175,29 @@ def test_timing_gate_invalid_tool_hint_only_visible_to_timing_gate() -> None:
assert planner_history == [] assert planner_history == []
def test_forced_timing_trigger_bypasses_message_frequency_threshold() -> None:
runtime = SimpleNamespace(
_STATE_WAIT="wait",
_agent_state="stop",
_message_turn_scheduled=False,
_internal_turn_queue=asyncio.Queue(),
_has_pending_messages=lambda: True,
_get_pending_message_count=lambda: 1,
_has_forced_timing_trigger=lambda: True,
_cancel_deferred_message_turn_task=lambda: None,
)
def _fail_get_message_trigger_threshold() -> int:
raise AssertionError("@/提及必回不应被普通聊天频率阈值拦住")
runtime._get_message_trigger_threshold = _fail_get_message_trigger_threshold
MaisakaHeartFlowChatting._schedule_message_turn(runtime) # type: ignore[arg-type]
assert runtime._message_turn_scheduled is True
assert runtime._internal_turn_queue.get_nowait() == "message"
def test_finish_tool_is_not_written_back_to_history() -> None: def test_finish_tool_is_not_written_back_to_history() -> None:
finish_call = ToolCall(call_id="finish-call", func_name="finish", args={}) finish_call = ToolCall(call_id="finish-call", func_name="finish", args={})
reply_call = ToolCall(call_id="reply-call", func_name="reply", args={}) reply_call = ToolCall(call_id="reply-call", func_name="reply", args={})

View File

@@ -473,13 +473,18 @@ class MaisakaHeartFlowChatting:
def _update_message_trigger_state(self, message: SessionMessage) -> None: def _update_message_trigger_state(self, message: SessionMessage) -> None:
"""补齐消息中的 @/提及 标记,并在命中时启用强制 continue。""" """补齐消息中的 @/提及 标记,并在命中时启用强制 continue。"""
detected_mentioned, detected_at, _ = is_mentioned_bot_in_message(message) detected_mentioned, detected_at, reply_probability_boost = is_mentioned_bot_in_message(message)
if detected_at: if detected_at:
message.is_at = True message.is_at = True
if detected_mentioned: if detected_mentioned:
message.is_mentioned = True message.is_mentioned = True
if not message.is_at and not message.is_mentioned: should_force_reply = (
reply_probability_boost >= 1.0
or (message.is_at and global_config.chat.at_bot_inevitable_reply)
or (message.is_mentioned and global_config.chat.mentioned_bot_reply)
)
if not should_force_reply or (not message.is_at and not message.is_mentioned):
return return
self._arm_force_next_timing_continue( self._arm_force_next_timing_continue(
@@ -537,6 +542,11 @@ class MaisakaHeartFlowChatting:
self._force_next_timing_reason = "" self._force_next_timing_reason = ""
return reason return reason
def _has_forced_timing_trigger(self) -> bool:
"""判断是否已有 @/提及必回触发,需绕过普通频率阈值。"""
return self._force_next_timing_continue
def _bind_planner_interrupt_flag(self, interrupt_flag: asyncio.Event) -> None: def _bind_planner_interrupt_flag(self, interrupt_flag: asyncio.Event) -> None:
"""绑定当前可打断请求使用的中断标记。""" """绑定当前可打断请求使用的中断标记。"""
self._planner_interrupt_flag = interrupt_flag self._planner_interrupt_flag = interrupt_flag
@@ -867,6 +877,12 @@ class MaisakaHeartFlowChatting:
if pending_count <= 0: if pending_count <= 0:
return return
if self._has_forced_timing_trigger():
self._cancel_deferred_message_turn_task()
self._message_turn_scheduled = True
self._internal_turn_queue.put_nowait("message")
return
trigger_threshold = self._get_message_trigger_threshold() trigger_threshold = self._get_message_trigger_threshold()
if pending_count >= trigger_threshold or self._should_trigger_message_turn_by_idle_compensation( if pending_count >= trigger_threshold or self._should_trigger_message_turn_by_idle_compensation(
pending_count=pending_count, pending_count=pending_count,