@@ -32,7 +32,7 @@ function flowAgent<TInput>(
3232| ` logger ` | ` Resolver<TInput, Logger> ` | No | default | Pino-compatible logger |
3333| ` onStart ` | ` (event: { input: TInput }) => void \| Promise<void> ` | No | — | Fires when flow starts |
3434| ` onError ` | ` (event: { input: TInput; error: Error }) => void \| Promise<void> ` | No | — | Fires on error |
35- | ` onStepStart ` | ` (event: { step: StepInfo } ) => void \| Promise<void> ` | No | — | Fires when a ` $ ` step starts |
35+ | ` onStepStart ` | ` (event: StepStartEvent ) => void \| Promise<void> ` | No | — | Fires when a ` $ ` step starts |
3636| ` onStepFinish ` | ` (event: StepFinishEvent) => void \| Promise<void> ` | No | — | Fires when a ` $ ` step finishes |
3737
3838### With output (` FlowAgentConfigWithOutput ` )
@@ -98,16 +98,16 @@ interface FlowAgent<TInput, TOutput> {
9898
9999The ` $ ` object provides tracked operations. Every call appears in the execution trace. ` $ ` is passed into nested callbacks so operations can be composed.
100100
101- | Method | Signature | Returns | Description |
102- | ---------- | -------------------------------------------------------------------------- | ---------------------------- | ------------------------------------------ |
103- | ` $.step ` | ` (config: StepConfig<T>) => Promise<StepResult <T>> ` | ` StepResult <T>` | Single unit of work |
104- | ` $.agent ` | ` (config: AgentStepConfig<TInput>) => Promise<StepResult<GenerateResult>> ` | ` StepResult<GenerateResult> ` | Agent call as tracked step |
105- | ` $.map ` | ` (config: MapConfig<T, R>) => Promise<StepResult <R[]>> ` | ` StepResult <R[]>` | Parallel map with optional concurrency |
106- | ` $.each ` | ` (config: EachConfig<T>) => Promise<StepResult <void>> ` | ` StepResult <void>` | Sequential side effects |
107- | ` $.reduce ` | ` (config: ReduceConfig<T, R>) => Promise<StepResult <R>> ` | ` StepResult <R>` | Sequential accumulation |
108- | ` $.while ` | ` (config: WhileConfig<T>) => Promise<StepResult <T \| undefined>> ` | ` StepResult <T \| undefined>` | Conditional loop |
109- | ` $.all ` | ` (config: AllConfig) => Promise<StepResult <unknown[]>> ` | ` StepResult <unknown[]>` | Concurrent heterogeneous ops (Promise.all) |
110- | ` $.race ` | ` (config: RaceConfig) => Promise<StepResult <unknown>> ` | ` StepResult <unknown>` | First-to-finish wins (Promise.race) |
101+ | Method | Signature | Returns | Description |
102+ | ---------- | --------------------------------------------------------------------- | -------------------------------- | ------------------------------------------ |
103+ | ` $.step ` | ` (config: StepConfig<T>) => Promise<FlowStepResult <T>> ` | ` FlowStepResult <T>` | Single unit of work |
104+ | ` $.agent ` | ` (config: AgentStepConfig<TInput>) => Promise<FlowAgentStepResult> ` | ` FlowAgentStepResult ` | Agent call as tracked step |
105+ | ` $.map ` | ` (config: MapConfig<T, R>) => Promise<FlowStepResult <R[]>> ` | ` FlowStepResult <R[]>` | Parallel map with optional concurrency |
106+ | ` $.each ` | ` (config: EachConfig<T>) => Promise<FlowStepResult <void>> ` | ` FlowStepResult <void>` | Sequential side effects |
107+ | ` $.reduce ` | ` (config: ReduceConfig<T, R>) => Promise<FlowStepResult <R>> ` | ` FlowStepResult <R>` | Sequential accumulation |
108+ | ` $.while ` | ` (config: WhileConfig<T>) => Promise<FlowStepResult <T \| undefined>> ` | ` FlowStepResult <T \| undefined>` | Conditional loop |
109+ | ` $.all ` | ` (config: AllConfig) => Promise<FlowStepResult <unknown[]>> ` | ` FlowStepResult <unknown[]>` | Concurrent heterogeneous ops (Promise.all) |
110+ | ` $.race ` | ` (config: RaceConfig) => Promise<FlowStepResult <unknown>> ` | ` FlowStepResult <unknown>` | First-to-finish wins (Promise.race) |
111111
112112### StepConfig
113113
@@ -220,12 +220,26 @@ interface RaceConfig {
220220}
221221```
222222
223- ## StepResult
223+ ## FlowStepResult
224224
225225``` typescript
226- type StepResult <T > =
227- | { ok: true ; value: T ; step: StepInfo ; duration: number }
228- | { ok: false ; error: StepError ; step: StepInfo ; duration: number };
226+ type FlowStepResult <T > =
227+ | {
228+ ok: true ;
229+ output: T ;
230+ stepId: string ;
231+ stepOperation: OperationType ;
232+ agentChain? : AgentChainEntry [];
233+ duration: number ;
234+ }
235+ | {
236+ ok: false ;
237+ error: StepError ;
238+ stepId: string ;
239+ stepOperation: OperationType ;
240+ agentChain? : AgentChainEntry [];
241+ duration: number ;
242+ };
229243
230244interface StepError extends ResultError {
231245 stepId: string ; // the id from the failed step config
@@ -254,29 +268,36 @@ interface TraceEntry {
254268type OperationType = " step" | " agent" | " map" | " each" | " reduce" | " while" | " all" | " race" ;
255269```
256270
257- ## StepInfo
271+ ## StepStartEvent
258272
259273``` typescript
260- interface StepInfo {
261- id : string ;
262- index : number ; // auto-incrementing, starts at 0
263- type : OperationType ;
274+ interface StepStartEvent {
275+ stepId : string ; // from the $ config's `id` field
276+ stepOperation : OperationType ; // 'step' | 'agent' | 'map' | 'each' | 'reduce' | 'while' | 'all' | 'race'
277+ agentChain ? : AgentChainEntry [] ;
264278}
265279```
266280
267281## StepFinishEvent
268282
269- Emitted by ` onStepFinish ` . Agent tool-loop steps populate the left columns; flow orchestration steps populate the right.
270-
271- | Field | Type | Present on |
272- | ------------- | -------------------------------------------------------------------- | ------------------------ |
273- | ` stepId ` | ` string ` | Agent tool-loop steps |
274- | ` toolCalls ` | ` readonly { toolName: string; argsTextLength: number }[] ` | Agent tool-loop steps |
275- | ` toolResults ` | ` readonly { toolName: string; resultTextLength: number }[] ` | Agent tool-loop steps |
276- | ` usage ` | ` { inputTokens: number; outputTokens: number; totalTokens: number } ` | Agent tool-loop steps |
277- | ` step ` | ` StepInfo ` | Flow orchestration steps |
278- | ` result ` | ` unknown ` | Flow orchestration steps |
279- | ` duration ` | ` number ` | Flow orchestration steps |
283+ Emitted by ` onStepFinish ` . For agent tool-loop steps, the event is a full superset of the Vercel AI SDK's ` StepResult<ToolSet> ` — all SDK fields are passed through unchanged, plus funkai-specific additions. For flow ` $.agent() ` steps, the event carries both flow fields (` output ` , ` duration ` ) and the AI SDK fields from the last tool-loop step. Non-agent flow steps (` $.step() ` , ` $.map() ` , etc.) only have the flow-specific fields.
284+
285+ | Field | Type | Present on | Description |
286+ | --------------- | ---------------------------------------------- | ---------------------------------- | ---------------------------------------------- |
287+ | ` stepId ` | ` string ` | All steps | funkai addition: the ` $ ` config ` id ` |
288+ | ` stepOperation ` | ` OperationType ` | All steps | funkai addition: operation type |
289+ | ` agentChain ` | ` AgentChainEntry[] ` | All steps | funkai addition: agent ancestry chain |
290+ | ` stepNumber ` | ` number ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: zero-based step index |
291+ | ` text ` | ` string ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: generated text |
292+ | ` toolCalls ` | ` TypedToolCall<ToolSet>[] ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: full tool call objects with ` input ` |
293+ | ` toolResults ` | ` TypedToolResult<ToolSet>[] ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: full tool result objects with ` output ` |
294+ | ` finishReason ` | ` FinishReason ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: why the step ended |
295+ | ` usage ` | ` LanguageModelUsage ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: token usage |
296+ | ` reasoning ` | ` ReasoningPart[] ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: reasoning content |
297+ | ` sources ` | ` Source[] ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: cited sources |
298+ | ` response ` | ` LanguageModelResponseMetadata & { messages } ` | Agent tool-loop + flow ` $.agent() ` | AI SDK: response metadata |
299+ | ` output ` | ` unknown ` | Flow orchestration steps | Flow step output value |
300+ | ` duration ` | ` number ` | Flow orchestration steps | Flow step duration in ms |
280301
281302## FlowAgentOverrides
282303
@@ -306,7 +327,7 @@ function createFlowEngine<TCustomSteps extends CustomStepDefinitions>(
306327| ` onStart ` | ` (event: { input: unknown }) => void \| Promise<void> ` | Default start hook for all flow agents |
307328| ` onFinish ` | ` (event: { input: unknown; result: unknown; duration: number }) => void \| Promise<void> ` | Default finish hook |
308329| ` onError ` | ` (event: { input: unknown; error: Error }) => void \| Promise<void> ` | Default error hook |
309- | ` onStepStart ` | ` (event: { step: StepInfo } ) => void \| Promise<void> ` | Default step-start hook |
330+ | ` onStepStart ` | ` (event: StepStartEvent ) => void \| Promise<void> ` | Default step-start hook |
310331| ` onStepFinish ` | ` (event: StepFinishEvent) => void \| Promise<void> ` | Default step-finish hook |
311332
312333### CustomStepFactory
0 commit comments