diff --git a/src/cron/service.issue-regressions.test.ts b/src/cron/service.issue-regressions.test.ts index e105aab48dc..8294661dd76 100644 --- a/src/cron/service.issue-regressions.test.ts +++ b/src/cron/service.issue-regressions.test.ts @@ -1523,7 +1523,7 @@ describe("Cron issue regressions", () => { // Keep this short for suite speed while still separating expected timeout // from the 1/3-regression timeout. - const timeoutSeconds = 0.12; + const timeoutSeconds = 0.06; const cronJob = createIsolatedRegressionJob({ id: "timeout-fraction-29774", name: "timeout fraction regression", diff --git a/src/media-understanding/apply.test.ts b/src/media-understanding/apply.test.ts index 1c0b8f142a8..880a7cc6244 100644 --- a/src/media-understanding/apply.test.ts +++ b/src/media-understanding/apply.test.ts @@ -1,3 +1,4 @@ +import crypto from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -36,6 +37,8 @@ let applyMediaUnderstanding: typeof import("./apply.js").applyMediaUnderstanding const TEMP_MEDIA_PREFIX = "openclaw-media-"; let suiteTempMediaRootDir = ""; let tempMediaDirCounter = 0; +let sharedTempMediaCacheDir = ""; +const tempMediaFileCache = new Map(); async function createTempMediaDir() { if (!suiteTempMediaRootDir) { @@ -47,6 +50,13 @@ async function createTempMediaDir() { return dir; } +async function getSharedTempMediaCacheDir() { + if (!sharedTempMediaCacheDir) { + sharedTempMediaCacheDir = await createTempMediaDir(); + } + return sharedTempMediaCacheDir; +} + function createGroqAudioConfig(): OpenClawConfig { return { tools: { @@ -111,9 +121,20 @@ function createMediaDisabledConfigWithAllowedMimes(allowedMimes: string[]): Open } async function createTempMediaFile(params: { fileName: string; content: Buffer | string }) { - const dir = await createTempMediaDir(); - const mediaPath = path.join(dir, params.fileName); + const normalizedContent = + typeof params.content === "string" ? Buffer.from(params.content) : params.content; + const contentHash = crypto.createHash("sha1").update(normalizedContent).digest("hex"); + const cacheKey = `${params.fileName}:${contentHash}`; + const cachedPath = tempMediaFileCache.get(cacheKey); + if (cachedPath) { + return cachedPath; + } + const cacheRootDir = await getSharedTempMediaCacheDir(); + const cacheDir = path.join(cacheRootDir, contentHash); + await fs.mkdir(cacheDir, { recursive: true }); + const mediaPath = path.join(cacheDir, params.fileName); await fs.writeFile(mediaPath, params.content); + tempMediaFileCache.set(cacheKey, mediaPath); return mediaPath; } @@ -234,6 +255,8 @@ describe("applyMediaUnderstanding", () => { } await fs.rm(suiteTempMediaRootDir, { recursive: true, force: true }); suiteTempMediaRootDir = ""; + sharedTempMediaCacheDir = ""; + tempMediaFileCache.clear(); }); it("sets Transcript and replaces Body when audio transcription succeeds", async () => { diff --git a/src/process/exec.test.ts b/src/process/exec.test.ts index 6f72875f05c..2df8269bff1 100644 --- a/src/process/exec.test.ts +++ b/src/process/exec.test.ts @@ -66,7 +66,7 @@ describe("runCommandWithTimeout", () => { 'process.stdout.write((process.env.OPENCLAW_BASE_ENV ?? "") + "|" + (process.env.OPENCLAW_TEST_ENV ?? ""))', ], { - timeoutMs: 5_000, + timeoutMs: 1_000, env: { OPENCLAW_TEST_ENV: "ok" }, }, ); @@ -82,7 +82,7 @@ describe("runCommandWithTimeout", () => { [process.execPath, "-e", "setTimeout(() => {}, 60)"], { timeoutMs: 500, - noOutputTimeoutMs: 20, + noOutputTimeoutMs: 12, }, );