@voltro/plugin-ai-flows 0.33.0 → 0.35.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/CHANGELOG.md +1968 -0
- package/dist/index.d.ts +415 -58
- package/dist/index.js +523 -291
- package/dist/ir-BOv5uwYI.js +142 -0
- package/dist/ir.d.ts +142 -7
- package/dist/ir.js +2 -102
- package/dist/web.d.ts +306 -7
- package/dist/web.js +96 -1
- package/dist/workflow.d.ts +42 -3
- package/dist/workflow.js +4 -3
- package/package.json +11 -10
package/dist/web.d.ts
CHANGED
|
@@ -9,7 +9,17 @@ export declare const BriefField: Schema.Struct<{
|
|
|
9
9
|
placeholder: Schema.optional<typeof Schema.String>;
|
|
10
10
|
}>;
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/** An INTERFACE for the same reason as {@link FlowStep} — it is reached from an
|
|
13
|
+
* exported table (`aiFlows.inputSchema`), so an alias to a mapped type gets
|
|
14
|
+
* expanded structurally into the api report, in an order that is not stable
|
|
15
|
+
* across build scopes. The `Equals` pin below fails to compile on any drift. */
|
|
16
|
+
export declare interface BriefField {
|
|
17
|
+
readonly key: string;
|
|
18
|
+
readonly label: string;
|
|
19
|
+
readonly type: 'text' | 'textarea' | 'number' | 'boolean';
|
|
20
|
+
readonly required?: boolean | undefined;
|
|
21
|
+
readonly placeholder?: string | undefined;
|
|
22
|
+
}
|
|
13
23
|
|
|
14
24
|
/**
|
|
15
25
|
* Does `cadence` fire at wall-clock `now`? True only on a 15-min slot matching
|
|
@@ -18,6 +28,13 @@ export declare type BriefField = typeof BriefField.Type;
|
|
|
18
28
|
*/
|
|
19
29
|
export declare const cadenceMatches: (cadence: FlowCadence, now: Date) => boolean;
|
|
20
30
|
|
|
31
|
+
/** The comparison a `when:` performs. */
|
|
32
|
+
declare const ConditionOp: Schema.Literal<["truthy", "falsy", "eq", "neq", "contains"]>;
|
|
33
|
+
|
|
34
|
+
declare type ConditionOp = typeof ConditionOp.Type;
|
|
35
|
+
|
|
36
|
+
export declare const DEFAULT_FLOW_RPC_TAGS: FlowRpcTags;
|
|
37
|
+
|
|
21
38
|
/** Schedule spec — richer than a single cron expr (weekly interval + anchor,
|
|
22
39
|
* monthly weekOfMonth), evaluated by the shared `cadenceMatches` predicate. */
|
|
23
40
|
export declare const FlowCadence: Schema.Struct<{
|
|
@@ -36,7 +53,25 @@ export declare const FlowCadence: Schema.Struct<{
|
|
|
36
53
|
defaultInput: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
|
|
37
54
|
}>;
|
|
38
55
|
|
|
39
|
-
|
|
56
|
+
/**
|
|
57
|
+
* An INTERFACE — reached from `aiFlows.cadence`; see {@link BriefField}.
|
|
58
|
+
*
|
|
59
|
+
* This one is not hypothetical: a single-package `api:report` and a
|
|
60
|
+
* full-monorepo build emitted `hour`/`minute` in DIFFERENT positions inside the
|
|
61
|
+
* structurally-expanded alias, so the api-surface gate rejected a file nobody
|
|
62
|
+
* had touched, showing the same members moving. That is the exact failure
|
|
63
|
+
* {@link FlowStep}'s comment describes.
|
|
64
|
+
*/
|
|
65
|
+
export declare interface FlowCadence {
|
|
66
|
+
readonly frequency?: 'weekly' | 'monthly' | undefined;
|
|
67
|
+
readonly repeats: ReadonlyArray<number>;
|
|
68
|
+
readonly intervalWeeks?: number | undefined;
|
|
69
|
+
readonly anchorDate?: string | undefined;
|
|
70
|
+
readonly weekOfMonth?: 1 | 2 | 3 | 4 | 'last' | undefined;
|
|
71
|
+
readonly hour?: number | undefined;
|
|
72
|
+
readonly minute?: 0 | 15 | 30 | 45 | undefined;
|
|
73
|
+
readonly defaultInput?: Json | undefined;
|
|
74
|
+
}
|
|
40
75
|
|
|
41
76
|
/** Follow-up flow spec. On success, map source → the child's brief. */
|
|
42
77
|
export declare const FlowChain: Schema.Struct<{
|
|
@@ -49,7 +84,23 @@ export declare const FlowChain: Schema.Struct<{
|
|
|
49
84
|
requireConfirmation: Schema.optional<typeof Schema.Boolean>;
|
|
50
85
|
}>;
|
|
51
86
|
|
|
52
|
-
|
|
87
|
+
/** An INTERFACE — reached from `aiFlows.chainTo`; see {@link BriefField}. */
|
|
88
|
+
export declare interface FlowChain {
|
|
89
|
+
readonly flowRef: string;
|
|
90
|
+
readonly mappings: ReadonlyArray<{
|
|
91
|
+
readonly targetKey: string;
|
|
92
|
+
readonly sourceKey: string;
|
|
93
|
+
}>;
|
|
94
|
+
readonly requireConfirmation?: boolean | undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Per-hook wiring: which api, and which tags if the app renamed them. */
|
|
98
|
+
export declare interface FlowHookOptions {
|
|
99
|
+
/** Framework api name. Default `'app'`. */
|
|
100
|
+
readonly apiName?: string;
|
|
101
|
+
/** Override any subset of {@link DEFAULT_FLOW_RPC_TAGS}. */
|
|
102
|
+
readonly tags?: Partial<FlowRpcTags>;
|
|
103
|
+
}
|
|
53
104
|
|
|
54
105
|
/** Execution mode. Replaces the legacy `allowDeviation` boolean — a mode is not
|
|
55
106
|
* a boolean. `deterministic` runs the plan verbatim (resumable per step);
|
|
@@ -58,6 +109,54 @@ export declare const FlowMode: Schema.Literal<["deterministic", "agentic"]>;
|
|
|
58
109
|
|
|
59
110
|
export declare type FlowMode = typeof FlowMode.Type;
|
|
60
111
|
|
|
112
|
+
/** The rpc tags the hooks call. Defaults match the convention the docs wire up
|
|
113
|
+
* (`api/flows/aiFlows.<verb>.{action,query}.server.ts`). */
|
|
114
|
+
export declare interface FlowRpcTags {
|
|
115
|
+
readonly launch: string;
|
|
116
|
+
readonly retry: string;
|
|
117
|
+
readonly cancel: string;
|
|
118
|
+
readonly respond: string;
|
|
119
|
+
/** Query returning ONE run row by id. */
|
|
120
|
+
readonly run: string;
|
|
121
|
+
/** Query returning the caller's recent runs. */
|
|
122
|
+
readonly runs: string;
|
|
123
|
+
/** Query returning the flow DEFINITIONS the caller may launch. */
|
|
124
|
+
readonly flows: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** What `useFlowRun` hands a timeline component. */
|
|
128
|
+
export declare interface FlowRunState {
|
|
129
|
+
readonly run: FlowRunView | undefined;
|
|
130
|
+
readonly steps: ReadonlyArray<RunStep>;
|
|
131
|
+
readonly status: RunStatus | undefined;
|
|
132
|
+
/** `true` while the run is parked on a human step. */
|
|
133
|
+
readonly awaitingReview: boolean;
|
|
134
|
+
/** The review the run is parked on (prompt + mode + options), if any. */
|
|
135
|
+
readonly review: RunReview | undefined;
|
|
136
|
+
/** Index of the step being executed / reviewed. */
|
|
137
|
+
readonly currentStep: number;
|
|
138
|
+
/** `true` once the run can no longer change. */
|
|
139
|
+
readonly done: boolean;
|
|
140
|
+
readonly loading: boolean;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** The run row shape the hooks project — the reactive columns a timeline needs. */
|
|
144
|
+
export declare interface FlowRunView {
|
|
145
|
+
readonly id: string;
|
|
146
|
+
readonly flowRef?: string;
|
|
147
|
+
readonly flowName?: string | null;
|
|
148
|
+
readonly status?: RunStatus;
|
|
149
|
+
readonly steps?: ReadonlyArray<RunStep> | null;
|
|
150
|
+
readonly currentStep?: number;
|
|
151
|
+
readonly totalSteps?: number;
|
|
152
|
+
readonly output?: Record<string, unknown> | null;
|
|
153
|
+
readonly humanResponse?: HumanResponse | null;
|
|
154
|
+
readonly costMicroUsd?: number;
|
|
155
|
+
readonly errorMessage?: string | null;
|
|
156
|
+
readonly startedAt?: string | null;
|
|
157
|
+
readonly completedAt?: string | null;
|
|
158
|
+
}
|
|
159
|
+
|
|
61
160
|
/** Flow-definition lifecycle. */
|
|
62
161
|
export declare const FlowStatus: Schema.Literal<["draft", "active", "archived"]>;
|
|
63
162
|
|
|
@@ -99,6 +198,29 @@ export declare const FlowStep: Schema.Struct<{
|
|
|
99
198
|
value: typeof Schema.String;
|
|
100
199
|
label: typeof Schema.String;
|
|
101
200
|
}>>>;
|
|
201
|
+
/** Gate this step on a prior value. Absent → the step always runs. A step
|
|
202
|
+
* whose condition is false is SKIPPED, not failed: it produces no output, so
|
|
203
|
+
* anything referencing its `outputKey` sees an absent value. */
|
|
204
|
+
when: Schema.optional<Schema.Struct<{
|
|
205
|
+
ref: typeof Schema.String;
|
|
206
|
+
op: Schema.Literal<["truthy", "falsy", "eq", "neq", "contains"]>;
|
|
207
|
+
value: Schema.optional<typeof Schema.Unknown>;
|
|
208
|
+
}>>;
|
|
209
|
+
/**
|
|
210
|
+
* Fan-out group. CONSECUTIVE steps sharing a group name run CONCURRENTLY,
|
|
211
|
+
* each still journaled as its own durable step.
|
|
212
|
+
*
|
|
213
|
+
* Steps in one group may not reference each other's outputs — they have no
|
|
214
|
+
* order between them — and `validateFlow` refuses a flow that tries. A `human`
|
|
215
|
+
* step may not join a group either: it suspends the whole workflow, which is
|
|
216
|
+
* not a thing one branch of a fan-out can do.
|
|
217
|
+
*/
|
|
218
|
+
group: Schema.optional<typeof Schema.String>;
|
|
219
|
+
/** `human` step only — how long the run parks awaiting this review before it
|
|
220
|
+
* fails, in milliseconds. Omitted → the flow's `humanTimeoutMs`, then the
|
|
221
|
+
* engine/plugin default (see `resolveHumanReviewTimeoutMs`). `0` means WAIT
|
|
222
|
+
* FOREVER (the park is slot-free, so an unbounded wait costs no worker). */
|
|
223
|
+
timeoutMs: Schema.optional<typeof Schema.Number>;
|
|
102
224
|
}>;
|
|
103
225
|
|
|
104
226
|
/**
|
|
@@ -139,6 +261,25 @@ export declare interface FlowStep {
|
|
|
139
261
|
readonly schema?: Json | undefined;
|
|
140
262
|
readonly reviewMode?: ReviewMode | undefined;
|
|
141
263
|
readonly options?: ReadonlyArray<ReviewOption> | undefined;
|
|
264
|
+
readonly when?: StepCondition | undefined;
|
|
265
|
+
readonly group?: string | undefined;
|
|
266
|
+
readonly timeoutMs?: number | undefined;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** The HITL answer, written by `respond`. */
|
|
270
|
+
export declare const HumanResponse: Schema.Struct<{
|
|
271
|
+
decision: Schema.optional<Schema.Literal<["approve", "reject"]>>;
|
|
272
|
+
value: Schema.optional<typeof Schema.String>;
|
|
273
|
+
text: Schema.optional<typeof Schema.String>;
|
|
274
|
+
respondedAt: Schema.optional<typeof Schema.String>;
|
|
275
|
+
}>;
|
|
276
|
+
|
|
277
|
+
/** An INTERFACE — reached from `aiFlowRuns.humanResponse`; see {@link BriefField}. */
|
|
278
|
+
export declare interface HumanResponse {
|
|
279
|
+
readonly decision?: 'approve' | 'reject' | undefined;
|
|
280
|
+
readonly value?: string | undefined;
|
|
281
|
+
readonly text?: string | undefined;
|
|
282
|
+
readonly respondedAt?: string | undefined;
|
|
142
283
|
}
|
|
143
284
|
|
|
144
285
|
/** A JSON value (for `params` / `input` / a `structured` step's JSON Schema). */
|
|
@@ -146,6 +287,18 @@ declare const Json: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
|
|
|
146
287
|
|
|
147
288
|
declare type Json = typeof Json.Type;
|
|
148
289
|
|
|
290
|
+
export declare interface LaunchFlowInput {
|
|
291
|
+
readonly flowRef: string;
|
|
292
|
+
readonly input?: Record<string, unknown>;
|
|
293
|
+
readonly source?: 'manual' | 'cron';
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export declare interface LaunchFlowResult {
|
|
297
|
+
readonly runId: string;
|
|
298
|
+
readonly requestId: string;
|
|
299
|
+
readonly status: RunStatus;
|
|
300
|
+
}
|
|
301
|
+
|
|
149
302
|
declare const MediaInputs: Schema.Record$<typeof Schema.String, Schema.Union<[Schema.Struct<{
|
|
150
303
|
from: Schema.Literal<["upload"]>;
|
|
151
304
|
url: typeof Schema.String;
|
|
@@ -179,7 +332,7 @@ export declare const ReviewOption: Schema.Struct<{
|
|
|
179
332
|
export declare type ReviewOption = typeof ReviewOption.Type;
|
|
180
333
|
|
|
181
334
|
/** Human-review config projected onto a `waiting` run step. */
|
|
182
|
-
declare const RunReview: Schema.Struct<{
|
|
335
|
+
export declare const RunReview: Schema.Struct<{
|
|
183
336
|
mode: Schema.Literal<["approve", "choice", "text"]>;
|
|
184
337
|
options: Schema.optional<Schema.Array$<Schema.Struct<{
|
|
185
338
|
value: typeof Schema.String;
|
|
@@ -188,7 +341,7 @@ declare const RunReview: Schema.Struct<{
|
|
|
188
341
|
prompt: typeof Schema.String;
|
|
189
342
|
}>;
|
|
190
343
|
|
|
191
|
-
declare type RunReview = typeof RunReview.Type;
|
|
344
|
+
export declare type RunReview = typeof RunReview.Type;
|
|
192
345
|
|
|
193
346
|
/** Run status — ONE canonical set (the legacy vocabulary; the Voltro-port
|
|
194
347
|
* additions `awaiting_human`/`completed`/`rejected` are collapsed: `waiting`
|
|
@@ -202,7 +355,7 @@ export declare const RunStep: Schema.Struct<{
|
|
|
202
355
|
title: typeof Schema.String;
|
|
203
356
|
description: Schema.optional<typeof Schema.String>;
|
|
204
357
|
type: Schema.Literal<["agent", "generate", "structured", "note", "human"]>;
|
|
205
|
-
status: Schema.Literal<["pending", "running", "waiting", "succeeded", "failed"]>;
|
|
358
|
+
status: Schema.Literal<["pending", "running", "waiting", "succeeded", "failed", "skipped"]>;
|
|
206
359
|
startedAt: Schema.optional<typeof Schema.String>;
|
|
207
360
|
completedAt: Schema.optional<typeof Schema.String>;
|
|
208
361
|
/** Per-step cost in micro-USD (the app view projects to €/cents). */
|
|
@@ -216,6 +369,9 @@ export declare const RunStep: Schema.Struct<{
|
|
|
216
369
|
text: typeof Schema.String;
|
|
217
370
|
}>>;
|
|
218
371
|
errorMessage: Schema.optional<typeof Schema.String>;
|
|
372
|
+
/** Why a `skipped` step was skipped — the rendered condition, so the timeline
|
|
373
|
+
* says "{{approved}} is not set" instead of leaving a silent gap. */
|
|
374
|
+
skipReason: Schema.optional<typeof Schema.String>;
|
|
219
375
|
review: Schema.optional<Schema.Struct<{
|
|
220
376
|
mode: Schema.Literal<["approve", "choice", "text"]>;
|
|
221
377
|
options: Schema.optional<Schema.Array$<Schema.Struct<{
|
|
@@ -244,18 +400,161 @@ export declare interface RunStep {
|
|
|
244
400
|
readonly text: string;
|
|
245
401
|
} | undefined;
|
|
246
402
|
readonly errorMessage?: string | undefined;
|
|
403
|
+
readonly skipReason?: string | undefined;
|
|
247
404
|
readonly review?: RunReview | undefined;
|
|
248
405
|
}
|
|
249
406
|
|
|
250
|
-
declare const RunStepStatus: Schema.Literal<["pending", "running", "waiting", "succeeded", "failed"]>;
|
|
407
|
+
declare const RunStepStatus: Schema.Literal<["pending", "running", "waiting", "succeeded", "failed", "skipped"]>;
|
|
251
408
|
|
|
252
409
|
declare type RunStepStatus = typeof RunStepStatus.Type;
|
|
253
410
|
|
|
411
|
+
declare const StepCondition: Schema.Struct<{
|
|
412
|
+
/** A brief-field key or an EARLIER step's `outputKey`. */
|
|
413
|
+
ref: typeof Schema.String;
|
|
414
|
+
op: Schema.Literal<["truthy", "falsy", "eq", "neq", "contains"]>;
|
|
415
|
+
/** The right-hand side for `eq` / `neq` / `contains`. Ignored by the unary ops. */
|
|
416
|
+
value: Schema.optional<typeof Schema.Unknown>;
|
|
417
|
+
}>;
|
|
418
|
+
|
|
419
|
+
/** An INTERFACE, for the same api-report reason as `FlowStep` — it is reached
|
|
420
|
+
* from an exported table column, and an alias to a mapped type gets expanded
|
|
421
|
+
* structurally in an order that is not stable across build scopes. */
|
|
422
|
+
declare interface StepCondition {
|
|
423
|
+
readonly ref: string;
|
|
424
|
+
readonly op: ConditionOp;
|
|
425
|
+
readonly value?: unknown;
|
|
426
|
+
}
|
|
427
|
+
|
|
254
428
|
/** The five step types. `generate` fans out to four modalities. */
|
|
255
429
|
export declare const StepType: Schema.Literal<["agent", "generate", "structured", "note", "human"]>;
|
|
256
430
|
|
|
257
431
|
export declare type StepType = typeof StepType.Type;
|
|
258
432
|
|
|
433
|
+
/** Cooperatively cancel a run (the engine stops before its next step). */
|
|
434
|
+
export declare const useCancelFlow: (options?: FlowHookOptions) => {
|
|
435
|
+
cancel: (runId: string) => Promise<{
|
|
436
|
+
runId: string;
|
|
437
|
+
status: RunStatus;
|
|
438
|
+
}>;
|
|
439
|
+
pending: boolean;
|
|
440
|
+
error: unknown;
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* The whole review widget in one hook: the live run + the answer callbacks,
|
|
445
|
+
* with the pending review's prompt/options already unwrapped.
|
|
446
|
+
*/
|
|
447
|
+
export declare const useFlowReview: (runId: string | undefined, options?: FlowHookOptions) => {
|
|
448
|
+
prompt: string | undefined;
|
|
449
|
+
mode: "text" | "approve" | "choice" | undefined;
|
|
450
|
+
options: readonly {
|
|
451
|
+
readonly value: string;
|
|
452
|
+
readonly label: string;
|
|
453
|
+
}[];
|
|
454
|
+
/** `true` when there is a review this caller can answer right now. */
|
|
455
|
+
canRespond: boolean;
|
|
456
|
+
respond: (runId: string, response: HumanResponse) => Promise<{
|
|
457
|
+
runId: string;
|
|
458
|
+
stepIndex?: number;
|
|
459
|
+
}>;
|
|
460
|
+
approve: (runId: string, text?: string) => Promise<{
|
|
461
|
+
runId: string;
|
|
462
|
+
stepIndex?: number;
|
|
463
|
+
}>;
|
|
464
|
+
reject: (runId: string, text?: string) => Promise<{
|
|
465
|
+
runId: string;
|
|
466
|
+
stepIndex?: number;
|
|
467
|
+
}>;
|
|
468
|
+
/** Pick one of a `choice` review's options. */
|
|
469
|
+
choose: (runId: string, value: string) => Promise<{
|
|
470
|
+
runId: string;
|
|
471
|
+
stepIndex?: number;
|
|
472
|
+
}>;
|
|
473
|
+
/** Answer a `text` review. */
|
|
474
|
+
submitText: (runId: string, text: string) => Promise<{
|
|
475
|
+
runId: string;
|
|
476
|
+
stepIndex?: number;
|
|
477
|
+
}>;
|
|
478
|
+
pending: boolean;
|
|
479
|
+
error: unknown;
|
|
480
|
+
run: FlowRunView | undefined;
|
|
481
|
+
steps: ReadonlyArray<RunStep>;
|
|
482
|
+
status: RunStatus | undefined;
|
|
483
|
+
awaitingReview: boolean;
|
|
484
|
+
review: RunReview | undefined;
|
|
485
|
+
currentStep: number;
|
|
486
|
+
done: boolean;
|
|
487
|
+
loading: boolean;
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Live view of ONE flow run. The run row is reactive, so the timeline streams:
|
|
492
|
+
* every step transition the engine writes shows up without a refetch.
|
|
493
|
+
*
|
|
494
|
+
* ```tsx
|
|
495
|
+
* const { steps, awaitingReview, review } = useFlowRun(runId)
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
export declare const useFlowRun: (runId: string | undefined, options?: FlowHookOptions) => FlowRunState;
|
|
499
|
+
|
|
500
|
+
/** The caller's recent runs (whatever the app's `runs` query returns). */
|
|
501
|
+
export declare const useFlowRuns: (filter?: Readonly<Record<string, unknown>>, options?: FlowHookOptions) => ReadonlyArray<FlowRunView>;
|
|
502
|
+
|
|
503
|
+
/** The flow DEFINITIONS the caller can launch (the gallery / picker). */
|
|
504
|
+
export declare const useFlows: <T = Record<string, unknown>>(filter?: Readonly<Record<string, unknown>>, options?: FlowHookOptions) => ReadonlyArray<T>;
|
|
505
|
+
|
|
506
|
+
/** Start a run. Returns the `runId` to hand `useFlowRun`. */
|
|
507
|
+
export declare const useLaunchFlow: (options?: FlowHookOptions) => {
|
|
508
|
+
launch: (input: LaunchFlowInput) => Promise<LaunchFlowResult>;
|
|
509
|
+
pending: boolean;
|
|
510
|
+
error: unknown;
|
|
511
|
+
lastRun: LaunchFlowResult | undefined;
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
/**
|
|
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.
|
|
518
|
+
*
|
|
519
|
+
* ```tsx
|
|
520
|
+
* const { approve, reject, choose, submitText } = useRespondToFlow()
|
|
521
|
+
* <button onClick={() => approve(runId)}>Approve</button>
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
export declare const useRespondToFlow: (options?: FlowHookOptions) => {
|
|
525
|
+
respond: (runId: string, response: HumanResponse) => Promise<{
|
|
526
|
+
runId: string;
|
|
527
|
+
stepIndex?: number;
|
|
528
|
+
}>;
|
|
529
|
+
approve: (runId: string, text?: string) => Promise<{
|
|
530
|
+
runId: string;
|
|
531
|
+
stepIndex?: number;
|
|
532
|
+
}>;
|
|
533
|
+
reject: (runId: string, text?: string) => Promise<{
|
|
534
|
+
runId: string;
|
|
535
|
+
stepIndex?: number;
|
|
536
|
+
}>;
|
|
537
|
+
/** Pick one of a `choice` review's options. */
|
|
538
|
+
choose: (runId: string, value: string) => Promise<{
|
|
539
|
+
runId: string;
|
|
540
|
+
stepIndex?: number;
|
|
541
|
+
}>;
|
|
542
|
+
/** Answer a `text` review. */
|
|
543
|
+
submitText: (runId: string, text: string) => Promise<{
|
|
544
|
+
runId: string;
|
|
545
|
+
stepIndex?: number;
|
|
546
|
+
}>;
|
|
547
|
+
pending: boolean;
|
|
548
|
+
error: unknown;
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
/** Re-run a run from its first unfinished step (same requestId → journal replay). */
|
|
552
|
+
export declare const useRetryFlow: (options?: FlowHookOptions) => {
|
|
553
|
+
retry: (runId: string) => Promise<LaunchFlowResult>;
|
|
554
|
+
pending: boolean;
|
|
555
|
+
error: unknown;
|
|
556
|
+
};
|
|
557
|
+
|
|
259
558
|
/** Gallery scope. `shared` → per-subject share list; `organization` → tenant. */
|
|
260
559
|
export declare const Visibility: Schema.Literal<["private", "organization", "shared"]>;
|
|
261
560
|
|
package/dist/web.js
CHANGED
|
@@ -1,2 +1,97 @@
|
|
|
1
1
|
import { n as e, t } from "./cadence-Bt6dPelT.js";
|
|
2
|
-
|
|
2
|
+
import { useAction as n, useSubscription as r } from "@voltro/client";
|
|
3
|
+
//#region src/web.ts
|
|
4
|
+
var i = {
|
|
5
|
+
launch: "aiFlows.launch",
|
|
6
|
+
retry: "aiFlows.retry",
|
|
7
|
+
cancel: "aiFlows.cancel",
|
|
8
|
+
respond: "aiFlows.respond",
|
|
9
|
+
run: "aiFlows.run",
|
|
10
|
+
runs: "aiFlows.runs",
|
|
11
|
+
flows: "aiFlows.flows"
|
|
12
|
+
}, a = (e) => e?.tags === void 0 ? i : {
|
|
13
|
+
...i,
|
|
14
|
+
...e.tags
|
|
15
|
+
}, o = (e) => e?.apiName ?? "app", s = [
|
|
16
|
+
"succeeded",
|
|
17
|
+
"failed",
|
|
18
|
+
"cancelled"
|
|
19
|
+
], c = (e, t) => {
|
|
20
|
+
let n = r(o(t), a(t).run, { id: e ?? "" }, { skip: e === void 0 || e === "" }), i = "data" in n ? n.data : void 0, c = (Array.isArray(i) ? i[0] : i) ?? void 0, l = c?.steps ?? [], u = l.find((e) => e.status === "waiting");
|
|
21
|
+
return {
|
|
22
|
+
run: c,
|
|
23
|
+
steps: l,
|
|
24
|
+
status: c?.status,
|
|
25
|
+
awaitingReview: c?.status === "waiting",
|
|
26
|
+
review: u?.review,
|
|
27
|
+
currentStep: c?.currentStep ?? 0,
|
|
28
|
+
done: c?.status !== void 0 && s.includes(c.status),
|
|
29
|
+
loading: c === void 0
|
|
30
|
+
};
|
|
31
|
+
}, l = (e = {}, t) => {
|
|
32
|
+
let n = r(o(t), a(t).runs, e);
|
|
33
|
+
return ("data" in n ? n.data : void 0) ?? [];
|
|
34
|
+
}, u = (e = {}, t) => {
|
|
35
|
+
let n = r(o(t), a(t).flows, e);
|
|
36
|
+
return ("data" in n ? n.data : void 0) ?? [];
|
|
37
|
+
}, d = (e) => {
|
|
38
|
+
let t = n(o(e), a(e).launch);
|
|
39
|
+
return {
|
|
40
|
+
launch: (e) => t.run(e),
|
|
41
|
+
pending: t.pending,
|
|
42
|
+
error: t.error,
|
|
43
|
+
lastRun: t.lastResult
|
|
44
|
+
};
|
|
45
|
+
}, f = (e) => {
|
|
46
|
+
let t = n(o(e), a(e).retry);
|
|
47
|
+
return {
|
|
48
|
+
retry: (e) => t.run({ runId: e }),
|
|
49
|
+
pending: t.pending,
|
|
50
|
+
error: t.error
|
|
51
|
+
};
|
|
52
|
+
}, p = (e) => {
|
|
53
|
+
let t = n(o(e), a(e).cancel);
|
|
54
|
+
return {
|
|
55
|
+
cancel: (e) => t.run({ runId: e }),
|
|
56
|
+
pending: t.pending,
|
|
57
|
+
error: t.error
|
|
58
|
+
};
|
|
59
|
+
}, m = (e) => {
|
|
60
|
+
let t = n(o(e), a(e).respond), r = (e, n) => t.run({
|
|
61
|
+
runId: e,
|
|
62
|
+
response: n
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
respond: r,
|
|
66
|
+
approve: (e, t) => r(e, {
|
|
67
|
+
decision: "approve",
|
|
68
|
+
...t === void 0 ? {} : { text: t }
|
|
69
|
+
}),
|
|
70
|
+
reject: (e, t) => r(e, {
|
|
71
|
+
decision: "reject",
|
|
72
|
+
...t === void 0 ? {} : { text: t }
|
|
73
|
+
}),
|
|
74
|
+
choose: (e, t) => r(e, {
|
|
75
|
+
decision: "approve",
|
|
76
|
+
value: t
|
|
77
|
+
}),
|
|
78
|
+
submitText: (e, t) => r(e, {
|
|
79
|
+
decision: "approve",
|
|
80
|
+
text: t
|
|
81
|
+
}),
|
|
82
|
+
pending: t.pending,
|
|
83
|
+
error: t.error
|
|
84
|
+
};
|
|
85
|
+
}, h = (e, t) => {
|
|
86
|
+
let n = c(e, t), r = m(t), i = n.review?.options ?? [];
|
|
87
|
+
return {
|
|
88
|
+
...n,
|
|
89
|
+
...r,
|
|
90
|
+
prompt: n.review?.prompt,
|
|
91
|
+
mode: n.review?.mode,
|
|
92
|
+
options: i,
|
|
93
|
+
canRespond: n.awaitingReview && e !== void 0
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
//#endregion
|
|
97
|
+
export { i as DEFAULT_FLOW_RPC_TAGS, t as cadenceMatches, e as nextRuns, p as useCancelFlow, h as useFlowReview, c as useFlowRun, l as useFlowRuns, u as useFlows, d as useLaunchFlow, m as useRespondToFlow, f as useRetryFlow };
|
package/dist/workflow.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare interface FlowRunPayload {
|
|
|
12
12
|
readonly input: Record<string, unknown>;
|
|
13
13
|
readonly source: 'manual' | 'cron';
|
|
14
14
|
readonly requestId: string;
|
|
15
|
+
readonly chainPath?: ReadonlyArray<string> | undefined;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -30,16 +31,54 @@ export declare const flowRunWorkflow: Workflow<"flow.run", Schema.Struct<{
|
|
|
30
31
|
source: Schema.Literal<["manual", "cron"]>;
|
|
31
32
|
/** Correlation + idempotency key. */
|
|
32
33
|
requestId: typeof Schema.String;
|
|
34
|
+
/**
|
|
35
|
+
* The chain of flows that led here, oldest first, INCLUDING this one.
|
|
36
|
+
*
|
|
37
|
+
* `chainTo` had a self-chain guard and nothing else, so A→B→A was an
|
|
38
|
+
* unbounded loop: each hop started a fresh child workflow with a fresh
|
|
39
|
+
* `requestId`, so idempotency never collapsed it and nothing counted the
|
|
40
|
+
* hops. The framework would happily run it until an operator noticed the
|
|
41
|
+
* bill.
|
|
42
|
+
*
|
|
43
|
+
* Optional so a run started by an older caller (or by hand) still decodes;
|
|
44
|
+
* an absent path is read as "this is the first flow", which it is.
|
|
45
|
+
*/
|
|
46
|
+
chainPath: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
33
47
|
}>, Schema.Struct<{
|
|
34
48
|
runId: typeof Schema.String;
|
|
35
49
|
status: Schema.Literal<["succeeded", "failed", "cancelled", "waiting"]>;
|
|
36
50
|
}>, typeof Schema.Never> & WorkflowMessagesCarrier<{
|
|
37
51
|
readonly signals: {};
|
|
38
52
|
readonly updates: {};
|
|
39
|
-
readonly queries: {};
|
|
40
53
|
}>;
|
|
41
54
|
|
|
42
|
-
/**
|
|
43
|
-
|
|
55
|
+
/** Namespace of the signal a `human` step parks on. Never used on its own —
|
|
56
|
+
* the signal a step actually awaits is {@link humanResponseSignalName}. */
|
|
57
|
+
export declare const HUMAN_RESPONSE_SIGNAL_PREFIX = "flow-human-response";
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The signal name ONE human step parks on, derived from that step's position in
|
|
61
|
+
* the (journal-pinned) plan.
|
|
62
|
+
*
|
|
63
|
+
* **Why this is per-step and not one constant.** `awaitSignalSuspending` derives
|
|
64
|
+
* its `DurableDeferred` from workflow-name + signal-name per execution, so a
|
|
65
|
+
* single `'flow-human-response'` for every human step in a flow meant the SECOND
|
|
66
|
+
* review awaited the deferred the FIRST answer had already completed — it
|
|
67
|
+
* resolved instantly, with the first reviewer's payload, and the run finished
|
|
68
|
+
* carrying an approval nobody gave. Measured before the fix: a two-review flow,
|
|
69
|
+
* one answer, `status: 'succeeded'`, `output: { first: 'answer-one', second:
|
|
70
|
+
* 'answer-one' }`. The same collision aliased the wait's durable timeout clock
|
|
71
|
+
* (`await-signal-timeout/<name>`), so the second park inherited the first's
|
|
72
|
+
* expiry too.
|
|
73
|
+
*
|
|
74
|
+
* **Why the INDEX is the identity.** It must be identical on every replay and
|
|
75
|
+
* derivable by the responder without re-resolving the flow definition (which may
|
|
76
|
+
* have been edited mid-run). The step list is pinned in the run's journal at
|
|
77
|
+
* step 0, so a step's index is fixed for the life of the run; the responder
|
|
78
|
+
* reads it back off the run row's live timeline. A counter, a clock, or a
|
|
79
|
+
* `randomUUID` would all break replay; the authored step `id` would break the
|
|
80
|
+
* moment a definition is re-ordered under a live run.
|
|
81
|
+
*/
|
|
82
|
+
export declare const humanResponseSignalName: (stepIndex: number) => string;
|
|
44
83
|
|
|
45
84
|
export { }
|
package/dist/workflow.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Schema as e } from "effect";
|
|
2
2
|
import { workflow as t } from "@voltro/workflow/define";
|
|
3
3
|
//#region src/workflow.ts
|
|
4
|
-
var n = "flow.run", r = "flow-human-response", i = t({
|
|
4
|
+
var n = "flow.run", r = "flow-human-response", i = (e) => `${r}:${e}`, a = t({
|
|
5
5
|
name: n,
|
|
6
6
|
payload: {
|
|
7
7
|
runId: e.String,
|
|
@@ -11,7 +11,8 @@ var n = "flow.run", r = "flow-human-response", i = t({
|
|
|
11
11
|
value: e.Unknown
|
|
12
12
|
}),
|
|
13
13
|
source: e.Literal("manual", "cron"),
|
|
14
|
-
requestId: e.String
|
|
14
|
+
requestId: e.String,
|
|
15
|
+
chainPath: e.optional(e.Array(e.String))
|
|
15
16
|
},
|
|
16
17
|
success: e.Struct({
|
|
17
18
|
runId: e.String,
|
|
@@ -20,4 +21,4 @@ var n = "flow.run", r = "flow-human-response", i = t({
|
|
|
20
21
|
idempotencyKey: ({ requestId: e }) => `flow-run:${e}`
|
|
21
22
|
});
|
|
22
23
|
//#endregion
|
|
23
|
-
export { n as FLOW_RUN_WORKFLOW, r as
|
|
24
|
+
export { n as FLOW_RUN_WORKFLOW, r as HUMAN_RESPONSE_SIGNAL_PREFIX, a as flowRunWorkflow, i as humanResponseSignalName };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-ai-flows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.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,15 +58,16 @@
|
|
|
58
58
|
"node": ">=24.0.0"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@voltro/ai": "0.
|
|
62
|
-
"@voltro/
|
|
63
|
-
"@voltro/
|
|
64
|
-
"@voltro/
|
|
65
|
-
"@voltro/plugin-
|
|
66
|
-
"@voltro/plugin-
|
|
67
|
-
"@voltro/
|
|
68
|
-
"@voltro/
|
|
69
|
-
"@voltro/
|
|
61
|
+
"@voltro/ai": "0.35.0",
|
|
62
|
+
"@voltro/client": "0.35.0",
|
|
63
|
+
"@voltro/database": "0.35.0",
|
|
64
|
+
"@voltro/env": "0.35.0",
|
|
65
|
+
"@voltro/plugin-audit": "0.35.0",
|
|
66
|
+
"@voltro/plugin-multitenancy": "0.35.0",
|
|
67
|
+
"@voltro/plugin-soft-delete": "0.35.0",
|
|
68
|
+
"@voltro/protocol": "0.35.0",
|
|
69
|
+
"@voltro/runtime": "0.35.0",
|
|
70
|
+
"@voltro/workflow": "0.35.0"
|
|
70
71
|
},
|
|
71
72
|
"peerDependencies": {
|
|
72
73
|
"effect": "^3.22.0"
|