feat(vocero): add linked content and TALKFIRST greetings (#2)
Opening a report or podcast link now establishes an authenticated starting reference for the conversation. Users can select other accessible content or compare reports while retaining the original link, and TALKFIRST greetings can name the verified report or podcast. Release notes: - Added authenticated report and episode link resolution with bounded lookups and unavailable-content handling - Added explicit conversation selection without restricting searches or changing the reference during comparisons - Added contextual TALKFIRST greetings through both voice-proxy and HTTP reasoning paths - Preserved backend permission checks, conversation isolation, cancellation, and the existing speech protocol Reviewed-on: AquaPortal/s2s#2
This commit is contained in:
@@ -113,6 +113,7 @@ def test_backend_login_validates_exact_contract_without_leaking_credentials(enab
|
||||
@pytest.mark.parametrize("use_sse", [False, True])
|
||||
def test_sdk_discovery_and_execution_preserve_nested_schema_results_and_per_user_headers(enabled, monkeypatch, use_sse):
|
||||
calls = []
|
||||
original = httpx.AsyncClient
|
||||
|
||||
def upstream(request):
|
||||
calls.append(request)
|
||||
@@ -141,6 +142,8 @@ def test_sdk_discovery_and_execution_preserve_nested_schema_results_and_per_user
|
||||
else:
|
||||
assert method == "tools/call"
|
||||
assert message["params"]["arguments"] == {"request": {"report_id": "r1"}}
|
||||
user = request.headers["authorization"].removeprefix("Bearer ")
|
||||
assert request.headers["x-vocero-podcast-id"] == f"report:{user}"
|
||||
result = {
|
||||
"content": [],
|
||||
"structuredContent": {"result": {"status": "found", "caller": request.headers["authorization"]}},
|
||||
@@ -153,11 +156,7 @@ def test_sdk_discovery_and_execution_preserve_nested_schema_results_and_per_user
|
||||
return httpx.Response(200, json=body)
|
||||
|
||||
monkeypatch.setattr(
|
||||
mcp,
|
||||
"http_client",
|
||||
lambda token: httpx.AsyncClient(
|
||||
transport=httpx.MockTransport(upstream), headers={"Authorization": f"Bearer {token}"}
|
||||
),
|
||||
mcp.httpx, "AsyncClient", lambda **kwargs: original(transport=httpx.MockTransport(upstream), **kwargs)
|
||||
)
|
||||
|
||||
async def scenario():
|
||||
@@ -165,7 +164,10 @@ def test_sdk_discovery_and_execution_preserve_nested_schema_results_and_per_user
|
||||
assert [tool.name for tool in catalog] == ["get_report"]
|
||||
assert catalog[0].parameters["properties"]["request"] == {"type": "object"}
|
||||
outputs = await asyncio.gather(
|
||||
*(mcp.execute(user, "get_report", {"request": {"report_id": "r1"}}) for user in ("alice", "bob"))
|
||||
*(
|
||||
mcp.execute(user, "get_report", {"request": {"report_id": "r1"}}, podcast_id=f"report:{user}")
|
||||
for user in ("alice", "bob")
|
||||
)
|
||||
)
|
||||
assert [output["data"]["result"]["caller"] for output in outputs] == ["Bearer alice", "Bearer bob"]
|
||||
|
||||
@@ -179,7 +181,7 @@ def test_mcp_transport_errors_are_safe_and_preserve_authentication_status(enable
|
||||
monkeypatch.setattr(
|
||||
mcp,
|
||||
"http_client",
|
||||
lambda token: httpx.AsyncClient(
|
||||
lambda token, podcast_id=None: httpx.AsyncClient(
|
||||
transport=httpx.MockTransport(lambda req: httpx.Response(status, text="secret-upstream-body"))
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user