fix: reconcile uncertain voice admission with bounded cancellation

This commit is contained in:
snowspeeder committed 2026-10-03 09:08:25 -04:00
1 parent 0cb00e6095
commit 0c57217ad9
3 files changed
+40 -4

No files matched your search

+14 -3
View File
@@ -65,6 +65,7 @@ class ConversationStream(llm.LLMStream):
if not text.strip(): raise HermesLLMError('empty_voice_turn')
timer = None
admission = None
admission_rejected = False
try:
# Do not abandon uncertain admission on barge-in. A successfully
# admitted remote action must be identified and cancelled, not left
@@ -72,7 +73,9 @@ class ConversationStream(llm.LLMStream):
admission = asyncio.create_task(self.bridge.client.post(self.bridge.root + '/messages', headers=self.bridge.headers,
json={'content': text, 'idempotency_key': self.operation_id, 'modality': 'voice'}, timeout=httpx.Timeout(20, connect=5)))
response = await asyncio.shield(admission)
if response.status_code != 202: raise HermesLLMError('voice_admission_failed')
if response.status_code != 202:
admission_rejected = 400 <= response.status_code < 500
raise HermesLLMError('voice_admission_failed')
self.run_id = response.json()['run']['id']
await self.progress('working', 'Working on your request.')
timer = asyncio.create_task(self.notice())
@@ -117,17 +120,25 @@ class ConversationStream(llm.LLMStream):
# admission, then return the run identity for cancellation.
try:
admitted = await self.bridge.client.post(self.bridge.root + '/messages', headers=self.bridge.headers,
json={'content': text, 'idempotency_key': self.operation_id, 'modality': 'voice'})
json={'content': text, 'idempotency_key': self.operation_id, 'modality': 'voice'}, timeout=httpx.Timeout(20, connect=5))
if admitted.status_code == 202:
self.run_id = admitted.json()['run']['id']
except Exception: pass
if self.run_id:
try:
await asyncio.shield(self.bridge.client.post(self.bridge.root + '/runs/' + self.run_id + '/cancel', headers=self.bridge.headers))
await asyncio.shield(self.bridge.client.post(self.bridge.root + '/runs/' + self.run_id + '/cancel', headers=self.bridge.headers, timeout=httpx.Timeout(10, connect=5)))
except Exception: pass
await self.progress('failed', 'Request cancelled.')
raise
except Exception:
# A failed HTTP receipt is not proof admission failed. Fail safely
# by tombstoning the stable operation key, including when JSON/SSE
# decoding failed after the coordinator already accepted the turn.
if not admission_rejected:
try:
await self.bridge.client.post(self.bridge.root + '/operations/' + self.operation_id + '/cancel',
headers=self.bridge.headers, timeout=httpx.Timeout(10, connect=5))
except Exception: pass
await self.progress('failed', 'Hope could not complete this response.')
raise HermesLLMError('voice_coordinator_failed') from None
finally: