fix(google): guard realtime browser session expiries

This commit is contained in:
Peter Steinberger
2026-05-30 08:33:06 -04:00
parent 3c41e1722f
commit 7ad2ebb515
2 changed files with 23 additions and 2 deletions

View File

@@ -100,6 +100,7 @@ describe("buildGoogleRealtimeVoiceProvider", () => {
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
for (const key of ENV_KEYS) {
const value = envSnapshot[key];
if (value === undefined) {
@@ -452,6 +453,20 @@ describe("buildGoogleRealtimeVoiceProvider", () => {
]);
});
it("rejects browser session expiry outside Date range", async () => {
vi.spyOn(Date, "now").mockReturnValue(8_640_000_000_000_001);
const provider = buildGoogleRealtimeVoiceProvider();
await expect(
provider.createBrowserSession?.({
providerConfig: {
apiKey: "gemini-key",
},
}),
).rejects.toThrow("Google realtime browser session expiry is outside the supported Date range");
expect(createTokenMock).not.toHaveBeenCalled();
});
it("can opt out of Google Live session resumption and context compression", async () => {
const provider = buildGoogleRealtimeVoiceProvider();
const bridge = provider.createBridge({

View File

@@ -16,6 +16,7 @@ import type {
ThinkingConfig,
TurnCoverage,
} from "@google/genai";
import { timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/provider-onboard";
import type {
RealtimeVoiceAudioFormat,
@@ -857,6 +858,11 @@ async function createGoogleRealtimeBrowserSession(
const voice = req.voice ?? config.voice ?? GOOGLE_REALTIME_DEFAULT_VOICE;
const expiresAtMs = Date.now() + GOOGLE_REALTIME_BROWSER_SESSION_TTL_MS;
const newSessionExpiresAtMs = Date.now() + GOOGLE_REALTIME_BROWSER_NEW_SESSION_TTL_MS;
const expireTime = timestampMsToIsoString(expiresAtMs);
const newSessionExpireTime = timestampMsToIsoString(newSessionExpiresAtMs);
if (!expireTime || !newSessionExpireTime) {
throw new Error("Google realtime browser session expiry is outside the supported Date range");
}
const ai = createGoogleGenAI({
apiKey,
httpOptions: {
@@ -866,8 +872,8 @@ async function createGoogleRealtimeBrowserSession(
const token = await ai.authTokens.create({
config: {
uses: 1,
expireTime: new Date(expiresAtMs).toISOString(),
newSessionExpireTime: new Date(newSessionExpiresAtMs).toISOString(),
expireTime,
newSessionExpireTime,
liveConnectConstraints: {
model,
config: buildGoogleLiveConnectConfig({