@tanstack/ai 0.41.0 → 0.43.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/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 +10 -4
- package/dist/esm/activities/chat/agent-loop-strategies.js +75 -17
- 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 -16
- package/dist/esm/activities/chat/index.js +2100 -1744
- 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 +23 -5
- package/dist/esm/index.js +30 -97
- 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.js +598 -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 +332 -21
- 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 +156 -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 -59
- package/src/activities/chat/agent-loop-strategies.ts +10 -4
- package/src/activities/chat/cancel.ts +81 -0
- package/src/activities/chat/index.ts +1152 -153
- 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 -0
- 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 +1 -0
- 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 +416 -24
- 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,119 +1,168 @@
|
|
|
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/generateSpeech/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* TTS Activity
|
|
9
|
+
*
|
|
10
|
+
* Generates speech audio from text using text-to-speech models.
|
|
11
|
+
* This is a self-contained module with implementation, types, and JSDoc.
|
|
12
|
+
*/
|
|
13
|
+
/** The adapter kind this activity handles */
|
|
14
|
+
var kind = "tts";
|
|
6
15
|
function createId(prefix) {
|
|
7
|
-
|
|
16
|
+
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
8
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* TTS activity - generates speech from text.
|
|
20
|
+
*
|
|
21
|
+
* Uses AI text-to-speech models to create audio from natural language text.
|
|
22
|
+
*
|
|
23
|
+
* @example Generate speech from text
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { generateSpeech } from '@tanstack/ai'
|
|
26
|
+
* import { openaiSpeech } from '@tanstack/ai-openai'
|
|
27
|
+
*
|
|
28
|
+
* const result = await generateSpeech({
|
|
29
|
+
* adapter: openaiSpeech('tts-1-hd'),
|
|
30
|
+
* text: 'Hello, welcome to TanStack AI!',
|
|
31
|
+
* voice: 'nova'
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* console.log(result.audio) // base64-encoded audio
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @example With format and speed options
|
|
38
|
+
* ```ts
|
|
39
|
+
* const result = await generateSpeech({
|
|
40
|
+
* adapter: openaiSpeech('tts-1'),
|
|
41
|
+
* text: 'This is slower speech.',
|
|
42
|
+
* voice: 'alloy',
|
|
43
|
+
* format: 'wav',
|
|
44
|
+
* speed: 0.8
|
|
45
|
+
* })
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
9
48
|
function generateSpeech(options) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return runGenerateSpeech(options);
|
|
49
|
+
if (options.stream) return streamGenerationResult((resolved) => runGenerateSpeech({
|
|
50
|
+
...options,
|
|
51
|
+
runId: resolved.runId
|
|
52
|
+
}), options);
|
|
53
|
+
return runGenerateSpeech(options);
|
|
16
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Run the core TTS generation logic (non-streaming).
|
|
57
|
+
*/
|
|
17
58
|
async function runGenerateSpeech(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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
59
|
+
const { adapter, stream: _stream, debug: _debug, middleware, threadId, runId, ...rest } = options;
|
|
60
|
+
const model = adapter.model;
|
|
61
|
+
const requestId = createId("speech");
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
const logger = resolveDebugOption(options.debug);
|
|
64
|
+
const providerName = adapter.provider ?? adapter.name ?? "unknown";
|
|
65
|
+
const mwCtx = createGenerationContext({
|
|
66
|
+
requestId,
|
|
67
|
+
activity: "tts",
|
|
68
|
+
provider: adapter.name,
|
|
69
|
+
model,
|
|
70
|
+
modelOptions: rest.modelOptions,
|
|
71
|
+
artifactInputs: {
|
|
72
|
+
text: rest.text,
|
|
73
|
+
voice: rest.voice,
|
|
74
|
+
format: rest.format,
|
|
75
|
+
speed: rest.speed
|
|
76
|
+
},
|
|
77
|
+
threadId,
|
|
78
|
+
runId,
|
|
79
|
+
createId
|
|
80
|
+
});
|
|
81
|
+
await runGenerationStart(middleware, mwCtx);
|
|
82
|
+
aiEventClient.emit("speech:request:started", {
|
|
83
|
+
requestId,
|
|
84
|
+
provider: adapter.name,
|
|
85
|
+
model,
|
|
86
|
+
text: rest.text,
|
|
87
|
+
voice: rest.voice,
|
|
88
|
+
format: rest.format,
|
|
89
|
+
speed: rest.speed,
|
|
90
|
+
modelOptions: rest.modelOptions,
|
|
91
|
+
timestamp: startTime
|
|
92
|
+
});
|
|
93
|
+
logger.request(`activity=generateSpeech provider=${providerName}`, {
|
|
94
|
+
provider: providerName,
|
|
95
|
+
model
|
|
96
|
+
});
|
|
97
|
+
try {
|
|
98
|
+
const result = await applyGenerationResultTransforms(mwCtx, await adapter.generateSpeech({
|
|
99
|
+
...rest,
|
|
100
|
+
model,
|
|
101
|
+
logger
|
|
102
|
+
}));
|
|
103
|
+
const duration = Date.now() - startTime;
|
|
104
|
+
aiEventClient.emit("speech:request:completed", {
|
|
105
|
+
requestId,
|
|
106
|
+
provider: adapter.name,
|
|
107
|
+
model,
|
|
108
|
+
audio: result.audio,
|
|
109
|
+
format: result.format,
|
|
110
|
+
audioDuration: result.duration,
|
|
111
|
+
contentType: result.contentType,
|
|
112
|
+
duration,
|
|
113
|
+
modelOptions: rest.modelOptions,
|
|
114
|
+
timestamp: Date.now()
|
|
115
|
+
});
|
|
116
|
+
if (result.usage) aiEventClient.emit("speech:usage", {
|
|
117
|
+
requestId,
|
|
118
|
+
model,
|
|
119
|
+
usage: result.usage,
|
|
120
|
+
modelOptions: rest.modelOptions,
|
|
121
|
+
timestamp: Date.now()
|
|
122
|
+
});
|
|
123
|
+
logger.output(`activity=generateSpeech bytes=${result.audio.length}`, {
|
|
124
|
+
bytes: result.audio.length,
|
|
125
|
+
contentType: result.contentType
|
|
126
|
+
});
|
|
127
|
+
if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage);
|
|
128
|
+
await runGenerationFinish(middleware, mwCtx, {
|
|
129
|
+
duration,
|
|
130
|
+
usage: result.usage
|
|
131
|
+
});
|
|
132
|
+
return result;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
const duration = Date.now() - startTime;
|
|
135
|
+
const err = error;
|
|
136
|
+
aiEventClient.emit("speech:request:error", {
|
|
137
|
+
requestId,
|
|
138
|
+
provider: adapter.name,
|
|
139
|
+
model,
|
|
140
|
+
error: {
|
|
141
|
+
message: err.message,
|
|
142
|
+
name: err.name
|
|
143
|
+
},
|
|
144
|
+
duration,
|
|
145
|
+
modelOptions: rest.modelOptions,
|
|
146
|
+
timestamp: Date.now()
|
|
147
|
+
});
|
|
148
|
+
await runGenerationError(middleware, mwCtx, {
|
|
149
|
+
error,
|
|
150
|
+
duration
|
|
151
|
+
});
|
|
152
|
+
logger.errors("generateSpeech activity failed", {
|
|
153
|
+
error,
|
|
154
|
+
source: "generateSpeech"
|
|
155
|
+
});
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
110
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Create typed options for the generateSpeech() function without executing.
|
|
161
|
+
*/
|
|
111
162
|
function createSpeechOptions(options) {
|
|
112
|
-
|
|
163
|
+
return options;
|
|
113
164
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
};
|
|
119
|
-
//# sourceMappingURL=index.js.map
|
|
165
|
+
//#endregion
|
|
166
|
+
export { createSpeechOptions, generateSpeech, kind };
|
|
167
|
+
|
|
168
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/activities/generateSpeech/index.ts"],"sourcesContent":["/**\n * TTS Activity\n *\n * Generates speech audio from text using text-to-speech models.\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 { TTSAdapter } from './adapter'\nimport type { StreamChunk, TTSResult } from '../../types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'tts' as const\n\n// ===========================\n// Type Extraction Helpers\n// ===========================\n\n/**\n * Extract provider options from a TTSAdapter via ~types.\n */\nexport type TTSProviderOptions<TAdapter> =\n TAdapter extends TTSAdapter<any, any>\n ? TAdapter['~types']['providerOptions']\n : object\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the TTS activity.\n * The model is extracted from the adapter's model property.\n *\n * @template TAdapter - The TTS adapter type\n * @template TStream - Whether to stream the output\n */\nexport interface TTSActivityOptions<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n> {\n /** The TTS adapter to use (must be created with a model) */\n adapter: TAdapter & { kind: typeof kind }\n /** The text to convert to speech */\n text: string\n /** The voice to use for generation */\n voice?: string\n /** The output audio format */\n format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'\n /** The speed of the generated audio (0.25 to 4.0) */\n speed?: number\n /** Provider-specific options for TTS generation */\n modelOptions?: TTSProviderOptions<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<TTSResult>.\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 TTS activity.\n * - If stream is true: AsyncIterable<StreamChunk>\n * - Otherwise: Promise<TTSResult>\n */\nexport type TTSActivityResult<TStream extends boolean = false> =\n TStream extends true ? AsyncIterable<StreamChunk> : Promise<TTSResult>\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 * TTS activity - generates speech from text.\n *\n * Uses AI text-to-speech models to create audio from natural language text.\n *\n * @example Generate speech from text\n * ```ts\n * import { generateSpeech } from '@tanstack/ai'\n * import { openaiSpeech } from '@tanstack/ai-openai'\n *\n * const result = await generateSpeech({\n * adapter: openaiSpeech('tts-1-hd'),\n * text: 'Hello, welcome to TanStack AI!',\n * voice: 'nova'\n * })\n *\n * console.log(result.audio) // base64-encoded audio\n * ```\n *\n * @example With format and speed options\n * ```ts\n * const result = await generateSpeech({\n * adapter: openaiSpeech('tts-1'),\n * text: 'This is slower speech.',\n * voice: 'alloy',\n * format: 'wav',\n * speed: 0.8\n * })\n * ```\n */\nexport function generateSpeech<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(options: TTSActivityOptions<TAdapter, TStream>): TTSActivityResult<TStream> {\n if (options.stream) {\n return streamGenerationResult(() =>\n runGenerateSpeech(options),\n ) as TTSActivityResult<TStream>\n }\n return runGenerateSpeech(options) as TTSActivityResult<TStream>\n}\n\n/**\n * Run the core TTS generation logic (non-streaming).\n */\nasync function runGenerateSpeech<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n>(options: TTSActivityOptions<TAdapter, boolean>): Promise<TTSResult> {\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('speech')\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: 'tts',\n provider: adapter.name,\n model,\n modelOptions: rest.modelOptions,\n createId,\n })\n\n await runGenerationStart(middleware, mwCtx)\n\n aiEventClient.emit('speech:request:started', {\n requestId,\n provider: adapter.name,\n model,\n text: rest.text,\n voice: rest.voice,\n format: rest.format,\n speed: rest.speed,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: startTime,\n })\n\n logger.request(`activity=generateSpeech provider=${providerName}`, {\n provider: providerName,\n model,\n })\n\n try {\n const result = await adapter.generateSpeech({ ...rest, model, logger })\n const duration = Date.now() - startTime\n\n aiEventClient.emit('speech:request:completed', {\n requestId,\n provider: adapter.name,\n model,\n audio: result.audio,\n format: result.format,\n audioDuration: result.duration,\n contentType: result.contentType,\n duration,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n\n if (result.usage) {\n aiEventClient.emit('speech: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=generateSpeech bytes=${result.audio.length}`, {\n bytes: result.audio.length,\n contentType: result.contentType,\n })\n\n if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage)\n await runGenerationFinish(middleware, mwCtx, {\n duration,\n usage: result.usage,\n })\n\n return result\n } catch (error) {\n const duration = Date.now() - startTime\n const err = error as Error\n aiEventClient.emit('speech:request:error', {\n requestId,\n provider: adapter.name,\n model,\n error: { message: err.message, name: err.name },\n duration,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n await runGenerationError(middleware, mwCtx, {\n error,\n duration,\n })\n logger.errors('generateSpeech activity failed', {\n error,\n source: 'generateSpeech',\n })\n throw error\n }\n}\n\n// ===========================\n// Options Factory\n// ===========================\n\n/**\n * Create typed options for the generateSpeech() function without executing.\n */\nexport function createSpeechOptions<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(\n options: TTSActivityOptions<TAdapter, TStream>,\n): TTSActivityOptions<TAdapter, TStream> {\n return options\n}\n\n// Re-export adapter types\nexport type { TTSAdapter, TTSAdapterConfig, AnyTTSAdapter } from './adapter'\nexport { BaseTTSAdapter } from './adapter'\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/activities/generateSpeech/index.ts"],"sourcesContent":["/**\n * TTS Activity\n *\n * Generates speech audio from text using text-to-speech models.\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 { TTSAdapter } from './adapter'\nimport type { StreamChunk, TTSResult } from '../../types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'tts' as const\n\n// ===========================\n// Type Extraction Helpers\n// ===========================\n\n/**\n * Extract provider options from a TTSAdapter via ~types.\n */\nexport type TTSProviderOptions<TAdapter> =\n TAdapter extends TTSAdapter<any, any>\n ? TAdapter['~types']['providerOptions']\n : object\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the TTS activity.\n * The model is extracted from the adapter's model property.\n *\n * @template TAdapter - The TTS adapter type\n * @template TStream - Whether to stream the output\n */\nexport interface TTSActivityOptions<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n> {\n /** The TTS adapter to use (must be created with a model) */\n adapter: TAdapter & { kind: typeof kind }\n /** The text to convert to speech */\n text: string\n /** The voice to use for generation */\n voice?: string\n /** The output audio format */\n format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'\n /** The speed of the generated audio (0.25 to 4.0) */\n speed?: number\n /** Provider-specific options for TTS generation */\n modelOptions?: TTSProviderOptions<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<TTSResult>.\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 TTS activity.\n * - If stream is true: AsyncIterable<StreamChunk>\n * - Otherwise: Promise<TTSResult>\n */\nexport type TTSActivityResult<TStream extends boolean = false> =\n TStream extends true ? AsyncIterable<StreamChunk> : Promise<TTSResult>\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 * TTS activity - generates speech from text.\n *\n * Uses AI text-to-speech models to create audio from natural language text.\n *\n * @example Generate speech from text\n * ```ts\n * import { generateSpeech } from '@tanstack/ai'\n * import { openaiSpeech } from '@tanstack/ai-openai'\n *\n * const result = await generateSpeech({\n * adapter: openaiSpeech('tts-1-hd'),\n * text: 'Hello, welcome to TanStack AI!',\n * voice: 'nova'\n * })\n *\n * console.log(result.audio) // base64-encoded audio\n * ```\n *\n * @example With format and speed options\n * ```ts\n * const result = await generateSpeech({\n * adapter: openaiSpeech('tts-1'),\n * text: 'This is slower speech.',\n * voice: 'alloy',\n * format: 'wav',\n * speed: 0.8\n * })\n * ```\n */\nexport function generateSpeech<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(options: TTSActivityOptions<TAdapter, TStream>): TTSActivityResult<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) => runGenerateSpeech({ ...options, runId: resolved.runId }),\n options,\n ) as TTSActivityResult<TStream>\n }\n return runGenerateSpeech(options) as TTSActivityResult<TStream>\n}\n\n/**\n * Run the core TTS generation logic (non-streaming).\n */\nasync function runGenerateSpeech<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n>(options: TTSActivityOptions<TAdapter, boolean>): Promise<TTSResult> {\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('speech')\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: 'tts',\n provider: adapter.name,\n model,\n modelOptions: rest.modelOptions,\n artifactInputs: {\n text: rest.text,\n voice: rest.voice,\n format: rest.format,\n speed: rest.speed,\n },\n threadId,\n runId,\n createId,\n })\n\n await runGenerationStart(middleware, mwCtx)\n\n aiEventClient.emit('speech:request:started', {\n requestId,\n provider: adapter.name,\n model,\n text: rest.text,\n voice: rest.voice,\n format: rest.format,\n speed: rest.speed,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: startTime,\n })\n\n logger.request(`activity=generateSpeech provider=${providerName}`, {\n provider: providerName,\n model,\n })\n\n try {\n const rawResult = await adapter.generateSpeech({ ...rest, model, logger })\n const result = await applyGenerationResultTransforms(mwCtx, rawResult)\n const duration = Date.now() - startTime\n\n aiEventClient.emit('speech:request:completed', {\n requestId,\n provider: adapter.name,\n model,\n audio: result.audio,\n format: result.format,\n audioDuration: result.duration,\n contentType: result.contentType,\n duration,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n\n if (result.usage) {\n aiEventClient.emit('speech: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=generateSpeech bytes=${result.audio.length}`, {\n bytes: result.audio.length,\n contentType: result.contentType,\n })\n\n if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage)\n await runGenerationFinish(middleware, mwCtx, {\n duration,\n usage: result.usage,\n })\n\n return result\n } catch (error) {\n const duration = Date.now() - startTime\n const err = error as Error\n aiEventClient.emit('speech:request:error', {\n requestId,\n provider: adapter.name,\n model,\n error: { message: err.message, name: err.name },\n duration,\n modelOptions: rest.modelOptions as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n })\n await runGenerationError(middleware, mwCtx, {\n error,\n duration,\n })\n logger.errors('generateSpeech activity failed', {\n error,\n source: 'generateSpeech',\n })\n throw error\n }\n}\n\n// ===========================\n// Options Factory\n// ===========================\n\n/**\n * Create typed options for the generateSpeech() function without executing.\n */\nexport function createSpeechOptions<\n TAdapter extends TTSAdapter<string, TTSProviderOptions<TAdapter>>,\n TStream extends boolean = false,\n>(\n options: TTSActivityOptions<TAdapter, TStream>,\n): TTSActivityOptions<TAdapter, TStream> {\n return options\n}\n\n// Re-export adapter types\nexport type { TTSAdapter, TTSAdapterConfig, AnyTTSAdapter } from './adapter'\nexport { BaseTTSAdapter } from './adapter'\n"],"mappings":";;;;;;;;;;;;;AA6BA,IAAa,OAAO;AA+EpB,SAAS,SAAS,QAAwB;CACxC,OAAO,GAAG,OAAO,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;AACzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,eAGd,SAA4E;CAC5E,IAAI,QAAQ,QACV,OAAO,wBAMJ,aAAa,kBAAkB;EAAE,GAAG;EAAS,OAAO,SAAS;CAAM,CAAC,GACrE,OACF;CAEF,OAAO,kBAAkB,OAAO;AAClC;;;;AAKA,eAAe,kBAEb,SAAoE;CACpE,MAAM,EACJ,SACA,QAAQ,SACR,OAAO,QACP,YACA,UACA,OACA,GAAG,SACD;CACJ,MAAM,QAAQ,QAAQ;CACtB,MAAM,YAAY,SAAS,QAAQ;CACnC,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,gBAAgB;GACd,MAAM,KAAK;GACX,OAAO,KAAK;GACZ,QAAQ,KAAK;GACb,OAAO,KAAK;EACd;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,mBAAmB,YAAY,KAAK;CAE1C,cAAc,KAAK,0BAA0B;EAC3C;EACA,UAAU,QAAQ;EAClB;EACA,MAAM,KAAK;EACX,OAAO,KAAK;EACZ,QAAQ,KAAK;EACb,OAAO,KAAK;EACZ,cAAc,KAAK;EACnB,WAAW;CACb,CAAC;CAED,OAAO,QAAQ,oCAAoC,gBAAgB;EACjE,UAAU;EACV;CACF,CAAC;CAED,IAAI;EAEF,MAAM,SAAS,MAAM,gCAAgC,OAAO,MADpC,QAAQ,eAAe;GAAE,GAAG;GAAM;GAAO;EAAO,CAAC,CACJ;EACrE,MAAM,WAAW,KAAK,IAAI,IAAI;EAE9B,cAAc,KAAK,4BAA4B;GAC7C;GACA,UAAU,QAAQ;GAClB;GACA,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,eAAe,OAAO;GACtB,aAAa,OAAO;GACpB;GACA,cAAc,KAAK;GACnB,WAAW,KAAK,IAAI;EACtB,CAAC;EAED,IAAI,OAAO,OACT,cAAc,KAAK,gBAAgB;GACjC;GACA;GACA,OAAO,OAAO;GACd,cAAc,KAAK;GACnB,WAAW,KAAK,IAAI;EACtB,CAAC;EAGH,OAAO,OAAO,iCAAiC,OAAO,MAAM,UAAU;GACpE,OAAO,OAAO,MAAM;GACpB,aAAa,OAAO;EACtB,CAAC;EAED,IAAI,OAAO,OAAO,MAAM,mBAAmB,YAAY,OAAO,OAAO,KAAK;EAC1E,MAAM,oBAAoB,YAAY,OAAO;GAC3C;GACA,OAAO,OAAO;EAChB,CAAC;EAED,OAAO;CACT,SAAS,OAAO;EACd,MAAM,WAAW,KAAK,IAAI,IAAI;EAC9B,MAAM,MAAM;EACZ,cAAc,KAAK,wBAAwB;GACzC;GACA,UAAU,QAAQ;GAClB;GACA,OAAO;IAAE,SAAS,IAAI;IAAS,MAAM,IAAI;GAAK;GAC9C;GACA,cAAc,KAAK;GACnB,WAAW,KAAK,IAAI;EACtB,CAAC;EACD,MAAM,mBAAmB,YAAY,OAAO;GAC1C;GACA;EACF,CAAC;EACD,OAAO,OAAO,kCAAkC;GAC9C;GACA,QAAQ;EACV,CAAC;EACD,MAAM;CACR;AACF;;;;AASA,SAAgB,oBAId,SACuC;CACvC,OAAO;AACT"}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
//#region src/activities/generateTranscription/adapter.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for audio transcription adapters.
|
|
4
|
+
* Extend this class to implement a transcription adapter for a specific provider.
|
|
5
|
+
*
|
|
6
|
+
* Generic parameters match TranscriptionAdapter - all pre-resolved by the provider function.
|
|
7
|
+
*/
|
|
8
|
+
var BaseTranscriptionAdapter = class {
|
|
9
|
+
kind = "transcription";
|
|
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 { BaseTranscriptionAdapter };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sources":["../../../../src/activities/generateTranscription/adapter.ts"],"sourcesContent":["import type { TranscriptionOptions, TranscriptionResult } from '../../types'\n\n/**\n * Configuration for transcription adapter instances\n */\nexport interface TranscriptionAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Transcription 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., 'whisper-1')\n * - TProviderOptions: Provider-specific options (already resolved)\n */\nexport interface TranscriptionAdapter<\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: 'transcription'\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 * Transcribe audio to text\n */\n transcribe: (\n options: TranscriptionOptions<TProviderOptions>,\n ) => Promise<TranscriptionResult>\n}\n\n/**\n * A TranscriptionAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyTranscriptionAdapter = TranscriptionAdapter<any, any>\n\n/**\n * Abstract base class for audio transcription adapters.\n * Extend this class to implement a transcription adapter for a specific provider.\n *\n * Generic parameters match TranscriptionAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseTranscriptionAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n> implements TranscriptionAdapter<TModel, TProviderOptions> {\n readonly kind = 'transcription' 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: TranscriptionAdapterConfig\n\n constructor(model: TModel, config: TranscriptionAdapterConfig = {}) {\n this.config = config\n this.model = model\n }\n\n abstract transcribe(\n options: TranscriptionOptions<TProviderOptions>,\n ): Promise<TranscriptionResult>\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/generateTranscription/adapter.ts"],"sourcesContent":["import type { TranscriptionOptions, TranscriptionResult } from '../../types'\n\n/**\n * Configuration for transcription adapter instances\n */\nexport interface TranscriptionAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Transcription 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., 'whisper-1')\n * - TProviderOptions: Provider-specific options (already resolved)\n */\nexport interface TranscriptionAdapter<\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: 'transcription'\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 * Transcribe audio to text\n */\n transcribe: (\n options: TranscriptionOptions<TProviderOptions>,\n ) => Promise<TranscriptionResult>\n}\n\n/**\n * A TranscriptionAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyTranscriptionAdapter = TranscriptionAdapter<any, any>\n\n/**\n * Abstract base class for audio transcription adapters.\n * Extend this class to implement a transcription adapter for a specific provider.\n *\n * Generic parameters match TranscriptionAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseTranscriptionAdapter<\n TModel extends string = string,\n TProviderOptions extends object = Record<string, unknown>,\n> implements TranscriptionAdapter<TModel, TProviderOptions> {\n readonly kind = 'transcription' 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: TranscriptionAdapterConfig\n\n constructor(model: TModel, config: TranscriptionAdapterConfig = {}) {\n this.config = config\n this.model = model\n }\n\n abstract transcribe(\n options: TranscriptionOptions<TProviderOptions>,\n ): Promise<TranscriptionResult>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"mappings":";;;;;;;AA6DA,IAAsB,2BAAtB,MAG4D;CAC1D,OAAgB;CAEhB;CAOA;CAEA,YAAY,OAAe,SAAqC,CAAC,GAAG;EAClE,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 TranscriptionActivityOptions<TAdapter extends TranscriptionAdap
|
|
|
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 transcription activity.
|