Add manual retry flow for failed meeting summaries

This commit is contained in:
2026-06-09 11:42:13 +00:00
parent d101c34156
commit 53d73df433
4 changed files with 308 additions and 24 deletions
+68
View File
@@ -0,0 +1,68 @@
import asyncio
import os
import sys
from pathlib import Path
from types import SimpleNamespace
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
import discord
import bot
class FakeChannel:
def __init__(self, failures_before_success=0, channel_id=999):
self.failures_before_success = failures_before_success
self.messages = []
self.attempts = 0
self.id = channel_id
async def send(self, text):
self.attempts += 1
if self.attempts <= self.failures_before_success:
response = SimpleNamespace(status=403, reason="Forbidden")
raise discord.Forbidden(response, {"message": "Missing Permissions", "code": 50013})
self.messages.append(text)
def test_safe_send_chunked_falls_back_to_secondary_channel():
async def run():
primary = FakeChannel(failures_before_success=1, channel_id=100)
fallback = FakeChannel(channel_id=200)
delivered = await bot.safe_send_chunked(
primary,
"hello world",
fallback_channels=[fallback],
purpose="test notification",
)
return delivered, fallback.messages
delivered, messages = asyncio.run(run())
assert messages == ["hello world"]
assert delivered is not None
def test_safe_send_chunked_returns_none_when_all_channels_fail():
async def run():
primary = FakeChannel(failures_before_success=10, channel_id=100)
fallback = FakeChannel(failures_before_success=10, channel_id=200)
return await bot.safe_send_chunked(
primary,
"hello world",
fallback_channels=[fallback],
purpose="test notification",
)
assert asyncio.run(run()) is None
def test_build_retry_notice_mentions_reason_and_path():
message = bot.build_retry_notice(
file_path=str(Path("recordings") / "1" / "session" / "meeting.wav"),
reason="OpenRouter 502",
)
assert "OpenRouter 502" in message
assert "meeting.wav" in message
assert "`/retry`" in message
+41
View File
@@ -0,0 +1,41 @@
import asyncio
import os
import sys
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
import config
def _reset_config_path(tmp_path: Path):
config.CONFIG_PATH = tmp_path / "config.json"
def test_retry_state_round_trip(tmp_path):
async def run():
_reset_config_path(tmp_path)
await config.set_retry_state(
guild_id=123,
file_path="recordings/123/session/meeting.wav",
source_channel_id=456,
reason="transcription failed",
)
return await config.get_retry_state(123)
state = asyncio.run(run())
assert state == {
"file_path": "recordings/123/session/meeting.wav",
"source_channel_id": 456,
"reason": "transcription failed",
}
def test_clear_retry_state_removes_saved_entry(tmp_path):
async def run():
_reset_config_path(tmp_path)
await config.set_retry_state(123, "a.wav", 456, "oops")
await config.clear_retry_state(123)
return await config.get_retry_state(123)
assert asyncio.run(run()) is None