@voltro/plugin-ai-flows 0.70.0 → 0.71.1

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/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
+ import { AnyTool } from '@voltro/ai';
1
2
  import { AppContext } from '@voltro/runtime';
2
3
  import { ColumnBuilder } from '@voltro/database';
3
4
  import { ColumnDefinition } from '@voltro/database';
4
5
  import { Effect } from 'effect';
5
6
  import { FieldDefinitions } from '@voltro/database';
7
+ import { GenerateTextOptions } from '@voltro/ai';
6
8
  import { ProviderConfig } from '@voltro/ai';
7
9
  import { Schema } from 'effect';
8
10
  import { Table } from '@voltro/database';
@@ -15,6 +17,10 @@ import { WorkflowInstance } from '@effect/workflow/WorkflowEngine';
15
17
  export declare interface AgentResolution {
16
18
  readonly system: string;
17
19
  readonly model: string;
20
+ /** Already authorized tools for this persona/run; never serialized into IR. */
21
+ readonly tools?: Record<string, AnyTool>;
22
+ /** Bound for this agent's model/tool loop, independent of the planner. Default 8. */
23
+ readonly maxSteps?: number;
18
24
  }
19
25
 
20
26
  /** `ai_flow_runs` — one execution. Reactive: the engine patches this row
@@ -33,6 +39,20 @@ export declare const aiFlowRunsTable: Table<"_voltro_ai_flow_runs", FieldDefinit
33
39
  readonly source: ColumnBuilder<string | null, "text", boolean>;
34
40
  /** Correlation + idempotency key (→ the workflow's idempotencyKey). */
35
41
  readonly requestId: ColumnBuilder<string, "text", boolean>;
42
+ /** Last observed admission answer, not current execution state. Null means
43
+ * no answer was recorded, not that submission did not reach the engine. */
44
+ readonly workflowStart: ColumnBuilder<{
45
+ readonly status: "dropped" | "skipped" | "running" | "succeeded" | "queued" | "replayed";
46
+ readonly id: string;
47
+ readonly executionId: string | null;
48
+ readonly workflowName: string;
49
+ readonly deferral?: {
50
+ readonly mode: string;
51
+ readonly retryAfterMs: number | null;
52
+ readonly dueAt: number | null;
53
+ readonly intentId: string | null;
54
+ } | undefined;
55
+ } | null, "json", boolean>;
36
56
  /** Brief values, keyed by `BriefField.key`. */
37
57
  readonly input: ColumnBuilder<Record<string, unknown> | null, "json", boolean>;
38
58
  /** The result bundle: `outputKey → value` (what the UI's result dialog reads). */
@@ -41,7 +61,7 @@ export declare const aiFlowRunsTable: Table<"_voltro_ai_flow_runs", FieldDefinit
41
61
  readonly steps: ColumnBuilder<readonly RunStep[] | null, "json", boolean>;
42
62
  readonly currentStep: ColumnBuilder<number, "integer", true>;
43
63
  readonly totalSteps: ColumnBuilder<number, "integer", true>;
44
- /** The HITL answer, written by `respond`. */
64
+ /** The HITL answer projected by the engine after consuming its signal. */
45
65
  readonly humanResponse: ColumnBuilder<HumanResponse | null, "json", boolean>;
46
66
  /** Staged follow-up when the chain requires confirmation. */
47
67
  readonly chainPending: ColumnBuilder<ChainPending | null, "json", boolean>;
@@ -305,8 +325,8 @@ export declare type ConditionOp = typeof ConditionOp.Type;
305
325
  * auto-stamped by the runtime. */
306
326
  export declare const createFlow: (ctx: AppContext, fields: Record<string, unknown>) => Effect.Effect<Readonly<Record<string, unknown>>, never, never>;
307
327
 
308
- /** Deterministic per-slot request id: same flow + same 15-min slot ⇒ same id. */
309
- export declare const cronRequestId: (flowRef: string, now: Date) => string;
328
+ /** Tenant, flow and absolute minute identify one cadence submission. */
329
+ export declare const cronRequestId: (flowRef: string, now: Date, tenantId: string | null) => string;
310
330
 
311
331
  /**
312
332
  * Declare a code-first flow. Normalizes to the Flow IR, validates its `{{ref}}`
@@ -342,9 +362,15 @@ export declare const deleteFlow: (ctx: AppContext, args: {
342
362
  export declare const describeCondition: (condition: StepCondition) => string;
343
363
 
344
364
  export declare interface EngineDeps {
345
- /** Resolve an `agent` step's `agentRef` → system prompt + model. Absent →
346
- * agent steps with an `agentRef` fail with FlowCapabilityMissing. */
347
- readonly resolveAgent?: (agentRef: string) => Effect.Effect<AgentResolution, FlowNotFound, unknown>;
365
+ /** Resolve an agent in the durable run's tenant, in deterministic steps AND
366
+ * the agentic `run_agent` tool. Do not infer tenancy from the current subject:
367
+ * a crash resume may run as system. Absent → FlowCapabilityMissing. */
368
+ readonly resolveAgent?: (agentRef: string, run: MediaRunContext) => Effect.Effect<AgentResolution, FlowNotFound, unknown>;
369
+ /** Additional tools for the agentic planner, resolved inside its durable step.
370
+ * The original flow reference and durable tenant are scope, not authorization.
371
+ * Enforce current access in this callback and the tools. Internal planner names
372
+ * cannot be replaced. Deterministic agent tools belong to AgentResolution. */
373
+ readonly resolveTools?: (flowRef: string, run: MediaRunContext) => Effect.Effect<Record<string, AnyTool>, FlowCapabilityMissing, unknown>;
348
374
  /** Media generator for image/video/audio steps (`makeMediaGenerator` in
349
375
  * `mediaAdapter.ts` is the @voltro/ai-backed implementation). */
350
376
  readonly generateMedia?: MediaGenerator;
@@ -555,6 +581,43 @@ declare const FlowNotFound_base: Schema.TaggedErrorClass<FlowNotFound, "FlowNotF
555
581
  message: typeof Schema.String;
556
582
  }>;
557
583
 
584
+ /** No review-delivery confirmation. Unknown delivery may already have been consumed. */
585
+ declare class FlowReviewDeliveryError extends FlowReviewDeliveryError_base {
586
+ }
587
+
588
+ declare const FlowReviewDeliveryError_base: Schema.TaggedErrorClass<FlowReviewDeliveryError, "FlowReviewDeliveryError", {
589
+ readonly _tag: Schema.tag<"FlowReviewDeliveryError">;
590
+ } & {
591
+ runId: typeof Schema.String;
592
+ reason: Schema.Literal<["runtime-unavailable", "invalid-run", "invalid-response", "delivery-unknown"]>;
593
+ message: typeof Schema.String;
594
+ }>;
595
+
596
+ /** Bind the answer to the review actually displayed, not the latest waiting step. */
597
+ export declare const FlowReviewInput: Schema.Struct<{
598
+ runId: typeof Schema.NonEmptyString;
599
+ stepIndex: Schema.filter<typeof Schema.Int>;
600
+ response: Schema.Struct<{
601
+ decision: Schema.optional<Schema.Literal<["approve", "reject"]>>;
602
+ value: Schema.optional<typeof Schema.String>;
603
+ text: Schema.optional<typeof Schema.String>;
604
+ respondedAt: Schema.optional<typeof Schema.String>;
605
+ }>;
606
+ }>;
607
+
608
+ export declare type FlowReviewInput = typeof FlowReviewInput.Type;
609
+
610
+ /** Delivery accepted; consumption and the run's eventual outcome remain reactive state. */
611
+ export declare const FlowReviewReceipt: Schema.Struct<{
612
+ runId: typeof Schema.NonEmptyString;
613
+ stepIndex: Schema.filter<typeof Schema.Int>;
614
+ executionId: typeof Schema.NonEmptyString;
615
+ eventId: typeof Schema.NonEmptyString;
616
+ status: Schema.Literal<["accepted"]>;
617
+ }>;
618
+
619
+ export declare type FlowReviewReceipt = typeof FlowReviewReceipt.Type;
620
+
558
621
  /** A flow run row could not be found. */
559
622
  declare class FlowRunNotFound extends FlowRunNotFound_base {
560
623
  }
@@ -601,6 +664,26 @@ export declare interface FlowSegment {
601
664
  */
602
665
  export declare const flowSegments: (steps: ReadonlyArray<FlowStep>) => ReadonlyArray<FlowSegment>;
603
666
 
667
+ /** Submission evidence, separate from the flow run's execution status. */
668
+ export declare const FlowStartReceipt: Schema.Struct<{
669
+ runId: typeof Schema.NonEmptyString;
670
+ requestId: typeof Schema.NonEmptyString;
671
+ admission: Schema.Struct<{
672
+ id: typeof Schema.String;
673
+ workflowName: typeof Schema.String;
674
+ executionId: Schema.NullOr<typeof Schema.String>;
675
+ status: Schema.Literal<["running", "succeeded", "queued", "dropped", "skipped", "replayed"]>;
676
+ deferral: Schema.optional<Schema.Struct<{
677
+ mode: typeof Schema.String;
678
+ dueAt: Schema.NullOr<typeof Schema.Number>;
679
+ retryAfterMs: Schema.NullOr<typeof Schema.Number>;
680
+ intentId: Schema.NullOr<typeof Schema.String>;
681
+ }>>;
682
+ }>;
683
+ }>;
684
+
685
+ export declare type FlowStartReceipt = typeof FlowStartReceipt.Type;
686
+
604
687
  /** Flow-definition lifecycle. */
605
688
  export declare const FlowStatus: Schema.Literal<["draft", "active", "archived"]>;
606
689
 
@@ -631,11 +714,11 @@ export declare const FlowStep: Schema.Struct<{
631
714
  }>, Schema.Struct<{
632
715
  from: Schema.Literal<["step"]>;
633
716
  ref: typeof Schema.String;
717
+ artifact: Schema.optional<Schema.filter<typeof Schema.Int>>;
634
718
  }>]>>>;
635
- /** Allowed sub-agent id/name. The framework resolves a real id; any
636
- * legacy-numeric bridge stays in the consumer app's mapping. */
719
+ /** Allowed sub-agent id/name, resolved and authorized by the host. */
637
720
  agentRef: Schema.optional<typeof Schema.String>;
638
- /** JSON Schema of the desired object (adapted to an Effect Schema at run). */
721
+ /** JSON Schema of the desired object, preserved and validated at run. */
639
722
  schema: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
640
723
  reviewMode: Schema.optional<Schema.Literal<["approve", "choice", "text"]>>;
641
724
  options: Schema.optional<Schema.Array$<Schema.Struct<{
@@ -719,6 +802,7 @@ export declare const flowStep: {
719
802
  description?: string;
720
803
  prompt: string;
721
804
  model?: string;
805
+ params?: FlowTextParams;
722
806
  outputKey?: string;
723
807
  } & StepControls) => FlowStepDraft;
724
808
  /** An image/video/audio generation. */
@@ -728,6 +812,7 @@ export declare const flowStep: {
728
812
  prompt: string;
729
813
  model?: string;
730
814
  params?: Record<string, unknown>;
815
+ mediaInputs?: MediaInputs;
731
816
  outputKey?: string;
732
817
  } & StepControls) => FlowStepDraft;
733
818
  /** Delegate to an allowed sub-agent (text-only). */
@@ -737,6 +822,7 @@ export declare const flowStep: {
737
822
  agentRef: string;
738
823
  prompt: string;
739
824
  model?: string;
825
+ params?: FlowTextParams;
740
826
  outputKey?: string;
741
827
  } & StepControls) => FlowStepDraft;
742
828
  /** Return a JSON object validated against a JSON Schema. */
@@ -746,6 +832,7 @@ export declare const flowStep: {
746
832
  prompt: string;
747
833
  schema: Record<string, unknown>;
748
834
  model?: string;
835
+ params?: FlowTextParams;
749
836
  outputKey?: string;
750
837
  } & StepControls) => FlowStepDraft;
751
838
  /** Free-text guidance — the interpolated prompt itself is the output. */
@@ -771,6 +858,8 @@ export declare const flowStep: {
771
858
  /** A step without its `id` — `defineFlow` assigns stable index-based ids. */
772
859
  export declare type FlowStepDraft = Omit<FlowStep, 'id'>;
773
860
 
861
+ export declare type FlowTextParams = Pick<GenerateTextOptions, 'maxTokens' | 'temperature' | 'providerOptions'>;
862
+
774
863
  /** The recorded `app.config.ts` tunables. */
775
864
  export declare const getAiFlowsDefaults: () => AiFlowsDefaults;
776
865
 
@@ -795,7 +884,7 @@ export declare const HUMAN_REVIEW_TIMEOUT_ENV = "VOLTRO_AI_FLOW_HUMAN_REVIEW_TIM
795
884
  * eventually settles instead of pinning a run forever. */
796
885
  export declare const HUMAN_REVIEW_TIMEOUT_HOURS_DEFAULT: number;
797
886
 
798
- /** The HITL answer, written by `respond`. */
887
+ /** The HITL answer; the engine projects it after consuming the durable signal. */
799
888
  export declare const HumanResponse: Schema.Struct<{
800
889
  decision: Schema.optional<Schema.Literal<["approve", "reject"]>>;
801
890
  value: Schema.optional<typeof Schema.String>;
@@ -859,25 +948,6 @@ export declare const Json: Schema.Record$<typeof Schema.String, typeof Schema.Un
859
948
 
860
949
  export declare type Json = typeof Json.Type;
861
950
 
862
- /** A JSON-Schema node as stored on a `structured` step. */
863
- export declare type JsonSchemaNode = Record<string, unknown>;
864
-
865
- /**
866
- * Adapt a `structured` step's JSON Schema to the Effect `Schema` the engine
867
- * hands `generateObject`. An absent / unusable schema falls back to the open
868
- * record, so a step authored without one behaves exactly as before.
869
- *
870
- * ```ts
871
- * jsonSchemaToEffectSchema({
872
- * type: 'object',
873
- * properties: { title: { type: 'string' }, tags: { type: 'array', items: { type: 'string' } } },
874
- * required: ['title'],
875
- * })
876
- * // ≡ Schema.Struct({ title: Schema.String, tags: Schema.optional(Schema.Array(Schema.String)) })
877
- * ```
878
- */
879
- export declare const jsonSchemaToEffectSchema: (jsonSchema: JsonSchemaNode | undefined) => Schema.Schema<unknown, unknown>;
880
-
881
951
  /** Launch a fresh run of a flow (by code name or row id). Validates the brief,
882
952
  * creates the run row, and starts the durable `flow.run` workflow. */
883
953
  export declare const launchFlow: (ctx: AppContext, args: {
@@ -885,9 +955,20 @@ export declare const launchFlow: (ctx: AppContext, args: {
885
955
  input?: Record<string, unknown>;
886
956
  source?: "manual" | "cron";
887
957
  }) => Effect.Effect<{
888
- runId: string;
889
- requestId: string;
890
- status: RunStatus;
958
+ readonly runId: string;
959
+ readonly requestId: string;
960
+ readonly admission: {
961
+ readonly status: "dropped" | "skipped" | "running" | "succeeded" | "queued" | "replayed";
962
+ readonly id: string;
963
+ readonly executionId: string | null;
964
+ readonly workflowName: string;
965
+ readonly deferral?: {
966
+ readonly mode: string;
967
+ readonly retryAfterMs: number | null;
968
+ readonly dueAt: number | null;
969
+ readonly intentId: string | null;
970
+ } | undefined;
971
+ };
891
972
  }, FlowNotFound | FlowBriefIncomplete, never>;
892
973
 
893
974
  /** All stored flows for the caller's tenant. */
@@ -898,7 +979,7 @@ export declare const listRegisteredFlows: () => ReadonlyArray<FlowIR>;
898
979
 
899
980
  /**
900
981
  * Build a `MediaGenerator` from a persistence adapter. Generates via @voltro/ai,
901
- * persists the artifact, and returns `{ url, costMicroUsd, requestId? }`. Any
982
+ * persists every artifact, and returns `{ artifacts, costMicroUsd }`. Any
902
983
  * failure (generation or persistence) surfaces as a typed `FlowCapabilityMissing`
903
984
  * so the engine records a clean per-step error.
904
985
  */
@@ -928,6 +1009,26 @@ export declare const MAX_STEPS_MAX = 100;
928
1009
 
929
1010
  export declare const MAX_STEPS_MIN = 1;
930
1011
 
1012
+ /** One persisted media artifact. Storage identity is not a provider request ID.
1013
+ * Exactly one artifact per result has role `primary`; other roles are host-defined. */
1014
+ export declare const MediaArtifact: Schema.Struct<{
1015
+ url: typeof Schema.NonEmptyString;
1016
+ mediaType: typeof Schema.NonEmptyString;
1017
+ role: typeof Schema.NonEmptyString;
1018
+ storageRefId: Schema.optional<typeof Schema.NonEmptyString>;
1019
+ providerMetadata: Schema.optional<typeof Schema.Unknown>;
1020
+ }>;
1021
+
1022
+ export declare type MediaArtifact = typeof MediaArtifact.Type;
1023
+
1024
+ export declare const MediaArtifacts: Schema.filter<Schema.Array$<Schema.Struct<{
1025
+ url: typeof Schema.NonEmptyString;
1026
+ mediaType: typeof Schema.NonEmptyString;
1027
+ role: typeof Schema.NonEmptyString;
1028
+ storageRefId: Schema.optional<typeof Schema.NonEmptyString>;
1029
+ providerMetadata: Schema.optional<typeof Schema.Unknown>;
1030
+ }>>>;
1031
+
931
1032
  /** Host-supplied media generator for image/video/audio steps — `@voltro/ai`'s
932
1033
  * `generateImage` / `generateVideo` / `generateSpeech` plug in here via the
933
1034
  * app's server re-export (see `mediaAdapter.ts`). */
@@ -936,7 +1037,7 @@ export declare type MediaGenerator = (args: {
936
1037
  readonly model?: string;
937
1038
  readonly prompt: string;
938
1039
  readonly params?: Record<string, unknown>;
939
- readonly inputs?: Record<string, unknown>;
1040
+ readonly inputs?: ResolvedMediaInputs;
940
1041
  /** The run this artifact belongs to — pin persistence to `run.tenantId` rather
941
1042
  * than the current subject, so a system/bootstrap resume stores it correctly. */
942
1043
  readonly run: MediaRunContext;
@@ -948,12 +1049,13 @@ export declare const MediaInputs: Schema.Record$<typeof Schema.String, Schema.Un
948
1049
  }>, Schema.Struct<{
949
1050
  from: Schema.Literal<["step"]>;
950
1051
  ref: typeof Schema.String;
1052
+ artifact: Schema.optional<Schema.filter<typeof Schema.Int>>;
951
1053
  }>]>>;
952
1054
 
953
1055
  export declare type MediaInputs = typeof MediaInputs.Type;
954
1056
 
955
- /** A media-input slot for a video `generate` step — either an uploaded URL or a
956
- * reference to a prior step's output. Keyed by capability slot name
1057
+ /** A media-input slot — an absolute HTTP(S) uploaded URL or a reference to a
1058
+ * brief field/prior step's URL output. Keyed by capability slot name
957
1059
  * (`referenceImageUrl`, `lastFrameImageUrl`, `referenceVideoUrl`, …). */
958
1060
  export declare const MediaInputSlot: Schema.Union<[Schema.Struct<{
959
1061
  from: Schema.Literal<["upload"]>;
@@ -961,6 +1063,7 @@ export declare const MediaInputSlot: Schema.Union<[Schema.Struct<{
961
1063
  }>, Schema.Struct<{
962
1064
  from: Schema.Literal<["step"]>;
963
1065
  ref: typeof Schema.String;
1066
+ artifact: Schema.optional<Schema.filter<typeof Schema.Int>>;
964
1067
  }>]>;
965
1068
 
966
1069
  export declare type MediaInputSlot = typeof MediaInputSlot.Type;
@@ -977,21 +1080,28 @@ export declare interface MediaPersist {
977
1080
  data: Uint8Array | string;
978
1081
  mediaType: string;
979
1082
  run: MediaRunContext;
980
- }) => Promise<StoredMedia>;
1083
+ }) => Effect.Effect<StoredMedia, unknown, unknown>;
981
1084
  /** Re-host a provider URL (StorageService.ingestUrl). If absent, a provider
982
1085
  * video URL is used as-is (no re-hosting). */
983
- readonly ingestUrl?: (url: string, run: MediaRunContext) => Promise<StoredMedia>;
1086
+ readonly ingestUrl?: (url: string, run: MediaRunContext) => Effect.Effect<StoredMedia, unknown, unknown>;
984
1087
  }
985
1088
 
986
- /** Media generation result (the host generator persists the artifact + returns
987
- * a hosted URL). */
988
- export declare interface MediaResult {
989
- readonly url: string;
990
- readonly costMicroUsd?: number;
991
- readonly requestId?: string;
992
- }
1089
+ export declare const MediaResult: Schema.Struct<{
1090
+ artifacts: Schema.filter<Schema.Array$<Schema.Struct<{
1091
+ url: typeof Schema.NonEmptyString;
1092
+ mediaType: typeof Schema.NonEmptyString;
1093
+ role: typeof Schema.NonEmptyString;
1094
+ storageRefId: Schema.optional<typeof Schema.NonEmptyString>;
1095
+ providerMetadata: Schema.optional<typeof Schema.Unknown>;
1096
+ }>>>;
1097
+ costMicroUsd: Schema.optional<Schema.filter<typeof Schema.Finite>>;
1098
+ /** A provider/usage correlation only, never a storage reference. */
1099
+ requestId: Schema.optional<typeof Schema.NonEmptyString>;
1100
+ }>;
993
1101
 
994
- /** The run a media step executes within, resolved from the durable RUN ROW —
1102
+ export declare type MediaResult = typeof MediaResult.Type;
1103
+
1104
+ /** The run an agent or media step executes within, resolved from the durable RUN ROW —
995
1105
  * not the caller subject. This is the difference between a normal call and a
996
1106
  * resume: a BOOTSTRAP/crash resume runs under a tenant-less `SYSTEM_SUBJECT`,
997
1107
  * so a host that persists artifacts per tenant cannot read the tenant from
@@ -999,7 +1109,7 @@ export declare interface MediaResult {
999
1109
  * under the old fallback, write into the wrong tenant. The engine reads the run
1000
1110
  * row it already loads and hands the original tenant down here, so persistence
1001
1111
  * continues in the right place on replay. */
1002
- declare interface MediaRunContext {
1112
+ export declare interface MediaRunContext {
1003
1113
  readonly runId: string;
1004
1114
  /** The run's tenant as stamped when it was created, or `null` for a
1005
1115
  * single-tenant app. Authoritative on resume, where the subject has none. */
@@ -1034,6 +1144,10 @@ export declare const registerFlow: (ir: FlowIR) => void;
1034
1144
  /** Test seam — forget the recorded tunables. */
1035
1145
  export declare const resetAiFlowsDefaults: () => void;
1036
1146
 
1147
+ declare const ResolvedMediaInputs: Schema.Record$<typeof Schema.String, Schema.filter<typeof Schema.String>>;
1148
+
1149
+ declare type ResolvedMediaInputs = typeof ResolvedMediaInputs.Type;
1150
+
1037
1151
  /**
1038
1152
  * Resolve a human step's park bound down the precedence ladder. Pure — the env
1039
1153
  * read is passed in so a test can drive it without touching `process.env`.
@@ -1068,26 +1182,37 @@ export declare const resolveMaxChainDepth: (deps?: {
1068
1182
  readonly env?: NodeJS.ProcessEnv;
1069
1183
  }) => number;
1070
1184
 
1071
- /** Record a human's answer to a `waiting` run + signal the parked workflow to
1072
- * resume. The signal is addressed to THAT STEP's own durable deferred — one
1073
- * shared name meant a later review resolved with an earlier answer. */
1074
- export declare const respondToFlow: (ctx: AppContext, args: {
1075
- runId: string;
1076
- response: HumanResponse;
1077
- }) => Effect.Effect<{
1078
- runId: string;
1079
- stepIndex: number;
1080
- }, FlowRunNotFound | FlowNotAwaitingResponse, never>;
1185
+ /** Deliver to the displayed review's actual workflow execution. The engine, not
1186
+ * this sender, projects the consumed answer into humanResponse. A lost delivery
1187
+ * acknowledgement is unknown, never a fabricated successful response. */
1188
+ export declare const respondToFlow: (ctx: AppContext, args: FlowReviewInput) => Effect.Effect<{
1189
+ readonly status: "accepted";
1190
+ readonly executionId: string;
1191
+ readonly runId: string;
1192
+ readonly eventId: string;
1193
+ readonly stepIndex: number;
1194
+ }, FlowRunNotFound | FlowNotAwaitingResponse | FlowReviewDeliveryError, never>;
1081
1195
 
1082
- /** Re-run a run from its first unfinished step. Reuses the SAME requestId so the
1083
- * workflow's idempotencyKey resolves to the same execution → journal replay
1084
- * resumes (deterministic runs skip already-succeeded steps). */
1196
+ /** Resubmit the persisted input under the same requestId. The returned admission
1197
+ * decides whether anything started; a replay is not a new execution. Previous
1198
+ * execution evidence stays intact until the executor actually changes it. */
1085
1199
  export declare const retryFlow: (ctx: AppContext, args: {
1086
1200
  runId: string;
1087
1201
  }) => Effect.Effect<{
1088
- runId: string;
1089
- requestId: string;
1090
- status: RunStatus;
1202
+ readonly runId: string;
1203
+ readonly requestId: string;
1204
+ readonly admission: {
1205
+ readonly status: "dropped" | "skipped" | "running" | "succeeded" | "queued" | "replayed";
1206
+ readonly id: string;
1207
+ readonly executionId: string | null;
1208
+ readonly workflowName: string;
1209
+ readonly deferral?: {
1210
+ readonly mode: string;
1211
+ readonly retryAfterMs: number | null;
1212
+ readonly dueAt: number | null;
1213
+ readonly intentId: string | null;
1214
+ } | undefined;
1215
+ };
1091
1216
  }, FlowRunNotFound, never>;
1092
1217
 
1093
1218
  export declare const ReviewMode: Schema.Literal<["approve", "choice", "text"]>;
@@ -1105,7 +1230,8 @@ export declare type ReviewOption = typeof ReviewOption.Type;
1105
1230
  * Evaluate every enabled flow's cadence against `now` and start a `flow.run` per
1106
1231
  * match. Returns the started request ids. Idempotent across replicas +
1107
1232
  * re-invocations within a slot (deterministic requestId + the run-row insert
1108
- * tolerates the duplicate). Never throws — a single bad flow can't abort the tick.
1233
+ * tolerates the duplicate). Candidate-read failures reject immediately. Per-flow
1234
+ * failures are collected and reject after the remaining candidates are attempted.
1109
1235
  */
1110
1236
  export declare const runCadenceTick: (ctx: AppContext, now?: Date) => Promise<{
1111
1237
  readonly matched: number;
@@ -1150,6 +1276,14 @@ export declare const RunStep: Schema.Struct<{
1150
1276
  requestId: Schema.optional<typeof Schema.String>;
1151
1277
  /** Hosted media artifact URL (image/video/audio), via storage. */
1152
1278
  url: Schema.optional<typeof Schema.String>;
1279
+ /** All media variants, including roles and storage references; url projects the primary artifact. */
1280
+ artifacts: Schema.optional<Schema.filter<Schema.Array$<Schema.Struct<{
1281
+ url: typeof Schema.NonEmptyString;
1282
+ mediaType: typeof Schema.NonEmptyString;
1283
+ role: typeof Schema.NonEmptyString;
1284
+ storageRefId: Schema.optional<typeof Schema.NonEmptyString>;
1285
+ providerMetadata: Schema.optional<typeof Schema.Unknown>;
1286
+ }>>>>;
1153
1287
  /** Inline text output (rendered as markdown). */
1154
1288
  output: Schema.optional<Schema.Struct<{
1155
1289
  text: typeof Schema.String;
@@ -1182,6 +1316,7 @@ export declare interface RunStep {
1182
1316
  readonly costMicroUsd?: number | undefined;
1183
1317
  readonly requestId?: string | undefined;
1184
1318
  readonly url?: string | undefined;
1319
+ readonly artifacts?: ReadonlyArray<MediaArtifact> | undefined;
1185
1320
  readonly output?: {
1186
1321
  readonly text: string;
1187
1322
  } | undefined;
@@ -1267,8 +1402,8 @@ export declare type Visibility = typeof Visibility.Type;
1267
1402
  * derive the step's signal name.
1268
1403
  *
1269
1404
  * Read from the LIVE TIMELINE the engine wrote when it parked (`steps[i].status
1270
- * === 'waiting'`), with `currentStep` as the fallback for a row whose timeline
1271
- * hasn't been written yet. Deliberately NOT re-resolved from the flow definition:
1405
+ * === 'waiting'`). Missing or ambiguous identity refuses; neither currentStep
1406
+ * nor zero is a substitute for an actual review. NOT re-resolved from the definition:
1272
1407
  * a definition edited mid-run would hand back a different plan than the one the
1273
1408
  * run's journal pinned, and the answer would be delivered to the wrong step.
1274
1409
  */