@voltro/ai 0.74.0 → 0.76.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.
@@ -60,8 +60,8 @@ var u = [], d = (...e) => {
60
60
  }, v = (e, t) => {
61
61
  let n = i(e).image(t), r = (n) => i(g(e, {
62
62
  seed: n.seed,
63
- duration: void 0,
64
- fps: void 0
63
+ size: n.size,
64
+ aspectRatio: n.aspectRatio
65
65
  })).image(t).doGenerate(n);
66
66
  return new Proxy(n, { get: (e, t) => t === "doGenerate" ? r : _(e, t) });
67
67
  }, y = (e, t) => {
@@ -69,7 +69,9 @@ var u = [], d = (...e) => {
69
69
  let r = i(g(e, {
70
70
  seed: n.seed,
71
71
  duration: n.duration,
72
- fps: n.fps
72
+ fps: n.fps,
73
+ aspectRatio: n.aspectRatio,
74
+ resolution: n.resolution
73
75
  })).video(t);
74
76
  if (!r.doGenerate) throw Error("Gateway video does not implement doGenerate");
75
77
  return r.doGenerate(n);
@@ -77,7 +79,9 @@ var u = [], d = (...e) => {
77
79
  let r = i(g(e, {
78
80
  seed: n.seed,
79
81
  duration: n.duration,
80
- fps: n.fps
82
+ fps: n.fps,
83
+ aspectRatio: n.aspectRatio,
84
+ resolution: n.resolution
81
85
  })).video(t);
82
86
  if (!r.doStart) throw Error("Gateway video does not implement doStart");
83
87
  return r.doStart(n);
package/dist/test.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as e, u as t } from "./provider-Cts1BRhY.js";
1
+ import { t as e, u as t } from "./provider-BsyDya-H.js";
2
2
  //#region src/test/index.ts
3
3
  var n = (e) => e.turns && e.turns.length > 0 ? e.turns : e.stream && e.stream.length > 0 ? [{ text: e.stream.join("") }] : e.generate ? [{ text: e.generate.text }] : [{ text: "" }], r = (t) => {
4
4
  let r = new e(n(t));
@@ -1,5 +1,6 @@
1
1
  import { DataStore } from '@voltro/database';
2
2
  import { Effect } from 'effect';
3
+ import { PluginMediaPersistMetadata } from '@voltro/protocol';
3
4
  import { Runtime } from 'effect';
4
5
  import { Schema } from 'effect';
5
6
  import { StepRetryPolicy } from '@voltro/workflow';
@@ -244,16 +245,23 @@ declare type GatewayModel = `${GatewayCreator}/${string}`;
244
245
  *
245
246
  * The queue row is the job's identity, allocated before the first paid call.
246
247
  * A replay finds the row; a dispatcher that dies mid-job leaves a lease that
247
- * expires — and the reclaiming dispatcher does NOT submit again: the provider
248
- * has no lookup, so the outcome is reported to the run as `unknown`
249
- * (`AiOffloadError.outcome`) rather than paid for twice. Artifacts are
250
- * persisted through the storage plugin's `mediaPersist` capability under
251
- * `<row>#<attempt>#<index>`, and the run receives URLs and ref ids.
248
+ * expires — and the reclaiming dispatcher does NOT submit again. With a
249
+ * provider registered through `registerMediaTaskProvider` the row also
250
+ * carries the provider's task handle, so the reclaim polls the same task and
251
+ * the run receives its result. A built-in generator has no lookup — and a
252
+ * task job whose handle never reached the row cannot be found either — so
253
+ * those are reported to the run as `unknown` (`AiOffloadError.outcome`)
254
+ * rather than paid for twice. Artifacts are persisted through the storage
255
+ * plugin's `mediaPersist` capability under `<row>#<attempt>#<index>`, and
256
+ * the run receives URLs and ref ids.
252
257
  */
253
258
  export declare const mediaStep: (options: MediaStepOptions) => Effect.Effect<MediaStepResult, unknown>;
254
259
 
255
- export declare interface MediaStepOptions extends Omit<AiStepBaseOptions, 'system' | 'promptTemplate' | 'promptVars' | 'offload' | 'tools' | 'maxSteps' | 'toolContext' | 'fallbacks' | 'maxTokens'> {
260
+ export declare interface MediaStepOptions extends Omit<AiStepBaseOptions, 'system' | 'promptTemplate' | 'promptVars' | 'offload' | 'tools' | 'maxSteps' | 'toolContext' | 'fallbacks' | 'maxTokens' | 'provider'> {
256
261
  readonly modality: 'image' | 'video' | 'speech';
262
+ /** A built-in provider, or the name of one registered with
263
+ * `registerMediaTaskProvider` — the dispatcher routes by the name. */
264
+ readonly provider?: ProviderConfig | RegisteredMediaTaskConfig;
257
265
  /** Provider parameters — `n`, `size`, `aspectRatio`, `seed` for an image;
258
266
  * `durationSeconds`, `resolution`, `fps` for a video; `voice`, `format` for
259
267
  * speech. Passed through to the generator, journaled with the job. */
@@ -263,6 +271,9 @@ export declare interface MediaStepOptions extends Omit<AiStepBaseOptions, 'syste
263
271
  readonly inputs?: Record<string, unknown>;
264
272
  /** Required: a media job is always an external job with a durable identity. */
265
273
  readonly store: DataStore;
274
+ /** Who the stored artifacts belong to, how they are served, and the tags they
275
+ * are found by — handed to the storage plugin's `mediaPersist` as-is. */
276
+ readonly persist?: PluginMediaPersistMetadata;
266
277
  }
267
278
 
268
279
  export declare interface MediaStepResult {
@@ -490,6 +501,15 @@ declare type ProviderConfig = {
490
501
  */
491
502
  declare type ProviderFallbacks = ReadonlyArray<ProviderConfig>;
492
503
 
504
+ /**
505
+ * The provider config `mediaStep` accepts for a registered task provider —
506
+ * named, not enumerated, exactly like `RegisteredSpeechConfig`.
507
+ */
508
+ declare interface RegisteredMediaTaskConfig {
509
+ readonly name: string;
510
+ readonly model?: string;
511
+ }
512
+
493
513
  /** What `.render(vars)` produces — a stamp plus the text to send. */
494
514
  declare interface RenderedPrompt extends PromptStamp {
495
515
  readonly prompt: string;
@@ -536,7 +556,7 @@ declare interface ToolContext {
536
556
  readonly runtime?: Runtime.Runtime<unknown>;
537
557
  /** SDK tool-call identity for this execution, not a durable application idempotency key. */
538
558
  readonly invocationId?: string;
539
- /** The SDK's cancellation signal; Promise handlers must pass it to their I/O. */
559
+ /** Cancellation from either the caller's turn or SDK invocation; Promise handlers must pass it to their I/O. */
540
560
  readonly abortSignal?: AbortSignal;
541
561
  }
542
562
 
package/dist/workflow.js CHANGED
@@ -1,17 +1,17 @@
1
- import { r as e } from "./provider-Cts1BRhY.js";
2
- import { D as t, E as n, O as r, R as i, U as a, Z as o, b as s, m as c, o as l, p as u, s as d, t as f, w as p, y as m } from "./inferenceQueue-CXEVU6mI.js";
1
+ import { r as e } from "./provider-BsyDya-H.js";
2
+ import { D as t, O as n, T as r, V as i, b as a, k as o, m as s, o as c, p as l, q as u, rt as d, s as f, t as p, y as m } from "./inferenceQueue-t5ayqzjs.js";
3
3
  import { Effect as h, Schema as g } from "effect";
4
4
  import { eq as _ } from "@voltro/database";
5
- import { CurrentWorkflowExecutionId as v, awaitSignalSuspending as y, step as b, suspendForBudget as x } from "@voltro/workflow";
5
+ import { BudgetHoldExpired as v, CurrentWorkflowExecutionId as y, awaitSignalSuspending as b, step as x, suspendForBudget as S } from "@voltro/workflow";
6
6
  //#region src/inferStep.ts
7
- var S = {
7
+ var C = {
8
8
  maxAttempts: 4,
9
9
  strategy: "exponential",
10
10
  baseDelay: "1 second",
11
11
  maxDelay: "30 seconds",
12
12
  jitter: !0,
13
13
  respectRetryAfter: !0
14
- }, C = 36e5, w = "ai-usd", T = (e, t, n, r) => {
14
+ }, w = 36e5, T = "ai-usd", E = (e, t, n, r) => {
15
15
  let i = r === void 0 ? {} : {
16
16
  promptId: r.promptId,
17
17
  promptVersion: r.digest,
@@ -24,14 +24,14 @@ var S = {
24
24
  ...t === void 0 ? {} : { system: t }
25
25
  } : {
26
26
  ...i,
27
- promptDigest: c(e),
27
+ promptDigest: s(e),
28
28
  promptChars: e.length,
29
29
  ...t === void 0 ? {} : {
30
- systemDigest: c(t),
30
+ systemDigest: s(t),
31
31
  systemChars: t.length
32
32
  }
33
33
  };
34
- }, E = (e) => u(e.prompt) ? {
34
+ }, D = (e) => l(e.prompt) ? {
35
35
  text: e.prompt.prompt,
36
36
  system: e.system ?? e.prompt.system,
37
37
  rendered: e.prompt
@@ -39,69 +39,69 @@ var S = {
39
39
  text: e.prompt,
40
40
  system: e.system,
41
41
  rendered: void 0
42
- }, D = (e) => ({
43
- provider: String(e.provider ?? "unknown"),
42
+ }, O = (e) => ({
43
+ provider: String(e.name),
44
44
  model: String(e.model ?? "unknown")
45
- }), O = (e, t, n, r, o) => {
46
- let s = e.store;
47
- if (s === void 0) return h.void;
48
- let { provider: c, model: l } = D(t), u = i(r.providerMetadata);
49
- return a(s, {
50
- provider: c,
51
- model: l,
45
+ }), k = (e, t, n, r, a) => {
46
+ let o = e.store;
47
+ if (o === void 0) return h.void;
48
+ let { provider: s, model: c } = O(t), l = i(r.providerMetadata);
49
+ return u(o, {
50
+ provider: s,
51
+ model: c,
52
52
  operation: n,
53
53
  agent: e.name,
54
54
  usage: r.usage,
55
55
  ...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
56
- ...u === void 0 ? {} : { actualCostUsd: u },
57
- ...o === void 0 ? {} : { prompt: o }
58
- }).pipe(h.asVoid, h.catchAllCause(() => h.void));
59
- }, k = (e, t) => {
56
+ ...l === void 0 ? {} : { actualCostUsd: l },
57
+ ...a === void 0 ? {} : { prompt: a }
58
+ });
59
+ }, A = (e, t) => {
60
60
  let n = e.store;
61
61
  return n === void 0 || t === void 0 ? h.void : m(n, {
62
62
  ...t.definition,
63
63
  digest: t.digest
64
64
  }).pipe(h.asVoid, h.catchAllCause(() => h.void));
65
- }, A = g.Struct({
65
+ }, j = g.Struct({
66
66
  text: g.String,
67
67
  inputTokens: g.NullOr(g.Number),
68
68
  outputTokens: g.NullOr(g.Number),
69
69
  totalTokens: g.NullOr(g.Number)
70
- }), j = (e) => typeof e == "object" && !!e && e.__voltro_ai_error === !0, M = class extends Error {
70
+ }), M = (e) => typeof e == "object" && !!e && e.__voltro_ai_error === !0, N = class extends Error {
71
71
  attempts;
72
72
  outcome;
73
73
  constructor(e, t, n, r = "failed") {
74
74
  super(`aiStep('${e}'): the offloaded model call gave up after ${n} attempt(s): ${t}. The queued call is in _voltro_ai_inferences with status 'failed' — the Flow tab shows it with the provider's own message.`), this.name = "AiOffloadError", this.attempts = n, this.outcome = r;
75
75
  }
76
- }, N = class extends Error {
76
+ }, P = class extends Error {
77
77
  constructor(e) {
78
78
  super(`aiStep('${e}'): offload: true needs \`store\` — the queued call lives in a table and the dispatcher reads it from there. Pass ctx.store.`), this.name = "AiOffloadMisuseError";
79
79
  }
80
- }, P = (e, t, n, r, i, a, o) => h.gen(function* () {
80
+ }, F = (e, t, n, r, i, a, o) => h.gen(function* () {
81
81
  let s = e.store;
82
- if (s === void 0) return yield* h.die(new N(e.name));
83
- let c = yield* v;
84
- if (c === void 0) return yield* h.die(/* @__PURE__ */ Error(`aiStep('${e.name}'): offload: true is only valid inside a workflow body — there is no execution to suspend here.`));
85
- let { provider: u, model: p } = D(t), m = d(c, e.name), g = yield* h.promise(() => s.query({
82
+ if (s === void 0) return yield* h.die(new P(e.name));
83
+ let l = yield* y;
84
+ if (l === void 0) return yield* h.die(/* @__PURE__ */ Error(`aiStep('${e.name}'): offload: true is only valid inside a workflow body — there is no execution to suspend here.`));
85
+ let { provider: u, model: d } = O(t), m = f(l, e.name), g = yield* h.promise(() => s.query({
86
86
  table: "_voltro_workflow_runs",
87
- predicate: _("executionId", c),
87
+ predicate: _("executionId", l),
88
88
  order: [],
89
89
  take: 1,
90
90
  skip: void 0,
91
91
  projection: void 0
92
- })), y = String(g[0]?.tag ?? ""), b = g[0]?.id;
93
- return yield* h.promise(() => s.insertIgnore(f, {
92
+ })), v = String(g[0]?.tag ?? ""), b = g[0]?.id;
93
+ return yield* h.promise(() => s.insertIgnore(p, {
94
94
  id: m,
95
95
  tenantId: e.tenantId ?? null,
96
- executionId: c,
97
- workflowName: y,
96
+ executionId: l,
97
+ workflowName: v,
98
98
  runId: typeof b == "string" ? b : null,
99
- signalName: l(m),
99
+ signalName: c(m),
100
100
  stepName: e.name,
101
101
  status: "pending",
102
102
  kind: n,
103
103
  provider: u,
104
- model: p,
104
+ model: d,
105
105
  prompt: i.text,
106
106
  system: i.system ?? null,
107
107
  promptId: i.rendered?.promptId ?? null,
@@ -116,59 +116,59 @@ var S = {
116
116
  fence: 0,
117
117
  enqueuedAt: /* @__PURE__ */ new Date()
118
118
  }, { conflictColumns: ["id"] })), m;
119
- }), F = (e, t, n, r, i, a, o, s) => h.gen(function* () {
120
- let c = yield* b({
119
+ }), I = (e, t, n, r, i, a, o, s) => h.gen(function* () {
120
+ let l = yield* x({
121
121
  name: `${e.name}:enqueue`,
122
122
  success: g.String,
123
123
  input: i,
124
- execute: P(e, t, n, r, a, o, s)
124
+ execute: F(e, t, n, r, a, o, s)
125
125
  });
126
- yield* k(e, a.rendered);
127
- let u = yield* y({ store: e.store }, {
128
- name: l(c),
126
+ yield* A(e, a.rendered);
127
+ let u = yield* b({ store: e.store }, {
128
+ name: c(l),
129
129
  schema: g.Unknown,
130
130
  timeoutMs: e.offloadTimeoutMs ?? 36e5
131
131
  });
132
- return j(u) ? yield* h.die(new M(e.name, u.message, u.attempts, u.outcome === "unknown" ? "unknown" : "failed")) : u;
133
- }), I = class extends Error {
132
+ return M(u) ? yield* h.die(new N(e.name, u.message, u.attempts, u.outcome === "unknown" ? "unknown" : "failed")) : u;
133
+ }), L = class extends Error {
134
134
  constructor(e) {
135
135
  super(`aiStep('${e}'): budget needs \`store\` — the reservation counter and the hold both live in tables. Pass ctx.store.`), this.name = "AiBudgetMisuseError";
136
136
  }
137
- }, L = (e) => h.gen(function* () {
137
+ }, R = (e) => h.gen(function* () {
138
138
  let t = e.budget;
139
139
  if (t === void 0) return;
140
140
  let n = e.store;
141
- if (n === void 0) return yield* h.die(new I(e.name));
142
- let r = e.tenantId ?? null, i = t.name ?? "ai-usd", a = yield* v, s = () => o(n, {
141
+ if (n === void 0) return yield* h.die(new L(e.name));
142
+ let r = e.tenantId ?? null, i = t.name ?? "ai-usd", a = yield* y, o = () => d(n, {
143
143
  tenantId: r,
144
144
  limitUsd: t.limitUsd,
145
145
  addUsd: 0,
146
146
  ...t.since === void 0 ? {} : { since: t.since }
147
- }).pipe(h.as(null), h.catchTag("AiBudgetExceeded", (e) => h.succeed(e))), c = () => t.estimateUsd === void 0 ? h.void : o(n, {
147
+ }).pipe(h.as(null), h.catchTag("AiBudgetExceeded", (e) => h.succeed(e))), s = () => t.estimateUsd === void 0 ? h.void : d(n, {
148
148
  tenantId: r,
149
149
  limitUsd: t.limitUsd,
150
150
  addUsd: t.estimateUsd,
151
- ...a === void 0 ? {} : { reservationId: d(a, JSON.stringify([
151
+ ...a === void 0 ? {} : { reservationId: f(a, JSON.stringify([
152
152
  "budget",
153
153
  i,
154
154
  e.name
155
155
  ])) },
156
156
  ...t.since === void 0 ? {} : { since: t.since }
157
- }).pipe(h.asVoid), l = yield* s();
158
- return l === null ? yield* c() : (t.onExceeded ?? "fail") !== "suspend" || a === void 0 ? yield* h.fail(l) : (yield* x({
157
+ }).pipe(h.asVoid), c = yield* t.estimateUsd !== void 0 && t.estimateUsd !== 0 ? s().pipe(h.as(null), h.catchTag("AiBudgetExceeded", (e) => h.succeed(e))) : o();
158
+ if (c !== null) return (t.onExceeded ?? "fail") !== "suspend" || a === void 0 ? yield* h.fail(c) : (yield* S({
159
159
  store: n,
160
160
  budget: i,
161
161
  tenantId: r,
162
162
  executionId: a,
163
- workflowName: yield* R(n, a),
163
+ workflowName: yield* z(n, a),
164
164
  stepName: e.name,
165
- spentMicroUsd: Math.round(l.spentUsd * 1e6),
165
+ spentMicroUsd: Math.round(c.spentUsd * 1e6),
166
166
  limitMicroUsd: Math.round(t.limitUsd * 1e6),
167
- hasHeadroom: s().pipe(h.map((e) => e === null)),
167
+ hasHeadroom: o().pipe(h.map((e) => e === null)),
168
168
  ...t.holdTimeoutMs === void 0 ? {} : { timeoutMs: t.holdTimeoutMs },
169
169
  ...t.recheckEveryMs === void 0 ? {} : { recheckEveryMs: t.recheckEveryMs }
170
- }).pipe(h.catchAll((e) => h.die(e))), yield* c());
171
- }), R = (e, t) => h.promise(async () => {
170
+ }).pipe(h.catchAll((e) => e instanceof v ? h.die(e) : h.fail(e))), yield* s());
171
+ }), z = (e, t) => h.promise(async () => {
172
172
  let n = await e.query({
173
173
  table: "_voltro_workflow_runs",
174
174
  predicate: _("executionId", t),
@@ -178,40 +178,40 @@ var S = {
178
178
  projection: void 0
179
179
  });
180
180
  return String(n[0]?.tag ?? "");
181
- }), z = (n) => {
182
- let r = n.provider ?? e(), i = E(n), a = {
183
- ...D(r),
181
+ }), B = (t) => {
182
+ let r = t.provider ?? e(), i = D(t), a = {
183
+ ...O(r),
184
184
  operation: "generateText",
185
- offloaded: n.offload === !0,
186
- ...T(i.text, i.system, n.recordPrompt ?? "digest", i.rendered)
187
- }, o = (e) => n.budget === void 0 ? e : h.zipRight(L(n), e);
188
- return n.offload === !0 ? o(F(n, r, "text", null, a, i)) : o(b({
189
- name: n.name,
190
- success: A,
185
+ offloaded: t.offload === !0,
186
+ ...E(i.text, i.system, t.recordPrompt ?? "digest", i.rendered)
187
+ }, o = (e) => t.budget === void 0 ? e : h.zipRight(R(t), e);
188
+ return t.offload === !0 ? o(I(t, r, "text", null, a, i)) : o(x({
189
+ name: t.name,
190
+ success: j,
191
191
  input: a,
192
- retry: n.retry ?? S,
193
- execute: t({
192
+ retry: t.retry ?? C,
193
+ execute: n({
194
194
  prompt: i.text,
195
195
  provider: r,
196
196
  ...i.system === void 0 ? {} : { system: i.system },
197
- ...n.fallbacks === void 0 ? {} : { fallbacks: n.fallbacks },
198
- ...n.maxTokens === void 0 ? {} : { maxTokens: n.maxTokens },
199
- ...n.providerOptions === void 0 ? {} : { providerOptions: n.providerOptions },
200
- ...n.tools === void 0 ? {} : { tools: n.tools },
201
- ...n.maxSteps === void 0 ? {} : { maxSteps: n.maxSteps },
202
- ...n.toolContext === void 0 ? {} : { toolContext: n.toolContext }
203
- }).pipe(h.tap((e) => O(n, r, "generateText", e, i.rendered)), h.tap(() => k(n, i.rendered)), h.map((e) => ({
197
+ ...t.fallbacks === void 0 ? {} : { fallbacks: t.fallbacks },
198
+ ...t.maxTokens === void 0 ? {} : { maxTokens: t.maxTokens },
199
+ ...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions },
200
+ ...t.tools === void 0 ? {} : { tools: t.tools },
201
+ ...t.maxSteps === void 0 ? {} : { maxSteps: t.maxSteps },
202
+ ...t.toolContext === void 0 ? {} : { toolContext: t.toolContext }
203
+ }).pipe(h.tap((e) => k(t, r, "generateText", e, i.rendered)), h.tap(() => A(t, i.rendered)), h.map((e) => ({
204
204
  text: e.text,
205
205
  inputTokens: e.usage.inputTokens ?? null,
206
206
  outputTokens: e.usage.outputTokens ?? null,
207
207
  totalTokens: e.usage.totalTokens ?? null
208
208
  })))
209
209
  }));
210
- }, B = g.Struct({
210
+ }, V = g.Struct({
211
211
  text: g.String,
212
212
  language: g.optional(g.String),
213
213
  durationSec: g.optional(g.Number)
214
- }), V = (t) => {
214
+ }), H = (t) => {
215
215
  let n = t.provider ?? e(), r = {
216
216
  source: t.source,
217
217
  ...t.language === void 0 ? {} : { language: t.language },
@@ -219,20 +219,20 @@ var S = {
219
219
  ...t.diarize === void 0 ? {} : { diarize: t.diarize },
220
220
  ...t.translateToEnglish === void 0 ? {} : { translateToEnglish: t.translateToEnglish }
221
221
  }, i = {
222
- ...D(n),
222
+ ...O(n),
223
223
  operation: "transcribe",
224
224
  offloaded: t.offload === !0
225
- }, a = (e) => t.budget === void 0 ? e : h.zipRight(L(t), e);
226
- return t.offload === !0 ? a(F(t, n, "transcription", null, i, {
225
+ }, o = (e) => t.budget === void 0 ? e : h.zipRight(R(t), e);
226
+ return t.offload === !0 ? o(I(t, n, "transcription", null, i, {
227
227
  text: "",
228
228
  system: void 0,
229
229
  rendered: void 0
230
- }, r)) : a(b({
230
+ }, r)) : o(x({
231
231
  name: t.name,
232
- success: B,
232
+ success: V,
233
233
  input: i,
234
- retry: t.retry ?? S,
235
- execute: s({
234
+ retry: t.retry ?? C,
235
+ execute: a({
236
236
  ...r,
237
237
  provider: n,
238
238
  ...t.resolveRef === void 0 ? {} : { resolveRef: t.resolveRef }
@@ -242,61 +242,62 @@ var S = {
242
242
  ...e.durationSec === void 0 ? {} : { durationSec: e.durationSec }
243
243
  })))
244
244
  }));
245
- }, H = (t) => {
246
- let n = t.provider ?? e(), r = E({
245
+ }, U = (t) => {
246
+ let n = t.provider ?? e(), r = D({
247
247
  ...t,
248
248
  prompt: t.prompt
249
249
  }), i = {
250
250
  modality: t.modality,
251
251
  params: t.params ?? {},
252
- inputs: t.inputs ?? {}
252
+ inputs: t.inputs ?? {},
253
+ ...t.persist === void 0 ? {} : { persist: t.persist }
253
254
  }, a = {
254
- ...D(n),
255
+ ...O(n),
255
256
  operation: `generate${t.modality[0].toUpperCase()}${t.modality.slice(1)}`,
256
257
  offloaded: !0,
257
258
  modality: t.modality,
258
- ...T(r.text, void 0, t.recordPrompt ?? "digest", r.rendered)
259
+ ...E(r.text, void 0, t.recordPrompt ?? "digest", r.rendered)
259
260
  };
260
- return ((e) => t.budget === void 0 ? e : h.zipRight(L(t), e))(F({
261
+ return ((e) => t.budget === void 0 ? e : h.zipRight(R(t), e))(I({
261
262
  ...t,
262
263
  offload: !0
263
264
  }, n, "media", null, a, r, void 0, i));
264
- }, U = (t) => {
265
- let i = t.provider ?? e(), a = E(t), o = {
266
- ...D(i),
265
+ }, W = (n) => {
266
+ let i = n.provider ?? e(), a = D(n), s = {
267
+ ...O(i),
267
268
  operation: "generateObject",
268
- offloaded: t.offload === !0,
269
- ...T(a.text, a.system, t.recordPrompt ?? "digest", a.rendered)
270
- }, s = (e) => t.budget === void 0 ? e : h.zipRight(L(t), e);
271
- return t.offload === !0 ? s(h.gen(function* () {
272
- let e = yield* r(t.schema, "aiObjectStep"), n = yield* F(t, i, "object", e, o, a);
273
- return yield* g.decodeUnknown(t.schema)(n);
274
- })) : s(b({
275
- name: t.name,
276
- success: t.schema,
277
- input: o,
278
- retry: t.retry ?? S,
279
- execute: (t.tools === void 0 ? p({
269
+ offloaded: n.offload === !0,
270
+ ...E(a.text, a.system, n.recordPrompt ?? "digest", a.rendered)
271
+ }, c = (e) => n.budget === void 0 ? e : h.zipRight(R(n), e);
272
+ return n.offload === !0 ? c(h.gen(function* () {
273
+ let e = yield* o(n.schema, "aiObjectStep"), t = yield* I(n, i, "object", e, s, a);
274
+ return yield* g.decodeUnknown(n.schema)(t);
275
+ })) : c(x({
276
+ name: n.name,
277
+ success: n.schema,
278
+ input: s,
279
+ retry: n.retry ?? C,
280
+ execute: (n.tools === void 0 ? r({
280
281
  prompt: a.text,
281
- schema: t.schema,
282
+ schema: n.schema,
282
283
  provider: i,
283
284
  ...a.system === void 0 ? {} : { system: a.system },
284
- ...t.fallbacks === void 0 ? {} : { fallbacks: t.fallbacks },
285
- ...t.maxTokens === void 0 ? {} : { maxTokens: t.maxTokens },
286
- ...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
287
- }) : n({
285
+ ...n.fallbacks === void 0 ? {} : { fallbacks: n.fallbacks },
286
+ ...n.maxTokens === void 0 ? {} : { maxTokens: n.maxTokens },
287
+ ...n.providerOptions === void 0 ? {} : { providerOptions: n.providerOptions }
288
+ }) : t({
288
289
  prompt: a.text,
289
- schema: t.schema,
290
+ schema: n.schema,
290
291
  provider: i,
291
- tools: t.tools,
292
- ...t.maxSteps === void 0 ? {} : { maxSteps: t.maxSteps },
293
- ...t.toolContext === void 0 ? {} : { toolContext: t.toolContext },
292
+ tools: n.tools,
293
+ ...n.maxSteps === void 0 ? {} : { maxSteps: n.maxSteps },
294
+ ...n.toolContext === void 0 ? {} : { toolContext: n.toolContext },
294
295
  ...a.system === void 0 ? {} : { system: a.system },
295
- ...t.fallbacks === void 0 ? {} : { fallbacks: t.fallbacks },
296
- ...t.maxTokens === void 0 ? {} : { maxTokens: t.maxTokens },
297
- ...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
298
- })).pipe(h.tap((e) => O(t, i, "generateObject", e, a.rendered)), h.tap(() => k(t, a.rendered)), h.map((e) => e.object))
296
+ ...n.fallbacks === void 0 ? {} : { fallbacks: n.fallbacks },
297
+ ...n.maxTokens === void 0 ? {} : { maxTokens: n.maxTokens },
298
+ ...n.providerOptions === void 0 ? {} : { providerOptions: n.providerOptions }
299
+ })).pipe(h.tap((e) => k(n, i, "generateObject", e, a.rendered)), h.tap(() => A(n, a.rendered)), h.map((e) => e.object))
299
300
  }));
300
301
  };
301
302
  //#endregion
302
- export { S as AI_STEP_RETRY, I as AiBudgetMisuseError, M as AiOffloadError, N as AiOffloadMisuseError, w as DEFAULT_AI_BUDGET_NAME, C as DEFAULT_OFFLOAD_TIMEOUT_MS, B as TranscriptionStepResult, U as aiObjectStep, z as aiStep, H as mediaStep, c as promptDigest, T as promptRecordFor, E as resolveStepPrompt, V as transcribeStep };
303
+ export { C as AI_STEP_RETRY, L as AiBudgetMisuseError, N as AiOffloadError, P as AiOffloadMisuseError, T as DEFAULT_AI_BUDGET_NAME, w as DEFAULT_OFFLOAD_TIMEOUT_MS, V as TranscriptionStepResult, W as aiObjectStep, B as aiStep, U as mediaStep, s as promptDigest, E as promptRecordFor, D as resolveStepPrompt, H as transcribeStep };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/ai",
3
- "version": "0.74.0",
3
+ "version": "0.76.0",
4
4
  "description": "Effect-native AI primitives — generateText / generateObject / streamText, tools, agents, media generation, cost tracking + budgets, and provider fallback.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -53,20 +53,21 @@
53
53
  "node": ">=24.0.0"
54
54
  },
55
55
  "dependencies": {
56
- "@ai-sdk/anthropic": "^4.0.49",
57
- "@ai-sdk/openai": "^4.0.58",
58
- "@voltro/cache": "0.74.0",
59
- "@voltro/database": "0.74.0",
60
- "@voltro/protocol": "0.74.0",
61
- "@voltro/workflow": "0.74.0",
56
+ "@ai-sdk/anthropic": "^4.0.56",
57
+ "@ai-sdk/openai": "^4.0.69",
58
+ "@voltro/cache": "0.76.0",
59
+ "@voltro/database": "0.76.0",
60
+ "@voltro/protocol": "0.76.0",
61
+ "@voltro/workflow": "0.76.0",
62
62
  "ajv": "^8.20.0",
63
- "ajv-formats": "^3.0.1"
63
+ "ajv-formats": "^3.0.1",
64
+ "ws": "^8.21.3"
64
65
  },
65
66
  "peerDependencies": {
66
67
  "@ai-sdk/gateway": "^4.0.74",
67
68
  "@ai-sdk/provider": "^4.0.10",
68
69
  "ai": "^7.0.92",
69
- "effect": "^3.22.1"
70
+ "effect": "^3.22.2"
70
71
  },
71
72
  "publishConfig": {
72
73
  "access": "public"