mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-05 19:42:54 +00:00
fix(voice-call): cap CLI gateway timeouts
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { MAX_TIMER_TIMEOUT_MS } from "openclaw/plugin-sdk/number-runtime";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { testing } from "./cli.js";
|
||||
|
||||
@@ -35,3 +36,35 @@ describe("parseVoiceCallIntOption", () => {
|
||||
).toThrow("Invalid numeric value for --port: 65536");
|
||||
});
|
||||
});
|
||||
|
||||
describe("voice-call CLI timeout helpers", () => {
|
||||
it("caps gateway operation timeout grace", () => {
|
||||
expect(testing.resolveGatewayOperationTimeoutMs({ ringTimeoutMs: 10_000 } as never)).toBe(
|
||||
30_000,
|
||||
);
|
||||
expect(testing.resolveGatewayOperationTimeoutMs({ ringTimeoutMs: 60_000 } as never)).toBe(
|
||||
65_000,
|
||||
);
|
||||
expect(
|
||||
testing.resolveGatewayOperationTimeoutMs({ ringTimeoutMs: Number.MAX_SAFE_INTEGER } as never),
|
||||
).toBe(MAX_TIMER_TIMEOUT_MS);
|
||||
});
|
||||
|
||||
it("caps gateway continue timeout totals", () => {
|
||||
expect(testing.resolveGatewayContinueTimeoutMs({ transcriptTimeoutMs: 180_000 } as never)).toBe(
|
||||
220_000,
|
||||
);
|
||||
expect(
|
||||
testing.resolveGatewayContinueTimeoutMs({
|
||||
transcriptTimeoutMs: Number.MAX_SAFE_INTEGER,
|
||||
} as never),
|
||||
).toBe(MAX_TIMER_TIMEOUT_MS);
|
||||
});
|
||||
|
||||
it("caps gateway polling deadlines", () => {
|
||||
expect(testing.resolveVoiceCallDeadlineMs(5_000, 10_000)).toBe(15_000);
|
||||
expect(testing.resolveVoiceCallDeadlineMs(Number.MAX_SAFE_INTEGER, 10_000)).toBe(
|
||||
10_000 + MAX_TIMER_TIMEOUT_MS,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,12 @@ import { format } from "node:util";
|
||||
import type { Command } from "commander";
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
||||
import { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
|
||||
import { MAX_TCP_PORT, parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
||||
import {
|
||||
clampTimerTimeoutMs,
|
||||
MAX_TIMER_TIMEOUT_MS,
|
||||
MAX_TCP_PORT,
|
||||
parseStrictNonNegativeInteger,
|
||||
} from "openclaw/plugin-sdk/number-runtime";
|
||||
import {
|
||||
isRecord,
|
||||
normalizeOptionalLowercaseString,
|
||||
@@ -66,6 +71,9 @@ export const testing = {
|
||||
},
|
||||
isGatewayUnavailableForLocalFallback,
|
||||
parseVoiceCallIntOption,
|
||||
resolveGatewayContinueTimeoutMs,
|
||||
resolveGatewayOperationTimeoutMs,
|
||||
resolveVoiceCallDeadlineMs,
|
||||
};
|
||||
|
||||
function writeStdoutLine(...values: unknown[]): void {
|
||||
@@ -128,17 +136,26 @@ async function callVoiceCallGateway(
|
||||
}
|
||||
|
||||
function resolveGatewayOperationTimeoutMs(config: VoiceCallConfig): number {
|
||||
return Math.max(VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS, config.ringTimeoutMs + 5000);
|
||||
return Math.max(
|
||||
VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS,
|
||||
clampTimerTimeoutMs(config.ringTimeoutMs + 5000) ?? 1,
|
||||
);
|
||||
}
|
||||
|
||||
function resolveGatewayContinueTimeoutMs(config: VoiceCallConfig): number {
|
||||
return (
|
||||
config.transcriptTimeoutMs +
|
||||
VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS +
|
||||
VOICE_CALL_GATEWAY_TRANSCRIPT_BUFFER_MS
|
||||
clampTimerTimeoutMs(
|
||||
config.transcriptTimeoutMs +
|
||||
VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS +
|
||||
VOICE_CALL_GATEWAY_TRANSCRIPT_BUFFER_MS,
|
||||
) ?? 1
|
||||
);
|
||||
}
|
||||
|
||||
function resolveVoiceCallDeadlineMs(timeoutMs: number, nowMs = Date.now()): number {
|
||||
return nowMs + (clampTimerTimeoutMs(timeoutMs) ?? MAX_TIMER_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
function isUnknownGatewayMethod(err: unknown, method: VoiceCallGatewayMethod): boolean {
|
||||
return formatErrorMessage(err).includes(`unknown method: ${method}`);
|
||||
}
|
||||
@@ -185,7 +202,7 @@ async function pollVoiceCallContinueGateway(params: {
|
||||
operationId: string;
|
||||
timeoutMs: number;
|
||||
}): Promise<unknown> {
|
||||
const deadlineMs = Date.now() + params.timeoutMs;
|
||||
const deadlineMs = resolveVoiceCallDeadlineMs(params.timeoutMs);
|
||||
|
||||
while (Date.now() <= deadlineMs) {
|
||||
const gateway = await callVoiceCallGateway(
|
||||
|
||||
Reference in New Issue
Block a user