@@ -8,6 +8,7 @@ const steerRuntimeMocks = vi.hoisted(() => ({
88 isEmbeddedAgentRunActive : vi . fn ( ) ,
99 queueEmbeddedAgentMessageWithOutcomeAsync : vi . fn ( ) ,
1010 resolveActiveEmbeddedRunSessionId : vi . fn ( ) ,
11+ resolveActiveEmbeddedRunSessionIdBySessionFile : vi . fn ( ) ,
1112} ) ) ;
1213
1314vi . mock ( "./commands-steer.runtime.js" , ( ) => steerRuntimeMocks ) ;
@@ -38,6 +39,9 @@ describe("handleSteerCommand", () => {
3839 gatewayHealth : "live" ,
3940 } ) ;
4041 steerRuntimeMocks . resolveActiveEmbeddedRunSessionId . mockReset ( ) . mockReturnValue ( undefined ) ;
42+ steerRuntimeMocks . resolveActiveEmbeddedRunSessionIdBySessionFile
43+ . mockReset ( )
44+ . mockReturnValue ( undefined ) ;
4145 } ) ;
4246
4347 it ( "queues steering for the active current text-command session" , async ( ) => {
@@ -107,6 +111,72 @@ describe("handleSteerCommand", () => {
107111 ) ;
108112 } ) ;
109113
114+ it ( "resolves an active run from the target session file before stored session id fallback" , async ( ) => {
115+ steerRuntimeMocks . resolveActiveEmbeddedRunSessionIdBySessionFile . mockReturnValue (
116+ "session-file-active" ,
117+ ) ;
118+
119+ const params = buildParams ( "/steer check the active file" ) ;
120+ params . ctx . CommandSource = "native" ;
121+ params . ctx . CommandTargetSessionKey = "agent:main:telegram:topic:5907" ;
122+ params . sessionKey = "agent:main:telegram:control" ;
123+ params . sessionStore = {
124+ "agent:main:telegram:topic:5907" : {
125+ sessionId : "stored-session-id" ,
126+ sessionFile : "/tmp/openclaw-topic-5907.jsonl" ,
127+ updatedAt : Date . now ( ) ,
128+ } ,
129+ } ;
130+
131+ await handleSteerCommand ( params , true ) ;
132+
133+ expect ( steerRuntimeMocks . resolveActiveEmbeddedRunSessionId ) . toHaveBeenCalledWith (
134+ "agent:main:telegram:topic:5907" ,
135+ ) ;
136+ expect ( steerRuntimeMocks . resolveActiveEmbeddedRunSessionIdBySessionFile ) . toHaveBeenCalledWith (
137+ "/tmp/openclaw-topic-5907.jsonl" ,
138+ ) ;
139+ expect ( steerRuntimeMocks . isEmbeddedAgentRunActive ) . not . toHaveBeenCalledWith (
140+ "stored-session-id" ,
141+ ) ;
142+ expect ( steerRuntimeMocks . queueEmbeddedAgentMessageWithOutcomeAsync ) . toHaveBeenCalledWith (
143+ "session-file-active" ,
144+ "check the active file" ,
145+ {
146+ steeringMode : "all" ,
147+ debounceMs : 0 ,
148+ } ,
149+ ) ;
150+ } ) ;
151+
152+ it ( "falls back from a slash-lane command session to an active direct sibling" , async ( ) => {
153+ steerRuntimeMocks . resolveActiveEmbeddedRunSessionId . mockImplementation ( ( key : string ) =>
154+ key === "agent:main:telegram:direct:123" ? "session-direct-active" : undefined ,
155+ ) ;
156+
157+ const params = buildParams ( "/steer use the active direct lane" ) ;
158+ params . sessionKey = "agent:main:telegram:slash:123" ;
159+
160+ await handleSteerCommand ( params , true ) ;
161+
162+ expect ( steerRuntimeMocks . resolveActiveEmbeddedRunSessionId ) . toHaveBeenNthCalledWith (
163+ 1 ,
164+ "agent:main:telegram:slash:123" ,
165+ ) ;
166+ expect ( steerRuntimeMocks . resolveActiveEmbeddedRunSessionId ) . toHaveBeenNthCalledWith (
167+ 2 ,
168+ "agent:main:telegram:direct:123" ,
169+ ) ;
170+ expect ( steerRuntimeMocks . queueEmbeddedAgentMessageWithOutcomeAsync ) . toHaveBeenCalledWith (
171+ "session-direct-active" ,
172+ "use the active direct lane" ,
173+ {
174+ steeringMode : "all" ,
175+ debounceMs : 0 ,
176+ } ,
177+ ) ;
178+ } ) ;
179+
110180 it ( "returns usage for an empty steer command" , async ( ) => {
111181 const result = await handleSteerCommand ( buildParams ( "/steer" ) , true ) ;
112182
0 commit comments