@@ -4,6 +4,7 @@ import os from "node:os";
44import path from "node:path" ;
55import { afterEach , beforeEach , describe , expect , it , vi } from "vitest" ;
66import type { EmbeddedAgentQueueMessageOutcome } from "../../agents/embedded-agent-runner/runs.js" ;
7+ import type { SessionEntry } from "../../config/sessions/types.js" ;
78import type { OpenClawConfig } from "../../config/types.openclaw.js" ;
89import type { TemplateContext } from "../templating.js" ;
910import type { FollowupRun , QueueSettings } from "./queue.js" ;
@@ -468,60 +469,66 @@ describe("runReplyAgent media path normalization", () => {
468469 await import ( "../../config/sessions/store-writer-state.js" ) ;
469470 const { loadSessionStore } = await import ( "../../config/sessions.js" ) ;
470471 const { updateSessionEntry } = await import ( "../../config/sessions/session-accessor.js" ) ;
471- const tmpDir = await mkdtemp ( path . join ( os . tmpdir ( ) , "steered-audio-test-" ) ) ;
472- cleanupPaths . push ( tmpDir ) ;
473- const storePath = path . join ( tmpDir , "store.json" ) ;
474- const sessionKey = "test-audio-session" ;
472+ const { withTempDir } = await import ( "../../test-helpers/temp-dir.js" ) ;
475473
476- // Pre-populate a session entry in the store so updateSessionEntry has something
477- // to merge into.
478- const preExistingEntry : Record < string , unknown > = {
479- sessionId : "test-audio" ,
480- updatedAt : Date . now ( ) ,
481- } ;
482- await writeFile ( storePath , JSON . stringify ( { [ sessionKey ] : preExistingEntry } ) , "utf-8" ) ;
483- clearSessionStoreCacheForTest ( ) ;
474+ await withTempDir ( { prefix : "steered-audio-test-" } , async ( tmpDir ) => {
475+ const storePath = path . join ( tmpDir , "store.json" ) ;
476+ const sessionKey = "test-audio-session" ;
484477
485- queueEmbeddedAgentMessageWithOutcomeAsyncMock . mockImplementation ( async ( sessionId : string ) => ( {
486- queued : true ,
487- sessionId,
488- target : "embedded_run" ,
489- gatewayHealth : "live" ,
490- } ) ) ;
478+ // Pre-populate a session entry in the store so updateSessionEntry has something
479+ // to merge into.
480+ const preExistingEntry : Record < string , unknown > = {
481+ sessionId : "test-audio" ,
482+ updatedAt : Date . now ( ) ,
483+ } ;
484+ await writeFile ( storePath , JSON . stringify ( { [ sessionKey ] : preExistingEntry } ) , "utf-8" ) ;
485+ clearSessionStoreCacheForTest ( ) ;
486+
487+ queueEmbeddedAgentMessageWithOutcomeAsyncMock . mockImplementation (
488+ async ( sessionId : string ) => ( {
489+ queued : true ,
490+ sessionId,
491+ target : "embedded_run" ,
492+ gatewayHealth : "live" ,
493+ } ) ,
494+ ) ;
491495
492- await runReplyAgent (
493- makeRunReplyAgentParams ( {
494- resolvedQueue : { mode : "steer" } as QueueSettings ,
495- shouldSteer : true ,
496- shouldFollowup : true ,
497- isStreaming : true ,
498- sessionKey,
499- storePath,
500- sessionStore : { [ sessionKey ] : preExistingEntry } as Record < string , unknown > ,
501- sessionEntry : preExistingEntry as Parameters < typeof runReplyAgent > [ 0 ] [ "sessionEntry" ] ,
502- followupRun : {
503- ...createMockFollowupRun ( { prompt : "generate chart" } ) ,
504- currentInboundAudio : true ,
505- } as unknown as FollowupRun ,
506- } ) ,
507- ) ;
496+ await runReplyAgent (
497+ makeRunReplyAgentParams ( {
498+ resolvedQueue : { mode : "steer" } as QueueSettings ,
499+ shouldSteer : true ,
500+ shouldFollowup : true ,
501+ isStreaming : true ,
502+ sessionKey,
503+ storePath,
504+ sessionStore : {
505+ [ sessionKey ] : preExistingEntry ,
506+ } as unknown as Record < string , SessionEntry > ,
507+ sessionEntry : preExistingEntry as Parameters < typeof runReplyAgent > [ 0 ] [ "sessionEntry" ] ,
508+ followupRun : {
509+ ...createMockFollowupRun ( { prompt : "generate chart" } ) ,
510+ currentInboundAudio : true ,
511+ } as unknown as FollowupRun ,
512+ } ) ,
513+ ) ;
508514
509- // Verify the flag was persisted through the session store path, not only
510- // on the local object.
511- clearSessionStoreCacheForTest ( ) ;
512- const persisted = loadSessionStore ( storePath , { skipCache : true } ) ;
513- expect ( persisted [ sessionKey ] ?. steeredInboundAudio ) . toBe ( true ) ;
514-
515- // Simulate the dispatch consuming the flag (the same clear step added
516- // to dispatch-from-config.ts).
517- await updateSessionEntry (
518- { storePath, sessionKey } ,
519- ( ) => ( { steeredInboundAudio : undefined } ) ,
520- { skipMaintenance : true , takeCacheOwnership : true } ,
521- ) ;
522- clearSessionStoreCacheForTest ( ) ;
523- const afterClear = loadSessionStore ( storePath , { skipCache : true } ) ;
524- expect ( afterClear [ sessionKey ] ?. steeredInboundAudio ) . toBeUndefined ( ) ;
515+ // Verify the flag was persisted through the session store path, not only
516+ // on the local object.
517+ clearSessionStoreCacheForTest ( ) ;
518+ const persisted = loadSessionStore ( storePath , { skipCache : true } ) ;
519+ expect ( persisted [ sessionKey ] ?. steeredInboundAudio ) . toBe ( true ) ;
520+
521+ // Simulate the dispatch consuming the flag (the same clear step added
522+ // to dispatch-from-config.ts).
523+ await updateSessionEntry (
524+ { storePath, sessionKey } ,
525+ ( ) => ( { steeredInboundAudio : undefined } ) ,
526+ { skipMaintenance : true , takeCacheOwnership : true } ,
527+ ) ;
528+ clearSessionStoreCacheForTest ( ) ;
529+ const afterClear = loadSessionStore ( storePath , { skipCache : true } ) ;
530+ expect ( afterClear [ sessionKey ] ?. steeredInboundAudio ) . toBeUndefined ( ) ;
531+ } ) ;
525532 } ) ;
526533
527534 it ( "queues active prompts in followup mode without steering" , async ( ) => {
0 commit comments