fix(tts): clamp summarization timeout

This commit is contained in:
Peter Steinberger
2026-05-30 16:00:45 -04:00
parent 0530596eef
commit cb79864cb9
2 changed files with 45 additions and 1 deletions

42
src/tts/tts-core.test.ts Normal file
View File

@@ -0,0 +1,42 @@
import { describe, expect, it, vi } from "vitest";
import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js";
import { summarizeText } from "./tts-core.js";
import type { ResolvedTtsConfig } from "./tts-types.js";
describe("TTS core", () => {
it("clamps oversized summarization timeout timers", async () => {
const setTimeoutSpy = vi.spyOn(globalThis, "setTimeout");
try {
const model = { provider: { id: "test-provider" } };
const config = {
summarizeModel: { primary: "test-provider/test-model" },
} as ResolvedTtsConfig;
const result = await summarizeText(
{
text: "Long text that should be summarized for speech.",
targetLength: 120,
cfg: {},
config,
timeoutMs: MAX_TIMER_TIMEOUT_MS + 1,
},
{
completeSimple: vi.fn(async () => ({
content: [{ type: "text", text: "Short summary." }],
stopReason: "stop",
usage: {},
})),
getApiKeyForModel: vi.fn(async () => "key"),
prepareModelForSimpleCompletion: vi.fn(() => model as never),
requireApiKey: vi.fn(() => "key"),
resolveModelAsync: vi.fn(async () => ({ model })),
},
);
expect(result.summary).toBe("Short summary.");
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), MAX_TIMER_TIMEOUT_MS);
} finally {
setTimeoutSpy.mockRestore();
}
});
});

View File

@@ -11,6 +11,7 @@ import { prepareModelForSimpleCompletion } from "../agents/simple-completion-tra
import type { OpenClawConfig } from "../config/types.js";
import { completeSimple } from "../llm/stream.js";
import type { TextContent } from "../llm/types.js";
import { resolveTimerTimeoutMs } from "../shared/number-coercion.js";
import type { ResolvedTtsConfig } from "./tts-types.js";
export {
normalizeApplyTextNormalization,
@@ -105,7 +106,8 @@ export async function summarizeText(
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
const resolvedTimeoutMs = resolveTimerTimeoutMs(timeoutMs, 1);
const timeout = setTimeout(() => controller.abort(), resolvedTimeoutMs);
try {
const res = await deps.completeSimple(