@voltro/plugin-ai-flows 0.70.0 → 0.71.0

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.
package/dist/web.d.ts CHANGED
@@ -109,6 +109,31 @@ export declare const FlowMode: Schema.Literal<["deterministic", "agentic"]>;
109
109
 
110
110
  export declare type FlowMode = typeof FlowMode.Type;
111
111
 
112
+ /** Bind the answer to the review actually displayed, not the latest waiting step. */
113
+ export declare const FlowReviewInput: Schema.Struct<{
114
+ runId: typeof Schema.NonEmptyString;
115
+ stepIndex: Schema.filter<typeof Schema.Int>;
116
+ response: Schema.Struct<{
117
+ decision: Schema.optional<Schema.Literal<["approve", "reject"]>>;
118
+ value: Schema.optional<typeof Schema.String>;
119
+ text: Schema.optional<typeof Schema.String>;
120
+ respondedAt: Schema.optional<typeof Schema.String>;
121
+ }>;
122
+ }>;
123
+
124
+ export declare type FlowReviewInput = typeof FlowReviewInput.Type;
125
+
126
+ /** Delivery accepted; consumption and the run's eventual outcome remain reactive state. */
127
+ export declare const FlowReviewReceipt: Schema.Struct<{
128
+ runId: typeof Schema.NonEmptyString;
129
+ stepIndex: Schema.filter<typeof Schema.Int>;
130
+ executionId: typeof Schema.NonEmptyString;
131
+ eventId: typeof Schema.NonEmptyString;
132
+ status: Schema.Literal<["accepted"]>;
133
+ }>;
134
+
135
+ export declare type FlowReviewReceipt = typeof FlowReviewReceipt.Type;
136
+
112
137
  /** The rpc tags the hooks call. Defaults match the convention the docs wire up
113
138
  * (`api/flows/aiFlows.<verb>.{action,query}.server.ts`). */
114
139
  export declare interface FlowRpcTags {
@@ -133,6 +158,8 @@ export declare interface FlowRunState {
133
158
  readonly awaitingReview: boolean;
134
159
  /** The review the run is parked on (prompt + mode + options), if any. */
135
160
  readonly review: RunReview | undefined;
161
+ /** Identity of the displayed waiting review; pass it with every answer. */
162
+ readonly reviewStepIndex: number | undefined;
136
163
  /** Index of the step being executed / reviewed. */
137
164
  readonly currentStep: number;
138
165
  /** `true` once the run can no longer change. */
@@ -157,6 +184,26 @@ export declare interface FlowRunView {
157
184
  readonly completedAt?: string | null;
158
185
  }
159
186
 
187
+ /** Submission evidence, separate from the flow run's execution status. */
188
+ declare const FlowStartReceipt: Schema.Struct<{
189
+ runId: typeof Schema.NonEmptyString;
190
+ requestId: typeof Schema.NonEmptyString;
191
+ admission: Schema.Struct<{
192
+ id: typeof Schema.String;
193
+ workflowName: typeof Schema.String;
194
+ executionId: Schema.NullOr<typeof Schema.String>;
195
+ status: Schema.Literal<["running", "succeeded", "queued", "dropped", "skipped", "replayed"]>;
196
+ deferral: Schema.optional<Schema.Struct<{
197
+ mode: typeof Schema.String;
198
+ dueAt: Schema.NullOr<typeof Schema.Number>;
199
+ retryAfterMs: Schema.NullOr<typeof Schema.Number>;
200
+ intentId: Schema.NullOr<typeof Schema.String>;
201
+ }>>;
202
+ }>;
203
+ }>;
204
+
205
+ declare type FlowStartReceipt = typeof FlowStartReceipt.Type;
206
+
160
207
  /** Flow-definition lifecycle. */
161
208
  export declare const FlowStatus: Schema.Literal<["draft", "active", "archived"]>;
162
209
 
@@ -187,11 +234,11 @@ export declare const FlowStep: Schema.Struct<{
187
234
  }>, Schema.Struct<{
188
235
  from: Schema.Literal<["step"]>;
189
236
  ref: typeof Schema.String;
237
+ artifact: Schema.optional<Schema.filter<typeof Schema.Int>>;
190
238
  }>]>>>;
191
- /** Allowed sub-agent id/name. The framework resolves a real id; any
192
- * legacy-numeric bridge stays in the consumer app's mapping. */
239
+ /** Allowed sub-agent id/name, resolved and authorized by the host. */
193
240
  agentRef: Schema.optional<typeof Schema.String>;
194
- /** JSON Schema of the desired object (adapted to an Effect Schema at run). */
241
+ /** JSON Schema of the desired object, preserved and validated at run. */
195
242
  schema: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
196
243
  reviewMode: Schema.optional<Schema.Literal<["approve", "choice", "text"]>>;
197
244
  options: Schema.optional<Schema.Array$<Schema.Struct<{
@@ -266,7 +313,7 @@ export declare interface FlowStep {
266
313
  readonly timeoutMs?: number | undefined;
267
314
  }
268
315
 
269
- /** The HITL answer, written by `respond`. */
316
+ /** The HITL answer; the engine projects it after consuming the durable signal. */
270
317
  export declare const HumanResponse: Schema.Struct<{
271
318
  decision: Schema.optional<Schema.Literal<["approve", "reject"]>>;
272
319
  value: Schema.optional<typeof Schema.String>;
@@ -293,11 +340,19 @@ export declare interface LaunchFlowInput {
293
340
  readonly source?: 'manual' | 'cron';
294
341
  }
295
342
 
296
- export declare interface LaunchFlowResult {
297
- readonly runId: string;
298
- readonly requestId: string;
299
- readonly status: RunStatus;
300
- }
343
+ export declare type LaunchFlowResult = FlowStartReceipt;
344
+
345
+ /** One persisted media artifact. Storage identity is not a provider request ID.
346
+ * Exactly one artifact per result has role `primary`; other roles are host-defined. */
347
+ declare const MediaArtifact: Schema.Struct<{
348
+ url: typeof Schema.NonEmptyString;
349
+ mediaType: typeof Schema.NonEmptyString;
350
+ role: typeof Schema.NonEmptyString;
351
+ storageRefId: Schema.optional<typeof Schema.NonEmptyString>;
352
+ providerMetadata: Schema.optional<typeof Schema.Unknown>;
353
+ }>;
354
+
355
+ declare type MediaArtifact = typeof MediaArtifact.Type;
301
356
 
302
357
  declare const MediaInputs: Schema.Record$<typeof Schema.String, Schema.Union<[Schema.Struct<{
303
358
  from: Schema.Literal<["upload"]>;
@@ -305,6 +360,7 @@ declare const MediaInputs: Schema.Record$<typeof Schema.String, Schema.Union<[Sc
305
360
  }>, Schema.Struct<{
306
361
  from: Schema.Literal<["step"]>;
307
362
  ref: typeof Schema.String;
363
+ artifact: Schema.optional<Schema.filter<typeof Schema.Int>>;
308
364
  }>]>>;
309
365
 
310
366
  declare type MediaInputs = typeof MediaInputs.Type;
@@ -364,6 +420,14 @@ export declare const RunStep: Schema.Struct<{
364
420
  requestId: Schema.optional<typeof Schema.String>;
365
421
  /** Hosted media artifact URL (image/video/audio), via storage. */
366
422
  url: Schema.optional<typeof Schema.String>;
423
+ /** All media variants, including roles and storage references; url projects the primary artifact. */
424
+ artifacts: Schema.optional<Schema.filter<Schema.Array$<Schema.Struct<{
425
+ url: typeof Schema.NonEmptyString;
426
+ mediaType: typeof Schema.NonEmptyString;
427
+ role: typeof Schema.NonEmptyString;
428
+ storageRefId: Schema.optional<typeof Schema.NonEmptyString>;
429
+ providerMetadata: Schema.optional<typeof Schema.Unknown>;
430
+ }>>>>;
367
431
  /** Inline text output (rendered as markdown). */
368
432
  output: Schema.optional<Schema.Struct<{
369
433
  text: typeof Schema.String;
@@ -396,6 +460,7 @@ export declare interface RunStep {
396
460
  readonly costMicroUsd?: number | undefined;
397
461
  readonly requestId?: string | undefined;
398
462
  readonly url?: string | undefined;
463
+ readonly artifacts?: ReadonlyArray<MediaArtifact> | undefined;
399
464
  readonly output?: {
400
465
  readonly text: string;
401
466
  } | undefined;
@@ -453,27 +518,42 @@ export declare const useFlowReview: (runId: string | undefined, options?: FlowHo
453
518
  }[];
454
519
  /** `true` when there is a review this caller can answer right now. */
455
520
  canRespond: boolean;
456
- respond: (runId: string, response: HumanResponse) => Promise<{
457
- runId: string;
458
- stepIndex?: number;
521
+ respond: (runId: string, stepIndex: number, response: HumanResponse) => Promise<{
522
+ readonly status: "accepted";
523
+ readonly executionId: string;
524
+ readonly runId: string;
525
+ readonly eventId: string;
526
+ readonly stepIndex: number;
459
527
  }>;
460
- approve: (runId: string, text?: string) => Promise<{
461
- runId: string;
462
- stepIndex?: number;
528
+ approve: (runId: string, stepIndex: number, text?: string) => Promise<{
529
+ readonly status: "accepted";
530
+ readonly executionId: string;
531
+ readonly runId: string;
532
+ readonly eventId: string;
533
+ readonly stepIndex: number;
463
534
  }>;
464
- reject: (runId: string, text?: string) => Promise<{
465
- runId: string;
466
- stepIndex?: number;
535
+ reject: (runId: string, stepIndex: number, text?: string) => Promise<{
536
+ readonly status: "accepted";
537
+ readonly executionId: string;
538
+ readonly runId: string;
539
+ readonly eventId: string;
540
+ readonly stepIndex: number;
467
541
  }>;
468
542
  /** Pick one of a `choice` review's options. */
469
- choose: (runId: string, value: string) => Promise<{
470
- runId: string;
471
- stepIndex?: number;
543
+ choose: (runId: string, stepIndex: number, value: string) => Promise<{
544
+ readonly status: "accepted";
545
+ readonly executionId: string;
546
+ readonly runId: string;
547
+ readonly eventId: string;
548
+ readonly stepIndex: number;
472
549
  }>;
473
550
  /** Answer a `text` review. */
474
- submitText: (runId: string, text: string) => Promise<{
475
- runId: string;
476
- stepIndex?: number;
551
+ submitText: (runId: string, stepIndex: number, text: string) => Promise<{
552
+ readonly status: "accepted";
553
+ readonly executionId: string;
554
+ readonly runId: string;
555
+ readonly eventId: string;
556
+ readonly stepIndex: number;
477
557
  }>;
478
558
  pending: boolean;
479
559
  error: unknown;
@@ -482,6 +562,7 @@ export declare const useFlowReview: (runId: string | undefined, options?: FlowHo
482
562
  status: RunStatus | undefined;
483
563
  awaitingReview: boolean;
484
564
  review: RunReview | undefined;
565
+ reviewStepIndex: number | undefined;
485
566
  currentStep: number;
486
567
  done: boolean;
487
568
  loading: boolean;
@@ -505,52 +586,111 @@ export declare const useFlows: <T = Record<string, unknown>>(filter?: Readonly<R
505
586
 
506
587
  /** Start a run. Returns the `runId` to hand `useFlowRun`. */
507
588
  export declare const useLaunchFlow: (options?: FlowHookOptions) => {
508
- launch: (input: LaunchFlowInput) => Promise<LaunchFlowResult>;
589
+ launch: (input: LaunchFlowInput) => Promise<{
590
+ readonly runId: string;
591
+ readonly requestId: string;
592
+ readonly admission: {
593
+ readonly status: "dropped" | "skipped" | "running" | "succeeded" | "queued" | "replayed";
594
+ readonly id: string;
595
+ readonly executionId: string | null;
596
+ readonly workflowName: string;
597
+ readonly deferral?: {
598
+ readonly mode: string;
599
+ readonly retryAfterMs: number | null;
600
+ readonly dueAt: number | null;
601
+ readonly intentId: string | null;
602
+ } | undefined;
603
+ };
604
+ }>;
509
605
  pending: boolean;
510
606
  error: unknown;
511
- lastRun: LaunchFlowResult | undefined;
607
+ lastRun: {
608
+ readonly runId: string;
609
+ readonly requestId: string;
610
+ readonly admission: {
611
+ readonly status: "dropped" | "skipped" | "running" | "succeeded" | "queued" | "replayed";
612
+ readonly id: string;
613
+ readonly executionId: string | null;
614
+ readonly workflowName: string;
615
+ readonly deferral?: {
616
+ readonly mode: string;
617
+ readonly retryAfterMs: number | null;
618
+ readonly dueAt: number | null;
619
+ readonly intentId: string | null;
620
+ } | undefined;
621
+ };
622
+ } | undefined;
512
623
  };
513
624
 
514
625
  /**
515
- * Answer the review a run is parked on. The server resolves WHICH human step the
516
- * answer belongs to from the run's live timeline, so the UI never has to track a
517
- * step index — and a flow with several reviews gets one answer per review.
626
+ * Answer the displayed review. Carry its step index so a delayed click cannot
627
+ * answer a later review of the same run. The server verifies it still waits.
518
628
  *
519
629
  * ```tsx
520
630
  * const { approve, reject, choose, submitText } = useRespondToFlow()
521
- * <button onClick={() => approve(runId)}>Approve</button>
631
+ * <button onClick={() => approve(runId, reviewStepIndex)}>Approve</button>
522
632
  * ```
523
633
  */
524
634
  export declare const useRespondToFlow: (options?: FlowHookOptions) => {
525
- respond: (runId: string, response: HumanResponse) => Promise<{
526
- runId: string;
527
- stepIndex?: number;
635
+ respond: (runId: string, stepIndex: number, response: HumanResponse) => Promise<{
636
+ readonly status: "accepted";
637
+ readonly executionId: string;
638
+ readonly runId: string;
639
+ readonly eventId: string;
640
+ readonly stepIndex: number;
528
641
  }>;
529
- approve: (runId: string, text?: string) => Promise<{
530
- runId: string;
531
- stepIndex?: number;
642
+ approve: (runId: string, stepIndex: number, text?: string) => Promise<{
643
+ readonly status: "accepted";
644
+ readonly executionId: string;
645
+ readonly runId: string;
646
+ readonly eventId: string;
647
+ readonly stepIndex: number;
532
648
  }>;
533
- reject: (runId: string, text?: string) => Promise<{
534
- runId: string;
535
- stepIndex?: number;
649
+ reject: (runId: string, stepIndex: number, text?: string) => Promise<{
650
+ readonly status: "accepted";
651
+ readonly executionId: string;
652
+ readonly runId: string;
653
+ readonly eventId: string;
654
+ readonly stepIndex: number;
536
655
  }>;
537
656
  /** Pick one of a `choice` review's options. */
538
- choose: (runId: string, value: string) => Promise<{
539
- runId: string;
540
- stepIndex?: number;
657
+ choose: (runId: string, stepIndex: number, value: string) => Promise<{
658
+ readonly status: "accepted";
659
+ readonly executionId: string;
660
+ readonly runId: string;
661
+ readonly eventId: string;
662
+ readonly stepIndex: number;
541
663
  }>;
542
664
  /** Answer a `text` review. */
543
- submitText: (runId: string, text: string) => Promise<{
544
- runId: string;
545
- stepIndex?: number;
665
+ submitText: (runId: string, stepIndex: number, text: string) => Promise<{
666
+ readonly status: "accepted";
667
+ readonly executionId: string;
668
+ readonly runId: string;
669
+ readonly eventId: string;
670
+ readonly stepIndex: number;
546
671
  }>;
547
672
  pending: boolean;
548
673
  error: unknown;
549
674
  };
550
675
 
551
- /** Re-run a run from its first unfinished step (same requestId → journal replay). */
676
+ /** Resubmit the stored request. Inspect admission before claiming a new start. */
552
677
  export declare const useRetryFlow: (options?: FlowHookOptions) => {
553
- retry: (runId: string) => Promise<LaunchFlowResult>;
678
+ retry: (runId: string) => Promise<{
679
+ readonly runId: string;
680
+ readonly requestId: string;
681
+ readonly admission: {
682
+ readonly status: "dropped" | "skipped" | "running" | "succeeded" | "queued" | "replayed";
683
+ readonly id: string;
684
+ readonly executionId: string | null;
685
+ readonly workflowName: string;
686
+ readonly deferral?: {
687
+ readonly mode: string;
688
+ readonly retryAfterMs: number | null;
689
+ readonly dueAt: number | null;
690
+ readonly intentId: string | null;
691
+ } | undefined;
692
+ };
693
+ }>;
554
694
  pending: boolean;
555
695
  error: unknown;
556
696
  };
package/dist/web.js CHANGED
@@ -24,6 +24,7 @@ var i = {
24
24
  status: c?.status,
25
25
  awaitingReview: c?.status === "waiting",
26
26
  review: u?.review,
27
+ reviewStepIndex: u?.id,
27
28
  currentStep: c?.currentStep ?? 0,
28
29
  done: c?.status !== void 0 && s.includes(c.status),
29
30
  loading: c === void 0
@@ -57,27 +58,28 @@ var i = {
57
58
  error: t.error
58
59
  };
59
60
  }, m = (e) => {
60
- let t = n(o(e), a(e).respond), r = (e, n) => t.run({
61
+ let t = n(o(e), a(e).respond), r = (e, n, r) => t.run({
61
62
  runId: e,
62
- response: n
63
+ stepIndex: n,
64
+ response: r
63
65
  });
64
66
  return {
65
67
  respond: r,
66
- approve: (e, t) => r(e, {
68
+ approve: (e, t, n) => r(e, t, {
67
69
  decision: "approve",
68
- ...t === void 0 ? {} : { text: t }
70
+ ...n === void 0 ? {} : { text: n }
69
71
  }),
70
- reject: (e, t) => r(e, {
72
+ reject: (e, t, n) => r(e, t, {
71
73
  decision: "reject",
72
- ...t === void 0 ? {} : { text: t }
74
+ ...n === void 0 ? {} : { text: n }
73
75
  }),
74
- choose: (e, t) => r(e, {
76
+ choose: (e, t, n) => r(e, t, {
75
77
  decision: "approve",
76
- value: t
78
+ value: n
77
79
  }),
78
- submitText: (e, t) => r(e, {
80
+ submitText: (e, t, n) => r(e, t, {
79
81
  decision: "approve",
80
- text: t
82
+ text: n
81
83
  }),
82
84
  pending: t.pending,
83
85
  error: t.error
@@ -90,7 +92,7 @@ var i = {
90
92
  prompt: n.review?.prompt,
91
93
  mode: n.review?.mode,
92
94
  options: i,
93
- canRespond: n.awaitingReview && e !== void 0
95
+ canRespond: n.awaitingReview && n.reviewStepIndex !== void 0 && e !== void 0
94
96
  };
95
97
  };
96
98
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/plugin-ai-flows",
3
- "version": "0.70.0",
3
+ "version": "0.71.0",
4
4
  "description": "AI Flows — durable multi-step AI pipelines (deterministic + agentic) with human-in-the-loop, chaining, and cadence. Author flows in code (defineFlow) or as data (visual editor rows); one engine runs both on @voltro/workflow durability, @voltro/ai generation, storage artifacts, and notifications.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -58,16 +58,16 @@
58
58
  "node": ">=24.0.0"
59
59
  },
60
60
  "dependencies": {
61
- "@voltro/ai": "0.70.0",
62
- "@voltro/client": "0.70.0",
63
- "@voltro/database": "0.70.0",
64
- "@voltro/env": "0.70.0",
65
- "@voltro/plugin-audit": "0.70.0",
66
- "@voltro/plugin-multitenancy": "0.70.0",
67
- "@voltro/plugin-soft-delete": "0.70.0",
68
- "@voltro/protocol": "0.70.0",
69
- "@voltro/runtime": "0.70.0",
70
- "@voltro/workflow": "0.70.0"
61
+ "@voltro/ai": "0.71.0",
62
+ "@voltro/client": "0.71.0",
63
+ "@voltro/database": "0.71.0",
64
+ "@voltro/env": "0.71.0",
65
+ "@voltro/plugin-audit": "0.71.0",
66
+ "@voltro/plugin-multitenancy": "0.71.0",
67
+ "@voltro/plugin-soft-delete": "0.71.0",
68
+ "@voltro/protocol": "0.71.0",
69
+ "@voltro/runtime": "0.71.0",
70
+ "@voltro/workflow": "0.71.0"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "effect": "^3.22.1"