@henjicc/ai-sdk 0.7.0 → 0.9.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +231 -211
  2. package/README.md +2 -2
  3. package/dist/capabilities/speech-recognition/bailian/module.js +29 -14
  4. package/dist/capabilities/speech-recognition/bailian/types.d.ts +2 -0
  5. package/dist/catalog/apimart/gemini-omni-flash.model.js +3 -14
  6. package/dist/catalog/bailian/cosyvoice-v3.5.model.js +1 -1
  7. package/dist/catalog/bailian/minimax-speech-2.8.model.js +1 -1
  8. package/dist/catalog/bailian/qwen-audio-3.1-tts-flash.model.js +1 -1
  9. package/dist/catalog/fal/eleven-v3-tts.model.js +1 -1
  10. package/dist/catalog/fal/minimax-speech-2.8.model.js +1 -1
  11. package/dist/catalog/kie/eleven-turbo-2.5-tts.model.js +1 -1
  12. package/dist/catalog/kie/eleven-v3-dialogue.model.js +1 -1
  13. package/dist/catalog/kie/gemini-3.1-flash-tts.model.js +1 -1
  14. package/dist/catalog/kie/gemini-omni-video.model.js +5 -26
  15. package/dist/catalog/ppio/minimax-speech.model.js +1 -1
  16. package/dist/catalog/siliconflow/cosyvoice2-tts.model.js +1 -1
  17. package/dist/catalog/siliconflow/moss-ttsd-0.5.model.js +1 -1
  18. package/dist/catalog/volcengine-speech/seed-icl-2.0.model.d.ts +1 -0
  19. package/dist/catalog/volcengine-speech/seed-icl-2.0.model.js +52 -10
  20. package/dist/catalog/volcengine-speech/seed-tts-2.0-voices.d.ts +2 -0
  21. package/dist/catalog/volcengine-speech/seed-tts-2.0-voices.js +438 -0
  22. package/dist/catalog/volcengine-speech/seed-tts-2.0.model.js +3 -3
  23. package/dist/generation/core.d.ts +6 -0
  24. package/dist/generation/core.js +10 -2
  25. package/dist/index.d.ts +5 -0
  26. package/dist/index.js +7 -0
  27. package/dist/providers/index.d.ts +1 -0
  28. package/dist/providers/index.js +1 -0
  29. package/dist/providers/tts-voices.d.ts +9 -0
  30. package/dist/providers/tts-voices.js +139 -0
  31. package/dist/providers/volcengine-speech.d.ts +1 -1
  32. package/dist/providers/volcengine-speech.js +9 -3
  33. package/dist/providers/volcengine-voice-clone.d.ts +3 -0
  34. package/dist/providers/volcengine-voice-clone.js +129 -0
  35. package/dist/types/runtime.d.ts +3 -0
  36. package/dist/upload/media-binary.js +1 -0
  37. package/docs/consumers.md +27 -3
  38. package/docs/model-adaptation/Gemini-Omni-Flash/Gemini-Omni-Flash_APIMart.md +1 -0
  39. package/docs/model-adaptation/Gemini-Omni-Flash/Gemini-Omni-Flash_KIE.md +1 -0
  40. package/docs/model-adaptation/README.md +11 -7
  41. package/docs/model-adaptation/Seed-ICL-2.0/Seed-ICL-2.0_/347/201/253/345/261/261/345/274/225/346/223/216.md +65 -0
  42. package/docs/model-adaptation/TTS-/345/244/232/344/276/233/345/272/224/345/225/206-2026-09.md +69 -55
  43. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//347/231/276/347/202/274.md +6 -0
  44. package/docs/model-adaptation//346/226/207/346/241/243/351/207/207/351/233/206/346/211/213/345/206/214.md +6 -5
  45. package/package.json +1 -1
@@ -86,12 +86,9 @@ export const apimartGeminiOmniFlashModel = defineModel({
86
86
  { value: 'reference' },
87
87
  { value: 'frame' }
88
88
  ]
89
- },
90
- {
91
- id: 'apimartGeminiOmniFlashExtendTaskId', type: 'text', order: 5,
92
- default: '',
93
- visible: { condition: (params) => params.apimartGeminiOmniFlashChannel !== 'ext' }
94
89
  }
90
+ // extend_from_task_id(多轮延续)要填供应商侧的上一次任务 ID,界面不展示任务 ID、用户也拿不到:
91
+ // 按“不显示且不请求”处理(界面计划 5.8,P-17);以后做成生成记录上的“继续编辑”动作再接入
95
92
  ],
96
93
  endpoints: '/v1/videos/generations',
97
94
  request: {
@@ -136,13 +133,7 @@ export const apimartGeminiOmniFlashModel = defineModel({
136
133
  body.video_urls = videos.slice(0, 1);
137
134
  return body;
138
135
  }
139
- const extendTaskId = typeof params.apimartGeminiOmniFlashExtendTaskId === 'string'
140
- ? params.apimartGeminiOmniFlashExtendTaskId.trim()
141
- : '';
142
- if (videos.length > 0 && extendTaskId) {
143
- throw new Error('Gemini Omni Flash 官方渠道不能同时传入参考视频和延续任务 ID');
144
- }
145
- if (!prompt && images.length + videos.length === 0 && !extendTaskId) {
136
+ if (!prompt && images.length + videos.length === 0) {
146
137
  throw new Error('Gemini Omni Flash 官方渠道至少需要提示词或一份参考素材');
147
138
  }
148
139
  const body = {
@@ -156,8 +147,6 @@ export const apimartGeminiOmniFlashModel = defineModel({
156
147
  body.image_urls = images.slice(0, 4);
157
148
  if (videos.length > 0)
158
149
  body.video_urls = videos.slice(0, 1);
159
- if (extendTaskId)
160
- body.extend_from_task_id = extendTaskId;
161
150
  return body;
162
151
  }
163
152
  },
@@ -8,7 +8,7 @@ export const bailianCosyVoice35Model = defineModel({
8
8
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
9
9
  params: [
10
10
  { id: 'bailianCosyVoiceSpec', type: 'dropdown', order: 1, default: 'flash', options: [{ value: 'flash' }, { value: 'plus' }] },
11
- { id: 'bailianCosyVoiceId', type: 'text', order: 2, required: true, default: '' },
11
+ { id: 'bailianCosyVoiceId', type: 'composite', valueType: 'string', order: 2, required: true, default: '' },
12
12
  { id: 'bailianCosyVoiceInstruction', type: 'text', order: 3, default: '' },
13
13
  { id: 'bailianCosyVoiceSpeed', type: 'number', order: 4, default: 1, min: 0.5, max: 2, step: 0.1 },
14
14
  ],
@@ -8,7 +8,7 @@ export const bailianMinimaxSpeech28Model = defineModel({
8
8
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
9
9
  params: [
10
10
  { id: 'bailianMinimaxSpeechSpec', type: 'dropdown', order: 1, default: 'hd', options: [{ value: 'hd' }, { value: 'turbo' }] },
11
- { id: 'bailianMinimaxSpeechVoice', type: 'text', order: 2, default: 'male-qn-qingse' },
11
+ { id: 'bailianMinimaxSpeechVoice', type: 'composite', valueType: 'string', order: 2, default: 'male-qn-qingse' },
12
12
  { id: 'bailianMinimaxSpeechSpeed', type: 'number', order: 3, default: 1, min: 0.5, max: 2, step: 0.1 },
13
13
  { id: 'bailianMinimaxSpeechEmotion', type: 'dropdown', order: 4, default: '', options: ['', 'happy', 'sad', 'angry', 'fearful', 'disgusted', 'surprised', 'calm'].map(value => ({ value })) },
14
14
  ],
@@ -8,7 +8,7 @@ export const bailianQwenAudio31TtsFlashModel = defineModel({
8
8
  },
9
9
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
10
10
  params: [
11
- { id: 'bailianQwenTtsVoice', type: 'dropdown', order: 1, default: 'longanhuan_v3.1', options: ['longanhuan_v3.1', 'longanlingxin_v3.1', 'longanfengyue_v3.1', 'xunanchuan_v3.1'].map(value => ({ value })) },
11
+ { id: 'bailianQwenTtsVoice', type: 'composite', valueType: 'string', order: 1, default: 'longanhuan_v3.1' },
12
12
  { id: 'bailianQwenTtsInstruction', type: 'text', order: 2, default: '' },
13
13
  { id: 'bailianQwenTtsSpeed', type: 'number', order: 3, default: 1, min: 0.5, max: 2, step: 0.1 },
14
14
  ],
@@ -8,7 +8,7 @@ export const falElevenV3TtsModel = defineModel({
8
8
  },
9
9
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
10
10
  params: [
11
- { id: 'falElevenV3Voice', type: 'text', order: 1, default: 'Rachel' },
11
+ { id: 'falElevenV3Voice', type: 'composite', valueType: 'string', order: 1, default: 'Rachel' },
12
12
  { id: 'falElevenV3Stability', type: 'number', order: 2, default: 0.5, min: 0, max: 1, step: 0.05 },
13
13
  { id: 'falElevenV3Language', type: 'text', order: 3, default: '' },
14
14
  ],
@@ -10,7 +10,7 @@ export const falMinimaxSpeech28Model = defineModel({
10
10
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
11
11
  params: [
12
12
  { id: 'falMinimaxSpeechSpec', type: 'dropdown', order: 1, default: 'hd', options: [{ value: 'hd' }, { value: 'turbo' }] },
13
- { id: 'falMinimaxSpeechVoice', type: 'text', order: 2, default: 'Wise_Woman' },
13
+ { id: 'falMinimaxSpeechVoice', type: 'composite', valueType: 'string', order: 2, default: 'Wise_Woman' },
14
14
  { id: 'falMinimaxSpeechSpeed', type: 'number', order: 3, default: 1, min: 0.5, max: 2, step: 0.1 },
15
15
  { id: 'falMinimaxSpeechEmotion', type: 'dropdown', order: 4, default: '', options: ['', 'happy', 'sad', 'angry', 'fearful', 'disgusted', 'surprised', 'neutral'].map(value => ({ value })) },
16
16
  ],
@@ -8,7 +8,7 @@ export const kieElevenTurbo25TtsModel = defineModel({
8
8
  },
9
9
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
10
10
  params: [
11
- { id: 'kieElevenTurboVoice', type: 'text', order: 1, default: 'Rachel' },
11
+ { id: 'kieElevenTurboVoice', type: 'composite', valueType: 'string', order: 1, default: 'Rachel' },
12
12
  { id: 'kieElevenTurboStability', type: 'number', order: 2, default: 0.5, min: 0, max: 1, step: 0.05 },
13
13
  { id: 'kieElevenTurboSpeed', type: 'number', order: 3, default: 1, min: 0.7, max: 1.2, step: 0.05 },
14
14
  ],
@@ -20,7 +20,7 @@ export const kieElevenV3DialogueModel = defineModel({
20
20
  },
21
21
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
22
22
  params: [
23
- { id: 'kieElevenDialogueVoice', type: 'text', order: 1, default: 'EkK5I93UQWFDigLMpZcX' },
23
+ { id: 'kieElevenDialogueVoice', type: 'composite', valueType: 'string', order: 1, default: 'EkK5I93UQWFDigLMpZcX' },
24
24
  ],
25
25
  endpoints: '/api/v1/jobs/createTask',
26
26
  request: {
@@ -8,7 +8,7 @@ export const kieGemini31FlashTtsModel = defineModel({
8
8
  },
9
9
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
10
10
  params: [
11
- { id: 'kieGeminiTtsVoice', type: 'text', order: 1, default: 'Fenrir' },
11
+ { id: 'kieGeminiTtsVoice', type: 'composite', valueType: 'string', order: 1, default: 'Fenrir' },
12
12
  { id: 'kieGeminiTtsScene', type: 'text', order: 2, default: '' },
13
13
  { id: 'kieGeminiTtsTemperature', type: 'number', order: 3, default: 1, min: 0, max: 2, step: 0.1 },
14
14
  ],
@@ -71,19 +71,9 @@ export const kieGeminiOmniVideoModel = defineModel({
71
71
  { value: '1080p' },
72
72
  { value: '4k' }
73
73
  ]
74
- },
75
- {
76
- id: 'kieGeminiOmniVideoAudioIds',
77
- type: 'textarea',
78
- order: 4,
79
- default: ''
80
- },
81
- {
82
- id: 'kieGeminiOmniVideoCharacterIds',
83
- type: 'textarea',
84
- order: 5,
85
- default: ''
86
74
  }
75
+ // audio_ids / character_ids 要先经 omni/audio、omni/character 两个端点创建资产才拿得到 ID,
76
+ // 本应用还没有资产创建与管理入口,用户填不出来:按“不显示且不请求”处理(界面计划 5.8,P-17)
87
77
  ],
88
78
  endpoints: KIE_CREATE_TASK_ENDPOINT,
89
79
  request: {
@@ -103,16 +93,9 @@ export const kieGeminiOmniVideoModel = defineModel({
103
93
  const images = pickSources(params.uploadedFilePaths, params.images);
104
94
  const videos = pickSources(params.uploadedVideoFilePaths, params.videos);
105
95
  const hasVideo = videos.length > 0;
106
- const splitIds = (value) => typeof value === 'string'
107
- ? value.split(/[\n,]/u).map((item) => item.trim()).filter(Boolean)
108
- : [];
109
- const audioIds = splitIds(params.kieGeminiOmniVideoAudioIds).slice(0, 3);
110
- const characterIds = splitIds(params.kieGeminiOmniVideoCharacterIds);
111
- if (hasVideo && characterIds.length > 3)
112
- throw new Error('Gemini Omni 带视频时最多支持 3 个角色资产');
113
- const availableImageSlots = (hasVideo ? MAX_IMAGES_WITH_VIDEO : MAX_IMAGES_NO_VIDEO) - characterIds.length;
114
- if (availableImageSlots < 0 || images.length > availableImageSlots) {
115
- throw new Error('Gemini Omni 的图片与角色资产超过共享的 7 个槽位');
96
+ const availableImageSlots = hasVideo ? MAX_IMAGES_WITH_VIDEO : MAX_IMAGES_NO_VIDEO;
97
+ if (images.length > availableImageSlots) {
98
+ throw new Error(`Gemini Omni 最多支持 ${availableImageSlots} 张参考图(共享 7 个槽位,参考视频占 2 个)`);
116
99
  }
117
100
  const resolution = params.kieGeminiOmniVideoResolution === '1080p' || params.kieGeminiOmniVideoResolution === '4k'
118
101
  ? params.kieGeminiOmniVideoResolution
@@ -149,10 +132,6 @@ export const kieGeminiOmniVideoModel = defineModel({
149
132
  if (images.length > 0) {
150
133
  input.image_urls = images;
151
134
  }
152
- if (audioIds.length > 0)
153
- input.audio_ids = audioIds;
154
- if (characterIds.length > 0)
155
- input.character_ids = characterIds;
156
135
  if (hasVideo) {
157
136
  const rawClipDuration = typeof params.__firstVideoDurationSeconds === 'number' && params.__firstVideoDurationSeconds > 0
158
137
  ? params.__firstVideoDurationSeconds
@@ -11,7 +11,7 @@ export const minimaxSpeechModel = defineModel({
11
11
  canonicalModelId: 'minimax-speech-2.8',
12
12
  provider: 'ppio',
13
13
  type: 'audio',
14
- tags: ['audio', 'text-to-speech', 'voice-synthesis', 'voice-cloning', 'provider-ppio'],
14
+ tags: ['audio', 'text-to-speech', 'voice-synthesis', 'voice-cloning', 'voice-clone', 'provider-ppio'],
15
15
  polling: {
16
16
  interval: 3000,
17
17
  maxAttempts: 120,
@@ -7,7 +7,7 @@ export const siliconflowCosyVoice2TtsModel = defineModel({
7
7
  },
8
8
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
9
9
  params: [
10
- { id: 'siliconflowCosyVoice', type: 'text', order: 1, default: 'FunAudioLLM/CosyVoice2-0.5B:alex' },
10
+ { id: 'siliconflowCosyVoice', type: 'composite', valueType: 'string', order: 1, default: 'FunAudioLLM/CosyVoice2-0.5B:alex' },
11
11
  { id: 'siliconflowCosySpeed', type: 'number', order: 2, default: 1, min: 0.25, max: 4, step: 0.05 },
12
12
  { id: 'siliconflowCosyFormat', type: 'dropdown', order: 3, default: 'mp3', options: ['mp3', 'opus', 'wav', 'pcm'].map(value => ({ value })) },
13
13
  ],
@@ -7,7 +7,7 @@ export const siliconflowMossTtsd05Model = defineModel({
7
7
  },
8
8
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
9
9
  params: [
10
- { id: 'siliconflowMossVoice', type: 'text', order: 1, default: 'fnlp/MOSS-TTSD-v0.5:alex' },
10
+ { id: 'siliconflowMossVoice', type: 'composite', valueType: 'string', order: 1, default: 'fnlp/MOSS-TTSD-v0.5:alex' },
11
11
  { id: 'siliconflowMossFormat', type: 'dropdown', order: 2, default: 'mp3', options: ['mp3', 'opus', 'wav', 'pcm'].map(value => ({ value })) },
12
12
  ],
13
13
  endpoints: '/v1/audio/speech',
@@ -1,2 +1,3 @@
1
+ export declare const VOLC_CLONE_LANGUAGES: number[];
1
2
  export declare const volcengineSeedIcl20Model: import("../../index.js").ModelRuntimeDefinition;
2
3
  export default volcengineSeedIcl20Model;
@@ -1,26 +1,68 @@
1
1
  import { defineModel } from '../defineModel.js';
2
- import { speechString, speechText } from '../audio/tts-common.js';
2
+ import { speechCharacterPrice, speechString, speechText } from '../audio/tts-common.js';
3
+ import { DEFAULT_SEED_TTS_20_VOICE, isSeedTts20SystemVoice } from './seed-tts-2.0-voices.js';
4
+ const cloning = (params) => params.volcIclMode === 'clone';
5
+ const synth = (params) => !cloning(params);
6
+ export const VOLC_CLONE_LANGUAGES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21];
3
7
  export const volcengineSeedIcl20Model = defineModel({
4
8
  meta: {
5
9
  id: 'volcengine-seed-icl-2.0', canonicalModelId: 'seed-icl-2.0', provider: 'volcengine-speech', type: 'audio',
6
- tags: ['text-to-audio', 'provider-volcengine'],
10
+ tags: ['text-to-audio', 'voice-clone', 'provider-volcengine'],
11
+ polling: { interval: 3000, maxAttempts: 120 },
7
12
  },
8
13
  inputLimits: { images: { max: 0 }, videos: { max: 0 } },
9
14
  params: [
10
- { id: 'volcSeedIclSpeaker', type: 'text', required: true, order: 1, default: '' },
15
+ { id: 'volcIclMode', type: 'dropdown', order: 1, default: 'speech', options: [{ value: 'speech' }, { value: 'clone' }] },
16
+ { id: 'volcSeedIclSpeaker', type: 'composite', valueType: 'string', required: true, order: 2, default: DEFAULT_SEED_TTS_20_VOICE, visible: { condition: synth } },
17
+ { id: 'volcIclActivationConsent', type: 'switch', order: 3, default: false, visible: { condition: p => synth(p) && Boolean(p.volcSeedIclSpeaker) && !isSeedTts20SystemVoice(String(p.volcSeedIclSpeaker)) && !/^S_/i.test(String(p.volcSeedIclSpeaker)) } },
18
+ { id: 'volcCloneName', type: 'text', order: 4, default: '', maxLength: 80, required: true, visible: { condition: cloning } },
19
+ { id: 'volcCloneAudio', type: 'file-upload', order: 5, default: [], maxCount: 1, maxSize: 10_000_000, accept: ['audio/wav', 'audio/x-wav', 'audio/mpeg', 'audio/ogg', 'audio/mp4', 'audio/x-m4a', 'audio/aac'], required: true, visible: { condition: cloning } },
20
+ { id: 'volcCloneLanguage', type: 'dropdown', order: 6, default: 0, options: VOLC_CLONE_LANGUAGES.map(value => ({ value })), visible: { condition: cloning } },
21
+ { id: 'volcCloneTranscript', type: 'textarea', order: 7, default: '', visible: { condition: cloning } },
22
+ { id: 'volcCloneDenoise', type: 'switch', order: 8, default: false, visible: { condition: cloning } },
23
+ { id: 'volcClonePreserveVolume', type: 'switch', order: 9, default: false, visible: { condition: cloning } },
24
+ { id: 'volcCloneExistingSlot', type: 'text', order: 10, default: '', visible: { condition: cloning } },
25
+ { id: 'volcCloneCustomId', type: 'text', order: 11, default: '', visible: { condition: () => false } },
11
26
  ],
12
- endpoints: '/api/v3/tts/unidirectional',
27
+ runtimeConstraints: { mediaFields: [{ field: 'clone_audio', kind: 'audio' }] },
28
+ endpoints: { selector: params => cloning(params) ? '/api/v3/tts/voice_clone' : '/api/v3/tts/unidirectional' },
13
29
  request: {
14
30
  builder: (params) => {
15
- const speaker = speechString(params.volcSeedIclSpeaker);
16
- if (!speaker)
17
- throw new Error('Seed-ICL 2.0 需要已创建的复刻音色 ID');
31
+ if (cloning(params)) {
32
+ const name = speechString(params.volcCloneName);
33
+ const source = Array.isArray(params.volcCloneAudio) ? params.volcCloneAudio[0] : params.volcCloneAudio;
34
+ const audio = typeof source === 'string' ? source : source && typeof source === 'object' && !Array.isArray(source) ? source.path ?? source.url : undefined;
35
+ const demo = speechText(params).trim();
36
+ if (!name)
37
+ throw new Error('请填写音色名称');
38
+ if (typeof audio !== 'string' || !audio)
39
+ throw new Error('请上传声音样本');
40
+ if (Array.from(demo).length < 4 || Array.from(demo).length > 300)
41
+ throw new Error('克隆试听文本须为 4–300 字');
42
+ const language = params.volcCloneLanguage ?? 0;
43
+ if (!VOLC_CLONE_LANGUAGES.includes(language))
44
+ throw new Error('请选择有效的录音语言');
45
+ const custom = speechString(params.volcCloneCustomId);
46
+ if (custom && !/^henji[a-zA-Z0-9]{8,64}$/.test(custom))
47
+ throw new Error('克隆音色代号无效');
48
+ return {
49
+ clone_audio: audio, voice_name: name, language,
50
+ ...(speechString(params.volcCloneExistingSlot) ? { speaker_id: speechString(params.volcCloneExistingSlot) } : {}),
51
+ ...(custom ? { custom_speaker_id: custom } : {}),
52
+ ...(speechString(params.volcCloneTranscript) ? { text: speechString(params.volcCloneTranscript) } : {}),
53
+ extra_params: { demo_text: demo, enable_audio_denoise: params.volcCloneDenoise === true, disable_volume_normalization: params.volcClonePreserveVolume === true },
54
+ };
55
+ }
56
+ const speaker = speechString(params.volcSeedIclSpeaker) ?? DEFAULT_SEED_TTS_20_VOICE;
57
+ const systemVoice = isSeedTts20SystemVoice(speaker);
58
+ if (!systemVoice && !/^S_/i.test(speaker) && params.volcIclActivationConsent !== true)
59
+ throw new Error('后付费音色首次正式合成将收取 138 元槽位费并锁定音色,请先确认费用');
18
60
  return {
19
- resource_id: 'seed-icl-2.0',
20
- req_params: { text: speechText(params), model: 'seed-tts-2.0-standard', speaker, audio_params: { format: 'mp3', sample_rate: 24000 } },
61
+ resource_id: systemVoice ? 'seed-tts-2.0' : 'seed-icl-2.0',
62
+ req_params: { text: speechText(params), ...(!systemVoice ? { model: 'seed-tts-2.0-standard' } : {}), speaker, audio_params: { format: 'mp3', sample_rate: 24000 } },
21
63
  };
22
64
  },
23
65
  },
24
- pricing: { currency: '¥', calculator: () => Number.NaN, description: '火山语音按量计费单价未核实;不显示费用预估' },
66
+ pricing: { currency: '¥', calculator: params => speechCharacterPrice(params, 0.3), description: '3 元/万字符;后付费音色首次正式合成另收 138 元槽位费,训练试听按字符计费' },
25
67
  });
26
68
  export default volcengineSeedIcl20Model;
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_SEED_TTS_20_VOICE = "zh_female_vv_uranus_bigtts";
2
+ export declare const isSeedTts20SystemVoice: (id: string) => boolean;