@@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
44import type { OpenClawConfig } from "../../config/config.js" ;
55import type { AcpSessionRuntimeOptions , SessionAcpMeta } from "../../config/sessions/types.js" ;
66import { resetHeartbeatWakeStateForTests } from "../../infra/heartbeat-wake.js" ;
7+ import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js" ;
78import { withTempDir } from "../../test-helpers/temp-dir.js" ;
89import type { AcpRuntime , AcpRuntimeCapabilities } from "../runtime/types.js" ;
910
@@ -807,6 +808,38 @@ describe("AcpSessionManager", () => {
807808 }
808809 } ) ;
809810
811+ it ( "caps ACP runtime option turn timeouts before arming the watchdog" , async ( ) => {
812+ const runtimeState = createRuntime ( ) ;
813+ hoisted . requireAcpRuntimeBackendMock . mockReturnValue ( {
814+ id : "acpx" ,
815+ runtime : runtimeState . runtime ,
816+ } ) ;
817+ hoisted . readAcpSessionEntryMock . mockReturnValue ( {
818+ sessionKey : "agent:codex:acp:session-1" ,
819+ storeSessionKey : "agent:codex:acp:session-1" ,
820+ acp : readySessionMeta ( {
821+ runtimeOptions : {
822+ timeoutSeconds : Number . MAX_SAFE_INTEGER ,
823+ } ,
824+ } ) ,
825+ } ) ;
826+ const timeoutSpy = vi . spyOn ( globalThis , "setTimeout" ) ;
827+ try {
828+ const manager = new AcpSessionManager ( ) ;
829+ await manager . runTurn ( {
830+ cfg : baseCfg ,
831+ sessionKey : "agent:codex:acp:session-1" ,
832+ text : "first" ,
833+ mode : "prompt" ,
834+ requestId : "r1" ,
835+ } ) ;
836+
837+ expect ( timeoutSpy ) . toHaveBeenCalledWith ( expect . any ( Function ) , MAX_TIMER_TIMEOUT_MS ) ;
838+ } finally {
839+ timeoutSpy . mockRestore ( ) ;
840+ }
841+ } ) ;
842+
810843 it ( "keeps timed-out runtime handles counted until timeout cleanup finishes" , async ( ) => {
811844 vi . useFakeTimers ( ) ;
812845 try {
0 commit comments