@yolk-sdk/vercel-workflows 0.1.0-canary.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,202 @@
1
+ import { Data, Effect } from 'effect'
2
+
3
+ export type DurableAgentEventSequencerState = {
4
+ readonly eventSequence: number
5
+ }
6
+
7
+ export type DurableAgentEvent<Event extends object = object> = Event & {
8
+ readonly eventId: string
9
+ readonly createdAtMs?: number
10
+ }
11
+
12
+ export type DurableAgentEventIdInput = {
13
+ readonly streamId: string
14
+ readonly turn: number
15
+ readonly eventSequence: number
16
+ }
17
+
18
+ export type SequenceDurableAgentEventInput<Event extends object = object> = {
19
+ readonly state: DurableAgentEventSequencerState
20
+ /**
21
+ * Stable id namespace for one independent durable stream.
22
+ *
23
+ * Include the workflow/session/run id when multiple logical runs can be
24
+ * projected in the same client. Replay-safe clients de-dupe by `eventId`, so
25
+ * reusing a stream id across runs can drop legitimate follow-up events.
26
+ */
27
+ readonly streamId: string
28
+ readonly turn: number
29
+ readonly event: Event
30
+ readonly createdAtMs?: number
31
+ }
32
+
33
+ export type SequencedDurableAgentEvent<Event extends object = object> = {
34
+ readonly event: DurableAgentEvent<Event>
35
+ readonly eventSequence: number
36
+ readonly nextEventSequence: number
37
+ readonly nextState: DurableAgentEventSequencerState
38
+ }
39
+
40
+ export type WriteDurableAgentEventInput<Event extends object = object> =
41
+ SequenceDurableAgentEventInput<Event> & {
42
+ readonly writer: WritableStreamDefaultWriter<Uint8Array>
43
+ }
44
+
45
+ export type CommitThenWriteTerminalEventInput<
46
+ TerminalEvent extends object,
47
+ TerminalWriteResult,
48
+ CommitErrorWriteResult,
49
+ CommitError,
50
+ TerminalWriteError,
51
+ CommitErrorWriteError
52
+ > = {
53
+ readonly commit: Effect.Effect<void, CommitError>
54
+ readonly terminal: TerminalEvent
55
+ readonly write: (event: TerminalEvent) => Effect.Effect<TerminalWriteResult, TerminalWriteError>
56
+ readonly writeCommitError: (
57
+ error: CommitError
58
+ ) => Effect.Effect<CommitErrorWriteResult, CommitErrorWriteError>
59
+ }
60
+
61
+ export type CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult> =
62
+ Data.TaggedEnum<{
63
+ Committed: {
64
+ readonly writeResult: TerminalWriteResult
65
+ }
66
+ CommitFailed: {
67
+ readonly commitError: unknown
68
+ readonly writeResult: CommitErrorWriteResult
69
+ }
70
+ TerminalWriteFailed: {
71
+ readonly error: unknown
72
+ }
73
+ CommitErrorWriteFailed: {
74
+ readonly commitError: unknown
75
+ readonly error: unknown
76
+ }
77
+ }>
78
+
79
+ interface CommitThenWriteTerminalEventResultDefinition extends Data.TaggedEnum.WithGenerics<2> {
80
+ readonly taggedEnum: CommitThenWriteTerminalEventResult<this['A'], this['B']>
81
+ }
82
+
83
+ export const CommitThenWriteTerminalEventResult =
84
+ Data.taggedEnum<CommitThenWriteTerminalEventResultDefinition>()
85
+
86
+ const textEncoder = new TextEncoder()
87
+
88
+ export const makeDurableAgentEventSequencerState = (
89
+ eventSequence = 0
90
+ ): DurableAgentEventSequencerState => ({ eventSequence })
91
+
92
+ export const durableAgentEventId = (input: DurableAgentEventIdInput) =>
93
+ `${input.streamId}:${input.turn}:${input.eventSequence}`
94
+
95
+ export const sequenceDurableAgentEvent = <Event extends object>(
96
+ input: SequenceDurableAgentEventInput<Event>
97
+ ): SequencedDurableAgentEvent<Event> => {
98
+ const eventSequence = input.state.eventSequence
99
+ const nextEventSequence = eventSequence + 1
100
+
101
+ type SequencedDurableAgentEventFields = Event & {
102
+ eventId: string
103
+ createdAtMs?: number
104
+ }
105
+
106
+ const event: SequencedDurableAgentEventFields = {
107
+ ...input.event,
108
+ eventId: durableAgentEventId({
109
+ streamId: input.streamId,
110
+ turn: input.turn,
111
+ eventSequence
112
+ })
113
+ }
114
+
115
+ if (input.createdAtMs !== undefined) {
116
+ event.createdAtMs = input.createdAtMs
117
+ }
118
+
119
+ return {
120
+ event,
121
+ eventSequence,
122
+ nextEventSequence,
123
+ nextState: makeDurableAgentEventSequencerState(nextEventSequence)
124
+ }
125
+ }
126
+
127
+ const encodeDurableAgentEventNdjson = <Event extends object>(event: DurableAgentEvent<Event>) =>
128
+ textEncoder.encode(`${JSON.stringify(event)}\n`)
129
+
130
+ export const writeDurableAgentEvent = <Event extends object>(
131
+ input: WriteDurableAgentEventInput<Event>
132
+ ): Effect.Effect<SequencedDurableAgentEvent<Event>, unknown> =>
133
+ Effect.gen(function* () {
134
+ const sequenced = sequenceDurableAgentEvent(input)
135
+ yield* Effect.tryPromise({
136
+ try: () => input.writer.write(encodeDurableAgentEventNdjson(sequenced.event)),
137
+ catch: cause => cause
138
+ })
139
+
140
+ return sequenced
141
+ })
142
+
143
+ export const commitThenWriteTerminalEvent = <
144
+ TerminalEvent extends object,
145
+ TerminalWriteResult,
146
+ CommitErrorWriteResult,
147
+ CommitError,
148
+ TerminalWriteError,
149
+ CommitErrorWriteError
150
+ >(
151
+ input: CommitThenWriteTerminalEventInput<
152
+ TerminalEvent,
153
+ TerminalWriteResult,
154
+ CommitErrorWriteResult,
155
+ CommitError,
156
+ TerminalWriteError,
157
+ CommitErrorWriteError
158
+ >
159
+ ): Effect.Effect<
160
+ CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult>,
161
+ never
162
+ > =>
163
+ input.commit.pipe(
164
+ Effect.matchEffect({
165
+ onFailure: commitError =>
166
+ input.writeCommitError(commitError).pipe(
167
+ Effect.match({
168
+ onFailure: error =>
169
+ CommitThenWriteTerminalEventResult.CommitErrorWriteFailed<
170
+ TerminalWriteResult,
171
+ CommitErrorWriteResult
172
+ >({
173
+ commitError,
174
+ error
175
+ }),
176
+ onSuccess: writeResult =>
177
+ CommitThenWriteTerminalEventResult.CommitFailed<
178
+ TerminalWriteResult,
179
+ CommitErrorWriteResult
180
+ >({
181
+ commitError,
182
+ writeResult
183
+ })
184
+ })
185
+ ),
186
+ onSuccess: () =>
187
+ input.write(input.terminal).pipe(
188
+ Effect.match({
189
+ onFailure: error =>
190
+ CommitThenWriteTerminalEventResult.TerminalWriteFailed<
191
+ TerminalWriteResult,
192
+ CommitErrorWriteResult
193
+ >({ error }),
194
+ onSuccess: writeResult =>
195
+ CommitThenWriteTerminalEventResult.Committed<
196
+ TerminalWriteResult,
197
+ CommitErrorWriteResult
198
+ >({ writeResult })
199
+ })
200
+ )
201
+ })
202
+ )
@@ -0,0 +1,404 @@
1
+ import { Data, Predicate } from 'effect'
2
+
3
+ export type VercelAgentWorkflowInput = {
4
+ readonly request: unknown
5
+ readonly context: unknown
6
+ }
7
+
8
+ export type SerializableWorkflowState = {
9
+ readonly request: unknown
10
+ readonly messages?: ReadonlyArray<unknown>
11
+ readonly createdMessages: ReadonlyArray<unknown>
12
+ readonly usage?: unknown
13
+ readonly turn: number
14
+ readonly eventSequence?: number
15
+ }
16
+
17
+ export type VercelAgentWorkflowModelStepInput = {
18
+ readonly context: unknown
19
+ readonly state: SerializableWorkflowState
20
+ }
21
+
22
+ export type VercelAgentWorkflowModelStepResult = {
23
+ readonly done: boolean
24
+ readonly messages: ReadonlyArray<unknown>
25
+ readonly createdMessages: ReadonlyArray<unknown>
26
+ readonly toolCalls: ReadonlyArray<unknown>
27
+ readonly usage: unknown
28
+ readonly turn: number
29
+ readonly eventSequence?: number
30
+ }
31
+
32
+ export type VercelAgentWorkflowToolBatchStepInput = {
33
+ readonly context: unknown
34
+ readonly request: unknown
35
+ readonly calls: ReadonlyArray<unknown>
36
+ readonly createdMessages: ReadonlyArray<unknown>
37
+ readonly hitlResponses?: ReadonlyArray<unknown>
38
+ readonly usage?: unknown
39
+ readonly turn?: number
40
+ readonly eventSequence?: number
41
+ }
42
+
43
+ export type VercelAgentWorkflowAwaitingInput = {
44
+ readonly hookToken: string
45
+ readonly requests: ReadonlyArray<unknown>
46
+ readonly messages: ReadonlyArray<unknown>
47
+ readonly usage: unknown
48
+ readonly turns: number
49
+ readonly eventSequence?: number
50
+ }
51
+
52
+ export type VercelAgentWorkflowToolBatchStepResult = {
53
+ readonly messages: ReadonlyArray<unknown>
54
+ readonly createdMessages: ReadonlyArray<unknown>
55
+ /** Updated cumulative usage when tools run nested model work such as subagents. */
56
+ readonly usage?: unknown
57
+ readonly awaitingInput?: VercelAgentWorkflowAwaitingInput
58
+ readonly eventSequence?: number
59
+ /**
60
+ * A plain wire-safe failure captured after partial progress. Returning it instead of rejecting
61
+ * lets orchestration retain usage and event sequencing from completed sibling tools.
62
+ */
63
+ readonly failure?: unknown
64
+ }
65
+
66
+ export type WorkflowStepResult<A> = Data.TaggedEnum<{
67
+ Success: {
68
+ readonly value: A
69
+ }
70
+ Failure: {
71
+ readonly error: unknown
72
+ }
73
+ }>
74
+
75
+ interface WorkflowStepResultDefinition extends Data.TaggedEnum.WithGenerics<1> {
76
+ readonly taggedEnum: WorkflowStepResult<this['A']>
77
+ }
78
+
79
+ export const WorkflowStepResult = Data.taggedEnum<WorkflowStepResultDefinition>()
80
+
81
+ export type VercelAgentWorkflowStepRetryPolicy = {
82
+ readonly maxAttempts: number
83
+ }
84
+
85
+ export type VercelAgentWorkflowRunResult = Data.TaggedEnum<{
86
+ Completed: {
87
+ readonly turns: number
88
+ readonly state: SerializableWorkflowState
89
+ }
90
+ ModelStepFailed: {
91
+ readonly turn: number
92
+ readonly error: unknown
93
+ readonly state: SerializableWorkflowState
94
+ }
95
+ ToolBatchStepFailed: {
96
+ readonly turn: number
97
+ readonly error: unknown
98
+ readonly state: SerializableWorkflowState
99
+ }
100
+ AwaitInputFailed: {
101
+ readonly turn: number
102
+ readonly error: unknown
103
+ readonly awaitingInput: VercelAgentWorkflowAwaitingInput
104
+ readonly state: SerializableWorkflowState
105
+ }
106
+ CloseStreamFailed: {
107
+ readonly turns: number
108
+ readonly error: unknown
109
+ readonly state: SerializableWorkflowState
110
+ }
111
+ MaxTurnsExceeded: {
112
+ readonly maxTurns: number
113
+ readonly error: Error
114
+ readonly state: SerializableWorkflowState
115
+ }
116
+ }>
117
+
118
+ export const VercelAgentWorkflowRunResult = Data.taggedEnum<VercelAgentWorkflowRunResult>()
119
+
120
+ export type VercelAgentWorkflowLoopConfig = {
121
+ readonly input: VercelAgentWorkflowInput
122
+ readonly maxTurns?: number
123
+ readonly runModelStep: (
124
+ input: VercelAgentWorkflowModelStepInput
125
+ ) => Promise<VercelAgentWorkflowModelStepResult>
126
+ readonly runToolBatchStep: (
127
+ input: VercelAgentWorkflowToolBatchStepInput
128
+ ) => Promise<VercelAgentWorkflowToolBatchStepResult>
129
+ /** Called only after a model step returns `done: true`. */
130
+ readonly closeStream: () => Promise<void>
131
+ /**
132
+ * Best-effort final failure handler. It must write a safe final error and
133
+ * close the failure stream; rejection is suppressed in favor of the
134
+ * original structured run result.
135
+ */
136
+ readonly writeError: (error: unknown) => Promise<void>
137
+ /** A successful await suspends/resumes without invoking either finalizer. */
138
+ readonly awaitInput?: (input: VercelAgentWorkflowAwaitingInput) => Promise<unknown>
139
+ readonly modelStepRetry?: VercelAgentWorkflowStepRetryPolicy
140
+ readonly toolBatchStepRetry?: VercelAgentWorkflowStepRetryPolicy
141
+ readonly awaitInputRetry?: VercelAgentWorkflowStepRetryPolicy
142
+ readonly closeStreamRetry?: VercelAgentWorkflowStepRetryPolicy
143
+ }
144
+
145
+ export const defaultMaxWorkflowTurns = 500
146
+
147
+ export const noWorkflowStepRetry: VercelAgentWorkflowStepRetryPolicy = { maxAttempts: 1 }
148
+
149
+ export const settleWorkflowStep = <A>(promise: Promise<A>): Promise<WorkflowStepResult<A>> =>
150
+ promise.then(
151
+ value => WorkflowStepResult.Success<A>({ value }),
152
+ error => WorkflowStepResult.Failure<A>({ error })
153
+ )
154
+
155
+ const workflowMaxTurnsError = (maxTurns: number) =>
156
+ new Error(`Vercel agent workflow exceeded max turns: ${maxTurns}`)
157
+
158
+ const writeErrorSafely = (writeError: (error: unknown) => Promise<void>, error: unknown) =>
159
+ writeError(error).catch(() => undefined)
160
+
161
+ const missingAwaitInputHandlerError = () =>
162
+ new Error(
163
+ 'Vercel agent workflow awaiting input requested but no awaitInput handler is configured'
164
+ )
165
+
166
+ const maxRetryAttempts = (policy: VercelAgentWorkflowStepRetryPolicy | undefined) => {
167
+ const configured = policy?.maxAttempts ?? noWorkflowStepRetry.maxAttempts
168
+
169
+ return Number.isFinite(configured) ? Math.max(1, Math.floor(configured)) : 1
170
+ }
171
+
172
+ const maxWorkflowTurns = (configured: number | undefined) => {
173
+ if (configured === undefined || !Number.isFinite(configured)) {
174
+ return defaultMaxWorkflowTurns
175
+ }
176
+
177
+ return Math.max(1, Math.floor(configured))
178
+ }
179
+
180
+ export async function retryWorkflowStep<A>(
181
+ runStep: () => Promise<A>,
182
+ policy?: VercelAgentWorkflowStepRetryPolicy
183
+ ): Promise<A> {
184
+ const maxAttempts = maxRetryAttempts(policy)
185
+
186
+ let attempt = 1
187
+
188
+ for (;;) {
189
+ try {
190
+ return await runStep()
191
+ } catch (error) {
192
+ if (attempt >= maxAttempts) {
193
+ throw error
194
+ }
195
+
196
+ attempt += 1
197
+ }
198
+ }
199
+ }
200
+
201
+ export async function runVercelAgentWorkflow(
202
+ config: VercelAgentWorkflowLoopConfig
203
+ ): Promise<VercelAgentWorkflowRunResult> {
204
+ const {
205
+ input,
206
+ maxTurns: configuredMaxTurns,
207
+ runModelStep,
208
+ runToolBatchStep,
209
+ closeStream,
210
+ writeError,
211
+ awaitInput,
212
+ modelStepRetry,
213
+ toolBatchStepRetry,
214
+ awaitInputRetry,
215
+ closeStreamRetry
216
+ } = config
217
+
218
+ let state: SerializableWorkflowState = {
219
+ request: input.request,
220
+ createdMessages: [],
221
+ turn: 1,
222
+ eventSequence: 0
223
+ }
224
+
225
+ const maxTurns = maxWorkflowTurns(configuredMaxTurns)
226
+
227
+ for (let step = 0; step < maxTurns; step++) {
228
+ const modelResult = await settleWorkflowStep(
229
+ retryWorkflowStep(() => runModelStep({ context: input.context, state }), modelStepRetry)
230
+ )
231
+
232
+ if (Predicate.isTagged(modelResult, 'Failure')) {
233
+ await writeErrorSafely(writeError, modelResult.error)
234
+
235
+ return VercelAgentWorkflowRunResult.ModelStepFailed({
236
+ turn: state.turn,
237
+ error: modelResult.error,
238
+ state
239
+ })
240
+ }
241
+
242
+ if (modelResult.value.done) {
243
+ const terminalState: SerializableWorkflowState = {
244
+ request: input.request,
245
+ messages: modelResult.value.messages,
246
+ createdMessages: modelResult.value.createdMessages,
247
+ usage: modelResult.value.usage,
248
+ turn: modelResult.value.turn,
249
+ eventSequence: modelResult.value.eventSequence ?? state.eventSequence
250
+ }
251
+
252
+ const closeResult = await settleWorkflowStep(retryWorkflowStep(closeStream, closeStreamRetry))
253
+
254
+ if (Predicate.isTagged(closeResult, 'Failure')) {
255
+ await writeErrorSafely(writeError, closeResult.error)
256
+
257
+ return VercelAgentWorkflowRunResult.CloseStreamFailed({
258
+ turns: modelResult.value.turn,
259
+ error: closeResult.error,
260
+ state: terminalState
261
+ })
262
+ }
263
+
264
+ return VercelAgentWorkflowRunResult.Completed({
265
+ turns: modelResult.value.turn,
266
+ state: terminalState
267
+ })
268
+ }
269
+
270
+ if (modelResult.value.toolCalls.length === 0) {
271
+ state = {
272
+ request: input.request,
273
+ messages: modelResult.value.messages,
274
+ createdMessages: modelResult.value.createdMessages,
275
+ usage: modelResult.value.usage,
276
+ turn: modelResult.value.turn + 1,
277
+ eventSequence: modelResult.value.eventSequence ?? state.eventSequence
278
+ }
279
+ continue
280
+ }
281
+
282
+ let completedToolsResult: VercelAgentWorkflowToolBatchStepResult | undefined
283
+ const toolHitlResponses: Array<unknown> = []
284
+ let cumulativeUsage = modelResult.value.usage
285
+ let toolEventSequence = modelResult.value.eventSequence ?? state.eventSequence
286
+
287
+ const currentTurnState = (
288
+ toolResult?: VercelAgentWorkflowToolBatchStepResult
289
+ ): SerializableWorkflowState => ({
290
+ request: input.request,
291
+ messages:
292
+ toolResult === undefined
293
+ ? modelResult.value.messages
294
+ : [...modelResult.value.messages, ...toolResult.messages],
295
+ createdMessages: toolResult?.createdMessages ?? modelResult.value.createdMessages,
296
+ usage: cumulativeUsage,
297
+ turn: modelResult.value.turn,
298
+ eventSequence: toolEventSequence
299
+ })
300
+
301
+ for (;;) {
302
+ const toolsResult = await settleWorkflowStep(
303
+ retryWorkflowStep(
304
+ () =>
305
+ runToolBatchStep({
306
+ context: input.context,
307
+ request: input.request,
308
+ calls: modelResult.value.toolCalls,
309
+ createdMessages: modelResult.value.createdMessages,
310
+ hitlResponses: toolHitlResponses.slice(),
311
+ usage: cumulativeUsage,
312
+ turn: modelResult.value.turn,
313
+ eventSequence: toolEventSequence
314
+ }),
315
+ toolBatchStepRetry
316
+ )
317
+ )
318
+
319
+ if (Predicate.isTagged(toolsResult, 'Failure')) {
320
+ await writeErrorSafely(writeError, toolsResult.error)
321
+
322
+ return VercelAgentWorkflowRunResult.ToolBatchStepFailed({
323
+ turn: modelResult.value.turn,
324
+ error: toolsResult.error,
325
+ state: currentTurnState()
326
+ })
327
+ }
328
+
329
+ cumulativeUsage = toolsResult.value.usage ?? cumulativeUsage
330
+ toolEventSequence = toolsResult.value.eventSequence ?? toolEventSequence
331
+
332
+ if (toolsResult.value.failure !== undefined) {
333
+ await writeErrorSafely(writeError, toolsResult.value.failure)
334
+
335
+ return VercelAgentWorkflowRunResult.ToolBatchStepFailed({
336
+ turn: modelResult.value.turn,
337
+ error: toolsResult.value.failure,
338
+ state: currentTurnState(toolsResult.value)
339
+ })
340
+ }
341
+
342
+ if (toolsResult.value.awaitingInput === undefined) {
343
+ completedToolsResult = toolsResult.value
344
+ break
345
+ }
346
+
347
+ const awaitingInput = toolsResult.value.awaitingInput
348
+ cumulativeUsage = toolsResult.value.usage ?? awaitingInput.usage ?? cumulativeUsage
349
+ toolEventSequence = awaitingInput.eventSequence ?? toolEventSequence
350
+
351
+ const hitlResponse = await settleWorkflowStep(
352
+ retryWorkflowStep(() => {
353
+ if (awaitInput === undefined) {
354
+ return Promise.reject(missingAwaitInputHandlerError())
355
+ }
356
+
357
+ return awaitInput(awaitingInput)
358
+ }, awaitInputRetry)
359
+ )
360
+
361
+ if (Predicate.isTagged(hitlResponse, 'Failure')) {
362
+ await writeErrorSafely(writeError, hitlResponse.error)
363
+
364
+ return VercelAgentWorkflowRunResult.AwaitInputFailed({
365
+ turn: modelResult.value.turn,
366
+ error: hitlResponse.error,
367
+ awaitingInput,
368
+ state: currentTurnState(toolsResult.value)
369
+ })
370
+ }
371
+
372
+ toolHitlResponses.push(hitlResponse.value)
373
+ }
374
+
375
+ if (completedToolsResult === undefined) {
376
+ const error = new Error('Vercel agent workflow tool batch did not complete')
377
+ await writeErrorSafely(writeError, error)
378
+
379
+ return VercelAgentWorkflowRunResult.ToolBatchStepFailed({
380
+ turn: modelResult.value.turn,
381
+ error,
382
+ state
383
+ })
384
+ }
385
+
386
+ state = {
387
+ request: input.request,
388
+ messages: [...modelResult.value.messages, ...completedToolsResult.messages],
389
+ createdMessages: completedToolsResult.createdMessages,
390
+ usage: completedToolsResult.usage ?? cumulativeUsage,
391
+ turn: modelResult.value.turn + 1,
392
+ eventSequence: completedToolsResult.eventSequence ?? toolEventSequence
393
+ }
394
+ }
395
+
396
+ const error = workflowMaxTurnsError(maxTurns)
397
+ await writeErrorSafely(writeError, error)
398
+
399
+ return VercelAgentWorkflowRunResult.MaxTurnsExceeded({
400
+ maxTurns,
401
+ error,
402
+ state
403
+ })
404
+ }
@@ -0,0 +1,42 @@
1
+ export {
2
+ defaultMaxWorkflowTurns,
3
+ noWorkflowStepRetry,
4
+ retryWorkflowStep,
5
+ runVercelAgentWorkflow,
6
+ settleWorkflowStep,
7
+ VercelAgentWorkflowRunResult,
8
+ WorkflowStepResult
9
+ } from './workflow-loop.ts'
10
+
11
+ export {
12
+ commitThenWriteTerminalEvent,
13
+ durableAgentEventId,
14
+ makeDurableAgentEventSequencerState,
15
+ sequenceDurableAgentEvent,
16
+ writeDurableAgentEvent
17
+ } from './workflow-events.ts'
18
+
19
+ export type {
20
+ SerializableWorkflowState,
21
+ VercelAgentWorkflowAwaitingInput,
22
+ VercelAgentWorkflowInput,
23
+ VercelAgentWorkflowLoopConfig,
24
+ VercelAgentWorkflowModelStepInput,
25
+ VercelAgentWorkflowModelStepResult,
26
+ VercelAgentWorkflowStepRetryPolicy,
27
+ VercelAgentWorkflowToolBatchStepInput,
28
+ VercelAgentWorkflowToolBatchStepResult
29
+ } from './workflow-loop.ts'
30
+
31
+ export type {
32
+ DurableAgentEvent,
33
+ DurableAgentEventIdInput,
34
+ DurableAgentEventSequencerState,
35
+ CommitThenWriteTerminalEventInput,
36
+ CommitThenWriteTerminalEventResult,
37
+ SequenceDurableAgentEventInput,
38
+ SequencedDurableAgentEvent,
39
+ WriteDurableAgentEventInput
40
+ } from './workflow-events.ts'
41
+
42
+ export { awaitWorkflowChild, orchestrateWorkflowToolBatch } from './workflow-children.ts'