Skip to content
Closed
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
23 changes: 23 additions & 0 deletions gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -6613,6 +6613,29 @@ async def _handle_message(self, event: MessageEvent) -> Optional[str]:
_pending_clarify = None
if _pending_clarify is not None:
_raw_clarify_reply = (event.text or "").strip()
if (
not _raw_clarify_reply
and getattr(event, "media_urls", None)
and not event.get_command()
):
try:
_raw_clarify_reply = (
await self._prepare_inbound_message_text(
event=event,
source=source,
history=[],
)
or ""
).strip()
except Exception as exc:
logger.warning(
"Gateway failed to prepare media clarify response "
"(session=%s, id=%s): %s",
_quick_key,
_pending_clarify.clarify_id,
exc,
)
_raw_clarify_reply = ""
# Skip slash commands — the user clearly wanted to issue a
# command, not answer the clarify. Leave the clarify pending
# so the user can retry; if it times out, the agent unblocks
Expand Down
46 changes: 45 additions & 1 deletion tests/gateway/test_telegram_audio_vs_voice.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from gateway.config import GatewayConfig, Platform
from gateway.platforms.base import MessageEvent, MessageType
from gateway.session import SessionSource
from gateway.session import SessionSource, build_session_key


def _make_runner(stt_enabled: bool = True) -> "GatewayRunner": # type: ignore[name-defined]
Expand Down Expand Up @@ -182,3 +182,47 @@ def test_telegram_media_type_detection_audio_vs_voice():
assert MessageType.VOICE.value == "voice"
# Sanity: they are distinct
assert MessageType.AUDIO != MessageType.VOICE


@pytest.mark.asyncio
async def test_voice_reply_resolves_pending_clarify_with_transcript():
"""A voice answer to an open clarify must unblock clarify, not interrupt the run."""
from gateway.run import GatewayRunner
from tools import clarify_gateway as cm

with cm._lock:
cm._entries.clear()
cm._session_index.clear()

runner = _make_runner(stt_enabled=True)
runner.session_store = None

source = SessionSource(
platform=Platform.TELEGRAM,
chat_id="1",
chat_type="dm",
user_id="user1",
)
session_key = build_session_key(source)
cm.register("cid-voice", session_key, "What should I do?", choices=None)

event = MessageEvent(
text="",
message_type=MessageType.VOICE,
source=source,
media_urls=["/tmp/voice.ogg"],
media_types=["audio/ogg"],
internal=True,
)

with patch(
"tools.transcription_tools.transcribe_audio",
return_value={"success": True, "transcript": "kurz und knackig", "provider": "whisper"},
) as mock_transcribe:
result = await GatewayRunner._handle_message(runner, event)

mock_transcribe.assert_called_once_with("/tmp/voice.ogg")
assert result == ""
response = cm.wait_for_response("cid-voice", timeout=0.01)
assert response is not None
assert "kurz und knackig" in response