@voltro/ai 0.84.0 → 0.86.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 +1215 -0
- package/THIRD-PARTY-NOTICES.md +5 -151
- package/dist/agent.d.ts +34 -41
- package/dist/agent.js +64 -2
- package/dist/agentConstants.js +4 -0
- package/dist/agentExecutor.js +51 -0
- package/dist/api.js +199 -0
- package/dist/appTools.js +80 -0
- package/dist/budget.js +201 -0
- package/dist/callEvidence.js +51 -0
- package/dist/copilot.js +126 -0
- package/dist/cost.js +242 -0
- package/dist/embed.js +41 -0
- package/dist/embeddingProvider.js +51 -0
- package/dist/eval.js +130 -0
- package/dist/events.d.ts +171 -168
- package/dist/events.js +81 -2
- package/dist/executableModalities.js +13 -0
- package/dist/gateway.js +58 -0
- package/dist/gatewayCatalog.js +47 -0
- package/dist/gatewayMedia.js +88 -0
- package/dist/index.d.ts +328 -326
- package/dist/index.js +42 -2581
- package/dist/inferenceDispatch.js +493 -0
- package/dist/inferenceQueue.js +96 -0
- package/dist/jsonOutputValidation.js +27 -0
- package/dist/mcpClient.js +332 -0
- package/dist/mcpTools.js +80 -0
- package/dist/media.js +182 -0
- package/dist/mediaBytes.js +19 -0
- package/dist/mediaCall.js +13 -0
- package/dist/mediaTaskProvider.js +16 -0
- package/dist/middleware.js +32 -0
- package/dist/observe.js +52 -0
- package/dist/prompts.js +103 -0
- package/dist/provider.js +303 -0
- package/dist/realtimeEvent.js +97 -0
- package/dist/realtimeSession.js +154 -0
- package/dist/rerank.js +61 -0
- package/dist/resumableStream.js +321 -0
- package/dist/retrieveReranked.js +16 -0
- package/dist/runAndPersist.js +148 -0
- package/dist/semanticCache.js +66 -0
- package/dist/speechProvider.js +16 -0
- package/dist/streamRegistry.js +14 -0
- package/dist/streamText.js +170 -0
- package/dist/streamTranscribe.js +74 -0
- package/dist/streamWakeups.js +44 -0
- package/dist/structuredEvidence.js +48 -0
- package/dist/test.js +1 -1
- package/dist/threads.js +92 -0
- package/dist/tools.js +68 -0
- package/dist/transcribe.js +64 -0
- package/dist/transcriptionEvent.js +46 -0
- package/dist/workflow.d.ts +12 -10
- package/dist/workflow.js +117 -112
- package/package.json +6 -6
- package/dist/agentDescriptor-DuxvWGDi.js +0 -63
- package/dist/agentEvent-BuXA7sRt.js +0 -152
- package/dist/inferenceQueue-BmtEm3YI.js +0 -1061
- package/dist/provider-BnemgE4D.js +0 -409
package/dist/tools.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsonSchema as e, tool as t } from "ai";
|
|
2
|
+
import { Context as n, Effect as r, Schema as i } from "effect";
|
|
3
|
+
import { jsonSchemaOf as a } from "@voltro/protocol";
|
|
4
|
+
//#region src/tools.ts
|
|
5
|
+
var o = (e, t) => e(t), s = Symbol.for("@voltro/ai/Tool"), c = (e) => ({
|
|
6
|
+
...e,
|
|
7
|
+
[s]: !0
|
|
8
|
+
}), l = (e) => typeof e == "object" && !!e && e[s] === !0, u = (e) => {
|
|
9
|
+
let t = e.default;
|
|
10
|
+
if (typeof t != "function") return 0;
|
|
11
|
+
let n = 0;
|
|
12
|
+
for (let r of Object.values(e)) l(r) && r.execution !== "client" && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
|
|
13
|
+
return n;
|
|
14
|
+
}, d = (e, t, i) => {
|
|
15
|
+
let a = t ?? n.empty();
|
|
16
|
+
return r.runPromiseWith(a)(e, i === void 0 ? {} : { signal: i });
|
|
17
|
+
}, f = (e, t, n) => n ? e.pipe(r.timeoutOrElse({
|
|
18
|
+
duration: `${n} millis`,
|
|
19
|
+
orElse: () => r.fail(/* @__PURE__ */ Error(`tool '${t}' timed out`))
|
|
20
|
+
})) : e, p = (e, t, n) => {
|
|
21
|
+
if (e.execute) return d(f(o(e.execute, t), e.name, e.timeoutMs), n.runtime, n.abortSignal);
|
|
22
|
+
if (e.handler) {
|
|
23
|
+
let i = e.handler, a = i(t, n);
|
|
24
|
+
return r.isEffect(a) ? d(f(a, e.name, e.timeoutMs), n.runtime, n.abortSignal) : a;
|
|
25
|
+
}
|
|
26
|
+
return Promise.reject(/* @__PURE__ */ Error(`tool '${e.name}' has neither execute nor handler`));
|
|
27
|
+
}, m = (e) => {
|
|
28
|
+
let t = a(e);
|
|
29
|
+
return t && t.type === "object" ? t : {
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {},
|
|
32
|
+
additionalProperties: !1
|
|
33
|
+
};
|
|
34
|
+
}, h = (e) => {
|
|
35
|
+
let t = e.inputJsonSchema;
|
|
36
|
+
return t === void 0 ? m(e.input) : t.type === "object" ? t : {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {},
|
|
39
|
+
additionalProperties: !0
|
|
40
|
+
};
|
|
41
|
+
}, g = (n, a = { store: void 0 }) => {
|
|
42
|
+
let o = {};
|
|
43
|
+
for (let [s, c] of Object.entries(n)) {
|
|
44
|
+
if (c.execution === "client" && (c.execute !== void 0 || c.handler !== void 0)) throw Error(`client tool '${c.name || s}' cannot declare execute or handler`);
|
|
45
|
+
c.execution === "client" ? o[c.name || s] = t({
|
|
46
|
+
description: c.description,
|
|
47
|
+
inputSchema: e(h(c))
|
|
48
|
+
}) : o[c.name || s] = t({
|
|
49
|
+
description: c.description,
|
|
50
|
+
inputSchema: e(h(c)),
|
|
51
|
+
execute: async (e, t) => {
|
|
52
|
+
let n = a.abortSignal, o = t?.abortSignal, s = n !== void 0 && o !== void 0 && n !== o ? AbortSignal.any([n, o]) : o ?? n;
|
|
53
|
+
s?.throwIfAborted();
|
|
54
|
+
let l = {
|
|
55
|
+
...a,
|
|
56
|
+
...t?.toolCallId === void 0 ? {} : { invocationId: t.toolCallId },
|
|
57
|
+
...s === void 0 ? {} : { abortSignal: s }
|
|
58
|
+
}, u = await r.runPromise(i.decodeUnknownEffect(c.input)(e));
|
|
59
|
+
s?.throwIfAborted();
|
|
60
|
+
let d = await p(c, u, l);
|
|
61
|
+
return c.output ? r.runPromise(i.decodeUnknownEffect(c.output)(d)) : d;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return o;
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { g as buildSdkTools, c as defineTool, l as isTool, u as resolveToolModuleHandlers };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { providerFromEnv as e, resolveTranscriptionModel as t } from "./provider.js";
|
|
2
|
+
import { aiCallAttributes as n, withAiCallSpan as r } from "./observe.js";
|
|
3
|
+
import { aiGenerationError as i } from "./api.js";
|
|
4
|
+
import { experimental_transcribe as a } from "ai";
|
|
5
|
+
import { Effect as o } from "effect";
|
|
6
|
+
//#region src/transcribe.ts
|
|
7
|
+
var s = async (e, t) => {
|
|
8
|
+
if ("bytes" in e) return {
|
|
9
|
+
audio: e.bytes,
|
|
10
|
+
mediaType: e.mediaType
|
|
11
|
+
};
|
|
12
|
+
if ("url" in e) {
|
|
13
|
+
let t = await fetch(e.url);
|
|
14
|
+
if (!t.ok) throw Error(`transcribe: GET ${e.url} answered ${t.status}.`);
|
|
15
|
+
let n = t.headers.get("content-type") ?? void 0;
|
|
16
|
+
return {
|
|
17
|
+
audio: new Uint8Array(await t.arrayBuffer()),
|
|
18
|
+
...n === void 0 ? {} : { mediaType: n }
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (t === void 0) throw Error("transcribe: `source.storageRef` needs a `resolveRef` to turn the reference into bytes.\n → pass `resolveRef: (ref) => storage.read(ref)`. It is injected rather than imported so @voltro/ai does not depend on storage; the app owns tenancy and signing for that read.");
|
|
22
|
+
let { bytes: n, mediaType: r } = await t(e.storageRef);
|
|
23
|
+
return {
|
|
24
|
+
audio: n,
|
|
25
|
+
mediaType: r
|
|
26
|
+
};
|
|
27
|
+
}, c = (e) => {
|
|
28
|
+
if (!Array.isArray(e) || e.length === 0) return;
|
|
29
|
+
let t = [];
|
|
30
|
+
for (let n of e) {
|
|
31
|
+
let e = typeof n.startSecond == "number" ? n.startSecond : typeof n.start == "number" ? n.start : void 0, r = typeof n.endSecond == "number" ? n.endSecond : typeof n.end == "number" ? n.end : void 0, i = typeof n.text == "string" ? n.text : void 0;
|
|
32
|
+
if (e === void 0 || r === void 0 || i === void 0) continue;
|
|
33
|
+
let a = typeof n.speaker == "string" ? n.speaker : void 0;
|
|
34
|
+
t.push({
|
|
35
|
+
start: e,
|
|
36
|
+
end: r,
|
|
37
|
+
text: i,
|
|
38
|
+
...a === void 0 ? {} : { speaker: a }
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return t.length > 0 ? t : void 0;
|
|
42
|
+
}, l = (l) => {
|
|
43
|
+
let u = l.provider ?? e();
|
|
44
|
+
return r(n(u, "transcribe"), () => ({}), o.tryPromise({
|
|
45
|
+
try: async () => {
|
|
46
|
+
let { audio: e, mediaType: n } = await s(l.source, l.resolveRef), r = await a({
|
|
47
|
+
model: t(u),
|
|
48
|
+
audio: e,
|
|
49
|
+
...n === void 0 ? {} : { mediaType: n },
|
|
50
|
+
...l.providerOptions === void 0 ? {} : { providerOptions: l.providerOptions }
|
|
51
|
+
}), i = l.timestamps === "none" ? void 0 : c(r.segments);
|
|
52
|
+
return {
|
|
53
|
+
text: r.text,
|
|
54
|
+
...r.language === void 0 ? {} : { language: r.language },
|
|
55
|
+
...r.durationInSeconds === void 0 ? {} : { durationSec: r.durationInSeconds },
|
|
56
|
+
...i === void 0 ? {} : { segments: i },
|
|
57
|
+
...r.providerMetadata === void 0 ? {} : { providerMetadata: r.providerMetadata }
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
catch: (e) => i(e)
|
|
61
|
+
}));
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
export { l as transcribe };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Schema as e } from "effect";
|
|
2
|
+
//#region src/transcriptionEvent.ts
|
|
3
|
+
var t = class extends e.TaggedError()("TranscriptionStreamError", {
|
|
4
|
+
reason: e.Literals([
|
|
5
|
+
"input",
|
|
6
|
+
"unsupported",
|
|
7
|
+
"provider",
|
|
8
|
+
"cancelled"
|
|
9
|
+
]),
|
|
10
|
+
message: e.String
|
|
11
|
+
}) {}, n = e.Struct({
|
|
12
|
+
text: e.String,
|
|
13
|
+
start: e.Number,
|
|
14
|
+
end: e.Number
|
|
15
|
+
}), r = { id: e.optional(e.String) }, i = e.Union([
|
|
16
|
+
e.Struct({
|
|
17
|
+
type: e.Literal("transcript-delta"),
|
|
18
|
+
...r,
|
|
19
|
+
delta: e.String
|
|
20
|
+
}),
|
|
21
|
+
e.Struct({
|
|
22
|
+
type: e.Literal("transcript-partial"),
|
|
23
|
+
...r,
|
|
24
|
+
text: e.String,
|
|
25
|
+
startSecond: e.optional(e.Number),
|
|
26
|
+
durationInSeconds: e.optional(e.Number),
|
|
27
|
+
channelIndex: e.optional(e.Number)
|
|
28
|
+
}),
|
|
29
|
+
e.Struct({
|
|
30
|
+
type: e.Literal("transcript-final"),
|
|
31
|
+
...r,
|
|
32
|
+
text: e.String,
|
|
33
|
+
startSecond: e.optional(e.Number),
|
|
34
|
+
endSecond: e.optional(e.Number),
|
|
35
|
+
channelIndex: e.optional(e.Number)
|
|
36
|
+
}),
|
|
37
|
+
e.Struct({
|
|
38
|
+
type: e.Literal("finish"),
|
|
39
|
+
text: e.String,
|
|
40
|
+
segments: e.Array(n),
|
|
41
|
+
language: e.optional(e.String),
|
|
42
|
+
durationSec: e.optional(e.Number)
|
|
43
|
+
})
|
|
44
|
+
]);
|
|
45
|
+
//#endregion
|
|
46
|
+
export { t as TranscriptionStreamError, i as TranscriptionStreamEvent };
|
package/dist/workflow.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Context } from 'effect';
|
|
1
2
|
import { DataStore } from '@voltro/database';
|
|
2
3
|
import { Effect } from 'effect';
|
|
3
4
|
import { PluginMediaPersistMetadata } from '@voltro/protocol';
|
|
4
|
-
import { Runtime } from 'effect';
|
|
5
5
|
import { Schema } from 'effect';
|
|
6
6
|
import { StepRetryPolicy } from '@voltro/workflow';
|
|
7
7
|
|
|
@@ -39,7 +39,7 @@ declare type AiJsonValue = null | boolean | number | string | {
|
|
|
39
39
|
export declare const aiObjectStep: <A, I>(options: AiObjectStepOptions<A, I>) => Effect.Effect<A, unknown>;
|
|
40
40
|
|
|
41
41
|
export declare interface AiObjectStepOptions<A, I> extends AiStepBaseOptions {
|
|
42
|
-
readonly schema: Schema.
|
|
42
|
+
readonly schema: Schema.Codec<A, I>;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export declare class AiOffloadError extends Error {
|
|
@@ -209,13 +209,15 @@ declare type AnthropicModel = 'claude-opus-4-8' | 'claude-sonnet-4-6' | 'claude-
|
|
|
209
209
|
declare interface AnyTool {
|
|
210
210
|
readonly name: string;
|
|
211
211
|
readonly description: string;
|
|
212
|
-
readonly input: Schema.
|
|
212
|
+
readonly input: Schema.Top;
|
|
213
213
|
/** See `ToolDef.inputJsonSchema` — a foreign parameter schema shown to the
|
|
214
214
|
* model in place of a rendered `input`. */
|
|
215
215
|
readonly inputJsonSchema?: Record<string, unknown>;
|
|
216
|
-
readonly output?: Schema.
|
|
216
|
+
readonly output?: Schema.Top;
|
|
217
217
|
readonly execute?: (input: never) => Effect.Effect<unknown, never, unknown>;
|
|
218
218
|
readonly handler?: ToolHandler<never, unknown>;
|
|
219
|
+
/** Client tools return a pending call to the caller; never run on the server. */
|
|
220
|
+
readonly execution?: 'server' | 'client';
|
|
219
221
|
readonly timeoutMs?: number;
|
|
220
222
|
}
|
|
221
223
|
|
|
@@ -547,18 +549,18 @@ export declare const resolveStepPrompt: (options: Pick<AiStepBaseOptions, "promp
|
|
|
547
549
|
* CLI discovery path passes the real `AppContext`, which is a superset.
|
|
548
550
|
*
|
|
549
551
|
* `runtime` is the caller's ambient Effect `Runtime`. When present, tool
|
|
550
|
-
* bodies are run through it (`
|
|
552
|
+
* bodies are run through it (`Effect.runPromiseWith(runtime)(eff)`) instead of
|
|
551
553
|
* bare `Effect.runPromise`, so a body may `yield*` any service the caller's
|
|
552
554
|
* runtime carries — `JiraService`, the data store layer, `HttpClient`, … —
|
|
553
555
|
* rather than being limited to `R = never`. The agent loop
|
|
554
|
-
* (`streamText`/`runAssistant`) captures `yield* Effect.
|
|
556
|
+
* (`streamText`/`runAssistant`) captures `yield* Effect.context<never>()` and threads
|
|
555
557
|
* it here; without a runtime, behaviour is unchanged. */
|
|
556
558
|
declare interface ToolContext {
|
|
557
559
|
readonly store: unknown;
|
|
558
560
|
readonly request?: {
|
|
559
561
|
readonly subject?: unknown;
|
|
560
562
|
};
|
|
561
|
-
readonly runtime?:
|
|
563
|
+
readonly runtime?: Context.Context<never>;
|
|
562
564
|
/** SDK tool-call identity for this execution, not a durable application idempotency key. */
|
|
563
565
|
readonly invocationId?: string;
|
|
564
566
|
/** Cancellation from either the caller's turn or SDK invocation; Promise handlers must pass it to their I/O. */
|
|
@@ -628,9 +630,9 @@ declare type TranscriptionSource =
|
|
|
628
630
|
/** What a `transcribeStep` journals. Structural, because a durable step's
|
|
629
631
|
* success schema is what a replay decodes through — see `AiStepText`. */
|
|
630
632
|
export declare const TranscriptionStepResult: Schema.Struct<{
|
|
631
|
-
text:
|
|
632
|
-
language: Schema.optional<
|
|
633
|
-
durationSec: Schema.optional<
|
|
633
|
+
readonly text: Schema.String;
|
|
634
|
+
readonly language: Schema.optional<Schema.String>;
|
|
635
|
+
readonly durationSec: Schema.optional<Schema.Number>;
|
|
634
636
|
}>;
|
|
635
637
|
|
|
636
638
|
/** How much timestamp detail to ask for. Providers charge for it. */
|
package/dist/workflow.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { providerFromEnv as e } from "./provider.js";
|
|
2
|
+
import { requireAiBudget as t } from "./budget.js";
|
|
3
|
+
import { gatewayCostUsd as n, recordAiUsageBestEffort as r } from "./cost.js";
|
|
4
|
+
import { generateObject as i, generateObjectWithTools as a, generateText as o, outputJsonSchema as s } from "./api.js";
|
|
5
|
+
import { transcribe as c } from "./transcribe.js";
|
|
6
|
+
import { isRenderedPrompt as l, promptDigest as u, recordPromptVersion as d } from "./prompts.js";
|
|
7
|
+
import { AI_INFERENCES_TABLE as f, inferenceSignalName as p, offloadedInferenceId as m } from "./inferenceQueue.js";
|
|
3
8
|
import { Effect as h, Schema as g } from "effect";
|
|
4
9
|
import { eq as _ } from "@voltro/database";
|
|
5
10
|
import { BudgetHoldExpired as v, CurrentWorkflowExecutionId as y, SuspensionUnavailable as b, WorkflowCannotPark as x, awaitSignalSuspending as S, step as C, suspendForBudget as w } from "@voltro/workflow";
|
|
@@ -24,10 +29,10 @@ var T = {
|
|
|
24
29
|
...t === void 0 ? {} : { system: t }
|
|
25
30
|
} : {
|
|
26
31
|
...i,
|
|
27
|
-
promptDigest:
|
|
32
|
+
promptDigest: u(e),
|
|
28
33
|
promptChars: e.length,
|
|
29
34
|
...t === void 0 ? {} : {
|
|
30
|
-
systemDigest:
|
|
35
|
+
systemDigest: u(t),
|
|
31
36
|
systemChars: t.length
|
|
32
37
|
}
|
|
33
38
|
};
|
|
@@ -42,26 +47,26 @@ var T = {
|
|
|
42
47
|
}, A = (e) => ({
|
|
43
48
|
provider: String(e.name),
|
|
44
49
|
model: String(e.model ?? "unknown")
|
|
45
|
-
}), j = (e, t,
|
|
46
|
-
let
|
|
47
|
-
if (
|
|
48
|
-
let { provider:
|
|
49
|
-
return
|
|
50
|
-
provider:
|
|
51
|
-
model:
|
|
52
|
-
operation:
|
|
50
|
+
}), j = (e, t, i, a, o) => {
|
|
51
|
+
let s = e.store;
|
|
52
|
+
if (s === void 0) return h.void;
|
|
53
|
+
let { provider: c, model: l } = A(t), u = n(a.providerMetadata);
|
|
54
|
+
return r(s, {
|
|
55
|
+
provider: c,
|
|
56
|
+
model: l,
|
|
57
|
+
operation: i,
|
|
53
58
|
agent: e.name,
|
|
54
|
-
usage:
|
|
59
|
+
usage: a.usage,
|
|
55
60
|
...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
|
|
56
|
-
...
|
|
57
|
-
...
|
|
61
|
+
...u === void 0 ? {} : { actualCostUsd: u },
|
|
62
|
+
...o === void 0 ? {} : { prompt: o }
|
|
58
63
|
});
|
|
59
64
|
}, M = (e, t) => {
|
|
60
65
|
let n = e.store;
|
|
61
|
-
return n === void 0 || t === void 0 ? h.void :
|
|
66
|
+
return n === void 0 || t === void 0 ? h.void : d(n, {
|
|
62
67
|
...t.definition,
|
|
63
68
|
digest: t.digest
|
|
64
|
-
}).pipe(h.asVoid, h.
|
|
69
|
+
}).pipe(h.asVoid, h.catchCause(() => h.void));
|
|
65
70
|
}, N = g.Struct({
|
|
66
71
|
text: g.String,
|
|
67
72
|
inputTokens: g.NullOr(g.Number),
|
|
@@ -80,28 +85,28 @@ var T = {
|
|
|
80
85
|
}, L = (e, t, n, r, i, a, o) => h.gen(function* () {
|
|
81
86
|
let s = e.store;
|
|
82
87
|
if (s === void 0) return yield* h.die(new I(e.name));
|
|
83
|
-
let
|
|
84
|
-
if (
|
|
85
|
-
let { provider:
|
|
88
|
+
let c = yield* y;
|
|
89
|
+
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.`));
|
|
90
|
+
let { provider: l, model: u } = A(t), d = m(c, e.name), g = yield* h.promise(() => s.query({
|
|
86
91
|
table: "_voltro_workflow_runs",
|
|
87
|
-
predicate: _("executionId",
|
|
92
|
+
predicate: _("executionId", c),
|
|
88
93
|
order: [],
|
|
89
94
|
take: 1,
|
|
90
95
|
skip: void 0,
|
|
91
96
|
projection: void 0
|
|
92
97
|
})), v = String(g[0]?.tag ?? ""), b = g[0]?.id, x = /* @__PURE__ */ new Date();
|
|
93
|
-
return yield* h.promise(() => s.insertIgnore(
|
|
94
|
-
id:
|
|
98
|
+
return yield* h.promise(() => s.insertIgnore(f, {
|
|
99
|
+
id: d,
|
|
95
100
|
tenantId: e.tenantId ?? null,
|
|
96
|
-
executionId:
|
|
101
|
+
executionId: c,
|
|
97
102
|
workflowName: v,
|
|
98
103
|
runId: typeof b == "string" ? b : null,
|
|
99
|
-
signalName:
|
|
104
|
+
signalName: p(d),
|
|
100
105
|
stepName: e.name,
|
|
101
106
|
status: "pending",
|
|
102
107
|
kind: n,
|
|
103
|
-
provider:
|
|
104
|
-
model:
|
|
108
|
+
provider: l,
|
|
109
|
+
model: u,
|
|
105
110
|
prompt: i.text,
|
|
106
111
|
system: i.system ?? null,
|
|
107
112
|
promptId: i.rendered?.promptId ?? null,
|
|
@@ -116,61 +121,61 @@ var T = {
|
|
|
116
121
|
fence: 0,
|
|
117
122
|
queuedAt: x,
|
|
118
123
|
enqueuedAt: x
|
|
119
|
-
}, { conflictColumns: ["id"] })),
|
|
124
|
+
}, { conflictColumns: ["id"] })), d;
|
|
120
125
|
}), R = (e, t, n, r, i, a, o, s) => h.gen(function* () {
|
|
121
|
-
let
|
|
122
|
-
if (
|
|
123
|
-
let
|
|
126
|
+
let c = yield* b;
|
|
127
|
+
if (c !== void 0) return yield* h.die(new x(`the offloaded call '${e.name}'`, c));
|
|
128
|
+
let l = yield* C({
|
|
124
129
|
name: `${e.name}:enqueue`,
|
|
125
130
|
success: g.String,
|
|
126
131
|
input: i,
|
|
127
132
|
execute: L(e, t, n, r, a, o, s)
|
|
128
133
|
});
|
|
129
134
|
yield* M(e, a.rendered);
|
|
130
|
-
let
|
|
131
|
-
name:
|
|
135
|
+
let u = yield* S({ store: e.store }, {
|
|
136
|
+
name: p(l),
|
|
132
137
|
schema: g.Unknown,
|
|
133
138
|
timeoutMs: e.offloadTimeoutMs ?? 36e5
|
|
134
139
|
});
|
|
135
|
-
return P(
|
|
140
|
+
return P(u) ? yield* h.die(new F(e.name, u.message, u.attempts, u.outcome === "unknown" ? "unknown" : "failed")) : u;
|
|
136
141
|
}), z = class extends Error {
|
|
137
142
|
constructor(e) {
|
|
138
143
|
super(`aiStep('${e}'): budget needs \`store\` — the reservation counter and the hold both live in tables. Pass ctx.store.`), this.name = "AiBudgetMisuseError";
|
|
139
144
|
}
|
|
140
145
|
}, B = (e) => h.gen(function* () {
|
|
141
|
-
let
|
|
142
|
-
if (
|
|
143
|
-
let
|
|
144
|
-
if (
|
|
145
|
-
let
|
|
146
|
-
tenantId:
|
|
147
|
-
limitUsd:
|
|
146
|
+
let n = e.budget;
|
|
147
|
+
if (n === void 0) return;
|
|
148
|
+
let r = e.store;
|
|
149
|
+
if (r === void 0) return yield* h.die(new z(e.name));
|
|
150
|
+
let i = e.tenantId ?? null, a = n.name ?? "ai-usd", o = yield* y, s = () => t(r, {
|
|
151
|
+
tenantId: i,
|
|
152
|
+
limitUsd: n.limitUsd,
|
|
148
153
|
addUsd: 0,
|
|
149
|
-
...
|
|
150
|
-
}).pipe(h.as(null), h.catchTag("AiBudgetExceeded", (e) => h.succeed(e))),
|
|
151
|
-
tenantId:
|
|
152
|
-
limitUsd:
|
|
153
|
-
addUsd:
|
|
154
|
-
...
|
|
154
|
+
...n.since === void 0 ? {} : { since: n.since }
|
|
155
|
+
}).pipe(h.as(null), h.catchTag("AiBudgetExceeded", (e) => h.succeed(e))), c = () => n.estimateUsd === void 0 ? h.void : t(r, {
|
|
156
|
+
tenantId: i,
|
|
157
|
+
limitUsd: n.limitUsd,
|
|
158
|
+
addUsd: n.estimateUsd,
|
|
159
|
+
...o === void 0 ? {} : { reservationId: m(o, JSON.stringify([
|
|
155
160
|
"budget",
|
|
156
|
-
|
|
161
|
+
a,
|
|
157
162
|
e.name
|
|
158
163
|
])) },
|
|
159
|
-
...
|
|
160
|
-
}).pipe(h.asVoid),
|
|
161
|
-
if (
|
|
162
|
-
store:
|
|
163
|
-
budget:
|
|
164
|
-
tenantId:
|
|
165
|
-
executionId:
|
|
166
|
-
workflowName: yield* V(
|
|
164
|
+
...n.since === void 0 ? {} : { since: n.since }
|
|
165
|
+
}).pipe(h.asVoid), l = yield* n.estimateUsd !== void 0 && n.estimateUsd !== 0 ? c().pipe(h.as(null), h.catchTag("AiBudgetExceeded", (e) => h.succeed(e))) : s();
|
|
166
|
+
if (l !== null) return (n.onExceeded ?? "fail") !== "suspend" || o === void 0 ? yield* h.fail(l) : (yield* w({
|
|
167
|
+
store: r,
|
|
168
|
+
budget: a,
|
|
169
|
+
tenantId: i,
|
|
170
|
+
executionId: o,
|
|
171
|
+
workflowName: yield* V(r, o),
|
|
167
172
|
stepName: e.name,
|
|
168
|
-
spentMicroUsd: Math.round(
|
|
169
|
-
limitMicroUsd: Math.round(
|
|
170
|
-
hasHeadroom:
|
|
171
|
-
...
|
|
172
|
-
...
|
|
173
|
-
}).pipe(h.
|
|
173
|
+
spentMicroUsd: Math.round(l.spentUsd * 1e6),
|
|
174
|
+
limitMicroUsd: Math.round(n.limitUsd * 1e6),
|
|
175
|
+
hasHeadroom: s().pipe(h.map((e) => e === null)),
|
|
176
|
+
...n.holdTimeoutMs === void 0 ? {} : { timeoutMs: n.holdTimeoutMs },
|
|
177
|
+
...n.recheckEveryMs === void 0 ? {} : { recheckEveryMs: n.recheckEveryMs }
|
|
178
|
+
}).pipe(h.catch((e) => e instanceof v ? h.die(e) : h.fail(e))), yield* c());
|
|
174
179
|
}), V = (e, t) => h.promise(async () => {
|
|
175
180
|
let n = await e.query({
|
|
176
181
|
table: "_voltro_workflow_runs",
|
|
@@ -182,28 +187,28 @@ var T = {
|
|
|
182
187
|
});
|
|
183
188
|
return String(n[0]?.tag ?? "");
|
|
184
189
|
}), H = (t) => {
|
|
185
|
-
let
|
|
186
|
-
...A(
|
|
190
|
+
let n = t.provider ?? e(), r = k(t), i = {
|
|
191
|
+
...A(n),
|
|
187
192
|
operation: "generateText",
|
|
188
193
|
offloaded: t.offload === !0,
|
|
189
|
-
...O(
|
|
190
|
-
},
|
|
191
|
-
return t.offload === !0 ?
|
|
194
|
+
...O(r.text, r.system, t.recordPrompt ?? "digest", r.rendered)
|
|
195
|
+
}, a = (e) => t.budget === void 0 ? e : h.andThen(B(t), e);
|
|
196
|
+
return t.offload === !0 ? a(R(t, n, "text", null, i, r)) : a(C({
|
|
192
197
|
name: t.name,
|
|
193
198
|
success: N,
|
|
194
|
-
input:
|
|
199
|
+
input: i,
|
|
195
200
|
retry: t.retry ?? T,
|
|
196
|
-
execute:
|
|
197
|
-
prompt:
|
|
198
|
-
provider:
|
|
199
|
-
...
|
|
201
|
+
execute: o({
|
|
202
|
+
prompt: r.text,
|
|
203
|
+
provider: n,
|
|
204
|
+
...r.system === void 0 ? {} : { system: r.system },
|
|
200
205
|
...t.fallbacks === void 0 ? {} : { fallbacks: t.fallbacks },
|
|
201
206
|
...t.maxTokens === void 0 ? {} : { maxTokens: t.maxTokens },
|
|
202
207
|
...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions },
|
|
203
208
|
...t.tools === void 0 ? {} : { tools: t.tools },
|
|
204
209
|
...t.maxSteps === void 0 ? {} : { maxSteps: t.maxSteps },
|
|
205
210
|
...t.toolContext === void 0 ? {} : { toolContext: t.toolContext }
|
|
206
|
-
}).pipe(h.tap((e) => j(t,
|
|
211
|
+
}).pipe(h.tap((e) => j(t, n, "generateText", e, r.rendered)), h.tap(() => M(t, r.rendered)), h.map((e) => ({
|
|
207
212
|
text: e.text,
|
|
208
213
|
inputTokens: e.usage.inputTokens ?? null,
|
|
209
214
|
outputTokens: e.usage.outputTokens ?? null,
|
|
@@ -225,17 +230,17 @@ var T = {
|
|
|
225
230
|
...A(n),
|
|
226
231
|
operation: "transcribe",
|
|
227
232
|
offloaded: t.offload === !0
|
|
228
|
-
},
|
|
229
|
-
return t.offload === !0 ?
|
|
233
|
+
}, a = (e) => t.budget === void 0 ? e : h.andThen(B(t), e);
|
|
234
|
+
return t.offload === !0 ? a(R(t, n, "transcription", null, i, {
|
|
230
235
|
text: "",
|
|
231
236
|
system: void 0,
|
|
232
237
|
rendered: void 0
|
|
233
|
-
}, r)) :
|
|
238
|
+
}, r)) : a(C({
|
|
234
239
|
name: t.name,
|
|
235
240
|
success: U,
|
|
236
241
|
input: i,
|
|
237
242
|
retry: t.retry ?? T,
|
|
238
|
-
execute:
|
|
243
|
+
execute: c({
|
|
239
244
|
...r,
|
|
240
245
|
provider: n,
|
|
241
246
|
...t.resolveRef === void 0 ? {} : { resolveRef: t.resolveRef }
|
|
@@ -261,46 +266,46 @@ var T = {
|
|
|
261
266
|
modality: t.modality,
|
|
262
267
|
...O(r.text, void 0, t.recordPrompt ?? "digest", r.rendered)
|
|
263
268
|
};
|
|
264
|
-
return ((e) => t.budget === void 0 ? e : h.
|
|
269
|
+
return ((e) => t.budget === void 0 ? e : h.andThen(B(t), e))(R({
|
|
265
270
|
...t,
|
|
266
271
|
offload: !0
|
|
267
272
|
}, n, "media", null, a, r, void 0, i));
|
|
268
|
-
}, K = (
|
|
269
|
-
let
|
|
270
|
-
...A(
|
|
273
|
+
}, K = (t) => {
|
|
274
|
+
let n = t.provider ?? e(), r = k(t), o = {
|
|
275
|
+
...A(n),
|
|
271
276
|
operation: "generateObject",
|
|
272
|
-
offloaded:
|
|
273
|
-
...O(
|
|
274
|
-
}, c = (e) =>
|
|
275
|
-
return
|
|
276
|
-
let e = yield*
|
|
277
|
-
return yield* g.
|
|
277
|
+
offloaded: t.offload === !0,
|
|
278
|
+
...O(r.text, r.system, t.recordPrompt ?? "digest", r.rendered)
|
|
279
|
+
}, c = (e) => t.budget === void 0 ? e : h.andThen(B(t), e);
|
|
280
|
+
return t.offload === !0 ? c(h.gen(function* () {
|
|
281
|
+
let e = yield* s(t.schema, "aiObjectStep"), i = yield* R(t, n, "object", e, o, r);
|
|
282
|
+
return yield* g.decodeUnknownEffect(t.schema)(i);
|
|
278
283
|
})) : c(C({
|
|
279
|
-
name:
|
|
280
|
-
success:
|
|
281
|
-
input:
|
|
282
|
-
retry:
|
|
283
|
-
execute: (
|
|
284
|
-
prompt:
|
|
285
|
-
schema:
|
|
286
|
-
provider:
|
|
287
|
-
...
|
|
288
|
-
...
|
|
289
|
-
...
|
|
290
|
-
...
|
|
291
|
-
}) :
|
|
292
|
-
prompt:
|
|
293
|
-
schema:
|
|
294
|
-
provider:
|
|
295
|
-
tools:
|
|
296
|
-
...
|
|
297
|
-
...
|
|
298
|
-
...
|
|
299
|
-
...
|
|
300
|
-
...
|
|
301
|
-
...
|
|
302
|
-
})).pipe(h.tap((e) => j(
|
|
284
|
+
name: t.name,
|
|
285
|
+
success: t.schema,
|
|
286
|
+
input: o,
|
|
287
|
+
retry: t.retry ?? T,
|
|
288
|
+
execute: (t.tools === void 0 ? i({
|
|
289
|
+
prompt: r.text,
|
|
290
|
+
schema: t.schema,
|
|
291
|
+
provider: n,
|
|
292
|
+
...r.system === void 0 ? {} : { system: r.system },
|
|
293
|
+
...t.fallbacks === void 0 ? {} : { fallbacks: t.fallbacks },
|
|
294
|
+
...t.maxTokens === void 0 ? {} : { maxTokens: t.maxTokens },
|
|
295
|
+
...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
|
|
296
|
+
}) : a({
|
|
297
|
+
prompt: r.text,
|
|
298
|
+
schema: t.schema,
|
|
299
|
+
provider: n,
|
|
300
|
+
tools: t.tools,
|
|
301
|
+
...t.maxSteps === void 0 ? {} : { maxSteps: t.maxSteps },
|
|
302
|
+
...t.toolContext === void 0 ? {} : { toolContext: t.toolContext },
|
|
303
|
+
...r.system === void 0 ? {} : { system: r.system },
|
|
304
|
+
...t.fallbacks === void 0 ? {} : { fallbacks: t.fallbacks },
|
|
305
|
+
...t.maxTokens === void 0 ? {} : { maxTokens: t.maxTokens },
|
|
306
|
+
...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
|
|
307
|
+
})).pipe(h.tap((e) => j(t, n, "generateObject", e, r.rendered)), h.tap(() => M(t, r.rendered)), h.map((e) => e.object))
|
|
303
308
|
}));
|
|
304
309
|
};
|
|
305
310
|
//#endregion
|
|
306
|
-
export { T as AI_STEP_RETRY, z as AiBudgetMisuseError, F as AiOffloadError, I as AiOffloadMisuseError, D as DEFAULT_AI_BUDGET_NAME, E as DEFAULT_OFFLOAD_TIMEOUT_MS, U as TranscriptionStepResult, K as aiObjectStep, H as aiStep, G as mediaStep,
|
|
311
|
+
export { T as AI_STEP_RETRY, z as AiBudgetMisuseError, F as AiOffloadError, I as AiOffloadMisuseError, D as DEFAULT_AI_BUDGET_NAME, E as DEFAULT_OFFLOAD_TIMEOUT_MS, U as TranscriptionStepResult, K as aiObjectStep, H as aiStep, G as mediaStep, u as promptDigest, O as promptRecordFor, k as resolveStepPrompt, W as transcribeStep };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.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",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@ai-sdk/anthropic": "^4.0.56",
|
|
57
57
|
"@ai-sdk/openai": "^4.0.69",
|
|
58
|
-
"@voltro/cache": "0.
|
|
59
|
-
"@voltro/database": "0.
|
|
60
|
-
"@voltro/protocol": "0.
|
|
61
|
-
"@voltro/workflow": "0.
|
|
58
|
+
"@voltro/cache": "0.86.0",
|
|
59
|
+
"@voltro/database": "0.86.0",
|
|
60
|
+
"@voltro/protocol": "0.86.0",
|
|
61
|
+
"@voltro/workflow": "0.86.0",
|
|
62
62
|
"ajv": "^8.20.0",
|
|
63
63
|
"ajv-formats": "^3.0.1",
|
|
64
64
|
"ws": "^8.21.3"
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"@ai-sdk/gateway": "^4.0.74",
|
|
68
68
|
"@ai-sdk/provider": "^4.0.10",
|
|
69
69
|
"ai": "^7.0.92",
|
|
70
|
-
"effect": "
|
|
70
|
+
"effect": "4.0.1"
|
|
71
71
|
},
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"access": "public"
|