@@ -656,24 +656,53 @@ export async function appendWakeToSession(args: {
656656 action : WatchWakeAction ;
657657 watch : Watch ;
658658} ) : Promise < void > {
659- await sessions . open ( args . chatId ) . in . send ( {
660- kind : "message" ,
661- payload : {
662- chatId : args . chatId ,
663- trigger : "action" ,
664- action : args . action ,
665- metadata : {
666- userId : args . watch . userId ,
667- organizationId : args . watch . organizationId ,
668- projectId : args . watch . projectId ,
669- environmentId : args . watch . environmentId ,
670- // The external ref a consented investigation is scoped by — the same
671- // one a normal turn carries, so a follow-up turn revises that
672- // investigation instead of opening a second one.
673- ...( args . watch . projectRef ? { projectRef : args . watch . projectRef } : { } ) ,
659+ const metadata = {
660+ userId : args . watch . userId ,
661+ organizationId : args . watch . organizationId ,
662+ projectId : args . watch . projectId ,
663+ environmentId : args . watch . environmentId ,
664+ // The external ref a consented investigation is scoped by — the same
665+ // one a normal turn carries, so a follow-up turn revises that
666+ // investigation instead of opening a second one.
667+ ...( args . watch . projectRef ? { projectRef : args . watch . projectRef } : { } ) ,
668+ } ;
669+
670+ const send = ( ) =>
671+ sessions . open ( args . chatId ) . in . send ( {
672+ kind : "message" ,
673+ payload : {
674+ chatId : args . chatId ,
675+ trigger : "action" ,
676+ action : args . action ,
677+ metadata,
674678 } ,
675- } ,
676- } ) ;
679+ } ) ;
680+
681+ try {
682+ await send ( ) ;
683+ } catch ( error ) {
684+ // A chat born from the configuration card (0 LLM) has no session yet —
685+ // the card's confirmation is a direct JSONB append. The wake is the first
686+ // thing that needs one, so create it here (idempotent on externalId) and
687+ // retry once. Any other failure keeps the claim's retry semantics.
688+ if ( ! isSessionNotFound ( error ) ) throw error ;
689+ await sessions . start ( {
690+ type : "chat.agent" ,
691+ externalId : args . chatId ,
692+ taskIdentifier : "dashboard-agent" ,
693+ triggerConfig : {
694+ basePayload : { trigger : "preload" , chatId : args . chatId , metadata } ,
695+ } ,
696+ } ) ;
697+ await send ( ) ;
698+ }
699+ }
700+
701+ /** A 404 from a session call: no Session row exists for this chat id. */
702+ function isSessionNotFound ( error : unknown ) : boolean {
703+ if ( error === null || typeof error !== "object" ) return false ;
704+ const e = error as { name ?: string ; status ?: number } ;
705+ return e . name === "TriggerApiError" && e . status === 404 ;
677706}
678707
679708export const watchTick = task ( {
0 commit comments