Add Athena WebRTC bridge for OpenClaw Talk
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { createServer } from "node:http";
|
||||
import { test } from "node:test";
|
||||
import plugin from "./dist/index.js";
|
||||
|
||||
async function listen(server) {
|
||||
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||
return `http://127.0.0.1:${server.address().port}`;
|
||||
}
|
||||
|
||||
test("browser session signs a short-lived token and proxies the SDP offer", async () => {
|
||||
let upstreamCalls = 0;
|
||||
const upstream = createServer(async (req, res) => {
|
||||
upstreamCalls += 1;
|
||||
assert.equal(req.method, "POST");
|
||||
assert.match(req.headers.authorization, /^Bearer [^.]+\.[^.]+$/);
|
||||
assert.equal(await new Response(req).text(), "offer-sdp");
|
||||
res.writeHead(200, { "Content-Type": "application/sdp" }).end("answer-sdp");
|
||||
});
|
||||
const upstreamBase = await listen(upstream);
|
||||
let provider;
|
||||
const routes = [];
|
||||
plugin.register({
|
||||
registerRealtimeVoiceProvider: (value) => { provider = value; },
|
||||
registerHttpRoute: (value) => { routes.push(value); },
|
||||
runtime: { config: { current: () => ({ talk: { realtime: { providers: {
|
||||
"athena-talk": { realtimeUpstreamUrl: `${upstreamBase}/v1/realtime/calls` },
|
||||
} } } }) } },
|
||||
});
|
||||
const route = routes.find((value) => value.path.endsWith("/calls"));
|
||||
const keyRoute = routes.find((value) => value.path.endsWith("/public-key"));
|
||||
assert.equal(route.path, "/plugins/athena-talk/realtime/calls");
|
||||
const browser = await provider.createBrowserSession({
|
||||
providerConfig: { realtimeUpstreamUrl: `${upstreamBase}/v1/realtime/calls` },
|
||||
model: "athena-local",
|
||||
});
|
||||
assert.equal(browser.transport, "webrtc");
|
||||
assert.ok(browser.expiresAt > Date.now());
|
||||
|
||||
const proxy = createServer((req, res) => {
|
||||
if (req.url === keyRoute.path) return keyRoute.handler(req, res);
|
||||
return route.handler(req, res);
|
||||
});
|
||||
const proxyBase = await listen(proxy);
|
||||
try {
|
||||
const response = await fetch(`${proxyBase}${browser.offerUrl}`, {
|
||||
method: "POST",
|
||||
headers: { Authorization: `Bearer ${browser.clientSecret}`, "Content-Type": "application/sdp" },
|
||||
body: "offer-sdp",
|
||||
});
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(await response.text(), "answer-sdp");
|
||||
assert.equal(upstreamCalls, 1);
|
||||
|
||||
const key = await fetch(`${proxyBase}${keyRoute.path}`);
|
||||
assert.equal(key.status, 200);
|
||||
assert.match(await key.text(), /BEGIN PUBLIC KEY/);
|
||||
|
||||
const invalid = await fetch(`${proxyBase}${browser.offerUrl}`, {
|
||||
method: "POST",
|
||||
headers: { Authorization: `Bearer ${browser.clientSecret}x` },
|
||||
body: "offer-sdp",
|
||||
});
|
||||
assert.equal(invalid.status, 401);
|
||||
assert.equal(upstreamCalls, 1);
|
||||
} finally {
|
||||
proxy.closeAllConnections();
|
||||
upstream.closeAllConnections();
|
||||
await Promise.all([
|
||||
new Promise((resolve) => proxy.close(resolve)),
|
||||
new Promise((resolve) => upstream.close(resolve)),
|
||||
]);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user