@@ -5,7 +5,6 @@ import * as config from "../config/config.js";
55import * as sessions from "../config/sessions.js" ;
66import * as sessionAccessor from "../config/sessions/session-accessor.js" ;
77import type { GatewayRecoveryRuntime } from "../gateway/server-instance-runtime.types.js" ;
8- import * as sessionUtils from "../gateway/session-transcript-readers.js" ;
98import {
109 getActiveGatewayRootWorkCount ,
1110 resetGatewayWorkAdmission ,
@@ -28,22 +27,37 @@ const loggerMocks = vi.hoisted(() => ({
2827const dispatchAgent = vi . fn ( async ( _payload : Record < string , unknown > , _timeoutMs ?: number ) => ( {
2928 runId : "test-run-id" ,
3029} ) ) ;
30+ const readSessionMessages = vi . fn ( async ( ) => [ ] as unknown [ ] ) ;
3131const gatewayRuntime : GatewayRecoveryRuntime = {
3232 dispatchAgent : dispatchAgent as GatewayRecoveryRuntime [ "dispatchAgent" ] ,
3333 waitForAgent : vi . fn ( ) ,
3434 sendRecoveryNotice : vi . fn ( ) ,
3535} ;
3636
3737function recoverOrphanedSubagentSessions (
38- params : Omit < Parameters < typeof recoverOrphanedSubagentSessionsWithRuntime > [ 0 ] , "gatewayRuntime" > ,
38+ params : Omit <
39+ Parameters < typeof recoverOrphanedSubagentSessionsWithRuntime > [ 0 ] ,
40+ "gatewayRuntime" | "readSessionMessages"
41+ > ,
3942) {
40- return recoverOrphanedSubagentSessionsWithRuntime ( { ...params , gatewayRuntime } ) ;
43+ return recoverOrphanedSubagentSessionsWithRuntime ( {
44+ ...params ,
45+ gatewayRuntime,
46+ readSessionMessages,
47+ } ) ;
4148}
4249
4350function scheduleOrphanRecovery (
44- params : Omit < Parameters < typeof scheduleOrphanRecoveryWithRuntime > [ 0 ] , "getGatewayRuntime" > ,
51+ params : Omit <
52+ Parameters < typeof scheduleOrphanRecoveryWithRuntime > [ 0 ] ,
53+ "getGatewayRuntime" | "readSessionMessages"
54+ > ,
4555) {
46- return scheduleOrphanRecoveryWithRuntime ( { ...params , getGatewayRuntime : ( ) => gatewayRuntime } ) ;
56+ return scheduleOrphanRecoveryWithRuntime ( {
57+ ...params ,
58+ getGatewayRuntime : ( ) => gatewayRuntime ,
59+ readSessionMessages,
60+ } ) ;
4761}
4862
4963// Mocks are installed before importing the recovery module so registry/runtime
@@ -116,10 +130,6 @@ vi.mock("../config/sessions/session-accessor.js", () => ({
116130 patchSessionEntry : sessionMocks . patchSessionEntry ,
117131} ) ) ;
118132
119- vi . mock ( "../gateway/session-transcript-readers.js" , ( ) => ( {
120- readSessionMessagesAsync : vi . fn ( async ( ) => [ ] ) ,
121- } ) ) ;
122-
123133vi . mock ( "./subagent-announce-delivery.js" , ( ) => ( {
124134 deliverSubagentAnnouncement : vi . fn ( async ( ) => ( { delivered : true , path : "direct" } ) ) ,
125135 isInternalAnnounceRequesterSession : vi . fn ( ( ) => false ) ,
@@ -210,6 +220,8 @@ describe("subagent-orphan-recovery", () => {
210220 resetGatewayWorkAdmission ( ) ;
211221 dispatchAgent . mockReset ( ) ;
212222 dispatchAgent . mockResolvedValue ( { runId : "test-run-id" } ) ;
223+ readSessionMessages . mockReset ( ) ;
224+ readSessionMessages . mockResolvedValue ( [ ] ) ;
213225 vi . mocked ( subagentRegistrySteerRuntime . finalizeInterruptedSubagentRun )
214226 . mockReset ( )
215227 . mockResolvedValue ( 1 ) ;
@@ -740,7 +752,7 @@ describe("subagent-orphan-recovery", () => {
740752 it ( "includes last human message in resume when available" , async ( ) => {
741753 mockSingleAbortedSession ( { sessionFile : "session-abc.jsonl" } ) ;
742754
743- vi . mocked ( sessionUtils . readSessionMessagesAsync ) . mockResolvedValue ( [
755+ readSessionMessages . mockResolvedValue ( [
744756 { role : "user" , content : [ { type : "text" , text : "Please build feature Y" } ] } ,
745757 { role : "assistant" , content : [ { type : "text" , text : "Working on it..." } ] } ,
746758 { role : "user" , content : [ { type : "text" , text : "Also add tests for it" } ] } ,
@@ -759,7 +771,7 @@ describe("subagent-orphan-recovery", () => {
759771 it ( "adds config change hint when assistant messages reference config modifications" , async ( ) => {
760772 mockSingleAbortedSession ( ) ;
761773
762- vi . mocked ( sessionUtils . readSessionMessagesAsync ) . mockResolvedValue ( [
774+ readSessionMessages . mockResolvedValue ( [
763775 { role : "user" , content : "Update the config" } ,
764776 { role : "assistant" , content : "I've modified openclaw.json to add the new setting." } ,
765777 ] ) ;
@@ -916,6 +928,7 @@ describe("subagent-orphan-recovery", () => {
916928 scheduleOrphanRecoveryWithRuntime ( {
917929 getGatewayRuntime : ( ) => currentRuntime ,
918930 getActiveRuns : ( ) => createActiveRuns ( createTestRunRecord ( ) ) ,
931+ readSessionMessages,
919932 delayMs : 1 ,
920933 maxRetries : 0 ,
921934 } ) ;
0 commit comments