mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:31:06 +00:00
fix: send OpenClaw attribution to OpenAI
This commit is contained in:
@@ -24,6 +24,7 @@ export type RealtimeTalkWebRtcSdpSessionResult = {
|
||||
transport?: "webrtc-sdp";
|
||||
clientSecret: string;
|
||||
offerUrl?: string;
|
||||
offerHeaders?: Record<string, string>;
|
||||
model?: string;
|
||||
voice?: string;
|
||||
expiresAt?: number;
|
||||
|
||||
@@ -72,6 +72,7 @@ export class WebRtcSdpRealtimeTalkTransport implements RealtimeTalkTransport {
|
||||
method: "POST",
|
||||
body: offer.sdp,
|
||||
headers: {
|
||||
...this.session.offerHeaders,
|
||||
Authorization: `Bearer ${this.session.clientSecret}`,
|
||||
"Content-Type": "application/sdp",
|
||||
},
|
||||
|
||||
96
ui/src/ui/realtime-talk-webrtc.test.ts
Normal file
96
ui/src/ui/realtime-talk-webrtc.test.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
// @vitest-environment jsdom
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { WebRtcSdpRealtimeTalkTransport } from "./chat/realtime-talk-webrtc.ts";
|
||||
|
||||
class FakeDataChannel extends EventTarget {
|
||||
readyState: RTCDataChannelState = "open";
|
||||
send = vi.fn();
|
||||
close = vi.fn(() => {
|
||||
this.readyState = "closed";
|
||||
});
|
||||
}
|
||||
|
||||
class FakePeerConnection extends EventTarget {
|
||||
connectionState: RTCPeerConnectionState = "new";
|
||||
readonly channel = new FakeDataChannel();
|
||||
readonly addTrack = vi.fn();
|
||||
localDescription: RTCSessionDescriptionInit | null = null;
|
||||
remoteDescription: RTCSessionDescriptionInit | null = null;
|
||||
|
||||
createDataChannel(): RTCDataChannel {
|
||||
return this.channel as unknown as RTCDataChannel;
|
||||
}
|
||||
|
||||
async createOffer(): Promise<RTCSessionDescriptionInit> {
|
||||
return { type: "offer", sdp: "offer-sdp" };
|
||||
}
|
||||
|
||||
async setLocalDescription(description: RTCSessionDescriptionInit): Promise<void> {
|
||||
this.localDescription = description;
|
||||
}
|
||||
|
||||
async setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void> {
|
||||
this.remoteDescription = description;
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.connectionState = "closed";
|
||||
}
|
||||
}
|
||||
|
||||
describe("WebRtcSdpRealtimeTalkTransport", () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
const track = { stop: vi.fn() } as unknown as MediaStreamTrack;
|
||||
const stream = {
|
||||
getAudioTracks: () => [track],
|
||||
getTracks: () => [track],
|
||||
} as unknown as MediaStream;
|
||||
Object.defineProperty(globalThis.navigator, "mediaDevices", {
|
||||
configurable: true,
|
||||
value: {
|
||||
getUserMedia: vi.fn(async () => stream),
|
||||
},
|
||||
});
|
||||
vi.stubGlobal("RTCPeerConnection", FakePeerConnection as unknown as typeof RTCPeerConnection);
|
||||
});
|
||||
|
||||
it("sends provider offer headers with the WebRTC SDP request", async () => {
|
||||
const fetchMock = vi.fn(async () => new Response("answer-sdp"));
|
||||
vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch);
|
||||
const transport = new WebRtcSdpRealtimeTalkTransport(
|
||||
{
|
||||
provider: "openai",
|
||||
transport: "webrtc-sdp",
|
||||
clientSecret: "client-secret-123",
|
||||
offerUrl: "https://api.openai.com/v1/realtime/calls",
|
||||
offerHeaders: {
|
||||
originator: "openclaw",
|
||||
version: "2026.3.22",
|
||||
},
|
||||
},
|
||||
{
|
||||
client: {} as never,
|
||||
sessionKey: "main",
|
||||
callbacks: {},
|
||||
},
|
||||
);
|
||||
|
||||
await transport.start();
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith("https://api.openai.com/v1/realtime/calls", {
|
||||
method: "POST",
|
||||
body: "offer-sdp",
|
||||
headers: {
|
||||
originator: "openclaw",
|
||||
version: "2026.3.22",
|
||||
Authorization: "Bearer client-secret-123",
|
||||
"Content-Type": "application/sdp",
|
||||
},
|
||||
});
|
||||
transport.stop();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user