@speech-sdk/core 0.6.1 → 0.6.2
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 +6 -6
- package/dist/__tests__/e2e/_save-audio.d.ts +28 -2
- package/dist/__tests__/e2e/_save-audio.d.ts.map +1 -1
- package/dist/__tests__/e2e/_save-audio.js +101 -9
- package/dist/__tests__/e2e/_save-audio.js.map +1 -1
- package/dist/conversation/validate.d.ts.map +1 -1
- package/dist/conversation/validate.js +0 -6
- package/dist/conversation/validate.js.map +1 -1
- package/dist/generate-conversation.d.ts +1 -0
- package/dist/generate-conversation.d.ts.map +1 -1
- package/dist/generate-conversation.js +13 -0
- package/dist/generate-conversation.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ The return type is the standard `SpeechResult`, so it composes with everything e
|
|
|
164
164
|
```ts
|
|
165
165
|
generateConversation({
|
|
166
166
|
model?: string | ResolvedModel, // default model for all turns
|
|
167
|
-
turns: ConversationTurn[], // 1..N turns;
|
|
167
|
+
turns: ConversationTurn[], // 1..N turns; any number of unique voices
|
|
168
168
|
gapMs?: number, // silence between turns (stitch path), default 300
|
|
169
169
|
normalizeVolume?: boolean, // RMS-level the output, default true
|
|
170
170
|
volumeDbfs?: number, // RMS target loudness in dBFS (≤0), default -20
|
|
@@ -180,10 +180,12 @@ interface ConversationTurn {
|
|
|
180
180
|
voice: Voice; // required
|
|
181
181
|
text: string; // required, non-empty
|
|
182
182
|
model?: string | ResolvedModel; // per-turn override of the top-level model
|
|
183
|
-
providerOptions?: Record<string, unknown>,
|
|
183
|
+
providerOptions?: Record<string, unknown>, // stitch path only; see note below
|
|
184
184
|
}
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
+
Per-turn `providerOptions` are merged with the top-level `providerOptions` on the stitch path — each turn's underlying `generateSpeech()` call receives `{ ...topLevel, ...turn, ...stitchDefaults }`. On the native-dialogue path the provider renders the whole script in one API call, so per-turn overrides have no well-defined meaning; setting `providerOptions` on any turn throws `ConversationInputError`. Move the options to the top-level `providerOptions` (forwarded once to the dialogue call) instead.
|
|
188
|
+
|
|
187
189
|
### Volume normalization
|
|
188
190
|
|
|
189
191
|
`normalizeVolume: true` (the default) RMS-normalizes the output to an absolute target loudness — broadcast/podcast voice convention — so two `generateConversation` calls produce comparable levels regardless of provider mix or content. The target defaults to **−20 dBFS** (~20 dB of peak headroom), and is configurable via `volumeDbfs` (must be ≤ 0; lower is quieter).
|
|
@@ -201,11 +203,11 @@ Pass `normalizeVolume: false` to skip normalization entirely (zero work) and kee
|
|
|
201
203
|
|
|
202
204
|
### Errors
|
|
203
205
|
|
|
204
|
-
Conversation-specific errors (importable from `@speech-sdk/core/conversation/errors`):
|
|
206
|
+
Conversation-specific errors (re-exported from `@speech-sdk/core/conversation` alongside `generateConversation`, or importable on their own from `@speech-sdk/core/conversation/errors`):
|
|
205
207
|
|
|
206
208
|
| Error | When |
|
|
207
209
|
|---|---|
|
|
208
|
-
| `ConversationInputError` | Validation failure — empty turns, blank text,
|
|
210
|
+
| `ConversationInputError` | Validation failure — empty turns, blank text, or a turn missing a model |
|
|
209
211
|
| `DialogueConstraintError` | A native-dialogue provider was selected but the conversation violates its constraints (e.g. 3 voices on Gemini, which requires exactly 2) |
|
|
210
212
|
| `StitchUnsupportedError` | The stitch path was selected but a chosen provider/model can't emit PCM/WAV |
|
|
211
213
|
|
|
@@ -219,8 +221,6 @@ Conversation-specific errors (importable from `@speech-sdk/core/conversation/err
|
|
|
219
221
|
| Fish Audio | `s2-pro` | 1–4 voices |
|
|
220
222
|
| fal | `dia-tts` | 1–2 voices |
|
|
221
223
|
|
|
222
|
-
Across the SDK, conversations are capped at **4 unique voices** total regardless of provider.
|
|
223
|
-
|
|
224
224
|
## Supported Providers
|
|
225
225
|
|
|
226
226
|
Use `provider/model` strings. Passing just the provider name uses its default model.
|
|
@@ -1,11 +1,37 @@
|
|
|
1
|
+
import { generateConversation as _generateConversation } from "../../generate-conversation.js";
|
|
2
|
+
import { generateSpeech as _generateSpeech } from "../../generate-speech.js";
|
|
1
3
|
/**
|
|
2
4
|
* Write a test-generated audio file to `SPEECH_SDK_E2E_OUTPUT_DIR` if the env
|
|
3
5
|
* var is set. No-op otherwise, so normal CI runs don't produce artifacts.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
+
* Usually you don't need to call this directly — use the `generateSpeech`,
|
|
7
|
+
* `generateConversation`, and `collectStreamAndSave` helpers exported from
|
|
8
|
+
* this module, which autosave using the current test name.
|
|
9
|
+
*
|
|
10
|
+
* Output layout: `$SPEECH_SDK_E2E_OUTPUT_DIR/<provider-file>/<test-slug>.<ext>`.
|
|
11
|
+
* If the same test saves multiple times, subsequent files are suffixed `-2`,
|
|
12
|
+
* `-3`, etc.
|
|
6
13
|
*/
|
|
7
14
|
export declare function maybeSaveAudio(name: string, audio: {
|
|
8
15
|
uint8Array: Uint8Array;
|
|
9
16
|
mediaType: string;
|
|
10
17
|
}): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Drop-in replacement for `generateSpeech` that autosaves to
|
|
20
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name.
|
|
21
|
+
*/
|
|
22
|
+
export declare const generateSpeech: typeof _generateSpeech;
|
|
23
|
+
/**
|
|
24
|
+
* Drop-in replacement for `generateConversation` that autosaves to
|
|
25
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name.
|
|
26
|
+
*/
|
|
27
|
+
export declare const generateConversation: typeof _generateConversation;
|
|
28
|
+
/**
|
|
29
|
+
* Collects a streamed `streamSpeech` result into bytes AND autosaves them to
|
|
30
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. Use in place
|
|
31
|
+
* of `collectStream(result.audio)` in e2e tests.
|
|
32
|
+
*/
|
|
33
|
+
export declare function collectStreamAndSave(result: {
|
|
34
|
+
audio: ReadableStream<Uint8Array>;
|
|
35
|
+
mediaType: string;
|
|
36
|
+
}): Promise<Uint8Array>;
|
|
11
37
|
//# sourceMappingURL=_save-audio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_save-audio.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"_save-audio.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAkF7E;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,IAAI,CAAC,CAaf;AAOD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,eAMR,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,OAAO,qBAMR,CAAC;AAEnC;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,UAAU,CAAC,CAOtB"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { expect } from "vitest";
|
|
4
|
+
import { generateConversation as _generateConversation } from "../../generate-conversation.js";
|
|
5
|
+
import { generateSpeech as _generateSpeech } from "../../generate-speech.js";
|
|
6
|
+
import { collectStream } from "./_collect-stream.js";
|
|
3
7
|
function extFor(mediaType) {
|
|
4
8
|
if (mediaType.includes("wav")) {
|
|
5
9
|
return "wav";
|
|
@@ -21,23 +25,111 @@ function extFor(mediaType) {
|
|
|
21
25
|
}
|
|
22
26
|
return "bin";
|
|
23
27
|
}
|
|
28
|
+
const NON_SLUG_CHARS = /[^a-zA-Z0-9._-]+/g;
|
|
29
|
+
const LEADING_OR_TRAILING_UNDERSCORES = /^_+|_+$/g;
|
|
30
|
+
const E2E_TEST_SUFFIX = /\.e2e\.test\.(ts|tsx|js|mjs)$/;
|
|
31
|
+
function slugify(name) {
|
|
32
|
+
return name
|
|
33
|
+
.replace(NON_SLUG_CHARS, "_")
|
|
34
|
+
.replace(LEADING_OR_TRAILING_UNDERSCORES, "");
|
|
35
|
+
}
|
|
36
|
+
function resolveOutputDir() {
|
|
37
|
+
const dir = process.env.SPEECH_SDK_E2E_OUTPUT_DIR;
|
|
38
|
+
if (!dir) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return dir.startsWith("~") ? join(process.env.HOME ?? "", dir.slice(1)) : dir;
|
|
42
|
+
}
|
|
43
|
+
function currentTestContext() {
|
|
44
|
+
// biome-ignore lint/suspicious/noMisplacedAssertion: reading vitest state, not asserting
|
|
45
|
+
const state = expect.getState();
|
|
46
|
+
return {
|
|
47
|
+
currentTestName: state.currentTestName,
|
|
48
|
+
testPath: state.testPath,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Derives the subdirectory for a given test file. e2e tests are named like
|
|
53
|
+
* `openai.e2e.test.ts` / `conversation-google.e2e.test.ts`; we strip the
|
|
54
|
+
* `.e2e.test.ts` suffix and use that as the per-provider bucket so a full run
|
|
55
|
+
* doesn't dump 100+ files into a single flat directory.
|
|
56
|
+
*/
|
|
57
|
+
function providerBucket(testPath) {
|
|
58
|
+
if (!testPath) {
|
|
59
|
+
return "unknown";
|
|
60
|
+
}
|
|
61
|
+
const base = basename(testPath).replace(E2E_TEST_SUFFIX, "");
|
|
62
|
+
return slugify(base) || "unknown";
|
|
63
|
+
}
|
|
64
|
+
// Counter keyed by `${bucket}/${slug}` so multiple generate/stream calls
|
|
65
|
+
// within a single test don't overwrite each other. Vitest isolates modules
|
|
66
|
+
// per file, so this resets per test file — collisions are only meaningful
|
|
67
|
+
// within the same `it`.
|
|
68
|
+
const callCounts = new Map();
|
|
69
|
+
function nextFilename(bucket, slug, ext) {
|
|
70
|
+
const key = `${bucket}/${slug}`;
|
|
71
|
+
const n = (callCounts.get(key) ?? 0) + 1;
|
|
72
|
+
callCounts.set(key, n);
|
|
73
|
+
return n === 1 ? `${slug}.${ext}` : `${slug}-${n}.${ext}`;
|
|
74
|
+
}
|
|
24
75
|
/**
|
|
25
76
|
* Write a test-generated audio file to `SPEECH_SDK_E2E_OUTPUT_DIR` if the env
|
|
26
77
|
* var is set. No-op otherwise, so normal CI runs don't produce artifacts.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
78
|
+
* Usually you don't need to call this directly — use the `generateSpeech`,
|
|
79
|
+
* `generateConversation`, and `collectStreamAndSave` helpers exported from
|
|
80
|
+
* this module, which autosave using the current test name.
|
|
81
|
+
*
|
|
82
|
+
* Output layout: `$SPEECH_SDK_E2E_OUTPUT_DIR/<provider-file>/<test-slug>.<ext>`.
|
|
83
|
+
* If the same test saves multiple times, subsequent files are suffixed `-2`,
|
|
84
|
+
* `-3`, etc.
|
|
29
85
|
*/
|
|
30
86
|
export async function maybeSaveAudio(name, audio) {
|
|
31
|
-
const dir =
|
|
87
|
+
const dir = resolveOutputDir();
|
|
32
88
|
if (!dir) {
|
|
33
89
|
return;
|
|
34
90
|
}
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
await mkdir(
|
|
39
|
-
const
|
|
91
|
+
const { testPath } = currentTestContext();
|
|
92
|
+
const bucket = providerBucket(testPath);
|
|
93
|
+
const bucketDir = join(dir, bucket);
|
|
94
|
+
await mkdir(bucketDir, { recursive: true });
|
|
95
|
+
const filename = nextFilename(bucket, slugify(name), extFor(audio.mediaType));
|
|
96
|
+
const file = join(bucketDir, filename);
|
|
40
97
|
await writeFile(file, audio.uint8Array);
|
|
41
98
|
console.log(`[maybeSaveAudio] wrote ${file}`);
|
|
42
99
|
}
|
|
100
|
+
function currentTestSlug() {
|
|
101
|
+
const { currentTestName } = currentTestContext();
|
|
102
|
+
return slugify(currentTestName ?? "unnamed") || "unnamed";
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Drop-in replacement for `generateSpeech` that autosaves to
|
|
106
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name.
|
|
107
|
+
*/
|
|
108
|
+
export const generateSpeech = (async (options) => {
|
|
109
|
+
const result = await _generateSpeech(options);
|
|
110
|
+
await maybeSaveAudio(currentTestSlug(), result.audio);
|
|
111
|
+
return result;
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* Drop-in replacement for `generateConversation` that autosaves to
|
|
115
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name.
|
|
116
|
+
*/
|
|
117
|
+
export const generateConversation = (async (options) => {
|
|
118
|
+
const result = await _generateConversation(options);
|
|
119
|
+
await maybeSaveAudio(currentTestSlug(), result.audio);
|
|
120
|
+
return result;
|
|
121
|
+
});
|
|
122
|
+
/**
|
|
123
|
+
* Collects a streamed `streamSpeech` result into bytes AND autosaves them to
|
|
124
|
+
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. Use in place
|
|
125
|
+
* of `collectStream(result.audio)` in e2e tests.
|
|
126
|
+
*/
|
|
127
|
+
export async function collectStreamAndSave(result) {
|
|
128
|
+
const bytes = await collectStream(result.audio);
|
|
129
|
+
await maybeSaveAudio(currentTestSlug(), {
|
|
130
|
+
uint8Array: bytes,
|
|
131
|
+
mediaType: result.mediaType,
|
|
132
|
+
});
|
|
133
|
+
return bytes;
|
|
134
|
+
}
|
|
43
135
|
//# sourceMappingURL=_save-audio.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_save-audio.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"_save-audio.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/conversation/validate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/conversation/validate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAEhF;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAChC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3B,MAAM,CAiBR;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,IAAI;IACpC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B,CAEA;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,2BAA2B,GACnC,IAAI,CAkBN"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ConversationInputError } from "./errors.js";
|
|
2
|
-
const MAX_UNIQUE_VOICES = 4;
|
|
3
2
|
/**
|
|
4
3
|
* Stable key for a voice so we can count unique voices across turns within
|
|
5
4
|
* one call. String voices and URL voices use their value; binary
|
|
@@ -41,10 +40,5 @@ export function validateConversationInput(options) {
|
|
|
41
40
|
throw new ConversationInputError(`turns[${i}]: model must be set, either at top-level or on the turn.`);
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
|
-
const ctx = newVoiceKeyContext();
|
|
45
|
-
const uniqueVoices = new Set(options.turns.map((t) => voiceKey(t.voice, ctx.refIds, ctx.refCounter)));
|
|
46
|
-
if (uniqueVoices.size > MAX_UNIQUE_VOICES) {
|
|
47
|
-
throw new ConversationInputError(`generateConversation accepts at most 4 unique voices; got ${uniqueVoices.size}.`);
|
|
48
|
-
}
|
|
49
43
|
}
|
|
50
44
|
//# sourceMappingURL=validate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/conversation/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGrD
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/conversation/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGrD;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAgC,EAChC,MAA+B,EAC/B,UAA4B;IAE5B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,KAAK,EAAE,CAAC;IACtB,CAAC;IACD,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,OAAO,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IACD,0EAA0E;IAC1E,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,EAAE,EAAE,CAAC;AACnB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB;IAIhC,OAAO,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,OAAoC;IAEpC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,sBAAsB,CAC9B,kDAAkD,CACnD,CAAC;IACJ,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,sBAAsB,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;YAChD,MAAM,IAAI,sBAAsB,CAC9B,SAAS,CAAC,2DAA2D,CACtE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { GenerateConversationOptions } from "./conversation/types.js";
|
|
2
2
|
import type { Voice } from "./speech-provider.js";
|
|
3
3
|
import type { SpeechResult } from "./speech-result.js";
|
|
4
|
+
export { ConversationInputError, DialogueConstraintError, StitchUnsupportedError, } from "./conversation/errors.js";
|
|
4
5
|
export type { ConversationTurn, GenerateConversationOptions, } from "./conversation/types.js";
|
|
5
6
|
export declare function generateConversation<V extends Voice = Voice>(options: GenerateConversationOptions<V>): Promise<SpeechResult>;
|
|
6
7
|
//# sourceMappingURL=generate-conversation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-conversation.d.ts","sourceRoot":"","sources":["../src/generate-conversation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-conversation.d.ts","sourceRoot":"","sources":["../src/generate-conversation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAK3E,OAAO,KAAK,EAAiB,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAMjC,wBAAsB,oBAAoB,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,EAChE,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACtC,OAAO,CAAC,YAAY,CAAC,CAqFvB"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import pRetry from "p-retry";
|
|
2
2
|
import { computeAudioDuration } from "./audio-duration.js";
|
|
3
3
|
import { chooseConversationPath } from "./conversation/dispatch.js";
|
|
4
|
+
import { ConversationInputError } from "./conversation/errors.js";
|
|
4
5
|
import { validateConversationInput } from "./conversation/validate.js";
|
|
5
6
|
import { ApiError, NoSpeechGeneratedError } from "./errors.js";
|
|
6
7
|
import { resolveModel } from "./resolve-provider.js";
|
|
7
8
|
import { DefaultGeneratedAudioFile } from "./speech-result.js";
|
|
9
|
+
// biome-ignore lint/performance/noBarrelFile: public entry point — re-export error classes so callers get fn + types + errors from one import
|
|
10
|
+
export { ConversationInputError, DialogueConstraintError, StitchUnsupportedError, } from "./conversation/errors.js";
|
|
8
11
|
const DEFAULT_GAP_MS = 300;
|
|
9
12
|
const DEFAULT_MAX_CONCURRENCY = 6;
|
|
10
13
|
const DEFAULT_MAX_RETRIES = 2;
|
|
@@ -22,6 +25,16 @@ export async function generateConversation(options) {
|
|
|
22
25
|
turns: options.turns,
|
|
23
26
|
});
|
|
24
27
|
if (path.kind === "native") {
|
|
28
|
+
// The native-dialogue path renders the entire script in a single provider
|
|
29
|
+
// API call, so per-turn providerOptions have no well-defined meaning —
|
|
30
|
+
// silently collapsing them to a single blob would lie to the caller. Fail
|
|
31
|
+
// loudly and let them move providerOptions to the top level (where it's
|
|
32
|
+
// forwarded once to the dialogue call) or pick a model that routes
|
|
33
|
+
// through the stitch path.
|
|
34
|
+
const turnWithOpts = options.turns.findIndex((t) => t.providerOptions !== undefined);
|
|
35
|
+
if (turnWithOpts !== -1) {
|
|
36
|
+
throw new ConversationInputError(`turns[${turnWithOpts}].providerOptions is set, but ${path.resolved.provider.id}/${path.resolved.modelId} dispatched to the native dialogue path, which renders all turns in one API call. Per-turn providerOptions are not supported on this path; move them to the top-level providerOptions instead.`);
|
|
37
|
+
}
|
|
25
38
|
return await runNative({
|
|
26
39
|
options,
|
|
27
40
|
resolved: path.resolved,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-conversation.js","sourceRoot":"","sources":["../src/generate-conversation.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"generate-conversation.js","sourceRoot":"","sources":["../src/generate-conversation.ts"],"names":[],"mappings":"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"}
|