flowneer 0.9.1 → 0.9.2

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.
@@ -62,7 +62,7 @@ interface RunOptions {
62
62
  /** Metadata exposed to hooks — intentionally minimal to avoid coupling. */
63
63
  interface StepMeta {
64
64
  index: number;
65
- type: "fn" | "branch" | "loop" | "batch" | "parallel" | "anchor";
65
+ type: "fn" | "branch" | "loop" | "batch" | "parallel" | "anchor" | "dag";
66
66
  label?: string;
67
67
  }
68
68
  /**
@@ -166,7 +166,35 @@ interface AnchorStep {
166
166
  /** Maximum number of times a goto may jump to this anchor per run. */
167
167
  maxVisits?: number;
168
168
  }
169
- type Step<S, P extends Record<string, unknown>> = FnStep<S, P> | BranchStep<S, P> | LoopStep<S, P> | BatchStep<S, P> | ParallelStep<S, P> | AnchorStep;
169
+ /**
170
+ * A compiled DAG step. Produced by the graph plugin's `.compile()` and
171
+ * executed by the registered "dag" step handler, which traverses nodes
172
+ * in topological order and fires per-node lifecycle hooks natively.
173
+ */
174
+ interface DagStep<S, P extends Record<string, unknown>> {
175
+ type: "dag";
176
+ nodes: Map<string, {
177
+ name: string;
178
+ fn: NodeFn<S, P>;
179
+ options?: NodeOptions<S, P>;
180
+ }>;
181
+ /** Topologically sorted node names. */
182
+ order: string[];
183
+ /** Conditional edges that point backwards (cycles). Always have a condition. */
184
+ backEdges: Array<{
185
+ from: string;
186
+ to: string;
187
+ condition: (shared: S, params: P) => boolean | Promise<boolean>;
188
+ }>;
189
+ /** Conditional edges that skip forward (not back-edges). Always have a condition. */
190
+ conditionalForward: Array<{
191
+ from: string;
192
+ to: string;
193
+ condition: (shared: S, params: P) => boolean | Promise<boolean>;
194
+ }>;
195
+ label?: string;
196
+ }
197
+ type Step<S, P extends Record<string, unknown>> = FnStep<S, P> | BranchStep<S, P> | LoopStep<S, P> | BatchStep<S, P> | ParallelStep<S, P> | AnchorStep | DagStep<S, P>;
170
198
 
171
199
  type ResolvedHooks<S, P extends Record<string, unknown>> = {
172
200
  beforeFlow: NonNullable<FlowHooks<S, P>["beforeFlow"]>[];
@@ -212,17 +240,30 @@ declare class CoreFlowBuilder<S = any, P extends Record<string, unknown> = Recor
212
240
  private _hooksList;
213
241
  private _hooksCache;
214
242
  private static _stepHandlers;
243
+ /**
244
+ * Step types registered with `{ transparent: true }` are invoked directly
245
+ * by `_execute` without wrapping in the outer beforeStep/wrapStep/afterStep
246
+ * lifecycle. Use this for step types that manage per-item lifecycle
247
+ * internally (e.g. a DAG handler that fires hooks once per graph node).
248
+ */
249
+ private static _transparentSteps;
215
250
  /**
216
251
  * Register a handler for a custom step type.
217
252
  * Called once at module load time from each step plugin.
218
253
  *
254
+ * Pass `{ transparent: true }` when the handler manages its own per-item
255
+ * lifecycle hooks internally and should not be wrapped by the outer
256
+ * beforeStep / wrapStep / afterStep guards.
257
+ *
219
258
  * @example
220
259
  * CoreFlowBuilder.registerStepType("myStep", async (step, ctx) => {
221
260
  * await doWork(ctx.shared);
222
261
  * return undefined;
223
262
  * });
224
263
  */
225
- static registerStepType(type: string, handler: StepHandler): void;
264
+ static registerStepType(type: string, handler: StepHandler, options?: {
265
+ transparent?: boolean;
266
+ }): void;
226
267
  private _hooks;
227
268
  /**
228
269
  * Register lifecycle hooks (called by plugin methods, not by consumers).
@@ -354,4 +395,4 @@ declare class FlowBuilder<S = any, P extends Record<string, unknown> = Record<st
354
395
  private _addFn;
355
396
  }
356
397
 
357
- export { type AnchorStep as A, type BatchStep as B, CoreFlowBuilder as C, FlowBuilder as F, type LoopStep as L, type NodeFn as N, type ParallelStep as P, type ResolvedHooks as R, type StepFilter as S, type Validator as V, type FlowneerPlugin as a, type NodeOptions as b, type FlowHooks as c, type StepMeta as d, type BranchStep as e, type FnStep as f, type NumberOrFn as g, type RunOptions as h, type Step as i, type StepContext as j, type StepHandler as k, type StreamEvent as l };
398
+ export { type AnchorStep as A, type BatchStep as B, CoreFlowBuilder as C, type DagStep as D, FlowBuilder as F, type LoopStep as L, type NodeFn as N, type ParallelStep as P, type ResolvedHooks as R, type StepFilter as S, type Validator as V, type FlowneerPlugin as a, type NodeOptions as b, type FlowHooks as c, type StepMeta as d, type BranchStep as e, type FnStep as f, type NumberOrFn as g, type RunOptions as h, type Step as i, type StepContext as j, type StepHandler as k, type StreamEvent as l };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { F as FlowBuilder, c as FlowHooks, a as FlowneerPlugin, N as NodeFn, b as NodeOptions, g as NumberOrFn, h as RunOptions, d as StepMeta, l as StreamEvent, V as Validator } from './FlowBuilder-CqWK42bA.js';
1
+ export { F as FlowBuilder, c as FlowHooks, a as FlowneerPlugin, N as NodeFn, b as NodeOptions, g as NumberOrFn, h as RunOptions, d as StepMeta, l as StreamEvent, V as Validator } from './FlowBuilder-G67AbbRt.js';
2
2
  export { Fragment, fragment } from './src/index.js';
3
3
  export { F as FlowError, I as InterruptError } from './errors-u-hq7p5N.js';
package/dist/index.js CHANGED
@@ -122,18 +122,30 @@ var CoreFlowBuilder = class _CoreFlowBuilder {
122
122
  // Step-type registry (static — shared across all instances)
123
123
  // -------------------------------------------------------------------------
124
124
  static _stepHandlers = /* @__PURE__ */ new Map();
125
+ /**
126
+ * Step types registered with `{ transparent: true }` are invoked directly
127
+ * by `_execute` without wrapping in the outer beforeStep/wrapStep/afterStep
128
+ * lifecycle. Use this for step types that manage per-item lifecycle
129
+ * internally (e.g. a DAG handler that fires hooks once per graph node).
130
+ */
131
+ static _transparentSteps = /* @__PURE__ */ new Set();
125
132
  /**
126
133
  * Register a handler for a custom step type.
127
134
  * Called once at module load time from each step plugin.
128
135
  *
136
+ * Pass `{ transparent: true }` when the handler manages its own per-item
137
+ * lifecycle hooks internally and should not be wrapped by the outer
138
+ * beforeStep / wrapStep / afterStep guards.
139
+ *
129
140
  * @example
130
141
  * CoreFlowBuilder.registerStepType("myStep", async (step, ctx) => {
131
142
  * await doWork(ctx.shared);
132
143
  * return undefined;
133
144
  * });
134
145
  */
135
- static registerStepType(type, handler) {
146
+ static registerStepType(type, handler, options) {
136
147
  _CoreFlowBuilder._stepHandlers.set(type, handler);
148
+ if (options?.transparent) _CoreFlowBuilder._transparentSteps.add(type);
137
149
  }
138
150
  // -------------------------------------------------------------------------
139
151
  // Hooks & plugins
@@ -263,6 +275,25 @@ var CoreFlowBuilder = class _CoreFlowBuilder {
263
275
  signal?.throwIfAborted();
264
276
  const step = this.steps[i];
265
277
  if (step.type === "anchor") continue;
278
+ if (_CoreFlowBuilder._transparentSteps.has(step.type)) {
279
+ const handler = _CoreFlowBuilder._stepHandlers.get(step.type);
280
+ if (handler) {
281
+ const meta2 = {
282
+ index: i,
283
+ type: step.type,
284
+ label: step.label
285
+ };
286
+ await handler(step, {
287
+ shared,
288
+ params,
289
+ signal,
290
+ hooks,
291
+ meta: meta2,
292
+ builder: this
293
+ });
294
+ }
295
+ continue;
296
+ }
266
297
  const stepLabel = step.label;
267
298
  const meta = {
268
299
  index: i,
@@ -1,4 +1,4 @@
1
- import { F as FlowBuilder, a as FlowneerPlugin } from '../../FlowBuilder-CqWK42bA.js';
1
+ import { F as FlowBuilder, a as FlowneerPlugin } from '../../FlowBuilder-G67AbbRt.js';
2
2
 
3
3
  interface HumanNodeOptions<S = any, P extends Record<string, unknown> = Record<string, unknown>> {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { a as FlowneerPlugin, N as NodeFn, b as NodeOptions, S as StepFilter } from '../../FlowBuilder-CqWK42bA.js';
1
+ import { a as FlowneerPlugin, N as NodeFn, b as NodeOptions, S as StepFilter } from '../../FlowBuilder-G67AbbRt.js';
2
2
 
3
3
  declare module "../../Flowneer" {
4
4
  interface FlowBuilder<S, P> {
@@ -1,4 +1,4 @@
1
- import { F as FlowBuilder } from '../../FlowBuilder-CqWK42bA.js';
1
+ import { F as FlowBuilder } from '../../FlowBuilder-G67AbbRt.js';
2
2
 
3
3
  /** Case-insensitive exact match. Returns 1.0 or 0.0. */
4
4
  declare function exactMatch(predicted: string, expected: string): number;
@@ -1,4 +1,4 @@
1
- import { a as FlowneerPlugin, N as NodeFn, b as NodeOptions } from '../../FlowBuilder-CqWK42bA.js';
1
+ import { a as FlowneerPlugin, N as NodeFn, b as NodeOptions } from '../../FlowBuilder-G67AbbRt.js';
2
2
 
3
3
  /** A single node entry in the exported graph. */
4
4
  interface GraphNodeExport {