@@ -4,7 +4,8 @@ import { createOrchestratorSession, executeOrchestrator } from './orchestrator'
44import { formatValidationFailure , validateTaskCompletion } from './task-validation'
55import { ensureTaskCompletionReport } from './task-reports'
66import { pushMainLoopEventToMainSessions } from './main-agent-loop'
7- import type { BoardTask } from '@/types'
7+ import { executeSessionChatTurn } from './chat-execution'
8+ import type { Agent , BoardTask } from '@/types'
89
910let processing = false
1011
@@ -13,6 +14,7 @@ interface SessionMessageLike {
1314 text ?: string
1415 time ?: number
1516 kind ?: 'chat' | 'heartbeat' | 'system'
17+ toolEvents ?: Array < { name ?: string ; output ?: string } >
1618}
1719
1820interface SessionLike {
@@ -115,6 +117,48 @@ function summarizeScheduleTaskResult(task: BoardTask): string {
115117 return 'No summary was returned.'
116118}
117119
120+ function extractLatestUploadUrl ( session : SessionLike | null | undefined ) : string | null {
121+ if ( ! Array . isArray ( session ?. messages ) ) return null
122+ for ( let i = session . messages . length - 1 ; i >= 0 ; i -- ) {
123+ const msg = session . messages [ i ]
124+ const text = typeof msg ?. text === 'string' ? msg . text : ''
125+ const textMatch = text . match ( / \/ a p i \/ u p l o a d s \/ [ ^ \s ) " ' > ] + / i)
126+ if ( textMatch ?. [ 0 ] ) return textMatch [ 0 ]
127+
128+ const events = Array . isArray ( msg ?. toolEvents ) ? msg . toolEvents : [ ]
129+ for ( let j = events . length - 1 ; j >= 0 ; j -- ) {
130+ const ev = events [ j ]
131+ if ( ev ?. name !== 'send_file' ) continue
132+ const output = typeof ev . output === 'string' ? ev . output : ''
133+ const match = output . match ( / \/ a p i \/ u p l o a d s \/ [ ^ \s ) " ' > ] + / i)
134+ if ( match ?. [ 0 ] ) return match [ 0 ]
135+ }
136+ }
137+ return null
138+ }
139+
140+ async function executeTaskRun (
141+ task : BoardTask ,
142+ agent : Agent ,
143+ sessionId : string ,
144+ ) : Promise < string > {
145+ const prompt = task . description || task . title
146+ if ( agent ?. isOrchestrator ) {
147+ return executeOrchestrator ( agent , prompt , sessionId )
148+ }
149+
150+ const run = await executeSessionChatTurn ( {
151+ sessionId,
152+ message : prompt ,
153+ internal : false ,
154+ source : 'task' ,
155+ } )
156+ const text = typeof run . text === 'string' ? run . text . trim ( ) : ''
157+ if ( text ) return text
158+ if ( run . error ) return `Error: ${ run . error } `
159+ return ''
160+ }
161+
118162function notifyMainChatScheduleResult ( task : BoardTask ) : void {
119163 const scheduleTask = task as ScheduleTaskMeta
120164 const sourceType = typeof scheduleTask . sourceType === 'string' ? scheduleTask . sourceType : ''
@@ -135,11 +179,15 @@ function notifyMainChatScheduleResult(task: BoardTask): void {
135179 ...task ,
136180 result : task . result || fallbackText || task . result ,
137181 } as BoardTask )
182+ const latestUploadUrl = extractLatestUploadUrl ( runSession )
138183
139184 const statusLabel = task . status === 'completed' ? 'completed' : 'failed'
185+ const summaryWithArtifact = ( latestUploadUrl && ! summary . includes ( latestUploadUrl ) )
186+ ? `${ summary } \n\nArtifact: ${ latestUploadUrl } `
187+ : summary
140188 const body = [
141189 `Scheduled run ${ statusLabel } : **${ scheduleName || 'Scheduled Task' } **` ,
142- summary ,
190+ summaryWithArtifact ,
143191 ] . join ( '\n\n' ) . trim ( )
144192 if ( ! body ) return
145193
@@ -437,7 +485,7 @@ export async function processNext() {
437485 console . log ( `[queue] Running task "${ task . title } " (${ taskId } ) with ${ agent . name } ` )
438486
439487 try {
440- const result = await executeOrchestrator ( agent , task . description || task . title , sessionId )
488+ const result = await executeTaskRun ( task , agent , sessionId )
441489 const t2 = loadTasks ( )
442490 if ( t2 [ taskId ] ) {
443491 applyTaskPolicyDefaults ( t2 [ taskId ] )
0 commit comments