@tanstack/ai 0.42.0 → 0.43.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/README.md +15 -1
- package/dist/esm/activities/chat/adapter.js +23 -16
- package/dist/esm/activities/chat/adapter.js.map +1 -1
- package/dist/esm/activities/chat/agent-loop-strategies.d.ts +5 -36
- package/dist/esm/activities/chat/agent-loop-strategies.js +75 -21
- package/dist/esm/activities/chat/agent-loop-strategies.js.map +1 -1
- package/dist/esm/activities/chat/cancel.d.ts +40 -0
- package/dist/esm/activities/chat/cancel.js +54 -0
- package/dist/esm/activities/chat/cancel.js.map +1 -0
- package/dist/esm/activities/chat/index.d.ts +28 -21
- package/dist/esm/activities/chat/index.js +2100 -1813
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/mcp/manager.d.ts +2 -2
- package/dist/esm/activities/chat/mcp/manager.js +90 -77
- package/dist/esm/activities/chat/mcp/manager.js.map +1 -1
- package/dist/esm/activities/chat/mcp/types.d.ts +2 -2
- package/dist/esm/activities/chat/messages.js +397 -346
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/middleware/builder.js +17 -15
- package/dist/esm/activities/chat/middleware/builder.js.map +1 -1
- package/dist/esm/activities/chat/middleware/capabilities.js +78 -43
- package/dist/esm/activities/chat/middleware/capabilities.js.map +1 -1
- package/dist/esm/activities/chat/middleware/compose.d.ts +94 -1
- package/dist/esm/activities/chat/middleware/compose.js +623 -531
- package/dist/esm/activities/chat/middleware/compose.js.map +1 -1
- package/dist/esm/activities/chat/middleware/define.js +12 -5
- package/dist/esm/activities/chat/middleware/define.js.map +1 -1
- package/dist/esm/activities/chat/middleware/index.d.ts +5 -1
- package/dist/esm/activities/chat/middleware/locks.d.ts +50 -0
- package/dist/esm/activities/chat/middleware/locks.js +71 -0
- package/dist/esm/activities/chat/middleware/locks.js.map +1 -0
- package/dist/esm/activities/chat/middleware/pending-turn.d.ts +15 -0
- package/dist/esm/activities/chat/middleware/pending-turn.js +35 -0
- package/dist/esm/activities/chat/middleware/pending-turn.js.map +1 -0
- package/dist/esm/activities/chat/middleware/run-disconnect.d.ts +23 -0
- package/dist/esm/activities/chat/middleware/run-disconnect.js +42 -0
- package/dist/esm/activities/chat/middleware/run-disconnect.js.map +1 -0
- package/dist/esm/activities/chat/middleware/run-store.d.ts +283 -0
- package/dist/esm/activities/chat/middleware/run-store.js +176 -0
- package/dist/esm/activities/chat/middleware/run-store.js.map +1 -0
- package/dist/esm/activities/chat/middleware/sandbox-runtime.js +14 -8
- package/dist/esm/activities/chat/middleware/sandbox-runtime.js.map +1 -1
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +79 -70
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +1 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +59 -2
- package/dist/esm/activities/chat/middleware/validate.js +23 -28
- package/dist/esm/activities/chat/middleware/validate.js.map +1 -1
- package/dist/esm/activities/chat/stream/json-parser.js +39 -25
- package/dist/esm/activities/chat/stream/json-parser.js.map +1 -1
- package/dist/esm/activities/chat/stream/message-updaters.js +275 -234
- package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +24 -4
- package/dist/esm/activities/chat/stream/processor.js +1341 -1542
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/stream/strategies.js +69 -53
- package/dist/esm/activities/chat/stream/strategies.js.map +1 -1
- package/dist/esm/activities/chat/tools/approval-schema.d.ts +19 -0
- package/dist/esm/activities/chat/tools/approval-schema.js +117 -0
- package/dist/esm/activities/chat/tools/approval-schema.js.map +1 -0
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js +164 -191
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +1 -1
- package/dist/esm/activities/chat/tools/lazy-tools.js +24 -12
- package/dist/esm/activities/chat/tools/lazy-tools.js.map +1 -1
- package/dist/esm/activities/chat/tools/schema-converter.js +293 -146
- package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +18 -2
- package/dist/esm/activities/chat/tools/tool-calls.js +522 -531
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-definition.d.ts +75 -16
- package/dist/esm/activities/chat/tools/tool-definition.js +95 -23
- package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
- package/dist/esm/activities/error-payload.js +85 -47
- package/dist/esm/activities/error-payload.js.map +1 -1
- package/dist/esm/activities/generateAudio/adapter.js +22 -15
- package/dist/esm/activities/generateAudio/adapter.js.map +1 -1
- package/dist/esm/activities/generateAudio/index.d.ts +4 -0
- package/dist/esm/activities/generateAudio/index.js +141 -105
- package/dist/esm/activities/generateAudio/index.js.map +1 -1
- package/dist/esm/activities/generateImage/adapter.js +22 -15
- package/dist/esm/activities/generateImage/adapter.js.map +1 -1
- package/dist/esm/activities/generateImage/index.d.ts +4 -0
- package/dist/esm/activities/generateImage/index.js +155 -111
- package/dist/esm/activities/generateImage/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/adapter.js +22 -15
- package/dist/esm/activities/generateSpeech/adapter.js.map +1 -1
- package/dist/esm/activities/generateSpeech/index.d.ts +4 -0
- package/dist/esm/activities/generateSpeech/index.js +159 -110
- package/dist/esm/activities/generateSpeech/index.js.map +1 -1
- package/dist/esm/activities/generateTranscription/adapter.js +22 -15
- package/dist/esm/activities/generateTranscription/adapter.js.map +1 -1
- package/dist/esm/activities/generateTranscription/index.d.ts +4 -0
- package/dist/esm/activities/generateTranscription/index.js +159 -100
- package/dist/esm/activities/generateTranscription/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/adapter.js +36 -29
- package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
- package/dist/esm/activities/generateVideo/index.d.ts +143 -19
- package/dist/esm/activities/generateVideo/index.js +456 -279
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/snap.js +60 -48
- package/dist/esm/activities/generateVideo/snap.js.map +1 -1
- package/dist/esm/activities/index.js +8 -34
- package/dist/esm/activities/middleware/index.d.ts +1 -1
- package/dist/esm/activities/middleware/run.d.ts +10 -0
- package/dist/esm/activities/middleware/run.js +53 -29
- package/dist/esm/activities/middleware/run.js.map +1 -1
- package/dist/esm/activities/middleware/types.d.ts +44 -6
- package/dist/esm/activities/stream-generation-result.d.ts +4 -1
- package/dist/esm/activities/stream-generation-result.js +79 -44
- package/dist/esm/activities/stream-generation-result.js.map +1 -1
- package/dist/esm/activities/summarize/adapter.js +22 -15
- package/dist/esm/activities/summarize/adapter.js.map +1 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.js +252 -202
- package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
- package/dist/esm/activities/summarize/index.d.ts +27 -0
- package/dist/esm/activities/summarize/index.js +268 -102
- package/dist/esm/activities/summarize/index.js.map +1 -1
- package/dist/esm/adapter-internals.d.ts +2 -1
- package/dist/esm/adapter-internals.js +4 -11
- package/dist/esm/client.d.ts +25 -3
- package/dist/esm/client.js +131 -64
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/custom-events.d.ts +76 -0
- package/dist/esm/custom-events.js +37 -0
- package/dist/esm/custom-events.js.map +1 -0
- package/dist/esm/delivery-detach.d.ts +50 -0
- package/dist/esm/delivery-detach.js +71 -0
- package/dist/esm/delivery-detach.js.map +1 -0
- package/dist/esm/delivery-disconnect.d.ts +62 -0
- package/dist/esm/delivery-disconnect.js +81 -0
- package/dist/esm/delivery-disconnect.js.map +1 -0
- package/dist/esm/extend-adapter.js +19 -17
- package/dist/esm/extend-adapter.js.map +1 -1
- package/dist/esm/index.d.ts +24 -6
- package/dist/esm/index.js +30 -98
- package/dist/esm/interrupt-resume.d.ts +71 -0
- package/dist/esm/interrupt-resume.js +438 -0
- package/dist/esm/interrupt-resume.js.map +1 -0
- package/dist/esm/interrupt-serialization.d.ts +12 -0
- package/dist/esm/interrupt-serialization.js +178 -0
- package/dist/esm/interrupt-serialization.js.map +1 -0
- package/dist/esm/interrupts.d.ts +84 -0
- package/dist/esm/interrupts.js +31 -0
- package/dist/esm/interrupts.js.map +1 -0
- package/dist/esm/locks.d.ts +10 -0
- package/dist/esm/locks.js +2 -0
- package/dist/esm/logger/console-logger.js +101 -78
- package/dist/esm/logger/console-logger.js.map +1 -1
- package/dist/esm/logger/internal-logger.js +104 -89
- package/dist/esm/logger/internal-logger.js.map +1 -1
- package/dist/esm/logger/resolve.js +54 -49
- package/dist/esm/logger/resolve.js.map +1 -1
- package/dist/esm/logger/types.d.ts +1 -1
- package/dist/esm/middlewares/content-guard.js +142 -148
- package/dist/esm/middlewares/content-guard.js.map +1 -1
- package/dist/esm/middlewares/index.js +2 -6
- package/dist/esm/middlewares/otel.d.ts +3 -1
- package/dist/esm/middlewares/otel.js +599 -732
- package/dist/esm/middlewares/otel.js.map +1 -1
- package/dist/esm/middlewares/usage-attributes.js +47 -40
- package/dist/esm/middlewares/usage-attributes.js.map +1 -1
- package/dist/esm/realtime/event-emitter.js +24 -25
- package/dist/esm/realtime/event-emitter.js.map +1 -1
- package/dist/esm/realtime/index.d.ts +5 -9
- package/dist/esm/realtime/index.js +29 -6
- package/dist/esm/realtime/index.js.map +1 -1
- package/dist/esm/scope.d.ts +47 -0
- package/dist/esm/stream-durability.d.ts +171 -0
- package/dist/esm/stream-durability.js +295 -0
- package/dist/esm/stream-durability.js.map +1 -0
- package/dist/esm/stream-to-response.d.ts +178 -13
- package/dist/esm/stream-to-response.js +663 -115
- package/dist/esm/stream-to-response.js.map +1 -1
- package/dist/esm/strip-to-spec-middleware.js +30 -16
- package/dist/esm/strip-to-spec-middleware.js.map +1 -1
- package/dist/esm/system-prompts.js +27 -21
- package/dist/esm/system-prompts.js.map +1 -1
- package/dist/esm/tool-registry.js +72 -45
- package/dist/esm/tool-registry.js.map +1 -1
- package/dist/esm/tools/provider-tool.js +14 -5
- package/dist/esm/tools/provider-tool.js.map +1 -1
- package/dist/esm/types.d.ts +321 -42
- package/dist/esm/types.js +2 -0
- package/dist/esm/utilities/ag-ui-wire.js +79 -93
- package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
- package/dist/esm/utilities/chat-params.d.ts +26 -4
- package/dist/esm/utilities/chat-params.js +218 -92
- package/dist/esm/utilities/chat-params.js.map +1 -1
- package/dist/esm/utilities/errors.js +28 -18
- package/dist/esm/utilities/errors.js.map +1 -1
- package/dist/esm/utilities/media-prompt.js +46 -41
- package/dist/esm/utilities/media-prompt.js.map +1 -1
- package/dist/esm/utilities/numbers.js +13 -10
- package/dist/esm/utilities/numbers.js.map +1 -1
- package/dist/esm/utilities/provider-executed.js +20 -11
- package/dist/esm/utilities/provider-executed.js.map +1 -1
- package/dist/esm/utilities/sampling-keys.js +31 -19
- package/dist/esm/utilities/sampling-keys.js.map +1 -1
- package/dist/esm/utilities/tool-result.js +42 -30
- package/dist/esm/utilities/tool-result.js.map +1 -1
- package/dist/esm/utilities/usage.js +27 -9
- package/dist/esm/utilities/usage.js.map +1 -1
- package/dist/esm/utils.js +26 -18
- package/dist/esm/utils.js.map +1 -1
- package/package.json +10 -6
- package/skills/ai-core/SKILL.md +69 -18
- package/skills/ai-core/adapter-configuration/SKILL.md +44 -21
- package/skills/ai-core/adapter-configuration/references/anthropic-adapter.md +1 -3
- package/skills/ai-core/adapter-configuration/references/byteplus-adapter.md +148 -0
- package/skills/ai-core/adapter-configuration/references/gemini-adapter.md +2 -6
- package/skills/ai-core/adapter-configuration/references/groq-adapter.md +2 -6
- package/skills/ai-core/adapter-configuration/references/openai-adapter.md +1 -3
- package/skills/ai-core/ag-ui-protocol/SKILL.md +1 -1
- package/skills/ai-core/chat-experience/SKILL.md +98 -11
- package/skills/ai-core/client-persistence/SKILL.md +277 -0
- package/skills/ai-core/custom-backend-integration/SKILL.md +1 -1
- package/skills/ai-core/debug-logging/SKILL.md +1 -1
- package/skills/ai-core/locks/SKILL.md +143 -0
- package/skills/ai-core/media-generation/SKILL.md +144 -12
- package/skills/ai-core/middleware/SKILL.md +258 -33
- package/skills/ai-core/structured-outputs/SKILL.md +1 -1
- package/skills/ai-core/tool-calling/SKILL.md +54 -61
- package/src/activities/chat/agent-loop-strategies.ts +5 -39
- package/src/activities/chat/cancel.ts +81 -0
- package/src/activities/chat/index.ts +1091 -200
- package/src/activities/chat/mcp/manager.ts +4 -4
- package/src/activities/chat/mcp/types.ts +2 -2
- package/src/activities/chat/messages.ts +5 -3
- package/src/activities/chat/middleware/builder.ts +1 -1
- package/src/activities/chat/middleware/compose.ts +186 -9
- package/src/activities/chat/middleware/index.ts +26 -0
- package/src/activities/chat/middleware/locks.ts +102 -0
- package/src/activities/chat/middleware/pending-turn.ts +47 -0
- package/src/activities/chat/middleware/run-disconnect.ts +62 -0
- package/src/activities/chat/middleware/run-store.ts +412 -0
- package/src/activities/chat/middleware/types.ts +62 -1
- package/src/activities/chat/stream/processor.ts +189 -5
- package/src/activities/chat/tools/approval-schema.ts +205 -0
- package/src/activities/chat/tools/tool-calls.ts +106 -13
- package/src/activities/chat/tools/tool-definition.ts +210 -39
- package/src/activities/generateAudio/index.ts +20 -3
- package/src/activities/generateImage/index.ts +20 -3
- package/src/activities/generateSpeech/index.ts +25 -3
- package/src/activities/generateTranscription/index.ts +26 -3
- package/src/activities/generateVideo/index.ts +345 -82
- package/src/activities/middleware/index.ts +2 -0
- package/src/activities/middleware/run.ts +31 -0
- package/src/activities/middleware/types.ts +49 -5
- package/src/activities/stream-generation-result.ts +30 -2
- package/src/activities/summarize/chat-stream-summarize.ts +5 -0
- package/src/activities/summarize/index.ts +200 -10
- package/src/adapter-internals.ts +10 -1
- package/src/client.ts +244 -0
- package/src/custom-events.ts +107 -0
- package/src/delivery-detach.ts +72 -0
- package/src/delivery-disconnect.ts +84 -0
- package/src/index.ts +138 -1
- package/src/interrupt-resume.ts +824 -0
- package/src/interrupt-serialization.ts +183 -0
- package/src/interrupts.ts +146 -0
- package/src/locks.ts +17 -0
- package/src/logger/types.ts +1 -1
- package/src/middlewares/otel.ts +23 -5
- package/src/realtime/index.ts +5 -9
- package/src/scope.ts +47 -0
- package/src/stream-durability.ts +598 -0
- package/src/stream-to-response.ts +1051 -95
- package/src/strip-to-spec-middleware.ts +3 -3
- package/src/types.ts +405 -45
- package/src/utilities/chat-params.ts +245 -55
- package/dist/esm/activities/index.js.map +0 -1
- package/dist/esm/adapter-internals.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/middlewares/index.js.map +0 -1
|
@@ -1,54 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
//#region src/activities/error-payload.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared error-narrowing helper for activities that convert thrown values
|
|
4
|
+
* into structured `RUN_ERROR` events.
|
|
5
|
+
*
|
|
6
|
+
* Accepts Error instances, objects with string-ish `message`/`code`, or bare
|
|
7
|
+
* strings; always returns a shape safe to serialize. Never leaks the full
|
|
8
|
+
* error object (which may carry request/response state from an SDK).
|
|
9
|
+
*
|
|
10
|
+
* Abort-shaped errors (DOM `AbortError`, OpenAI `APIUserAbortError`,
|
|
11
|
+
* OpenRouter `RequestAbortedError`) are normalized to a stable
|
|
12
|
+
* `{ message: 'Request aborted', code: 'aborted' }` shape so callers can
|
|
13
|
+
* discriminate user-initiated cancellation from other failures without
|
|
14
|
+
* matching on provider-specific message strings.
|
|
15
|
+
*/
|
|
16
|
+
var ABORT_ERROR_NAMES = /* @__PURE__ */ new Set([
|
|
17
|
+
"AbortError",
|
|
18
|
+
"APIUserAbortError",
|
|
19
|
+
"RequestAbortedError"
|
|
5
20
|
]);
|
|
6
21
|
function normalizeCode(codeField) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return String(codeField);
|
|
10
|
-
}
|
|
11
|
-
return void 0;
|
|
22
|
+
if (typeof codeField === "string") return codeField;
|
|
23
|
+
if (typeof codeField === "number" && Number.isFinite(codeField)) return String(codeField);
|
|
12
24
|
}
|
|
13
25
|
function toRunErrorPayload(error, fallbackMessage = "Unknown error occurred") {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
if (error && typeof error === "object") {
|
|
27
|
+
const name = error.name;
|
|
28
|
+
if (typeof name === "string" && ABORT_ERROR_NAMES.has(name)) return {
|
|
29
|
+
message: "Request aborted",
|
|
30
|
+
code: "aborted"
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (error instanceof Error) {
|
|
34
|
+
const codeField = error.code;
|
|
35
|
+
return {
|
|
36
|
+
message: error.message || fallbackMessage,
|
|
37
|
+
code: normalizeCode(codeField)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (typeof error === "object" && error !== null) {
|
|
41
|
+
const messageField = error.message;
|
|
42
|
+
const codeField = error.code;
|
|
43
|
+
return {
|
|
44
|
+
message: typeof messageField === "string" && messageField.length > 0 ? messageField : fallbackMessage,
|
|
45
|
+
code: normalizeCode(codeField)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (typeof error === "string" && error.length > 0) return {
|
|
49
|
+
message: error,
|
|
50
|
+
code: void 0
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
message: fallbackMessage,
|
|
54
|
+
code: void 0
|
|
55
|
+
};
|
|
39
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Extract the provider's *structured error body* from a thrown value, to attach
|
|
59
|
+
* as the AG-UI `rawEvent` on a RUN_ERROR event. This is the recoverable upstream
|
|
60
|
+
* detail (provider name, the upstream model's error JSON, rate-limit/overload
|
|
61
|
+
* codes, etc.) that `toRunErrorPayload`'s `{ message, code }` deliberately drops.
|
|
62
|
+
*
|
|
63
|
+
* Security boundary: only known provider-response-body fields are forwarded —
|
|
64
|
+
* never the raw SDK exception object, which can carry request metadata such as
|
|
65
|
+
* auth headers or request ids. The recognized sources, in priority order:
|
|
66
|
+
*
|
|
67
|
+
* - `error.rawEvent` — a provider body an adapter attached explicitly (e.g. the
|
|
68
|
+
* OpenRouter mid-stream `chunk.error`).
|
|
69
|
+
* - `error.error` (object) — the parsed provider response body exposed by SDK
|
|
70
|
+
* `APIError` instances (OpenAI/Anthropic `{ type, message, code, param }`,
|
|
71
|
+
* OpenRouter typed errors whose `.error` carries `.metadata`). This is
|
|
72
|
+
* provider-shaped data, distinct from `.headers` / `.request_id`.
|
|
73
|
+
* - `error.metadata` — OpenRouter's `provider_name` + raw upstream body, when
|
|
74
|
+
* surfaced directly on the thrown error.
|
|
75
|
+
*
|
|
76
|
+
* Returns `undefined` when no structured provider body is present, so callers
|
|
77
|
+
* omit the field entirely rather than setting it to `null`:
|
|
78
|
+
*
|
|
79
|
+
* const rawEvent = toRunErrorRawEvent(error)
|
|
80
|
+
* yield { type: EventType.RUN_ERROR, ..., ...(rawEvent !== undefined && { rawEvent }) }
|
|
81
|
+
*/
|
|
40
82
|
function toRunErrorRawEvent(error) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
if (e.metadata !== void 0 && e.metadata !== null) return e.metadata;
|
|
48
|
-
return void 0;
|
|
83
|
+
if (!error || typeof error !== "object") return void 0;
|
|
84
|
+
const e = error;
|
|
85
|
+
if (e.rawEvent !== void 0 && e.rawEvent !== null) return e.rawEvent;
|
|
86
|
+
if (e.error !== void 0 && e.error !== null && typeof e.error === "object") return e.error;
|
|
87
|
+
if (e.metadata !== void 0 && e.metadata !== null) return e.metadata;
|
|
49
88
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//# sourceMappingURL=error-payload.js.map
|
|
89
|
+
//#endregion
|
|
90
|
+
export { toRunErrorPayload, toRunErrorRawEvent };
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=error-payload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-payload.js","sources":["../../../src/activities/error-payload.ts"],"sourcesContent":["/**\n * Shared error-narrowing helper for activities that convert thrown values\n * into structured `RUN_ERROR` events.\n *\n * Accepts Error instances, objects with string-ish `message`/`code`, or bare\n * strings; always returns a shape safe to serialize. Never leaks the full\n * error object (which may carry request/response state from an SDK).\n *\n * Abort-shaped errors (DOM `AbortError`, OpenAI `APIUserAbortError`,\n * OpenRouter `RequestAbortedError`) are normalized to a stable\n * `{ message: 'Request aborted', code: 'aborted' }` shape so callers can\n * discriminate user-initiated cancellation from other failures without\n * matching on provider-specific message strings.\n */\nconst ABORT_ERROR_NAMES = new Set([\n 'AbortError',\n 'APIUserAbortError',\n 'RequestAbortedError',\n])\n\n// HTTP status codes carried as numbers (e.g. `error.status = 429`) are a\n// common variant on SDK error classes; coerce so the resulting `code` field\n// is stable as a string for downstream consumers.\nfunction normalizeCode(codeField: unknown): string | undefined {\n if (typeof codeField === 'string') return codeField\n if (typeof codeField === 'number' && Number.isFinite(codeField)) {\n return String(codeField)\n }\n return undefined\n}\n\nexport function toRunErrorPayload(\n error: unknown,\n fallbackMessage = 'Unknown error occurred',\n): { message: string; code: string | undefined } {\n if (error && typeof error === 'object') {\n const name = (error as { name?: unknown }).name\n if (typeof name === 'string' && ABORT_ERROR_NAMES.has(name)) {\n return { message: 'Request aborted', code: 'aborted' }\n }\n }\n if (error instanceof Error) {\n const codeField = (error as Error & { code?: unknown }).code\n return {\n message: error.message || fallbackMessage,\n code: normalizeCode(codeField),\n }\n }\n if (typeof error === 'object' && error !== null) {\n const messageField = (error as { message?: unknown }).message\n const codeField = (error as { code?: unknown }).code\n return {\n message:\n typeof messageField === 'string' && messageField.length > 0\n ? messageField\n : fallbackMessage,\n code: normalizeCode(codeField),\n }\n }\n if (typeof error === 'string' && error.length > 0) {\n return { message: error, code: undefined }\n }\n return { message: fallbackMessage, code: undefined }\n}\n\n/**\n * Extract the provider's *structured error body* from a thrown value, to attach\n * as the AG-UI `rawEvent` on a RUN_ERROR event. This is the recoverable upstream\n * detail (provider name, the upstream model's error JSON, rate-limit/overload\n * codes, etc.) that `toRunErrorPayload`'s `{ message, code }` deliberately drops.\n *\n * Security boundary: only known provider-response-body fields are forwarded —\n * never the raw SDK exception object, which can carry request metadata such as\n * auth headers or request ids. The recognized sources, in priority order:\n *\n * - `error.rawEvent` — a provider body an adapter attached explicitly (e.g. the\n * OpenRouter mid-stream `chunk.error`).\n * - `error.error` (object) — the parsed provider response body exposed by SDK\n * `APIError` instances (OpenAI/Anthropic `{ type, message, code, param }`,\n * OpenRouter typed errors whose `.error` carries `.metadata`). This is\n * provider-shaped data, distinct from `.headers` / `.request_id`.\n * - `error.metadata` — OpenRouter's `provider_name` + raw upstream body, when\n * surfaced directly on the thrown error.\n *\n * Returns `undefined` when no structured provider body is present, so callers\n * omit the field entirely rather than setting it to `null`:\n *\n * const rawEvent = toRunErrorRawEvent(error)\n * yield { type: EventType.RUN_ERROR, ..., ...(rawEvent !== undefined && { rawEvent }) }\n */\nexport function toRunErrorRawEvent(error: unknown): unknown {\n if (!error || typeof error !== 'object') return undefined\n const e = error as {\n rawEvent?: unknown\n error?: unknown\n metadata?: unknown\n }\n if (e.rawEvent !== undefined && e.rawEvent !== null) return e.rawEvent\n if (\n e.error !== undefined &&\n e.error !== null &&\n typeof e.error === 'object'\n ) {\n return e.error\n }\n if (e.metadata !== undefined && e.metadata !== null) return e.metadata\n return undefined\n}\n"],"
|
|
1
|
+
{"version":3,"file":"error-payload.js","names":[],"sources":["../../../src/activities/error-payload.ts"],"sourcesContent":["/**\n * Shared error-narrowing helper for activities that convert thrown values\n * into structured `RUN_ERROR` events.\n *\n * Accepts Error instances, objects with string-ish `message`/`code`, or bare\n * strings; always returns a shape safe to serialize. Never leaks the full\n * error object (which may carry request/response state from an SDK).\n *\n * Abort-shaped errors (DOM `AbortError`, OpenAI `APIUserAbortError`,\n * OpenRouter `RequestAbortedError`) are normalized to a stable\n * `{ message: 'Request aborted', code: 'aborted' }` shape so callers can\n * discriminate user-initiated cancellation from other failures without\n * matching on provider-specific message strings.\n */\nconst ABORT_ERROR_NAMES = new Set([\n 'AbortError',\n 'APIUserAbortError',\n 'RequestAbortedError',\n])\n\n// HTTP status codes carried as numbers (e.g. `error.status = 429`) are a\n// common variant on SDK error classes; coerce so the resulting `code` field\n// is stable as a string for downstream consumers.\nfunction normalizeCode(codeField: unknown): string | undefined {\n if (typeof codeField === 'string') return codeField\n if (typeof codeField === 'number' && Number.isFinite(codeField)) {\n return String(codeField)\n }\n return undefined\n}\n\nexport function toRunErrorPayload(\n error: unknown,\n fallbackMessage = 'Unknown error occurred',\n): { message: string; code: string | undefined } {\n if (error && typeof error === 'object') {\n const name = (error as { name?: unknown }).name\n if (typeof name === 'string' && ABORT_ERROR_NAMES.has(name)) {\n return { message: 'Request aborted', code: 'aborted' }\n }\n }\n if (error instanceof Error) {\n const codeField = (error as Error & { code?: unknown }).code\n return {\n message: error.message || fallbackMessage,\n code: normalizeCode(codeField),\n }\n }\n if (typeof error === 'object' && error !== null) {\n const messageField = (error as { message?: unknown }).message\n const codeField = (error as { code?: unknown }).code\n return {\n message:\n typeof messageField === 'string' && messageField.length > 0\n ? messageField\n : fallbackMessage,\n code: normalizeCode(codeField),\n }\n }\n if (typeof error === 'string' && error.length > 0) {\n return { message: error, code: undefined }\n }\n return { message: fallbackMessage, code: undefined }\n}\n\n/**\n * Extract the provider's *structured error body* from a thrown value, to attach\n * as the AG-UI `rawEvent` on a RUN_ERROR event. This is the recoverable upstream\n * detail (provider name, the upstream model's error JSON, rate-limit/overload\n * codes, etc.) that `toRunErrorPayload`'s `{ message, code }` deliberately drops.\n *\n * Security boundary: only known provider-response-body fields are forwarded —\n * never the raw SDK exception object, which can carry request metadata such as\n * auth headers or request ids. The recognized sources, in priority order:\n *\n * - `error.rawEvent` — a provider body an adapter attached explicitly (e.g. the\n * OpenRouter mid-stream `chunk.error`).\n * - `error.error` (object) — the parsed provider response body exposed by SDK\n * `APIError` instances (OpenAI/Anthropic `{ type, message, code, param }`,\n * OpenRouter typed errors whose `.error` carries `.metadata`). This is\n * provider-shaped data, distinct from `.headers` / `.request_id`.\n * - `error.metadata` — OpenRouter's `provider_name` + raw upstream body, when\n * surfaced directly on the thrown error.\n *\n * Returns `undefined` when no structured provider body is present, so callers\n * omit the field entirely rather than setting it to `null`:\n *\n * const rawEvent = toRunErrorRawEvent(error)\n * yield { type: EventType.RUN_ERROR, ..., ...(rawEvent !== undefined && { rawEvent }) }\n */\nexport function toRunErrorRawEvent(error: unknown): unknown {\n if (!error || typeof error !== 'object') return undefined\n const e = error as {\n rawEvent?: unknown\n error?: unknown\n metadata?: unknown\n }\n if (e.rawEvent !== undefined && e.rawEvent !== null) return e.rawEvent\n if (\n e.error !== undefined &&\n e.error !== null &&\n typeof e.error === 'object'\n ) {\n return e.error\n }\n if (e.metadata !== undefined && e.metadata !== null) return e.metadata\n return undefined\n}\n"],"mappings":";;;;;;;;;;;;;;;AAcA,IAAM,oCAAoB,IAAI,IAAI;CAChC;CACA;CACA;AACF,CAAC;AAKD,SAAS,cAAc,WAAwC;CAC7D,IAAI,OAAO,cAAc,UAAU,OAAO;CAC1C,IAAI,OAAO,cAAc,YAAY,OAAO,SAAS,SAAS,GAC5D,OAAO,OAAO,SAAS;AAG3B;AAEA,SAAgB,kBACd,OACA,kBAAkB,0BAC6B;CAC/C,IAAI,SAAS,OAAO,UAAU,UAAU;EACtC,MAAM,OAAQ,MAA6B;EAC3C,IAAI,OAAO,SAAS,YAAY,kBAAkB,IAAI,IAAI,GACxD,OAAO;GAAE,SAAS;GAAmB,MAAM;EAAU;CAEzD;CACA,IAAI,iBAAiB,OAAO;EAC1B,MAAM,YAAa,MAAqC;EACxD,OAAO;GACL,SAAS,MAAM,WAAW;GAC1B,MAAM,cAAc,SAAS;EAC/B;CACF;CACA,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAC/C,MAAM,eAAgB,MAAgC;EACtD,MAAM,YAAa,MAA6B;EAChD,OAAO;GACL,SACE,OAAO,iBAAiB,YAAY,aAAa,SAAS,IACtD,eACA;GACN,MAAM,cAAc,SAAS;EAC/B;CACF;CACA,IAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAC9C,OAAO;EAAE,SAAS;EAAO,MAAM,KAAA;CAAU;CAE3C,OAAO;EAAE,SAAS;EAAiB,MAAM,KAAA;CAAU;AACrD;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,mBAAmB,OAAyB;CAC1D,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO,KAAA;CAChD,MAAM,IAAI;CAKV,IAAI,EAAE,aAAa,KAAA,KAAa,EAAE,aAAa,MAAM,OAAO,EAAE;CAC9D,IACE,EAAE,UAAU,KAAA,KACZ,EAAE,UAAU,QACZ,OAAO,EAAE,UAAU,UAEnB,OAAO,EAAE;CAEX,IAAI,EAAE,aAAa,KAAA,KAAa,EAAE,aAAa,MAAM,OAAO,EAAE;AAEhE"}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
//#region src/activities/generateAudio/adapter.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for audio generation adapters.
|
|
4
|
+
* Extend this class to implement an audio adapter for a specific provider.
|
|
5
|
+
*
|
|
6
|
+
* Generic parameters match AudioAdapter - all pre-resolved by the provider function.
|
|
7
|
+
*/
|
|
8
|
+
var BaseAudioAdapter = class {
|
|
9
|
+
kind = "audio";
|
|
10
|
+
model;
|
|
11
|
+
config;
|
|
12
|
+
constructor(model, config = {}) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.model = model;
|
|
15
|
+
}
|
|
16
|
+
generateId() {
|
|
17
|
+
return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
18
|
+
}
|
|
15
19
|
};
|
|
16
|
-
//#
|
|
20
|
+
//#endregion
|
|
21
|
+
export { BaseAudioAdapter };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sources":["../../../../src/activities/generateAudio/adapter.ts"],"sourcesContent":["import type { AudioGenerationOptions, AudioGenerationResult } from '../../types'\n\n/**\n * Configuration for audio generation adapter instances\n */\nexport interface AudioAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Audio generation adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'fal-ai/diffrhythm')\n * - TProviderOptions: Provider-specific options (already resolved)\n */\nexport interface AudioAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n> {\n /** Discriminator for adapter kind - used to determine API shape */\n readonly kind: 'audio'\n /** Adapter name identifier */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n }\n\n /**\n * Generate audio from a text prompt\n */\n generateAudio: (\n options: AudioGenerationOptions<TProviderOptions>,\n ) => Promise<AudioGenerationResult>\n}\n\n/**\n * An AudioAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyAudioAdapter = AudioAdapter<any, any>\n\n/**\n * Abstract base class for audio generation adapters.\n * Extend this class to implement an audio adapter for a specific provider.\n *\n * Generic parameters match AudioAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseAudioAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n> implements AudioAdapter<TModel, TProviderOptions> {\n readonly kind = 'audio' as const\n abstract readonly name: string\n readonly model: TModel\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n }\n\n protected config: AudioAdapterConfig\n\n constructor(model: TModel, config: AudioAdapterConfig = {}) {\n this.config = config\n this.model = model\n }\n\n abstract generateAudio(\n options: AudioGenerationOptions<TProviderOptions>,\n ): Promise<AudioGenerationResult>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"
|
|
1
|
+
{"version":3,"file":"adapter.js","names":[],"sources":["../../../../src/activities/generateAudio/adapter.ts"],"sourcesContent":["import type { AudioGenerationOptions, AudioGenerationResult } from '../../types'\n\n/**\n * Configuration for audio generation adapter instances\n */\nexport interface AudioAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Audio generation adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'fal-ai/diffrhythm')\n * - TProviderOptions: Provider-specific options (already resolved)\n */\nexport interface AudioAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n> {\n /** Discriminator for adapter kind - used to determine API shape */\n readonly kind: 'audio'\n /** Adapter name identifier */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n }\n\n /**\n * Generate audio from a text prompt\n */\n generateAudio: (\n options: AudioGenerationOptions<TProviderOptions>,\n ) => Promise<AudioGenerationResult>\n}\n\n/**\n * An AudioAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyAudioAdapter = AudioAdapter<any, any>\n\n/**\n * Abstract base class for audio generation adapters.\n * Extend this class to implement an audio adapter for a specific provider.\n *\n * Generic parameters match AudioAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseAudioAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n> implements AudioAdapter<TModel, TProviderOptions> {\n readonly kind = 'audio' as const\n abstract readonly name: string\n readonly model: TModel\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n }\n\n protected config: AudioAdapterConfig\n\n constructor(model: TModel, config: AudioAdapterConfig = {}) {\n this.config = config\n this.model = model\n }\n\n abstract generateAudio(\n options: AudioGenerationOptions<TProviderOptions>,\n ): Promise<AudioGenerationResult>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"mappings":";;;;;;;AA6DA,IAAsB,mBAAtB,MAGoD;CAClD,OAAgB;CAEhB;CAOA;CAEA,YAAY,OAAe,SAA6B,CAAC,GAAG;EAC1D,KAAK,SAAS;EACd,KAAK,QAAQ;CACf;CAMA,aAA+B;EAC7B,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC;CAC7E;AACF"}
|
|
@@ -50,6 +50,10 @@ export interface AudioActivityOptions<TAdapter extends AudioAdapter<string, Audi
|
|
|
50
50
|
* `GenerationMiddleware` contract for a custom backend.
|
|
51
51
|
*/
|
|
52
52
|
middleware?: Array<GenerationMiddleware>;
|
|
53
|
+
/** Stable conversation/thread id for correlating this run when persisted. */
|
|
54
|
+
threadId?: string;
|
|
55
|
+
/** Stable run id for correlating this run when persisted. */
|
|
56
|
+
runId?: string;
|
|
53
57
|
}
|
|
54
58
|
/**
|
|
55
59
|
* Result type for the audio generation activity.
|
|
@@ -1,114 +1,150 @@
|
|
|
1
|
-
import { aiEventClient } from "@tanstack/ai-event-client";
|
|
2
|
-
import { streamGenerationResult } from "../stream-generation-result.js";
|
|
3
1
|
import { resolveDebugOption } from "../../logger/resolve.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
2
|
+
import { streamGenerationResult } from "../stream-generation-result.js";
|
|
3
|
+
import { applyGenerationResultTransforms, createGenerationContext, runGenerationError, runGenerationFinish, runGenerationStart, runGenerationUsage } from "../middleware/run.js";
|
|
4
|
+
import "./adapter.js";
|
|
5
|
+
import { aiEventClient } from "@tanstack/ai-event-client";
|
|
6
|
+
//#region src/activities/generateAudio/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* Audio Generation Activity
|
|
9
|
+
*
|
|
10
|
+
* Generates audio (music, sound effects, etc.) from text prompts.
|
|
11
|
+
* This is a self-contained module with implementation, types, and JSDoc.
|
|
12
|
+
*/
|
|
13
|
+
/** The adapter kind this activity handles */
|
|
14
|
+
var kind = "audio";
|
|
6
15
|
function createId(prefix) {
|
|
7
|
-
|
|
16
|
+
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
8
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Audio generation activity - generates audio from text prompts.
|
|
20
|
+
*
|
|
21
|
+
* Uses AI models to create music, sound effects, and other audio content.
|
|
22
|
+
*
|
|
23
|
+
* @example Generate music from a prompt
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { generateAudio } from '@tanstack/ai'
|
|
26
|
+
* import { falAudio } from '@tanstack/ai-fal'
|
|
27
|
+
*
|
|
28
|
+
* const result = await generateAudio({
|
|
29
|
+
* adapter: falAudio('fal-ai/diffrhythm'),
|
|
30
|
+
* prompt: 'An upbeat electronic track with synths',
|
|
31
|
+
* duration: 10
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* console.log(result.audio.url) // URL to generated audio
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
9
37
|
function generateAudio(options) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return runGenerateAudio(options);
|
|
38
|
+
if (options.stream) return streamGenerationResult((resolved) => runGenerateAudio({
|
|
39
|
+
...options,
|
|
40
|
+
runId: resolved.runId
|
|
41
|
+
}), options);
|
|
42
|
+
return runGenerateAudio(options);
|
|
16
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Run the core audio generation logic (non-streaming).
|
|
46
|
+
*/
|
|
17
47
|
async function runGenerateAudio(options) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
48
|
+
const { adapter, stream: _stream, debug: _debug, middleware, threadId, runId, ...rest } = options;
|
|
49
|
+
const model = adapter.model;
|
|
50
|
+
const requestId = createId("audio");
|
|
51
|
+
const startTime = Date.now();
|
|
52
|
+
const logger = resolveDebugOption(options.debug);
|
|
53
|
+
const providerName = adapter.provider ?? adapter.name ?? "unknown";
|
|
54
|
+
const mwCtx = createGenerationContext({
|
|
55
|
+
requestId,
|
|
56
|
+
activity: "audio",
|
|
57
|
+
provider: adapter.name,
|
|
58
|
+
model,
|
|
59
|
+
modelOptions: rest.modelOptions,
|
|
60
|
+
threadId,
|
|
61
|
+
runId,
|
|
62
|
+
artifactInputs: {
|
|
63
|
+
prompt: rest.prompt,
|
|
64
|
+
duration: rest.duration
|
|
65
|
+
},
|
|
66
|
+
createId
|
|
67
|
+
});
|
|
68
|
+
await runGenerationStart(middleware, mwCtx);
|
|
69
|
+
aiEventClient.emit("audio:request:started", {
|
|
70
|
+
requestId,
|
|
71
|
+
provider: adapter.name,
|
|
72
|
+
model,
|
|
73
|
+
prompt: rest.prompt,
|
|
74
|
+
duration: rest.duration,
|
|
75
|
+
modelOptions: rest.modelOptions,
|
|
76
|
+
timestamp: startTime
|
|
77
|
+
});
|
|
78
|
+
logger.request(`activity=generateAudio provider=${providerName}`, {
|
|
79
|
+
provider: providerName,
|
|
80
|
+
model
|
|
81
|
+
});
|
|
82
|
+
try {
|
|
83
|
+
const result = await applyGenerationResultTransforms(mwCtx, await adapter.generateAudio({
|
|
84
|
+
...rest,
|
|
85
|
+
model,
|
|
86
|
+
logger
|
|
87
|
+
}));
|
|
88
|
+
const elapsedMs = Date.now() - startTime;
|
|
89
|
+
aiEventClient.emit("audio:request:completed", {
|
|
90
|
+
requestId,
|
|
91
|
+
provider: adapter.name,
|
|
92
|
+
model,
|
|
93
|
+
audio: result.audio,
|
|
94
|
+
duration: elapsedMs,
|
|
95
|
+
modelOptions: rest.modelOptions,
|
|
96
|
+
timestamp: Date.now()
|
|
97
|
+
});
|
|
98
|
+
if (result.usage) aiEventClient.emit("audio:usage", {
|
|
99
|
+
requestId,
|
|
100
|
+
model,
|
|
101
|
+
usage: result.usage,
|
|
102
|
+
modelOptions: rest.modelOptions,
|
|
103
|
+
timestamp: Date.now()
|
|
104
|
+
});
|
|
105
|
+
logger.output(`activity=generateAudio provider=${providerName}`, {
|
|
106
|
+
contentType: result.audio.contentType,
|
|
107
|
+
audioDuration: result.audio.duration
|
|
108
|
+
});
|
|
109
|
+
if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage);
|
|
110
|
+
await runGenerationFinish(middleware, mwCtx, {
|
|
111
|
+
duration: elapsedMs,
|
|
112
|
+
usage: result.usage
|
|
113
|
+
});
|
|
114
|
+
return result;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
const elapsedMs = Date.now() - startTime;
|
|
117
|
+
const err = error;
|
|
118
|
+
aiEventClient.emit("audio:request:error", {
|
|
119
|
+
requestId,
|
|
120
|
+
provider: adapter.name,
|
|
121
|
+
model,
|
|
122
|
+
error: {
|
|
123
|
+
message: err.message,
|
|
124
|
+
name: err.name
|
|
125
|
+
},
|
|
126
|
+
duration: elapsedMs,
|
|
127
|
+
modelOptions: rest.modelOptions,
|
|
128
|
+
timestamp: Date.now()
|
|
129
|
+
});
|
|
130
|
+
await runGenerationError(middleware, mwCtx, {
|
|
131
|
+
error,
|
|
132
|
+
duration: elapsedMs
|
|
133
|
+
});
|
|
134
|
+
logger.errors("generateAudio activity failed", {
|
|
135
|
+
error,
|
|
136
|
+
source: "generateAudio"
|
|
137
|
+
});
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
105
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Create typed options for the generateAudio() function without executing.
|
|
143
|
+
*/
|
|
106
144
|
function createAudioOptions(options) {
|
|
107
|
-
|
|
145
|
+
return options;
|
|
108
146
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
};
|
|
114
|
-
//# sourceMappingURL=index.js.map
|
|
147
|
+
//#endregion
|
|
148
|
+
export { createAudioOptions, generateAudio, kind };
|
|
149
|
+
|
|
150
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/activities/generateAudio/index.ts"],"sourcesContent":["/**\n * Audio Generation Activity\n *\n * Generates audio (music, sound effects, etc.) from text prompts.\n * This is a self-contained module with implementation, types, and JSDoc.\n */\n\nimport { aiEventClient } from '@tanstack/ai-event-client'\nimport { streamGenerationResult } from '../stream-generation-result.js'\nimport { resolveDebugOption } from '../../logger/resolve'\nimport {\n createGenerationContext,\n runGenerationError,\n runGenerationFinish,\n runGenerationStart,\n runGenerationUsage,\n} from '../middleware/run'\nimport type { InternalLogger } from '../../logger/internal-logger'\nimport type { DebugOption } from '../../logger/types'\nimport type { GenerationMiddleware } from '../middleware/types'\nimport type { AudioAdapter } from './adapter'\nimport type { AudioGenerationResult, StreamChunk } from '../../types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'audio' as const\n\n// ===========================\n// Type Extraction Helpers\n// ===========================\n\n/**\n * Extract provider options from an AudioAdapter via ~types.\n */\nexport type AudioProviderOptions<TAdapter> = TAdapter extends {\n '~types': { providerOptions: infer P extends object }\n}\n ? P\n : object\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the audio generation activity.\n * The model is extracted from the adapter's model property.\n *\n * @template TAdapter - The audio adapter type\n * @template TStream - Whether to stream the output\n */\nexport interface AudioActivityOptions<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n> {\n /** The audio adapter to use (must be created with a model) */\n adapter: TAdapter & { kind: typeof kind }\n /** Text description of the desired audio */\n prompt: string\n /** Desired duration in seconds */\n duration?: number\n /** Provider-specific options for audio generation */\n modelOptions?: AudioProviderOptions<TAdapter>\n /**\n * Whether to stream the generation result.\n * When true, returns an AsyncIterable<StreamChunk> for streaming transport.\n * When false or not provided, returns a Promise<AudioGenerationResult>.\n *\n * @default false\n */\n stream?: TStream\n /**\n * Enable debug logging. Pass `true` to enable all categories, `false` to\n * silence everything including errors, or a `DebugConfig` object for granular\n * control and/or a custom `Logger`.\n */\n debug?: DebugOption\n /**\n * Observe-only middleware notified on start, usage, success, and error. Pass\n * `otelMiddleware()` to emit OpenTelemetry spans, or implement the\n * `GenerationMiddleware` contract for a custom backend.\n */\n middleware?: Array<GenerationMiddleware>\n}\n\n// ===========================\n// Activity Result Type\n// ===========================\n\n/**\n * Result type for the audio generation activity.\n * - If stream is true: AsyncIterable<StreamChunk>\n * - Otherwise: Promise<AudioGenerationResult>\n */\nexport type AudioActivityResult<TStream extends boolean = false> =\n TStream extends true\n ? AsyncIterable<StreamChunk>\n : Promise<AudioGenerationResult>\n\nfunction createId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n// ===========================\n// Activity Implementation\n// ===========================\n\n/**\n * Audio generation activity - generates audio from text prompts.\n *\n * Uses AI models to create music, sound effects, and other audio content.\n *\n * @example Generate music from a prompt\n * ```ts\n * import { generateAudio } from '@tanstack/ai'\n * import { falAudio } from '@tanstack/ai-fal'\n *\n * const result = await generateAudio({\n * adapter: falAudio('fal-ai/diffrhythm'),\n * prompt: 'An upbeat electronic track with synths',\n * duration: 10\n * })\n *\n * console.log(result.audio.url) // URL to generated audio\n * ```\n */\nexport function generateAudio<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(\n options: AudioActivityOptions<TAdapter, TStream>,\n): AudioActivityResult<TStream> {\n if (options.stream) {\n return streamGenerationResult(() =>\n runGenerateAudio(options),\n ) as AudioActivityResult<TStream>\n }\n return runGenerateAudio(options) as AudioActivityResult<TStream>\n}\n\n/**\n * Run the core audio generation logic (non-streaming).\n */\nasync function runGenerateAudio<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n>(\n options: AudioActivityOptions<TAdapter, boolean>,\n): Promise<AudioGenerationResult> {\n const {\n adapter,\n stream: _stream,\n debug: _debug,\n middleware,\n ...rest\n } = options\n const model = adapter.model\n const requestId = createId('audio')\n const startTime = Date.now()\n const logger: InternalLogger = resolveDebugOption(options.debug)\n const providerName =\n (adapter as { name?: string; provider?: string }).provider ??\n (adapter as { name?: string }).name ??\n 'unknown'\n\n const mwCtx = createGenerationContext({\n requestId,\n activity: 'audio',\n provider: adapter.name,\n model,\n modelOptions: rest.modelOptions,\n createId,\n })\n\n await runGenerationStart(middleware, mwCtx)\n\n aiEventClient.emit('audio:request:started', {\n requestId,\n provider: adapter.name,\n model,\n prompt: rest.prompt,\n duration: rest.duration,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: startTime,\n })\n\n logger.request(`activity=generateAudio provider=${providerName}`, {\n provider: providerName,\n model,\n })\n\n try {\n const result = await adapter.generateAudio({ ...rest, model, logger })\n const elapsedMs = Date.now() - startTime\n\n aiEventClient.emit('audio:request:completed', {\n requestId,\n provider: adapter.name,\n model,\n audio: result.audio,\n duration: elapsedMs,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n\n if (result.usage) {\n aiEventClient.emit('audio:usage', {\n requestId,\n model,\n usage: result.usage,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n }\n\n logger.output(`activity=generateAudio provider=${providerName}`, {\n contentType: result.audio.contentType,\n audioDuration: result.audio.duration,\n })\n\n if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage)\n await runGenerationFinish(middleware, mwCtx, {\n duration: elapsedMs,\n usage: result.usage,\n })\n\n return result\n } catch (error) {\n const elapsedMs = Date.now() - startTime\n const err = error as Error\n aiEventClient.emit('audio:request:error', {\n requestId,\n provider: adapter.name,\n model,\n error: { message: err.message, name: err.name },\n duration: elapsedMs,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n await runGenerationError(middleware, mwCtx, {\n error,\n duration: elapsedMs,\n })\n logger.errors('generateAudio activity failed', {\n error,\n source: 'generateAudio',\n })\n throw error\n }\n}\n\n// ===========================\n// Options Factory\n// ===========================\n\n/**\n * Create typed options for the generateAudio() function without executing.\n */\nexport function createAudioOptions<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(\n options: AudioActivityOptions<TAdapter, TStream>,\n): AudioActivityOptions<TAdapter, TStream> {\n return options\n}\n\n// Re-export adapter types\nexport type {\n AudioAdapter,\n AudioAdapterConfig,\n AnyAudioAdapter,\n} from './adapter'\nexport { BaseAudioAdapter } from './adapter'\n"],"names":[],"mappings":";;;;AA4BO,MAAM,OAAO;AA0EpB,SAAS,SAAS,QAAwB;AACxC,SAAO,GAAG,MAAM,IAAI,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC1E;AAyBO,SAAS,cAId,SAC8B;AAC9B,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,MAAuB,MAC5B,iBAAiB,OAAO;AAAA,IAAA;AAAA,EAE5B;AACA,SAAO,iBAAiB,OAAO;AACjC;AAKA,eAAe,iBAGb,SACgC;AAChC,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP;AAAA,IACA,GAAG;AAAA,EAAA,IACD;AACJ,QAAM,QAAQ,QAAQ;AACtB,QAAM,YAAY,SAAS,OAAO;AAClC,QAAM,YAAY,KAAK,IAAA;AACvB,QAAM,SAAyB,mBAAmB,QAAQ,KAAK;AAC/D,QAAM,eACH,QAAiD,YACjD,QAA8B,QAC/B;AAEF,QAAM,QAAQ,wBAAwB;AAAA,IACpC;AAAA,IACA,UAAU;AAAA,IACV,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,cAAc,KAAK;AAAA,IACnB;AAAA,EAAA,CACD;AAED,QAAM,mBAAmB,YAAY,KAAK;AAE1C,gBAAc,KAAK,yBAAyB;AAAA,IAC1C;AAAA,IACA,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK;AAAA,IACf,cAAc,KAAK;AAAA,IACnB,WAAW;AAAA,EAAA,CACZ;AAED,SAAO,QAAQ,mCAAmC,YAAY,IAAI;AAAA,IAChE,UAAU;AAAA,IACV;AAAA,EAAA,CACD;AAED,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,cAAc,EAAE,GAAG,MAAM,OAAO,QAAQ;AACrE,UAAM,YAAY,KAAK,IAAA,IAAQ;AAE/B,kBAAc,KAAK,2BAA2B;AAAA,MAC5C;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,cAAc,KAAK;AAAA,MACnB,WAAW,KAAK,IAAA;AAAA,IAAI,CACrB;AAED,QAAI,OAAO,OAAO;AAChB,oBAAc,KAAK,eAAe;AAAA,QAChC;AAAA,QACA;AAAA,QACA,OAAO,OAAO;AAAA,QACd,cAAc,KAAK;AAAA,QACnB,WAAW,KAAK,IAAA;AAAA,MAAI,CACrB;AAAA,IACH;AAEA,WAAO,OAAO,mCAAmC,YAAY,IAAI;AAAA,MAC/D,aAAa,OAAO,MAAM;AAAA,MAC1B,eAAe,OAAO,MAAM;AAAA,IAAA,CAC7B;AAED,QAAI,OAAO,MAAO,OAAM,mBAAmB,YAAY,OAAO,OAAO,KAAK;AAC1E,UAAM,oBAAoB,YAAY,OAAO;AAAA,MAC3C,UAAU;AAAA,MACV,OAAO,OAAO;AAAA,IAAA,CACf;AAED,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,YAAY,KAAK,IAAA,IAAQ;AAC/B,UAAM,MAAM;AACZ,kBAAc,KAAK,uBAAuB;AAAA,MACxC;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,OAAO,EAAE,SAAS,IAAI,SAAS,MAAM,IAAI,KAAA;AAAA,MACzC,UAAU;AAAA,MACV,cAAc,KAAK;AAAA,MACnB,WAAW,KAAK,IAAA;AAAA,IAAI,CACrB;AACD,UAAM,mBAAmB,YAAY,OAAO;AAAA,MAC1C;AAAA,MACA,UAAU;AAAA,IAAA,CACX;AACD,WAAO,OAAO,iCAAiC;AAAA,MAC7C;AAAA,MACA,QAAQ;AAAA,IAAA,CACT;AACD,UAAM;AAAA,EACR;AACF;AASO,SAAS,mBAId,SACyC;AACzC,SAAO;AACT;"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/activities/generateAudio/index.ts"],"sourcesContent":["/**\n * Audio Generation Activity\n *\n * Generates audio (music, sound effects, etc.) from text prompts.\n * This is a self-contained module with implementation, types, and JSDoc.\n */\n\nimport { aiEventClient } from '@tanstack/ai-event-client'\nimport { streamGenerationResult } from '../stream-generation-result.js'\nimport { resolveDebugOption } from '../../logger/resolve'\nimport {\n applyGenerationResultTransforms,\n createGenerationContext,\n runGenerationError,\n runGenerationFinish,\n runGenerationStart,\n runGenerationUsage,\n} from '../middleware/run'\nimport type { InternalLogger } from '../../logger/internal-logger'\nimport type { DebugOption } from '../../logger/types'\nimport type { GenerationMiddleware } from '../middleware/types'\nimport type { AudioAdapter } from './adapter'\nimport type { AudioGenerationResult, StreamChunk } from '../../types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'audio' as const\n\n// ===========================\n// Type Extraction Helpers\n// ===========================\n\n/**\n * Extract provider options from an AudioAdapter via ~types.\n */\nexport type AudioProviderOptions<TAdapter> = TAdapter extends {\n '~types': { providerOptions: infer P extends object }\n}\n ? P\n : object\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the audio generation activity.\n * The model is extracted from the adapter's model property.\n *\n * @template TAdapter - The audio adapter type\n * @template TStream - Whether to stream the output\n */\nexport interface AudioActivityOptions<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n> {\n /** The audio adapter to use (must be created with a model) */\n adapter: TAdapter & { kind: typeof kind }\n /** Text description of the desired audio */\n prompt: string\n /** Desired duration in seconds */\n duration?: number\n /** Provider-specific options for audio generation */\n modelOptions?: AudioProviderOptions<TAdapter>\n /**\n * Whether to stream the generation result.\n * When true, returns an AsyncIterable<StreamChunk> for streaming transport.\n * When false or not provided, returns a Promise<AudioGenerationResult>.\n *\n * @default false\n */\n stream?: TStream\n /**\n * Enable debug logging. Pass `true` to enable all categories, `false` to\n * silence everything including errors, or a `DebugConfig` object for granular\n * control and/or a custom `Logger`.\n */\n debug?: DebugOption\n /**\n * Observe-only middleware notified on start, usage, success, and error. Pass\n * `otelMiddleware()` to emit OpenTelemetry spans, or implement the\n * `GenerationMiddleware` contract for a custom backend.\n */\n middleware?: Array<GenerationMiddleware>\n /** Stable conversation/thread id for correlating this run when persisted. */\n threadId?: string\n /** Stable run id for correlating this run when persisted. */\n runId?: string\n}\n\n// ===========================\n// Activity Result Type\n// ===========================\n\n/**\n * Result type for the audio generation activity.\n * - If stream is true: AsyncIterable<StreamChunk>\n * - Otherwise: Promise<AudioGenerationResult>\n */\nexport type AudioActivityResult<TStream extends boolean = false> =\n TStream extends true\n ? AsyncIterable<StreamChunk>\n : Promise<AudioGenerationResult>\n\nfunction createId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n// ===========================\n// Activity Implementation\n// ===========================\n\n/**\n * Audio generation activity - generates audio from text prompts.\n *\n * Uses AI models to create music, sound effects, and other audio content.\n *\n * @example Generate music from a prompt\n * ```ts\n * import { generateAudio } from '@tanstack/ai'\n * import { falAudio } from '@tanstack/ai-fal'\n *\n * const result = await generateAudio({\n * adapter: falAudio('fal-ai/diffrhythm'),\n * prompt: 'An upbeat electronic track with synths',\n * duration: 10\n * })\n *\n * console.log(result.audio.url) // URL to generated audio\n * ```\n */\nexport function generateAudio<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(\n options: AudioActivityOptions<TAdapter, TStream>,\n): AudioActivityResult<TStream> {\n if (options.stream) {\n return streamGenerationResult(\n // Only `runId` is taken from the resolved wire identity. `threadId` stays\n // the CALLER's: `streamGenerationResult` mints one for the RUN_* chunks\n // when none was passed, and spreading that over the options would hand\n // middleware a thread id known to nobody, which persistence would then\n // file the run under. Matches `generateVideo`.\n (resolved) => runGenerateAudio({ ...options, runId: resolved.runId }),\n options,\n ) as AudioActivityResult<TStream>\n }\n return runGenerateAudio(options) as AudioActivityResult<TStream>\n}\n\n/**\n * Run the core audio generation logic (non-streaming).\n */\nasync function runGenerateAudio<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n>(\n options: AudioActivityOptions<TAdapter, boolean>,\n): Promise<AudioGenerationResult> {\n const {\n adapter,\n stream: _stream,\n debug: _debug,\n middleware,\n threadId,\n runId,\n ...rest\n } = options\n const model = adapter.model\n const requestId = createId('audio')\n const startTime = Date.now()\n const logger: InternalLogger = resolveDebugOption(options.debug)\n const providerName =\n (adapter as { name?: string; provider?: string }).provider ??\n (adapter as { name?: string }).name ??\n 'unknown'\n\n const mwCtx = createGenerationContext({\n requestId,\n activity: 'audio',\n provider: adapter.name,\n model,\n modelOptions: rest.modelOptions,\n threadId,\n runId,\n artifactInputs: { prompt: rest.prompt, duration: rest.duration },\n createId,\n })\n\n await runGenerationStart(middleware, mwCtx)\n\n aiEventClient.emit('audio:request:started', {\n requestId,\n provider: adapter.name,\n model,\n prompt: rest.prompt,\n duration: rest.duration,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: startTime,\n })\n\n logger.request(`activity=generateAudio provider=${providerName}`, {\n provider: providerName,\n model,\n })\n\n try {\n const rawResult = await adapter.generateAudio({ ...rest, model, logger })\n const result = await applyGenerationResultTransforms(mwCtx, rawResult)\n const elapsedMs = Date.now() - startTime\n\n aiEventClient.emit('audio:request:completed', {\n requestId,\n provider: adapter.name,\n model,\n audio: result.audio,\n duration: elapsedMs,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n\n if (result.usage) {\n aiEventClient.emit('audio:usage', {\n requestId,\n model,\n usage: result.usage,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n }\n\n logger.output(`activity=generateAudio provider=${providerName}`, {\n contentType: result.audio.contentType,\n audioDuration: result.audio.duration,\n })\n\n if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage)\n await runGenerationFinish(middleware, mwCtx, {\n duration: elapsedMs,\n usage: result.usage,\n })\n\n return result\n } catch (error) {\n const elapsedMs = Date.now() - startTime\n const err = error as Error\n aiEventClient.emit('audio:request:error', {\n requestId,\n provider: adapter.name,\n model,\n error: { message: err.message, name: err.name },\n duration: elapsedMs,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n await runGenerationError(middleware, mwCtx, {\n error,\n duration: elapsedMs,\n })\n logger.errors('generateAudio activity failed', {\n error,\n source: 'generateAudio',\n })\n throw error\n }\n}\n\n// ===========================\n// Options Factory\n// ===========================\n\n/**\n * Create typed options for the generateAudio() function without executing.\n */\nexport function createAudioOptions<\n TAdapter extends AudioAdapter<string, AudioProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(\n options: AudioActivityOptions<TAdapter, TStream>,\n): AudioActivityOptions<TAdapter, TStream> {\n return options\n}\n\n// Re-export adapter types\nexport type {\n AudioAdapter,\n AudioAdapterConfig,\n AnyAudioAdapter,\n} from './adapter'\nexport { BaseAudioAdapter } from './adapter'\n"],"mappings":";;;;;;;;;;;;;AA6BA,IAAa,OAAO;AA8EpB,SAAS,SAAS,QAAwB;CACxC,OAAO,GAAG,OAAO,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;AACzE;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,cAId,SAC8B;CAC9B,IAAI,QAAQ,QACV,OAAO,wBAMJ,aAAa,iBAAiB;EAAE,GAAG;EAAS,OAAO,SAAS;CAAM,CAAC,GACpE,OACF;CAEF,OAAO,iBAAiB,OAAO;AACjC;;;;AAKA,eAAe,iBAGb,SACgC;CAChC,MAAM,EACJ,SACA,QAAQ,SACR,OAAO,QACP,YACA,UACA,OACA,GAAG,SACD;CACJ,MAAM,QAAQ,QAAQ;CACtB,MAAM,YAAY,SAAS,OAAO;CAClC,MAAM,YAAY,KAAK,IAAI;CAC3B,MAAM,SAAyB,mBAAmB,QAAQ,KAAK;CAC/D,MAAM,eACH,QAAiD,YACjD,QAA8B,QAC/B;CAEF,MAAM,QAAQ,wBAAwB;EACpC;EACA,UAAU;EACV,UAAU,QAAQ;EAClB;EACA,cAAc,KAAK;EACnB;EACA;EACA,gBAAgB;GAAE,QAAQ,KAAK;GAAQ,UAAU,KAAK;EAAS;EAC/D;CACF,CAAC;CAED,MAAM,mBAAmB,YAAY,KAAK;CAE1C,cAAc,KAAK,yBAAyB;EAC1C;EACA,UAAU,QAAQ;EAClB;EACA,QAAQ,KAAK;EACb,UAAU,KAAK;EACf,cAAc,KAAK;EACnB,WAAW;CACb,CAAC;CAED,OAAO,QAAQ,mCAAmC,gBAAgB;EAChE,UAAU;EACV;CACF,CAAC;CAED,IAAI;EAEF,MAAM,SAAS,MAAM,gCAAgC,OAAO,MADpC,QAAQ,cAAc;GAAE,GAAG;GAAM;GAAO;EAAO,CAAC,CACH;EACrE,MAAM,YAAY,KAAK,IAAI,IAAI;EAE/B,cAAc,KAAK,2BAA2B;GAC5C;GACA,UAAU,QAAQ;GAClB;GACA,OAAO,OAAO;GACd,UAAU;GACV,cAAc,KAAK;GACnB,WAAW,KAAK,IAAI;EACtB,CAAC;EAED,IAAI,OAAO,OACT,cAAc,KAAK,eAAe;GAChC;GACA;GACA,OAAO,OAAO;GACd,cAAc,KAAK;GACnB,WAAW,KAAK,IAAI;EACtB,CAAC;EAGH,OAAO,OAAO,mCAAmC,gBAAgB;GAC/D,aAAa,OAAO,MAAM;GAC1B,eAAe,OAAO,MAAM;EAC9B,CAAC;EAED,IAAI,OAAO,OAAO,MAAM,mBAAmB,YAAY,OAAO,OAAO,KAAK;EAC1E,MAAM,oBAAoB,YAAY,OAAO;GAC3C,UAAU;GACV,OAAO,OAAO;EAChB,CAAC;EAED,OAAO;CACT,SAAS,OAAO;EACd,MAAM,YAAY,KAAK,IAAI,IAAI;EAC/B,MAAM,MAAM;EACZ,cAAc,KAAK,uBAAuB;GACxC;GACA,UAAU,QAAQ;GAClB;GACA,OAAO;IAAE,SAAS,IAAI;IAAS,MAAM,IAAI;GAAK;GAC9C,UAAU;GACV,cAAc,KAAK;GACnB,WAAW,KAAK,IAAI;EACtB,CAAC;EACD,MAAM,mBAAmB,YAAY,OAAO;GAC1C;GACA,UAAU;EACZ,CAAC;EACD,OAAO,OAAO,iCAAiC;GAC7C;GACA,QAAQ;EACV,CAAC;EACD,MAAM;CACR;AACF;;;;AASA,SAAgB,mBAId,SACyC;CACzC,OAAO;AACT"}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
//#region src/activities/generateImage/adapter.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for image generation adapters.
|
|
4
|
+
* Extend this class to implement an image adapter for a specific provider.
|
|
5
|
+
*
|
|
6
|
+
* Generic parameters match ImageAdapter - all pre-resolved by the provider function.
|
|
7
|
+
*/
|
|
8
|
+
var BaseImageAdapter = class {
|
|
9
|
+
kind = "image";
|
|
10
|
+
model;
|
|
11
|
+
config;
|
|
12
|
+
constructor(model, config = {}) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.model = model;
|
|
15
|
+
}
|
|
16
|
+
generateId() {
|
|
17
|
+
return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
18
|
+
}
|
|
15
19
|
};
|
|
16
|
-
//#
|
|
20
|
+
//#endregion
|
|
21
|
+
export { BaseImageAdapter };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sources":["../../../../src/activities/generateImage/adapter.ts"],"sourcesContent":["import type {\n ImageGenerationOptions,\n ImageGenerationResult,\n ModelInputModalitiesByName,\n} from '../../types'\n\n/**\n * Resolve the size type for a model from the model-size map.\n * If the map has an index signature (i.e. no explicit keys), falls back to string.\n * If the model is an explicit key, uses its mapped size type.\n * Otherwise falls back to string.\n */\n\n/**\n * Configuration for image adapter instances\n */\nexport interface ImageAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Image adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'dall-e-3')\n * - TProviderOptions: Base provider-specific options (already resolved)\n * - TModelProviderOptionsByName: Map from model name to its specific provider options\n * - TModelSizeByName: Map from model name to its supported sizes\n * - TModelInputModalitiesByName: Map from model name to the non-text prompt\n * modalities it accepts (constrains the `prompt` part types at compile time)\n */\nexport interface ImageAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n TModelProviderOptionsByName extends Record<string, any> = Record<string, any>,\n TModelSizeByName extends Record<string, string | undefined> = Record<\n string,\n string\n >,\n TModelInputModalitiesByName extends ModelInputModalitiesByName =\n ModelInputModalitiesByName,\n> {\n /** Discriminator for adapter kind - used by generate() to determine API shape */\n readonly kind: 'image'\n /** Adapter name identifier */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n modelProviderOptionsByName: TModelProviderOptionsByName\n modelSizeByName: TModelSizeByName\n modelInputModalitiesByName: TModelInputModalitiesByName\n }\n\n /**\n * Generate images from a prompt\n */\n generateImages: (\n options: ImageGenerationOptions<TProviderOptions, TModelSizeByName[TModel]>,\n ) => Promise<ImageGenerationResult>\n}\n\n/**\n * An ImageAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyImageAdapter = ImageAdapter<any, any, any, any, any>\n\n/**\n * Abstract base class for image generation adapters.\n * Extend this class to implement an image adapter for a specific provider.\n *\n * Generic parameters match ImageAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseImageAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n TModelProviderOptionsByName extends Record<string, any> = Record<string, any>,\n TModelSizeByName extends Record<string, string | undefined> = Record<\n string,\n string\n >,\n TModelInputModalitiesByName extends ModelInputModalitiesByName =\n ModelInputModalitiesByName,\n> implements ImageAdapter<\n TModel,\n TProviderOptions,\n TModelProviderOptionsByName,\n TModelSizeByName,\n TModelInputModalitiesByName\n> {\n readonly kind = 'image' as const\n abstract readonly name: string\n readonly model: TModel\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n modelProviderOptionsByName: TModelProviderOptionsByName\n modelSizeByName: TModelSizeByName\n modelInputModalitiesByName: TModelInputModalitiesByName\n }\n\n protected config: ImageAdapterConfig\n\n constructor(model: TModel, config: ImageAdapterConfig = {}) {\n this.config = config\n this.model = model\n }\n\n abstract generateImages(\n options: ImageGenerationOptions<TProviderOptions, TModelSizeByName[TModel]>,\n ): Promise<ImageGenerationResult>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"
|
|
1
|
+
{"version":3,"file":"adapter.js","names":[],"sources":["../../../../src/activities/generateImage/adapter.ts"],"sourcesContent":["import type {\n ImageGenerationOptions,\n ImageGenerationResult,\n ModelInputModalitiesByName,\n} from '../../types'\n\n/**\n * Resolve the size type for a model from the model-size map.\n * If the map has an index signature (i.e. no explicit keys), falls back to string.\n * If the model is an explicit key, uses its mapped size type.\n * Otherwise falls back to string.\n */\n\n/**\n * Configuration for image adapter instances\n */\nexport interface ImageAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Image adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'dall-e-3')\n * - TProviderOptions: Base provider-specific options (already resolved)\n * - TModelProviderOptionsByName: Map from model name to its specific provider options\n * - TModelSizeByName: Map from model name to its supported sizes\n * - TModelInputModalitiesByName: Map from model name to the non-text prompt\n * modalities it accepts (constrains the `prompt` part types at compile time)\n */\nexport interface ImageAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n TModelProviderOptionsByName extends Record<string, any> = Record<string, any>,\n TModelSizeByName extends Record<string, string | undefined> = Record<\n string,\n string\n >,\n TModelInputModalitiesByName extends ModelInputModalitiesByName =\n ModelInputModalitiesByName,\n> {\n /** Discriminator for adapter kind - used by generate() to determine API shape */\n readonly kind: 'image'\n /** Adapter name identifier */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n modelProviderOptionsByName: TModelProviderOptionsByName\n modelSizeByName: TModelSizeByName\n modelInputModalitiesByName: TModelInputModalitiesByName\n }\n\n /**\n * Generate images from a prompt\n */\n generateImages: (\n options: ImageGenerationOptions<TProviderOptions, TModelSizeByName[TModel]>,\n ) => Promise<ImageGenerationResult>\n}\n\n/**\n * An ImageAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyImageAdapter = ImageAdapter<any, any, any, any, any>\n\n/**\n * Abstract base class for image generation adapters.\n * Extend this class to implement an image adapter for a specific provider.\n *\n * Generic parameters match ImageAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseImageAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n TModelProviderOptionsByName extends Record<string, any> = Record<string, any>,\n TModelSizeByName extends Record<string, string | undefined> = Record<\n string,\n string\n >,\n TModelInputModalitiesByName extends ModelInputModalitiesByName =\n ModelInputModalitiesByName,\n> implements ImageAdapter<\n TModel,\n TProviderOptions,\n TModelProviderOptionsByName,\n TModelSizeByName,\n TModelInputModalitiesByName\n> {\n readonly kind = 'image' as const\n abstract readonly name: string\n readonly model: TModel\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n modelProviderOptionsByName: TModelProviderOptionsByName\n modelSizeByName: TModelSizeByName\n modelInputModalitiesByName: TModelInputModalitiesByName\n }\n\n protected config: ImageAdapterConfig\n\n constructor(model: TModel, config: ImageAdapterConfig = {}) {\n this.config = config\n this.model = model\n }\n\n abstract generateImages(\n options: ImageGenerationOptions<TProviderOptions, TModelSizeByName[TModel]>,\n ): Promise<ImageGenerationResult>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"mappings":";;;;;;;AAsFA,IAAsB,mBAAtB,MAgBE;CACA,OAAgB;CAEhB;CAUA;CAEA,YAAY,OAAe,SAA6B,CAAC,GAAG;EAC1D,KAAK,SAAS;EACd,KAAK,QAAQ;CACf;CAMA,aAA+B;EAC7B,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC;CAC7E;AACF"}
|
|
@@ -69,6 +69,10 @@ export type ImageActivityOptions<TAdapter extends ImageAdapter<string, any, any,
|
|
|
69
69
|
* `GenerationMiddleware` contract for a custom backend.
|
|
70
70
|
*/
|
|
71
71
|
middleware?: Array<GenerationMiddleware>;
|
|
72
|
+
/** Stable conversation/thread id for correlating this run when persisted. */
|
|
73
|
+
threadId?: string;
|
|
74
|
+
/** Stable run id for correlating this run when persisted. */
|
|
75
|
+
runId?: string;
|
|
72
76
|
} & ({} extends ImageProviderOptionsForModel<TAdapter, TAdapter['model']> ? {
|
|
73
77
|
/** Provider-specific options for image generation */ modelOptions?: ImageProviderOptionsForModel<TAdapter, TAdapter['model']>;
|
|
74
78
|
} : {
|