fix(redis): 修复 Redis 流读取兼容性问题

- 支持 bytes 和 str 类型的 entry_id
- 支持 list 类型响应格式
- 优化 payload 解码处理
This commit is contained in:
qzl
2026-03-11 21:33:25 +08:00
parent e4f69a64bd
commit 18db6c50e7
17 changed files with 359 additions and 54 deletions
@@ -2,7 +2,7 @@ from __future__ import annotations
import pytest
from v1.agent.dependencies import TaskiqQueueClient
from v1.agent.dependencies import RedisEventStream, TaskiqQueueClient
class _FakeRedis:
@@ -39,6 +39,10 @@ class _FakeAsyncResult:
self.task_id = task_id
class _FakeRedisStreamClient:
pass
@pytest.mark.asyncio
async def test_enqueue_returns_task_id(monkeypatch: pytest.MonkeyPatch) -> None:
from v1.agent import dependencies as deps
@@ -89,7 +93,11 @@ async def test_enqueue_resume_dedup_returns_existing_task_id(
client = TaskiqQueueClient()
task_id = await client.enqueue(
command={"command": "resume", "session_id": "session-1", "tool_call_id": "call-1"},
command={
"command": "resume",
"session_id": "session-1",
"tool_call_id": "call-1",
},
dedup_key=dedup_key,
)
@@ -132,7 +140,11 @@ async def test_enqueue_inflight_dedup_waits_and_reuses_existing_task_id(
client = TaskiqQueueClient()
task_id = await client.enqueue(
command={"command": "resume", "session_id": "session-1", "tool_call_id": "call-1"},
command={
"command": "resume",
"session_id": "session-1",
"tool_call_id": "call-1",
},
dedup_key=dedup_key,
)
@@ -140,7 +152,9 @@ async def test_enqueue_inflight_dedup_waits_and_reuses_existing_task_id(
@pytest.mark.asyncio
async def test_enqueue_failure_cleans_dedup_lock(monkeypatch: pytest.MonkeyPatch) -> None:
async def test_enqueue_failure_cleans_dedup_lock(
monkeypatch: pytest.MonkeyPatch,
) -> None:
from v1.agent import dependencies as deps
fake_redis = _FakeRedis()
@@ -160,7 +174,11 @@ async def test_enqueue_failure_cleans_dedup_lock(monkeypatch: pytest.MonkeyPatch
client = TaskiqQueueClient()
with pytest.raises(RuntimeError, match="enqueue failed"):
await client.enqueue(
command={"command": "resume", "session_id": "session-1", "tool_call_id": "call-1"},
command={
"command": "resume",
"session_id": "session-1",
"tool_call_id": "call-1",
},
dedup_key=dedup_key,
)
@@ -225,3 +243,41 @@ async def test_enqueue_uses_bulk_queue_when_requested(
)
assert task_id == "bulk-task-id"
@pytest.mark.asyncio
async def test_event_stream_caps_block_ms_below_socket_timeout(
monkeypatch: pytest.MonkeyPatch,
) -> None:
from v1.agent import dependencies as deps
async def _fake_get_or_init_client() -> _FakeRedisStreamClient:
return _FakeRedisStreamClient()
monkeypatch.setattr(deps, "get_or_init_redis_client", _fake_get_or_init_client)
monkeypatch.setattr(deps.config.agent_runtime, "redis_stream_block_ms", 5000)
monkeypatch.setattr(deps.config.redis, "socket_timeout", 1.0)
stream = RedisEventStream()
bus = await stream._get_bus()
assert bus._block_ms == 900
@pytest.mark.asyncio
async def test_event_stream_uses_configured_block_ms_when_safe(
monkeypatch: pytest.MonkeyPatch,
) -> None:
from v1.agent import dependencies as deps
async def _fake_get_or_init_client() -> _FakeRedisStreamClient:
return _FakeRedisStreamClient()
monkeypatch.setattr(deps, "get_or_init_redis_client", _fake_get_or_init_client)
monkeypatch.setattr(deps.config.agent_runtime, "redis_stream_block_ms", 200)
monkeypatch.setattr(deps.config.redis, "socket_timeout", 2.0)
stream = RedisEventStream()
bus = await stream._get_bus()
assert bus._block_ms == 200