@@ -7,12 +7,14 @@ import { getRuntimeConfig } from "../config/io.js";
77import { normalizeAgentId } from "../routing/session-key.js" ;
88import type { SessionLifecycleEvent } from "../sessions/session-lifecycle-events.js" ;
99import type { SessionTranscriptUpdate } from "../sessions/transcript-events.js" ;
10+ import type { ChatAbortControllerEntry } from "./chat-abort.js" ;
1011import { projectChatDisplayMessage } from "./chat-display-projection.js" ;
1112import type { GatewayBroadcastToConnIdsFn } from "./server-broadcast-types.js" ;
1213import type {
1314 SessionEventSubscriberRegistry ,
1415 SessionMessageSubscriberRegistry ,
1516} from "./server-chat.js" ;
17+ import { hasTrackedActiveSessionRun } from "./server-methods/session-active-runs.js" ;
1618import { resolveSessionKeyForTranscriptFile } from "./session-transcript-key.js" ;
1719import {
1820 attachOpenClawTranscriptMeta ,
@@ -49,6 +51,7 @@ function buildGatewaySessionSnapshot(params: {
4951 label ?: string ;
5052 displayName ?: string ;
5153 parentSessionKey ?: string ;
54+ hasActiveRun ?: boolean ;
5255} ) : Record < string , unknown > {
5356 const { sessionRow } = params ;
5457 if ( ! sessionRow ) {
@@ -61,6 +64,9 @@ function buildGatewaySessionSnapshot(params: {
6164 if ( session && omitUnscopedGlobalGoal ) {
6265 delete session . goal ;
6366 }
67+ if ( session && params . hasActiveRun !== undefined ) {
68+ session . hasActiveRun = params . hasActiveRun ;
69+ }
6470 return {
6571 ...( session ? { session } : { } ) ,
6672 updatedAt : sessionRow . updatedAt ?? undefined ,
@@ -107,6 +113,7 @@ function buildGatewaySessionSnapshot(params: {
107113 modelProvider : sessionRow . modelProvider ,
108114 model : sessionRow . model ,
109115 status : sessionRow . status ,
116+ ...( params . hasActiveRun === undefined ? { } : { hasActiveRun : params . hasActiveRun } ) ,
110117 subagentRunState : sessionRow . subagentRunState ,
111118 hasActiveSubagentRun : sessionRow . hasActiveSubagentRun ,
112119 startedAt : sessionRow . startedAt ,
@@ -122,6 +129,7 @@ export function createTranscriptUpdateBroadcastHandler(params: {
122129 broadcastToConnIds : GatewayBroadcastToConnIdsFn ;
123130 sessionEventSubscribers : SessionEventSubscribers ;
124131 sessionMessageSubscribers : SessionMessageSubscribers ;
132+ chatAbortControllers : Map < string , ChatAbortControllerEntry > ;
125133} ) {
126134 let broadcastQueue = Promise . resolve ( ) ;
127135 return ( update : SessionTranscriptUpdate ) : void => {
@@ -138,6 +146,7 @@ async function handleTranscriptUpdateBroadcast(
138146 broadcastToConnIds : GatewayBroadcastToConnIdsFn ;
139147 sessionEventSubscribers : SessionEventSubscribers ;
140148 sessionMessageSubscribers : SessionMessageSubscribers ;
149+ chatAbortControllers : Map < string , ChatAbortControllerEntry > ;
141150 } ,
142151 update : SessionTranscriptUpdate ,
143152) : Promise < void > {
@@ -176,13 +185,24 @@ async function handleTranscriptUpdateBroadcast(
176185 )
177186 : undefined ;
178187 }
188+ const sessionRow = loadGatewaySessionRow ( sessionKey , {
189+ agentId : visibleAgentId ,
190+ transcriptUsageMaxBytes : 64 * 1024 ,
191+ } ) ;
192+ const hasActiveRun = sessionRow
193+ ? hasTrackedActiveSessionRun ( {
194+ context : params ,
195+ requestedKey : sessionKey ,
196+ canonicalKey : sessionRow . key ,
197+ ...( sessionRow . key === "global" && visibleAgentId ? { agentId : visibleAgentId } : { } ) ,
198+ defaultAgentId : normalizeAgentId ( resolveDefaultAgentId ( getRuntimeConfig ( ) ) ) ,
199+ } )
200+ : false ;
179201 const sessionSnapshot = buildGatewaySessionSnapshot ( {
180- sessionRow : loadGatewaySessionRow ( sessionKey , {
181- agentId : visibleAgentId ,
182- transcriptUsageMaxBytes : 64 * 1024 ,
183- } ) ,
202+ sessionRow,
184203 agentId : visibleAgentId ,
185204 includeSession : true ,
205+ hasActiveRun,
186206 } ) ;
187207 const rawMessage = attachOpenClawTranscriptMeta ( update . message , {
188208 ...( typeof update . messageId === "string" ? { id : update . messageId } : { } ) ,
0 commit comments