@@ -10,10 +10,9 @@ import { SSE_HEADERS } from '@/lib/core/utils/sse'
1010import { markExecutionCancelled } from '@/lib/execution/cancellation'
1111import { LoggingSession } from '@/lib/logs/execution/logging-session'
1212import { executeWorkflowCore } from '@/lib/workflows/executor/execution-core'
13- import { type ExecutionEvent , encodeSSEEvent } from '@/lib/workflows/executor/execution-events'
13+ import { createSSECallbacks } from '@/lib/workflows/executor/execution-events'
1414import { ExecutionSnapshot } from '@/executor/execution/snapshot'
15- import type { IterationContext , SerializableExecutionState } from '@/executor/execution/types'
16- import type { NormalizedBlockOutput } from '@/executor/types'
15+ import type { ExecutionMetadata , SerializableExecutionState } from '@/executor/execution/types'
1716import { hasExecutionResult } from '@/executor/utils/errors'
1817
1918const logger = createLogger ( 'ExecuteFromBlockAPI' )
@@ -100,16 +99,17 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
10099
101100 const stream = new ReadableStream < Uint8Array > ( {
102101 async start ( controller ) {
103- const sendEvent = ( event : ExecutionEvent ) => {
104- if ( isStreamClosed ) return
105- try {
106- controller . enqueue ( encodeSSEEvent ( event ) )
107- } catch {
102+ const { sendEvent, onBlockStart, onBlockComplete, onStream } = createSSECallbacks ( {
103+ executionId,
104+ workflowId,
105+ controller,
106+ isStreamClosed : ( ) => isStreamClosed ,
107+ setStreamClosed : ( ) => {
108108 isStreamClosed = true
109- }
110- }
109+ } ,
110+ } )
111111
112- const snapshot = new ExecutionSnapshot ( {
112+ const metadata : ExecutionMetadata = {
113113 requestId,
114114 workflowId,
115115 userId,
@@ -119,7 +119,10 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
119119 workflowUserId,
120120 useDraftState : true ,
121121 isClientSession : true ,
122- } )
122+ startTime : new Date ( ) . toISOString ( ) ,
123+ }
124+
125+ const snapshot = new ExecutionSnapshot ( metadata , { } , { } , { } )
123126
124127 try {
125128 const startTime = new Date ( )
@@ -140,100 +143,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
140143 startBlockId,
141144 sourceSnapshot : sourceSnapshot as SerializableExecutionState ,
142145 } ,
143- callbacks : {
144- onBlockStart : async (
145- blockId : string ,
146- blockName : string ,
147- blockType : string ,
148- iterationContext ?: IterationContext
149- ) => {
150- sendEvent ( {
151- type : 'block:started' ,
152- timestamp : new Date ( ) . toISOString ( ) ,
153- executionId,
154- workflowId,
155- data : {
156- blockId,
157- blockName,
158- blockType,
159- ...( iterationContext && {
160- iterationCurrent : iterationContext . iterationCurrent ,
161- iterationTotal : iterationContext . iterationTotal ,
162- iterationType : iterationContext . iterationType ,
163- } ) ,
164- } ,
165- } )
166- } ,
167- onBlockComplete : async (
168- blockId : string ,
169- blockName : string ,
170- blockType : string ,
171- callbackData : {
172- input ?: unknown
173- output : NormalizedBlockOutput
174- executionTime : number
175- } ,
176- iterationContext ?: IterationContext
177- ) => {
178- const hasError = ( callbackData . output as any ) ?. error
179- sendEvent ( {
180- type : hasError ? 'block:error' : 'block:completed' ,
181- timestamp : new Date ( ) . toISOString ( ) ,
182- executionId,
183- workflowId,
184- data : {
185- blockId,
186- blockName,
187- blockType,
188- input : callbackData . input ,
189- ...( hasError
190- ? { error : ( callbackData . output as any ) . error }
191- : { output : callbackData . output } ) ,
192- durationMs : callbackData . executionTime || 0 ,
193- ...( iterationContext && {
194- iterationCurrent : iterationContext . iterationCurrent ,
195- iterationTotal : iterationContext . iterationTotal ,
196- iterationType : iterationContext . iterationType ,
197- } ) ,
198- } ,
199- } )
200- } ,
201- onStream : async ( streamingExecution : unknown ) => {
202- const streamingExec = streamingExecution as {
203- stream : ReadableStream
204- execution : any
205- }
206- const blockId = streamingExec . execution ?. blockId
207- const reader = streamingExec . stream . getReader ( )
208- const decoder = new TextDecoder ( )
209-
210- try {
211- while ( true ) {
212- const { done, value } = await reader . read ( )
213- if ( done ) break
214- const chunk = decoder . decode ( value , { stream : true } )
215- sendEvent ( {
216- type : 'stream:chunk' ,
217- timestamp : new Date ( ) . toISOString ( ) ,
218- executionId,
219- workflowId,
220- data : { blockId, chunk } ,
221- } )
222- }
223- sendEvent ( {
224- type : 'stream:done' ,
225- timestamp : new Date ( ) . toISOString ( ) ,
226- executionId,
227- workflowId,
228- data : { blockId } ,
229- } )
230- } finally {
231- try {
232- reader . releaseLock ( )
233- } catch { }
234- }
235- } ,
236- } ,
146+ callbacks : { onBlockStart, onBlockComplete, onStream } ,
237147 } )
238148
239149 if ( result . status === 'cancelled' ) {
0 commit comments