@@ -8,6 +8,7 @@ import type { SessionEntry } from "../../config/sessions.js";
88import {
99 adoptCronRunSessionMetadata ,
1010 createPersistCronSessionEntry ,
11+ setCronSessionDeliveryContextFromResolvedDelivery ,
1112 type MutableCronSession ,
1213} from "./run-session-state.js" ;
1314
@@ -216,6 +217,70 @@ describe("createPersistCronSessionEntry", () => {
216217 } ) ;
217218} ) ;
218219
220+ describe ( "setCronSessionDeliveryContextFromResolvedDelivery" , ( ) => {
221+ it ( "persists a resolved explicit delivery target on the session entry" , ( ) => {
222+ const cronSession = makeCronSession ( ) ;
223+ setCronSessionDeliveryContextFromResolvedDelivery ( cronSession . sessionEntry , {
224+ ok : true ,
225+ channel : "webchat" ,
226+ 227+ accountId : "account-1" ,
228+ threadId : "thread-1" ,
229+ mode : "explicit" ,
230+ } ) ;
231+ expect ( cronSession . sessionEntry . deliveryContext ) . toEqual ( {
232+ channel : "webchat" ,
233+ 234+ accountId : "account-1" ,
235+ threadId : "thread-1" ,
236+ } ) ;
237+ } ) ;
238+
239+ it ( "persists the resolved target without optional account/thread fields" , ( ) => {
240+ const cronSession = makeCronSession ( ) ;
241+ setCronSessionDeliveryContextFromResolvedDelivery ( cronSession . sessionEntry , {
242+ ok : true ,
243+ channel : "webchat" ,
244+ 245+ mode : "explicit" ,
246+ } ) ;
247+ expect ( cronSession . sessionEntry . deliveryContext ) . toEqual ( {
248+ channel : "webchat" ,
249+ 250+ } ) ;
251+ } ) ;
252+
253+ it ( "leaves deliveryContext unchanged when target resolution fails" , ( ) => {
254+ const cronSession = makeCronSession (
255+ makeSessionEntry ( { deliveryContext : { channel : "webchat" , to : "stale" } } ) ,
256+ ) ;
257+ setCronSessionDeliveryContextFromResolvedDelivery ( cronSession . sessionEntry , {
258+ ok : false ,
259+ channel : undefined ,
260+ to : undefined ,
261+ accountId : undefined ,
262+ threadId : undefined ,
263+ mode : "implicit" ,
264+ error : new Error ( "Channel is required" ) ,
265+ } ) ;
266+ expect ( cronSession . sessionEntry . deliveryContext ) . toEqual ( {
267+ channel : "webchat" ,
268+ to : "stale" ,
269+ } ) ;
270+ } ) ;
271+
272+ it ( "does not create an empty deliveryContext when the resolved target has no routable channel" , ( ) => {
273+ const cronSession = makeCronSession ( ) ;
274+ setCronSessionDeliveryContextFromResolvedDelivery ( cronSession . sessionEntry , {
275+ ok : true ,
276+ channel : "webchat" ,
277+ to : "" ,
278+ mode : "explicit" ,
279+ } ) ;
280+ expect ( cronSession . sessionEntry . deliveryContext ) . toBeUndefined ( ) ;
281+ } ) ;
282+ } ) ;
283+
219284async function createTranscriptFile ( ) : Promise < string > {
220285 const dir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , "openclaw-cron-session-" ) ) ;
221286 const file = path . join ( dir , "session.jsonl" ) ;
0 commit comments