108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from opensquilla.channels.types import IncomingMessage
|
|
|
|
|
|
def test_channel_dispatch_no_longer_uses_gateway_cron_intent_preflight() -> None:
|
|
source = Path("src/opensquilla/gateway/channel_dispatch.py").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
|
|
assert "channel_cron_intent" not in source
|
|
assert "_dispatch_channel_cron_intent" not in source
|
|
|
|
|
|
def test_gateway_cron_intent_module_removed_from_runtime_surface() -> None:
|
|
assert not Path("src/opensquilla/gateway/channel_cron_intent.py").exists()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_schedule_like_channel_text_reaches_normal_runtime() -> None:
|
|
from opensquilla.gateway.channel_dispatch import _ChannelInFlightSet, run_channel_dispatch
|
|
|
|
msg = IncomingMessage(
|
|
sender_id="ou_user",
|
|
channel_id="oc_chat",
|
|
content="每过五分钟提醒我喝水",
|
|
metadata={"account_id": "tenant-a", "native_thread_id": "thread-1"},
|
|
)
|
|
channel = MagicMock()
|
|
channel.channel_id = "feishu"
|
|
channel.send = AsyncMock()
|
|
channel.build_reply_message = None
|
|
channel.streaming_reply_kwargs = None
|
|
calls = 0
|
|
|
|
async def _receive() -> IncomingMessage:
|
|
nonlocal calls
|
|
calls += 1
|
|
if calls == 1:
|
|
return msg
|
|
raise asyncio.CancelledError
|
|
|
|
channel.receive = _receive
|
|
session_manager = MagicMock()
|
|
session_manager.get_or_create = AsyncMock(return_value=(MagicMock(), False))
|
|
session_manager.update = AsyncMock()
|
|
task_runtime = MagicMock()
|
|
turn_runner = MagicMock()
|
|
turn_runner._get_session_lock.return_value = None
|
|
status_reactor = SimpleNamespace(
|
|
received=AsyncMock(),
|
|
running=AsyncMock(),
|
|
completed=AsyncMock(),
|
|
failed=AsyncMock(),
|
|
)
|
|
|
|
with (
|
|
patch(
|
|
"opensquilla.gateway.channel_dispatch._record_delivery_context",
|
|
new=AsyncMock(return_value=(MagicMock(), False)),
|
|
),
|
|
patch(
|
|
"opensquilla.gateway.channel_dispatch._should_skip_unmentioned",
|
|
new=MagicMock(return_value=False),
|
|
),
|
|
patch(
|
|
"opensquilla.gateway.channel_dispatch._transcript_watermark",
|
|
new=AsyncMock(return_value=0),
|
|
),
|
|
patch(
|
|
"opensquilla.gateway.channel_dispatch.start_turn_via_runtime",
|
|
new=AsyncMock(return_value=SimpleNamespace(task_id="task-1")),
|
|
) as start_turn,
|
|
patch(
|
|
"opensquilla.gateway.channel_dispatch._append_channel_user_message",
|
|
new=AsyncMock(return_value=(MagicMock(), msg.content)),
|
|
),
|
|
patch(
|
|
"opensquilla.gateway.channel_dispatch._deliver_runtime_channel_reply",
|
|
new=AsyncMock(),
|
|
),
|
|
patch(
|
|
"opensquilla.gateway.channel_dispatch._status_reactor",
|
|
new=MagicMock(return_value=status_reactor),
|
|
),
|
|
):
|
|
with pytest.raises(asyncio.CancelledError):
|
|
await run_channel_dispatch(
|
|
channel=channel,
|
|
turn_runner=turn_runner,
|
|
session_manager=session_manager,
|
|
session_key_builder=lambda _msg: "agent:main:feishu:ou_user",
|
|
session_prefix="feishu",
|
|
task_runtime=task_runtime,
|
|
_in_flight=_ChannelInFlightSet(cap=1),
|
|
)
|
|
|
|
start_turn.assert_awaited_once()
|
|
assert start_turn.await_args.kwargs["run_kind"] == "channel_turn"
|
|
channel.send.assert_not_awaited()
|