fix(proxy): pass the ApiPilot catalog with the correct argument

This commit is contained in:
2026-10-06 17:44:43 -03:00
parent c375581077
commit 3d42df5749
2 changed files with 61 additions and 2 deletions
+1 -1
View File
@@ -4549,7 +4549,7 @@ async def realtime_proxy(ws: WebSocket):
pass pass
session_ctx_apipilot_defaults = dict(_apipilot_defaults_p1) session_ctx_apipilot_defaults = dict(_apipilot_defaults_p1)
injected_apipilot_pass1 = _resolve_apipilot_reasoning_context_block( injected_apipilot_pass1 = _resolve_apipilot_reasoning_context_block(
tools=apipilot_tools_pass1, context_defaults=_apipilot_defaults_p1, tools_list=apipilot_tools_pass1, context_defaults=_apipilot_defaults_p1,
) or "" ) or ""
if injected_apipilot_pass1.strip(): if injected_apipilot_pass1.strip():
logger.info( logger.info(
+60 -1
View File
@@ -9,7 +9,7 @@ from pathlib import Path
import sys import sys
import threading import threading
import unittest import unittest
from unittest.mock import Mock, patch from unittest.mock import ANY, AsyncMock, Mock, patch
import httpx import httpx
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
@@ -173,6 +173,65 @@ class BackendContractTests(unittest.TestCase):
class VoiceProxyTests(unittest.TestCase): class VoiceProxyTests(unittest.TestCase):
def test_apipilot_catalog_and_caller_defaults_reach_the_voice_session(self):
closed = threading.Event()
catalog = AsyncMock(return_value=[{
"name": "get_caller_briefing",
"description": "Retrieve the caller's local test briefing.",
"requires_auth": True,
"parameters": {"required": ["phone", "episode_id", "email"]},
}])
login = AsyncMock(return_value=("fixture-token", {}))
profile = AsyncMock(return_value={"user": {"email": "caller@example.test"}})
def voice(socket):
try:
socket.send(json.dumps({"type": "session.created"}))
for frame in socket:
socket.send(frame)
finally:
closed.set()
with serve(voice, "127.0.0.1", 0) as upstream:
thread = threading.Thread(target=upstream.serve_forever, daemon=True)
thread.start()
self.addCleanup(thread.join, 5)
target = f"ws://127.0.0.1:{upstream.socket.getsockname()[1]}/v1/realtime"
with (
patch.object(server, "S2S_PROXY_TARGET", target),
patch.object(server, "S2S_INJECT_PROFILE", False),
patch.object(server, "S2S_APIPILOT_TOOLS_URL", "http://catalog.test/tools"),
patch.object(server, "S2S_LOGIN_BY_PHONE", "http://profile.test/login"),
patch.object(server, "VOCERO_USER_PHONE_AUTH_URL", "http://profile.test/user"),
patch.object(server, "_apipilot_fetch_tools", catalog),
patch.object(server, "_login_by_phone", login),
patch.object(server, "_fetch_user_profile_for_phone", profile),
patch.object(server.httpx, "AsyncClient", side_effect=AssertionError("Unexpected HTTP request")),
TestClient(server.app) as client,
):
with client.websocket_connect(
"/v1/realtime?phoneNumber=%2B56000000000&episode_id=fixture-episode",
) as socket:
self.assertEqual(socket.receive_json(), {"type": "session.created"})
socket.send_json({"type": "session.update", "session": {"instructions": "Local fixture"}})
update = socket.receive_json()
self.assertEqual(update["type"], "session.update")
instructions = update["session"]["instructions"]
for expected in (
"Local fixture", server.APIPILOT_PASS1_LIST_MARKER, "name: get_caller_briefing",
'phone = "+56000000000"', 'episode_id = "fixture-episode"',
'email = "caller@example.test"',
):
self.assertIn(expected, instructions)
# Configuration injection must preserve ordinary audio forwarding.
audio = {"type": "input_audio_buffer.append", "audio": "AAA="}
socket.send_json(audio)
self.assertEqual(socket.receive_json(), audio)
self.assertTrue(closed.wait(3), "Client disconnect must close the upstream WebSocket")
login.assert_awaited_once_with("+56000000000")
profile.assert_awaited_once_with("+56000000000", auth_token="fixture-token")
catalog.assert_awaited_once_with(auth_header="Bearer fixture-token", demo_session=ANY, refresh=False)
def test_proxy_voice_frames_keepalive_and_client_disconnect(self): def test_proxy_voice_frames_keepalive_and_client_disconnect(self):
closed = threading.Event() closed = threading.Event()
received = [] received = []