@mingxy/ocosay 1.0.6 → 1.0.7
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/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -2
- package/dist/config.js.map +1 -1
- package/dist/plugin.js +10 -2
- package/dist/plugin.js.map +2 -2
- package/package.json +1 -1
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE;QACT,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAA;YACd,OAAO,EAAE,MAAM,CAAA;YACf,OAAO,EAAE,MAAM,CAAA;YACf,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;YAClC,QAAQ,EAAE,MAAM,CAAA;YAChB,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;SACpC,CAAA;KACF,CAAA;CACF;AAiBD,wBAAgB,qBAAqB,IAAI,YAAY,CAcpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmDnD;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,GACxC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAYjC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE;QACT,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAA;YACd,OAAO,EAAE,MAAM,CAAA;YACf,OAAO,EAAE,MAAM,CAAA;YACf,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;YAClC,QAAQ,EAAE,MAAM,CAAA;YAChB,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;SACpC,CAAA;KACF,CAAA;CACF;AAiBD,wBAAgB,qBAAqB,IAAI,YAAY,CAcpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmDnD;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,GACxC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAYjC;AAcD,wBAAgB,kBAAkB,IAAI,YAAY,CAsDjD"}
|
package/dist/config.js
CHANGED
|
@@ -86,6 +86,18 @@ export function mergeWithDefaults(loaded, defaults) {
|
|
|
86
86
|
pitch: loaded.pitch ?? defaults.pitch
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* 解析配置值,支持 {env:VAR_NAME} 格式的环境变量引用
|
|
91
|
+
*/
|
|
92
|
+
function resolveEnvValue(value) {
|
|
93
|
+
if (!value)
|
|
94
|
+
return '';
|
|
95
|
+
if (value.startsWith('{env:') && value.endsWith('}')) {
|
|
96
|
+
const envVar = value.slice(5, -1);
|
|
97
|
+
return process.env[envVar] || '';
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
89
101
|
export function loadOrCreateConfig() {
|
|
90
102
|
const configDir = path.dirname(CONFIG_PATH);
|
|
91
103
|
if (!fs.existsSync(configDir)) {
|
|
@@ -125,8 +137,8 @@ export function loadOrCreateConfig() {
|
|
|
125
137
|
...merged,
|
|
126
138
|
providers: {
|
|
127
139
|
minimax: {
|
|
128
|
-
apiKey: loaded.providers?.minimax?.apiKey
|
|
129
|
-
baseURL: loaded.providers?.minimax?.baseURL
|
|
140
|
+
apiKey: resolveEnvValue(loaded.providers?.minimax?.apiKey),
|
|
141
|
+
baseURL: resolveEnvValue(loaded.providers?.minimax?.baseURL),
|
|
130
142
|
voiceId: loaded.providers?.minimax?.voiceId ?? '',
|
|
131
143
|
model: loaded.providers?.minimax?.model ?? 'stream',
|
|
132
144
|
ttsModel: loaded.providers?.minimax?.ttsModel ?? 'speech-2.8-hd',
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -1716,6 +1716,14 @@ function mergeWithDefaults(loaded, defaults) {
|
|
|
1716
1716
|
pitch: loaded.pitch ?? defaults.pitch
|
|
1717
1717
|
};
|
|
1718
1718
|
}
|
|
1719
|
+
function resolveEnvValue(value) {
|
|
1720
|
+
if (!value) return "";
|
|
1721
|
+
if (value.startsWith("{env:") && value.endsWith("}")) {
|
|
1722
|
+
const envVar = value.slice(5, -1);
|
|
1723
|
+
return process.env[envVar] || "";
|
|
1724
|
+
}
|
|
1725
|
+
return value;
|
|
1726
|
+
}
|
|
1719
1727
|
function loadOrCreateConfig() {
|
|
1720
1728
|
const configDir = path.dirname(CONFIG_PATH);
|
|
1721
1729
|
if (!fs3.existsSync(configDir)) {
|
|
@@ -1752,8 +1760,8 @@ function loadOrCreateConfig() {
|
|
|
1752
1760
|
...merged,
|
|
1753
1761
|
providers: {
|
|
1754
1762
|
minimax: {
|
|
1755
|
-
apiKey: loaded.providers?.minimax?.apiKey
|
|
1756
|
-
baseURL: loaded.providers?.minimax?.baseURL
|
|
1763
|
+
apiKey: resolveEnvValue(loaded.providers?.minimax?.apiKey),
|
|
1764
|
+
baseURL: resolveEnvValue(loaded.providers?.minimax?.baseURL),
|
|
1757
1765
|
voiceId: loaded.providers?.minimax?.voiceId ?? "",
|
|
1758
1766
|
model: loaded.providers?.minimax?.model ?? "stream",
|
|
1759
1767
|
ttsModel: loaded.providers?.minimax?.ttsModel ?? "speech-2.8-hd",
|
package/dist/plugin.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/plugin.ts", "../src/core/speaker.ts", "../src/core/types.ts", "../src/providers/base.ts", "../src/core/player.ts", "../src/tools/tts.ts", "../src/providers/minimax.ts", "../src/core/stream-reader.ts", "../src/core/streaming-synthesizer.ts", "../src/core/stream-player.ts", "../src/index.ts", "../src/config.ts"],
|
|
4
|
-
"sourcesContent": ["import { tool } from '@opencode-ai/plugin'\nimport type { Plugin, PluginInput, PluginOptions } from '@opencode-ai/plugin'\nimport { handleToolCall } from './index'\nimport { initialize, destroy } from './index'\nimport { loadOrCreateConfig } from './config'\n\nconst pluginName = 'ocosay'\n\nconst ttsSpeakTool = tool({\n description: '\u5C06\u6587\u672C\u8F6C\u6362\u4E3A\u8BED\u97F3\u5E76\u64AD\u653E',\n args: {\n text: tool.schema.string().describe('\u8981\u8F6C\u6362\u7684\u6587\u672C\u5185\u5BB9'),\n provider: tool.schema.string().optional().describe('TTS \u63D0\u4F9B\u5546\u540D\u79F0'),\n voice: tool.schema.string().optional().describe('\u97F3\u8272 ID'),\n model: tool.schema.enum(['sync', 'async', 'stream']).optional().describe('\u5408\u6210\u6A21\u5F0F'),\n speed: tool.schema.number().optional().describe('\u8BED\u901F 0.5-2.0'),\n volume: tool.schema.number().optional().describe('\u97F3\u91CF 0-100'),\n pitch: tool.schema.number().optional().describe('\u97F3\u8C03 0.5-2.0')\n },\n execute: async (args) => {\n const result = await handleToolCall('tts_speak', args)\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStopTool = tool({\n description: '\u505C\u6B62\u5F53\u524D TTS \u64AD\u653E',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_stop')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsPauseTool = tool({\n description: '\u6682\u505C\u5F53\u524D TTS \u64AD\u653E',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_pause')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsResumeTool = tool({\n description: '\u6062\u590D\u6682\u505C\u7684 TTS \u64AD\u653E',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_resume')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsListVoicesTool = tool({\n description: '\u5217\u51FA\u53EF\u7528\u7684\u97F3\u8272',\n args: {\n provider: tool.schema.string().optional().describe('TTS \u63D0\u4F9B\u5546\u540D\u79F0')\n },\n execute: async (args) => {\n const result = await handleToolCall('tts_list_voices', args)\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsListProvidersTool = tool({\n description: '\u5217\u51FA\u6240\u6709\u5DF2\u6CE8\u518C\u7684 TTS \u63D0\u4F9B\u5546',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_list_providers')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStatusTool = tool({\n description: '\u83B7\u53D6\u5F53\u524D TTS \u64AD\u653E\u72B6\u6001',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_status')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStreamSpeakTool = tool({\n description: '\u542F\u52A8\u6D41\u5F0F\u6717\u8BFB\uFF08\u8C46\u5305\u6A21\u5F0F\uFF09\uFF0C\u8BA2\u9605AI\u56DE\u590D\u5E76\u8FB9\u751F\u6210\u8FB9\u6717\u8BFB',\n args: {\n text: tool.schema.string().optional().describe('\u521D\u59CB\u6587\u672C\uFF08\u53EF\u9009\uFF09'),\n voice: tool.schema.string().optional().describe('\u97F3\u8272ID'),\n model: tool.schema.enum(['sync', 'async', 'stream']).optional().describe('\u5408\u6210\u6A21\u5F0F')\n },\n execute: async (args) => {\n const result = await handleToolCall('tts_stream_speak', args)\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStreamStopTool = tool({\n description: '\u505C\u6B62\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_stream_stop')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStreamStatusTool = tool({\n description: '\u83B7\u53D6\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB\u72B6\u6001',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_stream_status')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return typeof result === 'string' ? result : JSON.stringify(result)\n }\n})\n\nconst OcosayPlugin: Plugin = async (_input: PluginInput, _options?: PluginOptions) => {\n console.info(`${pluginName}: initializing...`)\n\n const config = loadOrCreateConfig()\n\n await initialize({\n autoRead: config.autoRead,\n providers: {\n minimax: {\n apiKey: config.providers.minimax.apiKey,\n baseURL: config.providers.minimax.baseURL || undefined,\n voiceId: config.providers.minimax.voiceId || undefined\n }\n }\n })\n\n return {\n tool: {\n tts_speak: ttsSpeakTool,\n tts_stop: ttsStopTool,\n tts_pause: ttsPauseTool,\n tts_resume: ttsResumeTool,\n tts_list_voices: ttsListVoicesTool,\n tts_list_providers: ttsListProvidersTool,\n tts_status: ttsStatusTool,\n tts_stream_speak: ttsStreamSpeakTool,\n tts_stream_stop: ttsStreamStopTool,\n tts_stream_status: ttsStreamStatusTool\n },\n config: async () => {\n return\n }\n }\n}\n\nexport const server = OcosayPlugin\nexport default OcosayPlugin\n", "/**\n * Speaker - TTS \u7EDF\u4E00\u8C03\u7528\u5165\u53E3\n * \u63D0\u4F9B\u7B80\u6D01\u7684 API \u548C\u4FBF\u6377\u51FD\u6570\n */\n\nimport { EventEmitter } from 'events'\nimport { \n TTSProvider, \n TTSError, \n TTSErrorCode,\n SpeakOptions,\n AudioResult,\n Voice,\n TTSEvent,\n SynthesisModel\n} from './types'\nimport { getProvider, listProviders, hasProvider } from '../providers/base'\nimport { AudioPlayer, PlayerEvents } from './player'\n\nexport interface SpeakerOptions {\n defaultProvider?: string\n defaultModel?: SynthesisModel\n defaultVoice?: string\n onEvent?: (event: TTSEvent, data?: any) => void\n}\n\n/**\n * Speaker - TTS \u7EDF\u4E00\u8C03\u7528\u5165\u53E3\u7C7B\n * \u5C01\u88C5 Provider \u548C Player\uFF0C\u63D0\u4F9B\u7B80\u6D01\u7684 speak/pause/resume/stop API\n */\nexport class Speaker extends EventEmitter {\n private currentProvider?: TTSProvider\n private player?: AudioPlayer\n private currentText?: string\n private isSpeaking = false\n private isPaused = false\n \n constructor(private options: SpeakerOptions = {}) {\n super()\n \n // \u521D\u59CB\u5316\u64AD\u653E\u5668\n const playerEvents: PlayerEvents = {\n onStart: () => this.emit('start', this.currentText),\n onEnd: () => {\n this.isSpeaking = false\n this.emit('end', this.currentText)\n },\n onError: (error) => this.emit('error', error),\n onPause: () => {\n this.isPaused = true\n this.emit('pause')\n },\n onResume: () => {\n this.isPaused = false\n this.emit('resume')\n },\n onStop: () => {\n this.isSpeaking = false\n this.isPaused = false\n this.emit('stop')\n }\n }\n \n this.player = new AudioPlayer(playerEvents)\n }\n \n /**\n * \u8BF4\u8BDD - \u6838\u5FC3\u65B9\u6CD5\n * @param text \u8981\u8BF4\u7684\u6587\u672C\n * @param options \u53EF\u9009\u53C2\u6570\n */\n async speak(\n text: string, \n options: SpeakOptions & { provider?: string } = {}\n ): Promise<void> {\n // \u53C2\u6570\u6821\u9A8C\n if (!text || text.trim().length === 0) {\n throw new TTSError(\n 'Text cannot be empty',\n TTSErrorCode.INVALID_PARAMS,\n 'speaker'\n )\n }\n \n // \u505C\u6B62\u5F53\u524D\u64AD\u653E\n if (this.isSpeaking) {\n await this.stop()\n }\n \n this.isSpeaking = true\n this.currentText = text\n \n try {\n // \u83B7\u53D6 provider\n const providerName = options.provider || this.options.defaultProvider || 'minimax'\n if (!hasProvider(providerName)) {\n throw new TTSError(\n `Provider \"${providerName}\" not found`,\n TTSErrorCode.UNKNOWN,\n 'speaker'\n )\n }\n \n this.currentProvider = getProvider(providerName)\n \n // \u8C03\u7528 provider \u751F\u6210\u97F3\u9891\n const result = await this.currentProvider.speak(text, {\n model: options.model || this.options.defaultModel || 'stream',\n voice: options.voice || this.options.defaultVoice,\n speed: options.speed,\n volume: options.volume,\n pitch: options.pitch,\n sourceVoice: options.sourceVoice\n })\n \n // \u64AD\u653E\u97F3\u9891\n if (this.player) {\n await this.player.play(result.audioData, result.format)\n }\n \n } catch (error) {\n this.isSpeaking = false\n if (error instanceof TTSError) {\n this.emit('error', error)\n throw error\n }\n const ttsError = new TTSError(\n 'Speak failed',\n TTSErrorCode.UNKNOWN,\n 'speaker',\n error\n )\n this.emit('error', ttsError)\n throw ttsError\n }\n }\n \n /**\n * \u6682\u505C\u64AD\u653E\n */\n pause(): void {\n if (this.player && this.isSpeaking && !this.isPaused) {\n this.player.pause()\n }\n }\n \n /**\n * \u6062\u590D\u64AD\u653E\n */\n resume(): void {\n if (this.player && this.isPaused) {\n this.player.resume()\n }\n }\n \n /**\n * \u505C\u6B62\u64AD\u653E\n */\n async stop(): Promise<void> {\n this.isSpeaking = false\n this.isPaused = false\n \n if (this.player) {\n await this.player.stop()\n }\n }\n \n /**\n * \u9500\u6BC1 Speaker\uFF0C\u91CA\u653E\u8D44\u6E90\n */\n async destroy(): Promise<void> {\n this.isSpeaking = false\n this.isPaused = false\n \n if (this.player) {\n await this.player.stop()\n this.player = undefined\n }\n \n this.currentProvider = undefined\n this.currentText = undefined\n }\n \n /**\n * \u5217\u51FA\u53EF\u7528\u97F3\u8272\n */\n async listVoices(providerName?: string): Promise<Voice[]> {\n const name = providerName || this.options.defaultProvider || 'minimax'\n const provider = getProvider(name)\n return provider.listVoices()\n }\n \n /**\n * \u83B7\u53D6 Provider \u80FD\u529B\n */\n getCapabilities(providerName?: string) {\n const name = providerName || this.options.defaultProvider || 'minimax'\n const provider = getProvider(name)\n return provider.getCapabilities()\n }\n \n /**\n * \u83B7\u53D6\u6240\u6709\u5DF2\u6CE8\u518C\u7684 Provider\n */\n getProviders(): string[] {\n return listProviders()\n }\n \n /**\n * \u662F\u5426\u6B63\u5728\u64AD\u653E\n */\n isPlaying(): boolean {\n return this.isSpeaking && !this.isPaused\n }\n \n /**\n * \u662F\u5426\u6682\u505C\n */\n isPausedState(): boolean {\n return this.isPaused\n }\n}\n\n// ============================================================================\n// \u4FBF\u6377\u51FD\u6570 - \u9ED8\u8BA4 Speaker \u5B9E\u4F8B\n// ============================================================================\n\nlet defaultSpeaker: Speaker | undefined\n\n/**\n * \u83B7\u53D6\u9ED8\u8BA4 Speaker \u5B9E\u4F8B\uFF08\u5355\u4F8B\uFF09\n */\nexport function getDefaultSpeaker(): Speaker {\n if (!defaultSpeaker) {\n defaultSpeaker = new Speaker()\n }\n return defaultSpeaker\n}\n\n/**\n * \u8BF4\u8BDD\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport async function speak(\n text: string, \n options?: SpeakOptions & { provider?: string }\n): Promise<void> {\n const speaker = getDefaultSpeaker()\n return speaker.speak(text, options)\n}\n\n/**\n * \u505C\u6B62\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport async function stop(): Promise<void> {\n const speaker = getDefaultSpeaker()\n return speaker.stop()\n}\n\n/**\n * \u6682\u505C\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport function pause(): void {\n const speaker = getDefaultSpeaker()\n speaker.pause()\n}\n\n/**\n * \u6062\u590D\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport function resume(): void {\n const speaker = getDefaultSpeaker()\n speaker.resume()\n}\n\n/**\n * \u5217\u51FA\u97F3\u8272\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport async function listVoices(providerName?: string): Promise<Voice[]> {\n const speaker = getDefaultSpeaker()\n return speaker.listVoices(providerName)\n}\n\nexport default Speaker\n", "/**\n * TTS Core Types\n * \u6838\u5FC3\u7C7B\u578B\u5B9A\u4E49\n */\n\nexport enum TTSErrorCode {\n NETWORK = 'NETWORK',\n AUTH = 'AUTH',\n QUOTA = 'QUOTA',\n INVALID_VOICE = 'INVALID_VOICE',\n INVALID_PARAMS = 'INVALID_PARAMS',\n PLAYER_ERROR = 'PLAYER_ERROR',\n UNKNOWN = 'UNKNOWN'\n}\n\nexport class TTSError extends Error {\n constructor(\n message: string,\n code: TTSErrorCode,\n provider: string,\n details?: unknown\n ) {\n super(message)\n this.name = 'TTSError'\n this.code = code\n this.provider = provider\n this.details = details\n }\n \n code: TTSErrorCode\n provider: string\n details?: unknown\n}\n\nexport interface Voice {\n id: string\n name: string\n language?: string\n gender?: 'male' | 'female' | 'neutral'\n previewUrl?: string\n}\n\nexport interface TTSCapabilities {\n speak: true\n voiceClone?: boolean\n stream?: boolean\n voiceList?: boolean\n sync?: boolean\n async?: boolean\n}\n\nexport type SynthesisModel = 'sync' | 'async' | 'stream'\n\nexport interface SpeakOptions {\n voice?: string\n model?: SynthesisModel\n speed?: number\n volume?: number\n pitch?: number\n sourceVoice?: string\n}\n\nexport interface AudioResult {\n audioData: Buffer | ReadableStream\n sampleRate?: number\n channels?: number\n duration?: number\n format: string\n isStream: boolean\n}\n\nexport type TTSEvent = \n | 'start'\n | 'end'\n | 'error'\n | 'progress'\n | 'pause'\n | 'resume'\n | 'stop'\n\nexport interface SpeakerEvents {\n on(event: 'start', handler: (text: string) => void): void\n on(event: 'end', handler: (text: string) => void): void\n on(event: 'error', handler: (error: TTSError) => void): void\n on(event: 'progress', handler: (progress: { current: number; total: number }) => void): void\n on(event: 'pause', handler: () => void): void\n on(event: 'resume', handler: () => void): void\n on(event: 'stop', handler: () => void): void\n off(event: TTSEvent, handler: Function): void\n}\n\nexport interface TTSProvider {\n name: string\n capabilities: TTSCapabilities\n \n initialize(): Promise<void>\n destroy(): Promise<void>\n \n speak(text: string, options?: SpeakOptions): Promise<AudioResult>\n pause(): Promise<void>\n resume(): Promise<void>\n stop(): Promise<void>\n listVoices(): Promise<Voice[]>\n \n getCapabilities(): TTSCapabilities\n}\n\n// ============================================================================\n// \u914D\u7F6E\u76F8\u5173\u7C7B\u578B\n// ============================================================================\n\nexport interface GlobalConfig {\n defaultProvider: string\n defaultModel?: SynthesisModel\n defaultVoice?: string\n}\n\nexport interface ProviderConfig {\n enabled?: boolean\n apiKey?: string\n [key: string]: unknown\n}\n\nexport interface OcosayConfig {\n enabled?: boolean\n autoPlay?: boolean\n autoRead?: boolean\n streamMode?: boolean\n streamBufferSize?: number\n streamBufferTimeout?: number\n provider?: string\n ttsModel?: string\n baseURL?: string\n speed?: number\n volume?: number\n pitch?: number\n}\n\n// ============================================================================\n// \u6D41\u5F0F\u6717\u8BFB\u76F8\u5173\u7C7B\u578B\n// ============================================================================\n\nexport enum StreamState {\n IDLE = 'idle',\n BUFFERING = 'buffering',\n STREAMING = 'streaming',\n ENDED = 'ended'\n}\n\nexport interface OcosayStreamConfig {\n enabled: boolean\n autoPlay: boolean\n autoRead: boolean\n streamMode: boolean\n streamBufferSize: number\n streamBufferTimeout: number\n provider: string\n voiceId?: string\n ttsModel?: string\n baseURL?: string\n speed?: number\n volume?: number\n pitch?: number\n apiKey?: string\n}\n\nexport interface StreamReaderEvents {\n onTextReady: (text: string) => void\n onStreamStart: () => void\n onStreamEnd: () => void\n onStreamError: (error: TTSError) => void\n}\n\nexport interface StreamingSynthesizerOptions {\n provider: TTSProvider\n voice?: string\n speed?: number\n volume?: number\n pitch?: number\n}\n\nexport interface StreamPlayerOptions {\n format?: 'mp3' | 'wav' | 'flac'\n onProgress?: (bytesReceived: number) => void\n}\n", "/**\n * TTS Provider Base Class and Registry\n * Provider \u57FA\u7C7B\u548C\u6CE8\u518C\u673A\u5236\n */\n\nimport { TTSProvider, TTSError, TTSErrorCode, Voice, TTSCapabilities, SpeakOptions, AudioResult } from '../core/types'\n\n// Provider \u6CE8\u518C\u8868\nconst providers = new Map<string, TTSProvider>()\n\n/**\n * \u6CE8\u518C TTS Provider\n */\nexport function registerProvider(name: string, provider: TTSProvider): void {\n if (providers.has(name)) {\n throw new TTSError(\n `Provider \"${name}\" is already registered`,\n TTSErrorCode.UNKNOWN,\n 'system'\n )\n }\n providers.set(name, provider)\n}\n\n/**\n * \u83B7\u53D6 TTS Provider\n */\nexport function getProvider(name: string): TTSProvider {\n const provider = providers.get(name)\n if (!provider) {\n throw new TTSError(\n `TTS Provider \"${name}\" not found`,\n TTSErrorCode.UNKNOWN,\n 'system'\n )\n }\n return provider\n}\n\n/**\n * \u83B7\u53D6\u6240\u6709\u5DF2\u6CE8\u518C\u7684 Provider \u540D\u79F0\n */\nexport function listProviders(): string[] {\n return Array.from(providers.keys())\n}\n\n/**\n * \u68C0\u67E5 Provider \u662F\u5426\u5DF2\u6CE8\u518C\n */\nexport function hasProvider(name: string): boolean {\n return providers.has(name)\n}\n\n/**\n * \u6CE8\u9500 Provider\n */\nexport function unregisterProvider(name: string): boolean {\n return providers.delete(name)\n}\n\n/**\n * Provider \u62BD\u8C61\u57FA\u7C7B\uFF0C\u63D0\u4F9B\u901A\u7528\u5B9E\u73B0\n */\nexport abstract class BaseTTSProvider implements TTSProvider {\n abstract name: string\n abstract capabilities: TTSCapabilities\n \n protected apiKey?: string\n protected defaultVoice?: string\n protected defaultModel: 'sync' | 'async' | 'stream' = 'stream'\n \n async initialize(): Promise<void> {\n // \u5B50\u7C7B\u53EFoverride\n }\n \n async destroy(): Promise<void> {\n // \u5B50\u7C7B\u53EFoverride\n }\n \n /**\n * \u901A\u7528 speak \u5B9E\u73B0\uFF0C\u5904\u7406\u901A\u7528\u903B\u8F91\n */\n async speak(text: string, options?: SpeakOptions): Promise<AudioResult> {\n if (!text || text.trim().length === 0) {\n throw new TTSError(\n 'Text cannot be empty',\n TTSErrorCode.INVALID_PARAMS,\n this.name\n )\n }\n \n const voice = options?.voice || this.defaultVoice\n const model = options?.model || this.defaultModel\n \n return this.doSpeak(text, voice, model, options)\n }\n \n /**\n * \u5B50\u7C7B\u5B9E\u73B0\u7684\u5B9E\u9645 speak \u903B\u8F91\n */\n protected abstract doSpeak(\n text: string, \n voice: string | undefined, \n model: 'sync' | 'async' | 'stream',\n options?: SpeakOptions\n ): Promise<AudioResult>\n \n pause(): Promise<void> {\n throw new TTSError(\n 'Pause is not supported by this provider',\n TTSErrorCode.UNKNOWN,\n this.name\n )\n }\n \n resume(): Promise<void> {\n throw new TTSError(\n 'Resume is not supported by this provider',\n TTSErrorCode.UNKNOWN,\n this.name\n )\n }\n \n stop(): Promise<void> {\n // \u9ED8\u8BA4\u7A7A\u5B9E\u73B0\n return Promise.resolve()\n }\n \n async listVoices(): Promise<Voice[]> {\n // \u9ED8\u8BA4\u8FD4\u56DE\u7A7A\u6570\u7EC4\uFF0C\u5B50\u7C7B\u53EFoverride\n return []\n }\n \n getCapabilities(): TTSCapabilities {\n return this.capabilities\n }\n \n /**\n * \u9A8C\u8BC1 API Key\n */\n protected validateApiKey(): void {\n if (!this.apiKey) {\n throw new TTSError(\n `API key is required for provider \"${this.name}\"`,\n TTSErrorCode.AUTH,\n this.name\n )\n }\n }\n}\n", "/**\n * Audio Player Module\n * \u97F3\u9891\u64AD\u653E\u5F15\u64CE - \u652F\u6301 pause/resume/stop \u548C\u6D41\u5F0F\u64AD\u653E\n */\n\nimport { EventEmitter } from 'events'\nimport { spawn, ChildProcess } from 'child_process'\nimport fs from 'fs'\nimport { createWriteStream } from 'fs'\nimport { tmpdir } from 'os'\nimport { join } from 'path'\nimport { TTSError, TTSErrorCode } from './types'\n\n/**\n * Player Events - \u64AD\u653E\u4E8B\u4EF6\u56DE\u8C03\u63A5\u53E3\n */\nexport interface PlayerEvents {\n onStart?: () => void\n onEnd?: () => void\n onError?: (error: Error) => void\n onProgress?: (progress: { current: number; total: number }) => void\n onPause?: () => void\n onResume?: () => void\n onStop?: () => void\n}\n\n/**\n * Player \u63A5\u53E3 - \u97F3\u9891\u64AD\u653E\u5668\u6807\u51C6\u63A5\u53E3\n */\nexport interface Player {\n play(audioData: Buffer | ReadableStream, format: string): Promise<void>\n pause(): void\n resume(): void\n stop(): void\n isPlaying(): boolean\n isPaused(): boolean\n}\n\n/**\n * AudioPlayer - \u57FA\u4E8E\u7CFB\u7EDF\u64AD\u653E\u5668\u7684\u97F3\u9891\u64AD\u653E\u5B9E\u73B0\n * \u652F\u6301 macOS (afplay), Linux (aplay), Windows (PowerShell)\n */\nexport class AudioPlayer extends EventEmitter implements Player {\n private _playing = false\n private _paused = false\n private currentProcess?: ChildProcess\n private currentFile?: string\n\n constructor(protected events?: PlayerEvents) {\n super()\n }\n\n /**\n * \u64AD\u653E\u97F3\u9891\n * @param audioData \u97F3\u9891\u6570\u636E (Buffer \u6216 ReadableStream)\n * @param format \u97F3\u9891\u683C\u5F0F (mp3, wav, etc.)\n */\n async play(audioData: Buffer | ReadableStream, format: string): Promise<void> {\n // \u5982\u679C\u6B63\u5728\u64AD\u653E\uFF0C\u5148\u505C\u6B62\n if (this._playing) {\n await this.stop()\n }\n\n this._playing = true\n this._paused = false\n\n try {\n // \u5C06\u97F3\u9891\u6570\u636E\u5199\u5165\u4E34\u65F6\u6587\u4EF6\n const tempFile = join(tmpdir(), `ocosay-${Date.now()}.${format}`)\n this.currentFile = tempFile\n\n if (Buffer.isBuffer(audioData)) {\n fs.writeFileSync(tempFile, audioData)\n } else {\n const writeStream = createWriteStream(tempFile)\n const reader = audioData.getReader()\n \n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n if (value instanceof Uint8Array) {\n writeStream.write(Buffer.from(value))\n }\n }\n writeStream.end()\n } finally {\n reader.releaseLock()\n }\n \n await new Promise<void>((resolve, reject) => {\n writeStream.on('finish', resolve)\n writeStream.on('error', reject)\n })\n }\n\n // \u89E6\u53D1\u5F00\u59CB\u4E8B\u4EF6\n this.events?.onStart?.()\n this.emit('start')\n\n // \u6839\u636E\u683C\u5F0F\u9009\u62E9\u64AD\u653E\u5668\n await this.playFile(tempFile, format)\n\n // \u64AD\u653E\u5B8C\u6210\n this._playing = false\n this.events?.onEnd?.()\n this.emit('end')\n\n // \u6E05\u7406\u4E34\u65F6\u6587\u4EF6\n this.cleanup()\n\n } catch (error: any) {\n this._playing = false\n const ttsError = new TTSError(\n error.message || 'Playback failed',\n TTSErrorCode.PLAYER_ERROR,\n 'player'\n )\n this.events?.onError?.(ttsError)\n this.emit('error', ttsError)\n throw ttsError\n }\n }\n\n /**\n * \u64AD\u653E\u97F3\u9891\u6587\u4EF6\n * \u4F18\u5148\u4F7F\u7528 afplay (macOS), aplay (Linux), \u5426\u5219\u7528 PowerShell (Windows)\n */\n private playFile(filePath: string, format: string): Promise<void> {\n const platform = process.platform\n\n return new Promise((resolve, reject) => {\n let command: string\n let args: string[]\n\n if (platform === 'darwin') {\n // macOS\n command = 'afplay'\n args = [filePath]\n } else if (platform === 'linux') {\n // Linux\n command = 'aplay'\n args = [filePath]\n } else {\n // Windows \u6216\u5176\u4ED6\n command = 'powershell'\n args = ['-c', `(New-Object System.Media.SoundPlayer('${filePath.replace(/\\\\/g, '\\\\\\\\')}')).PlaySync()`]\n }\n\n this.currentProcess = spawn(command, args, {\n stdio: 'ignore',\n detached: false\n })\n\n this.currentProcess.on('exit', (code: number | null, signal: string | null) => {\n // \u5982\u679C\u662F\u88AB\u4FE1\u53F7\u7EC8\u6B62\uFF08\u5982 SIGTERM\uFF09\uFF0C\u4E0D\u5F53\u4F5C\u9519\u8BEF\n if (signal === 'SIGTERM' || signal === 'SIGINT') {\n resolve()\n } else if (code === 0) {\n resolve()\n } else {\n reject(new Error(`Player exited with code ${code}`))\n }\n })\n\n this.currentProcess.on('error', (error: Error) => {\n reject(error)\n })\n })\n }\n\n /**\n * \u6682\u505C\u64AD\u653E\n * \u6CE8\u610F: \u76EE\u524D\u901A\u8FC7 SIGSTOP \u5B9E\u73B0\uFF0C\u771F\u6B63\u7684 pause \u9700\u8981\u652F\u6301\u6682\u505C\u7684\u97F3\u9891\u5E93\n */\n pause(): void {\n if (!this._playing || this._paused) return\n\n if (this.currentProcess) {\n try {\n this.currentProcess.kill('SIGSTOP')\n this._paused = true\n this.events?.onPause?.()\n this.emit('pause')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u6062\u590D\u64AD\u653E\n */\n resume(): void {\n if (!this._playing || !this._paused) return\n\n if (this.currentProcess) {\n try {\n this.currentProcess.kill('SIGCONT')\n this._paused = false\n this.events?.onResume?.()\n this.emit('resume')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u505C\u6B62\u64AD\u653E\n */\n async stop(): Promise<void> {\n this._playing = false\n this._paused = false\n\n if (this.currentProcess) {\n try {\n this.currentProcess.kill('SIGTERM')\n } catch (e) {\n // \u5FFD\u7565\u9519\u8BEF\n }\n this.currentProcess = undefined\n }\n\n this.cleanup()\n\n this.events?.onStop?.()\n this.emit('stop')\n }\n\n /**\n * \u662F\u5426\u6B63\u5728\u64AD\u653E\n */\n isPlaying(): boolean {\n return this._playing\n }\n\n /**\n * \u662F\u5426\u6682\u505C\n */\n isPaused(): boolean {\n return this._paused\n }\n\n /**\n * \u6E05\u7406\u4E34\u65F6\u6587\u4EF6\n */\n private cleanup(): void {\n if (this.currentFile) {\n try {\n if (fs.existsSync(this.currentFile)) {\n fs.unlinkSync(this.currentFile)\n }\n } catch (e) {\n // \u5FFD\u7565\u6E05\u7406\u9519\u8BEF\n }\n this.currentFile = undefined\n }\n }\n}\n\n/**\n * StreamingPlayer - \u6D41\u5F0F\u64AD\u653E\u5668\uFF0C\u652F\u6301\u8FB9\u4E0B\u8F7D\u8FB9\u64AD\u653E\n * \u6CE8\u610F: \u5F53\u524D\u5B9E\u73B0\u662F\u4E0B\u8F7D\u5B8C\u6BD5\u540E\u518D\u64AD\u653E\uFF0ConProgress \u4E8B\u4EF6\u7528\u4E8E\u62A5\u544A\u4E0B\u8F7D\u8FDB\u5EA6\n */\nexport class StreamingPlayer extends AudioPlayer {\n private chunks: Buffer[] = []\n private downloadedSize = 0\n\n constructor(events?: PlayerEvents) {\n super(events)\n }\n\n /**\n * \u6D41\u5F0F\u4E0B\u8F7D\u5E76\u64AD\u653E\n * @param stream \u53EF\u8BFB\u6D41\n * @param format \u97F3\u9891\u683C\u5F0F\n * @param expectedSize \u9884\u671F\u5927\u5C0F\uFF08\u53EF\u9009\uFF09\uFF0C\u7528\u4E8E\u8FDB\u5EA6\u62A5\u544A\n */\n async streamAndPlay(\n stream: ReadableStream,\n format: string,\n expectedSize?: number\n ): Promise<void> {\n const reader = stream.getReader()\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n if (value instanceof Buffer) {\n this.chunks.push(value)\n this.downloadedSize += value.length\n\n // \u89E6\u53D1\u4E0B\u8F7D\u8FDB\u5EA6\n if (expectedSize) {\n this.emit('progress', {\n current: this.downloadedSize,\n total: expectedSize\n })\n this.events?.onProgress?.({\n current: this.downloadedSize,\n total: expectedSize\n })\n }\n }\n }\n\n // \u5408\u5E76\u6240\u6709 chunk \u5E76\u64AD\u653E\n const fullAudio = Buffer.concat(this.chunks)\n await this.play(fullAudio, format)\n\n } finally {\n reader.releaseLock()\n this.chunks = []\n this.downloadedSize = 0\n }\n }\n}\n\nexport default AudioPlayer\n", "/**\n * OpenCode TTS \u5DE5\u5177\u5B9A\u4E49\n * \u7528\u4E8E OpenCode Plugin \u6CE8\u518C\n */\n\nimport { speak, stop, pause, resume, listVoices, getDefaultSpeaker } from '../core/speaker'\nimport { TTSError, TTSErrorCode } from '../core/types'\nimport { \n isStreamEnabled, \n isAutoReadEnabled,\n getStreamStatus, \n getStreamReader, \n getStreamingSynthesizer,\n getStreamPlayer \n} from '../index'\n\n/**\n * OpenCode TTS \u5DE5\u5177\u5B9A\u4E49\n * \u7528\u4E8E OpenCode Plugin \u6CE8\u518C\n */\nexport const ttsTools = [\n {\n name: 'tts_speak',\n description: '\u5C06\u6587\u672C\u8F6C\u6362\u4E3A\u8BED\u97F3\u5E76\u64AD\u653E',\n input: {\n type: 'object',\n properties: {\n text: { \n type: 'string', \n description: '\u8981\u8F6C\u6362\u7684\u6587\u672C\u5185\u5BB9' \n },\n provider: { \n type: 'string', \n description: 'TTS \u63D0\u4F9B\u5546\u540D\u79F0',\n default: 'minimax'\n },\n voice: { \n type: 'string', \n description: '\u97F3\u8272 ID' \n },\n model: { \n type: 'string', \n enum: ['sync', 'async', 'stream'],\n description: '\u5408\u6210\u6A21\u5F0F',\n default: 'stream'\n },\n speed: { \n type: 'number', \n description: '\u8BED\u901F 0.5-2.0' \n },\n volume: { \n type: 'number', \n description: '\u97F3\u91CF 0-100' \n },\n pitch: { \n type: 'number', \n description: '\u97F3\u8C03 0.5-2.0' \n }\n },\n required: ['text']\n }\n },\n {\n name: 'tts_stop',\n description: '\u505C\u6B62\u5F53\u524D TTS \u64AD\u653E'\n },\n {\n name: 'tts_pause',\n description: '\u6682\u505C\u5F53\u524D TTS \u64AD\u653E'\n },\n {\n name: 'tts_resume',\n description: '\u6062\u590D\u6682\u505C\u7684 TTS \u64AD\u653E'\n },\n {\n name: 'tts_list_voices',\n description: '\u5217\u51FA\u53EF\u7528\u7684\u97F3\u8272',\n input: {\n type: 'object',\n properties: {\n provider: { \n type: 'string', \n description: 'TTS \u63D0\u4F9B\u5546\u540D\u79F0',\n default: 'minimax'\n }\n }\n }\n },\n {\n name: 'tts_list_providers',\n description: '\u5217\u51FA\u6240\u6709\u5DF2\u6CE8\u518C\u7684 TTS \u63D0\u4F9B\u5546'\n },\n {\n name: 'tts_status',\n description: '\u83B7\u53D6\u5F53\u524D TTS \u64AD\u653E\u72B6\u6001',\n output: {\n type: 'object',\n properties: {\n isPlaying: { type: 'boolean' },\n isPaused: { type: 'boolean' }\n }\n }\n },\n {\n name: 'tts_stream_speak',\n description: '\u542F\u52A8\u6D41\u5F0F\u6717\u8BFB\uFF08\u8C46\u5305\u6A21\u5F0F\uFF09\uFF0C\u8BA2\u9605AI\u56DE\u590D\u5E76\u8FB9\u751F\u6210\u8FB9\u6717\u8BFB',\n input: {\n type: 'object',\n properties: {\n text: { \n type: 'string', \n description: '\u521D\u59CB\u6587\u672C\uFF08\u53EF\u9009\uFF09' \n },\n voice: { \n type: 'string', \n description: '\u97F3\u8272ID' \n },\n model: { \n type: 'string', \n enum: ['sync', 'async', 'stream'], \n default: 'stream' \n }\n }\n }\n },\n {\n name: 'tts_stream_stop',\n description: '\u505C\u6B62\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB'\n },\n {\n name: 'tts_stream_status',\n description: '\u83B7\u53D6\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB\u72B6\u6001',\n output: {\n type: 'object',\n properties: {\n isActive: { type: 'boolean' },\n bytesWritten: { type: 'number' },\n state: { type: 'string' }\n }\n }\n }\n]\n\n/**\n * \u5DE5\u5177\u6267\u884C\u5904\u7406\u5668\n */\nexport async function handleToolCall(\n toolName: string, \n args?: Record<string, any>\n): Promise<any> {\n try {\n switch (toolName) {\n case 'tts_speak':\n await speak(args?.text, {\n provider: args?.provider,\n voice: args?.voice,\n model: args?.model,\n speed: args?.speed,\n volume: args?.volume,\n pitch: args?.pitch\n })\n return { success: true, message: 'Speech completed' }\n \n case 'tts_stop':\n await stop()\n return { success: true, message: 'Stopped' }\n \n case 'tts_pause':\n pause()\n return { success: true, message: 'Paused' }\n \n case 'tts_resume':\n resume()\n return { success: true, message: 'Resumed' }\n \n case 'tts_list_voices':\n const voices = await listVoices(args?.provider as string | undefined)\n return { success: true, voices }\n \n case 'tts_list_providers':\n const speaker = getDefaultSpeaker()\n const providers = speaker.getProviders()\n return { success: true, providers }\n \n case 'tts_status':\n const s = getDefaultSpeaker()\n return {\n success: true,\n isPlaying: s.isPlaying(),\n isPaused: s.isPausedState()\n }\n \n case 'tts_stream_speak':\n if (!isAutoReadEnabled()) {\n throw new TTSError(\n 'Stream mode is not enabled. autoRead must be enabled in configuration to use tts_stream_speak.',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n }\n if (!isStreamEnabled()) {\n throw new TTSError(\n 'Stream components not initialized. Please initialize with autoRead enabled.',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n }\n const streamReader = getStreamReader()\n const synthesizer = getStreamingSynthesizer()\n if (streamReader && synthesizer) {\n streamReader.start()\n if (args?.text) {\n synthesizer.synthesize(args.text)\n }\n return { success: true, message: 'Stream speak started' }\n }\n throw new TTSError(\n 'Stream components not available',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n \n case 'tts_stream_stop':\n if (!isStreamEnabled()) {\n throw new TTSError(\n 'Stream mode is not enabled. Please enable autoRead in configuration.',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n }\n const player = getStreamPlayer()\n if (player) {\n player.stop()\n return { success: true, message: 'Stream stopped' }\n }\n throw new TTSError(\n 'Stream player not available',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n \n case 'tts_stream_status':\n if (!isStreamEnabled()) {\n return {\n success: true,\n isActive: false,\n bytesWritten: 0,\n state: 'not_initialized'\n }\n }\n return {\n success: true,\n ...getStreamStatus()\n }\n \n default:\n throw new TTSError(\n `Unknown tool: ${toolName}`,\n TTSErrorCode.UNKNOWN,\n 'tools'\n )\n }\n } catch (error) {\n if (error instanceof TTSError) {\n return {\n success: false,\n error: error.message,\n code: error.code,\n provider: error.provider\n }\n }\n return {\n success: false,\n error: String(error)\n }\n }\n}\n", "/**\n * MiniMax TTS Provider\n * \u652F\u6301 T2A v2 (\u540C\u6B65/\u6D41\u5F0FHTTP)\u3001T2A Async v2 (\u5F02\u6B65HTTP\u8F6E\u8BE2)\n * \u7AEF\u70B9\u53EF\u914D\u7F6E: baseURL (\u9ED8\u8BA4 https://api.minimaxi.com)\n */\n\nimport { BaseTTSProvider } from './base'\nimport {\n TTSError,\n TTSErrorCode,\n AudioResult,\n Voice,\n SpeakOptions\n} from '../core/types'\nimport axios, { AxiosInstance } from 'axios'\nimport { WebSocket } from 'ws'\n\nexport interface MiniMaxConfig {\n apiKey: string\n baseURL?: string\n voiceId?: string\n model?: 'sync' | 'async' | 'stream'\n ttsModel?: string\n audioFormat?: 'mp3' | 'wav' | 'flac'\n speed?: number\n volume?: number\n pitch?: number\n groupId?: string\n}\n\n/**\n * MiniMax TTS Provider\n * \u5B98\u7F51: https://www.minimax.io/\n * API\u6587\u6863: https://www.minimaxi.com/document/T2A\n */\nexport class MiniMaxProvider extends BaseTTSProvider {\n name = 'minimax'\n capabilities = {\n speak: true,\n stream: true,\n sync: true,\n async: true,\n voiceList: true,\n voiceClone: true\n } as const\n\n private config: MiniMaxConfig\n private httpClient: AxiosInstance\n private wsConnection?: WebSocket\n private currentAudioData: Buffer[] = []\n private audioFormat: 'mp3' | 'wav' | 'flac' = 'mp3'\n\n constructor(config: MiniMaxConfig) {\n super()\n this.config = config\n this.apiKey = config.apiKey\n this.defaultVoice = config.voiceId\n this.defaultModel = config.model || 'stream'\n this.audioFormat = config.audioFormat || 'mp3'\n\n this.httpClient = axios.create({\n baseURL: this.config.baseURL || 'https://api.minimaxi.com',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n },\n timeout: 30000\n })\n }\n\n async initialize(): Promise<void> {\n this.validateApiKey()\n }\n\n async destroy(): Promise<void> {\n if (this.wsConnection) {\n this.wsConnection.close()\n this.wsConnection = undefined\n }\n }\n\n protected async doSpeak(\n text: string,\n voice: string | undefined,\n model: 'sync' | 'async' | 'stream',\n options?: SpeakOptions\n ): Promise<AudioResult> {\n this.validateApiKey()\n\n switch (model) {\n case 'stream':\n return this.streamingSpeak(text, voice, options)\n case 'sync':\n return this.syncSpeak(text, voice, options)\n case 'async':\n return this.asyncSpeak(text, voice, options)\n default:\n return this.streamingSpeak(text, voice, options)\n }\n }\n\n /**\n * \u6D41\u5F0F\u5408\u6210 (HTTP) - T2A v2 with stream: true\n */\n private async streamingSpeak(\n text: string,\n voice: string | undefined,\n options?: SpeakOptions\n ): Promise<AudioResult> {\n try {\n const voiceId = voice || this.defaultVoice || 'male-qn-qingse'\n const speed = options?.speed || this.config.speed || 1.0\n const vol = options?.volume !== undefined ? options.volume / 10 : (this.config.volume !== undefined ? this.config.volume / 10 : 1.0)\n const pitch = options?.pitch !== undefined ? Math.round((options.pitch - 1) * 12) : (this.config.pitch !== undefined ? Math.round((this.config.pitch - 1) * 12) : 0)\n\n const response = await this.httpClient.post('/v1/t2a_v2', {\n model: this.config.ttsModel || 'speech-2.8-hd',\n text,\n stream: true,\n voice_setting: {\n voice_id: voiceId,\n speed: speed,\n vol: vol,\n pitch: pitch\n },\n audio_setting: {\n sample_rate: 32000,\n bitrate: 128000,\n format: this.audioFormat,\n channel: 1\n }\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n },\n responseType: 'stream'\n })\n\n const stream = response.data\n const audioChunks: Buffer[] = []\n\n return new Promise((resolve, reject) => {\n stream.on('data', (chunk: Buffer) => {\n try {\n const lines = chunk.toString().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data:')) {\n const data = JSON.parse(line.slice(5))\n if (data.data?.audio) {\n audioChunks.push(Buffer.from(data.data.audio, 'hex'))\n }\n if (data.data?.status === 2) {\n const fullAudio = Buffer.concat(audioChunks)\n resolve({\n audioData: fullAudio,\n format: this.audioFormat,\n isStream: true,\n duration: this.estimateDuration(fullAudio.length)\n })\n }\n }\n }\n } catch (e) {\n audioChunks.push(chunk)\n }\n })\n\n stream.on('error', (err: any) => {\n reject(new TTSError(\n 'Stream error',\n TTSErrorCode.NETWORK,\n this.name,\n err\n ))\n })\n\n stream.on('end', () => {\n if (audioChunks.length > 0) {\n const fullAudio = Buffer.concat(audioChunks)\n resolve({\n audioData: fullAudio,\n format: this.audioFormat,\n isStream: true,\n duration: this.estimateDuration(fullAudio.length)\n })\n }\n })\n })\n } catch (error: any) {\n if (error instanceof TTSError) throw error\n throw this.mapError(error)\n }\n }\n\n /**\n * \u540C\u6B65\u5408\u6210 (HTTP) - T2A v2\n * API: POST https://api.minimax.io/v1/t2a_v2\n */\n private async syncSpeak(\n text: string,\n voice: string | undefined,\n options?: SpeakOptions\n ): Promise<AudioResult> {\n try {\n const voiceId = voice || this.defaultVoice || 'male-qn-qingse'\n const speed = options?.speed || this.config.speed || 1.0\n const vol = options?.volume !== undefined ? options.volume / 10 : (this.config.volume !== undefined ? this.config.volume / 10 : 1.0)\n const pitch = options?.pitch !== undefined ? Math.round((options.pitch - 1) * 12) : (this.config.pitch !== undefined ? Math.round((this.config.pitch - 1) * 12) : 0)\n\n const response = await this.httpClient.post('/v1/t2a_v2', {\n model: this.config.ttsModel || 'speech-2.8-hd',\n text,\n stream: false,\n output_format: 'hex',\n voice_setting: {\n voice_id: voiceId,\n speed: speed,\n vol: vol,\n pitch: pitch\n },\n audio_setting: {\n sample_rate: 32000,\n bitrate: 128000,\n format: this.audioFormat,\n channel: 1\n }\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n }\n })\n\n if (response.data.base_resp?.status_code !== 0) {\n throw new TTSError(\n response.data.base_resp?.status_msg || 'API request failed',\n TTSErrorCode.UNKNOWN,\n this.name,\n response.data.base_resp\n )\n }\n\n const audioHex = response.data.data?.audio\n if (!audioHex) {\n throw new TTSError(\n 'No audio data in response',\n TTSErrorCode.UNKNOWN,\n this.name\n )\n }\n\n const audioBuffer = Buffer.from(audioHex, 'hex')\n\n return {\n audioData: audioBuffer,\n format: this.audioFormat,\n isStream: false,\n duration: response.data.extra_info?.audio_length \n ? response.data.extra_info.audio_length / 1000 \n : this.estimateDuration(audioBuffer.length)\n }\n } catch (error: any) {\n if (error instanceof TTSError) throw error\n throw this.mapError(error)\n }\n }\n\n /**\n * \u5F02\u6B65\u5408\u6210 (\u8F6E\u8BE2) - T2A Async v2\n */\n private async asyncSpeak(\n text: string,\n voice: string | undefined,\n options?: SpeakOptions\n ): Promise<AudioResult> {\n try {\n const voiceId = voice || this.defaultVoice || 'male-qn-qingse'\n const speed = options?.speed || this.config.speed || 1.0\n const vol = options?.volume !== undefined ? options.volume / 10 : (this.config.volume !== undefined ? this.config.volume / 10 : 1.0)\n const pitch = options?.pitch !== undefined ? Math.round((options.pitch - 1) * 12) : (this.config.pitch !== undefined ? Math.round((this.config.pitch - 1) * 12) : 0)\n\n const createResponse = await this.httpClient.post('/v1/t2a_async_v2', {\n model: this.config.ttsModel || 'speech-2.8-hd',\n text,\n voice_setting: {\n voice_id: voiceId,\n speed: speed,\n vol: vol,\n pitch: pitch\n },\n audio_setting: {\n sample_rate: 32000,\n bitrate: 128000,\n format: this.audioFormat,\n channel: 1\n }\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n }\n })\n\n const taskId = createResponse.data.task_id\n if (!taskId) {\n throw new TTSError(\n 'No task_id in async response',\n TTSErrorCode.UNKNOWN,\n this.name,\n createResponse.data\n )\n }\n\n let attempts = 0\n const maxAttempts = 60\n\n while (attempts < maxAttempts) {\n await this.delay(2000)\n\n const statusResponse = await this.httpClient.get(\n `/v1/query/t2a_async_query_v2?task_id=${taskId}`,\n {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n }\n }\n )\n\n if (statusResponse.data.status === 'success') {\n const fileId = statusResponse.data.file_id\n if (!fileId) {\n throw new TTSError(\n 'No file_id in async response',\n TTSErrorCode.UNKNOWN,\n this.name,\n statusResponse.data\n )\n }\n\n const downloadResponse = await this.httpClient.get(\n `/v1/files/retrieve_content?file_id=${fileId}`,\n { \n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n },\n responseType: 'arraybuffer'\n }\n )\n\n return {\n audioData: Buffer.from(downloadResponse.data),\n format: this.audioFormat,\n isStream: false,\n duration: 0\n }\n }\n\n if (statusResponse.data.status === 'failed') {\n throw new TTSError(\n 'Async TTS task failed',\n TTSErrorCode.UNKNOWN,\n this.name,\n statusResponse.data\n )\n }\n\n attempts++\n }\n\n throw new TTSError(\n 'Async TTS task timeout',\n TTSErrorCode.NETWORK,\n this.name\n )\n } catch (error: any) {\n if (error instanceof TTSError) throw error\n throw this.mapError(error)\n }\n }\n\n /**\n * \u97F3\u8272\u514B\u9686 - \u4F7F\u7528\u53C2\u8003\u97F3\u9891\u514B\u9686\u58F0\u97F3\n */\n async voiceClone(audioUrl: string, text: string, voice?: string): Promise<AudioResult> {\n this.validateApiKey()\n\n try {\n const response = await this.httpClient.post('/v1/t2a_v2/voice_clone', {\n audio_url: audioUrl,\n text,\n voice_id: voice || 'custom_clone'\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n },\n responseType: 'arraybuffer'\n })\n\n return {\n audioData: Buffer.from(response.data),\n format: this.audioFormat,\n isStream: false,\n duration: this.estimateDuration(response.data.length)\n }\n } catch (error: any) {\n throw this.mapError(error)\n }\n }\n\n /**\n * \u83B7\u53D6\u97F3\u8272\u5217\u8868\n */\n async listVoices(): Promise<Voice[]> {\n this.validateApiKey()\n\n try {\n const response = await this.httpClient.get('/v1/t2a/voices', {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n }\n })\n\n return response.data.voices.map((v: any) => ({\n id: v.voice_id,\n name: v.name,\n language: v.language,\n gender: v.gender\n }))\n } catch (error: any) {\n // \u5982\u679CAPI\u8C03\u7528\u5931\u8D25\uFF0C\u8FD4\u56DE\u9884\u5B9A\u4E49\u97F3\u8272\u5217\u8868\n return MINIMAX_VOICES\n }\n }\n\n /**\n * \u9519\u8BEF\u6620\u5C04\n */\n private mapError(error: any): TTSError {\n if (error.response) {\n const status = error.response.status\n const code =\n status === 401 ? TTSErrorCode.AUTH :\n status === 429 ? TTSErrorCode.QUOTA :\n status >= 500 ? TTSErrorCode.NETWORK :\n TTSErrorCode.UNKNOWN\n\n return new TTSError(\n error.response.data?.message || 'API request failed',\n code,\n this.name,\n error.response.data\n )\n }\n\n if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {\n return new TTSError(\n 'Network error: Unable to connect to MiniMax API',\n TTSErrorCode.NETWORK,\n this.name,\n error.message\n )\n }\n\n return new TTSError(\n error.message || 'Unknown error',\n TTSErrorCode.UNKNOWN,\n this.name,\n error\n )\n }\n\n /**\n * \u5EF6\u8FDF\u8F85\u52A9\u51FD\u6570\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n /**\n * \u4F30\u7B97\u97F3\u9891\u65F6\u957F\n * \u57FA\u4E8E 32kbps MP3 \u4F30\u7B97\n */\n private estimateDuration(bytes: number): number {\n return (bytes * 8) / (32000 * 60)\n }\n}\n\n/**\n * MiniMax \u9884\u5B9A\u4E49\u97F3\u8272\u5217\u8868\n * \u5B98\u65B9\u97F3\u8272ID\u53C2\u8003\n */\nexport const MINIMAX_VOICES: Voice[] = [\n { id: 'male-qn-qingse', name: '\u9752\u5E74\u6E05\u6F88', language: 'zh-CN', gender: 'male' },\n { id: 'male-qn-qingse_2', name: '\u9752\u5E74\u6E05\u6F88v2', language: 'zh-CN', gender: 'male' },\n { id: 'female-shaonv', name: '\u5C11\u5973', language: 'zh-CN', gender: 'female' },\n { id: 'male-baiming', name: '\u6210\u719F\u7537\u58F0', language: 'zh-CN', gender: 'male' },\n { id: 'female-tianmei', name: '\u751C\u7F8E\u5973\u58F0', language: 'zh-CN', gender: 'female' },\n { id: 'male-zhongnan', name: '\u4E2D\u5E74\u7537\u58F0', language: 'zh-CN', gender: 'male' },\n { id: 'female-yujie', name: '\u5FA1\u59D0\u97F3', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-xiaoao', name: '\u9752\u5E74\u8C6A\u723D', language: 'zh-CN', gender: 'male' },\n { id: 'female-shandian', name: '\u751C\u5FC3\u5C0F\u5A18', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-buke', name: '\u9752\u5E74\u4F4E\u6C89', language: 'zh-CN', gender: 'male' },\n { id: 'male-qn-wenlv', name: '\u6587\u7EFF\u9752\u5E74', language: 'zh-CN', gender: 'male' },\n { id: 'female-tianmei-2', name: '\u751C\u7F8E\u5973\u58F0v2', language: 'zh-CN', gender: 'female' },\n { id: 'female-yujie-2', name: '\u5FA1\u59D0\u97F3v2', language: 'zh-CN', gender: 'female' },\n { id: 'male-shaonian', name: '\u5C11\u5E74\u97F3', language: 'zh-CN', gender: 'male' },\n { id: 'female-yunv', name: '\u6E29\u67D4\u5973\u58F0', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-jingdian', name: '\u7ECF\u5178\u7537\u58F0', language: 'zh-CN', gender: 'male' },\n { id: 'male-qn-kuang\u91CE', name: '\u72C2\u91CE\u9752\u5E74', language: 'zh-CN', gender: 'male' },\n { id: 'female-yujie-old', name: '\u4F18\u96C5\u4F4E\u6C89', language: 'zh-CN', gender: 'female' },\n { id: 'female-tianmei-old', name: '\u751C\u7F8E\u5973\u5B69', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-taohua', name: '\u6843\u82B1\u9752\u5E74', language: 'zh-CN', gender: 'male' }\n]\n", "/**\n * StreamReader - \u6D41\u5F0F\u6587\u672C\u7F13\u51B2\u4E0E\u53E5\u5B50\u8FB9\u754C\u68C0\u6D4B\n * \n * \u529F\u80FD\uFF1A\n * - \u8BA2\u9605 TuiEventBus \u7684 message.part.delta \u4E8B\u4EF6\n * - \u7F13\u51B2\u533A\u6EE1\u6216\u9047\u5230\u53E5\u5B50\u7ED3\u675F\u7B26\u65F6\u89E6\u53D1 textReady \u4E8B\u4EF6\n * - \u652F\u6301\u8D85\u65F6\u5F3A\u5236\u53D1\u9001\n */\n\nimport { EventEmitter } from 'events'\nimport { StreamState, TTSError, TTSErrorCode } from './types'\n\nexport class StreamReader extends EventEmitter {\n private state: StreamState = StreamState.IDLE\n private buffer: string = ''\n private sessionID?: string\n private messageID?: string\n private partID?: string\n private timeoutHandle?: NodeJS.Timeout\n \n constructor(\n private bufferSize: number = 30,\n private bufferTimeout: number = 2000\n ) {\n super()\n }\n\n /**\n * \u542F\u52A8\u6D41\u5F0F\u76D1\u542C\n * \u5C06\u72B6\u6001\u4ECE IDLE \u5207\u6362\u5230 BUFFERING\uFF0C\u5F00\u59CB\u76D1\u542C\u4E8B\u4EF6\n */\n start(): void {\n if (this.state === StreamState.IDLE) {\n this.state = StreamState.BUFFERING\n this.emit('streamStart')\n }\n }\n \n /**\n * \u5904\u7406 message.part.delta \u4E8B\u4EF6\n */\n handleDelta(sessionID: string, messageID: string, partID: string, delta: string): void {\n if (this.state === StreamState.IDLE) {\n this.state = StreamState.BUFFERING\n this.sessionID = sessionID\n this.messageID = messageID\n this.partID = partID\n this.emit('streamStart')\n }\n \n this.buffer += delta\n this.resetTimeout()\n \n if (this.shouldFlush()) {\n this.flushBuffer()\n }\n }\n \n /**\n * \u5904\u7406\u6D41\u7ED3\u675F\n */\n handleEnd(): void {\n if (this.state === StreamState.ENDED) {\n return\n }\n if (this.buffer.length > 0) {\n this.flushBuffer()\n }\n this.state = StreamState.ENDED\n this.clearTimeout()\n this.emit('streamEnd')\n }\n \n /**\n * \u5904\u7406\u9519\u8BEF\n */\n handleError(error: TTSError): void {\n this.clearTimeout()\n this.state = StreamState.IDLE\n this.buffer = ''\n this.emit('streamError', error)\n }\n \n /**\n * \u91CD\u7F6E\u7F13\u51B2\u5668\n */\n reset(): void {\n this.state = StreamState.IDLE\n this.buffer = ''\n this.sessionID = undefined\n this.messageID = undefined\n this.partID = undefined\n this.clearTimeout()\n }\n \n /**\n * \u5224\u65AD\u662F\u5426\u5E94\u8BE5\u5237\u65B0\u7F13\u51B2\u533A\n * \u6761\u4EF6\uFF1A\n * 1. \u5305\u542B\u53E5\u5B50\u7ED3\u675F\u7B26\uFF08\u4EFB\u4F55\u957F\u5EA6\uFF09\n * 2. \u7F13\u51B2\u533A\u957F\u5EA6 >= bufferSize\n */\n private shouldFlush(): boolean {\n // \u53E5\u5B50\u7ED3\u675F\u6807\u8BB0\uFF1A\u3002\uFF01\uFF1F.!?\u2026\u2026\uFF08\u4E2D\u6587\u53E5\u53F7\u3001\u611F\u53F9\u53F7\u3001\u95EE\u53F7\u3001\u7701\u7565\u53F7\uFF09\n const sentenceEnd = /[\u3002\uFF01\uFF1F.!?]|\u2026\u2026/\n if (sentenceEnd.test(this.buffer)) {\n return true\n }\n // \u7F13\u51B2\u533A\u8FBE\u5230\u9608\u503C\n if (this.buffer.length >= this.bufferSize) {\n return true\n }\n return false\n }\n \n /**\n * \u5237\u65B0\u7F13\u51B2\u533A\uFF0C\u53D1\u9001textReady\u4E8B\u4EF6\n */\n private flushBuffer(): void {\n const text = this.buffer.trim()\n if (text.length > 0) {\n this.emit('textReady', text)\n }\n this.buffer = ''\n this.resetTimeout()\n }\n \n /**\n * \u91CD\u7F6E\u8D85\u65F6\u8BA1\u65F6\u5668\n */\n private resetTimeout(): void {\n this.clearTimeout()\n this.timeoutHandle = setTimeout(() => {\n if (this.buffer.length > 0) {\n this.flushBuffer()\n }\n }, this.bufferTimeout)\n }\n \n /**\n * \u6E05\u9664\u8D85\u65F6\u8BA1\u65F6\u5668\n */\n private clearTimeout(): void {\n if (this.timeoutHandle) {\n clearTimeout(this.timeoutHandle)\n this.timeoutHandle = undefined\n }\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u72B6\u6001\n */\n getState(): StreamState {\n return this.state\n }\n \n /**\n * \u68C0\u67E5\u6D41\u662F\u5426\u5904\u4E8E\u6D3B\u8DC3\u72B6\u6001\n */\n isActive(): boolean {\n return this.state === StreamState.BUFFERING\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u7F13\u51B2\u533A\u5185\u5BB9\n */\n getBuffer(): string {\n return this.buffer\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u4F1A\u8BDDID\n */\n getSessionID(): string | undefined {\n return this.sessionID\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u6D88\u606FID\n */\n getMessageID(): string | undefined {\n return this.messageID\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u5206\u5757ID\n */\n getPartID(): string | undefined {\n return this.partID\n }\n}\n", "/**\n * StreamingSynthesizer - \u6D41\u5F0F\u5408\u6210\u5668\n * \n * \u529F\u80FD\uFF1A\n * - \u63A5\u6536 StreamReader \u53D1\u6765\u7684\u6587\u672C\uFF08\u901A\u8FC7 synthesize \u65B9\u6CD5\uFF09\n * - \u8C03\u7528 TTSProvider \u7684\u6D41\u5F0F\u5408\u6210\u63A5\u53E3\n * - \u5C06\u8FD4\u56DE\u7684\u97F3\u9891 chunk \u4F20\u9012\u7ED9\u4E0B\u6E38\uFF08StreamPlayer\uFF09\n * \n * \u6570\u636E\u6D41\uFF1A\n * StreamReader.textReady \u2192 StreamingSynthesizer.synthesize() \u2192 StreamPlayer (\u8FB9\u6536\u8FB9\u64AD)\n */\n\nimport { EventEmitter } from 'events'\nimport { TTSProvider, TTSError, TTSErrorCode, StreamingSynthesizerOptions, AudioResult } from './types'\n\nexport interface StreamingSynthesizerEvents {\n on(event: 'chunk', handler: (chunk: Buffer) => void): void\n on(event: 'error', handler: (error: TTSError) => void): void\n on(event: 'done', handler: () => void): void\n}\n\nexport class StreamingSynthesizer extends EventEmitter {\n private audioChunks: Buffer[] = []\n \n constructor(private options: StreamingSynthesizerOptions) {\n super()\n }\n \n /**\n * \u53D1\u9001\u6587\u672C\u7247\u6BB5\u8FDB\u884C\u5408\u6210\n * \u8C03\u7528 provider.speak() \u5E76\u5904\u7406\u8FD4\u56DE\u7684\u97F3\u9891\u6D41\n */\n async synthesize(text: string): Promise<void> {\n if (!text || text.trim().length === 0) {\n return\n }\n \n try {\n const result = await this.options.provider.speak(text, {\n model: 'stream',\n voice: this.options.voice,\n speed: this.options.speed,\n volume: this.options.volume,\n pitch: this.options.pitch\n })\n \n await this.processAudioResult(result)\n \n this.emit('done')\n } catch (error) {\n const ttsError = error instanceof TTSError \n ? error \n : new TTSError(\n error instanceof Error ? error.message : 'Synthesis failed',\n 'UNKNOWN' as TTSErrorCode,\n this.options.provider.name,\n error\n )\n this.emit('error', ttsError)\n }\n }\n \n /**\n * \u5904\u7406 AudioResult\uFF0C\u6839\u636E audioData \u7C7B\u578B\u8FDB\u884C\u76F8\u5E94\u5904\u7406\n */\n private async processAudioResult(result: AudioResult): Promise<void> {\n if (result.isStream && result.audioData instanceof ReadableStream) {\n // \u6D41\u5F0F\u6570\u636E\uFF1AReadableStream\n await this.processReadableStream(result.audioData)\n } else if (Buffer.isBuffer(result.audioData)) {\n // \u975E\u6D41\u5F0F\u6570\u636E\uFF1ABuffer\n this.emitChunk(result.audioData)\n }\n }\n \n /**\n * \u5904\u7406 ReadableStream\uFF0C\u9010chunk emit\n */\n private async processReadableStream(stream: ReadableStream): Promise<void> {\n const reader = stream.getReader()\n \n try {\n while (true) {\n const { done, value } = await reader.read()\n \n if (done) {\n break\n }\n \n if (value) {\n const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value)\n this.emitChunk(chunk)\n }\n }\n } finally {\n reader.releaseLock()\n }\n }\n \n /**\n * emit chunk \u5E76\u7D2F\u79EF\n */\n private emitChunk(chunk: Buffer): void {\n this.audioChunks.push(chunk)\n this.emit('chunk', chunk)\n }\n \n /**\n * \u91CD\u7F6E\u72B6\u6001\n * \u6E05\u7A7A\u7D2F\u79EF\u7684\u97F3\u9891\u6570\u636E\n */\n reset(): void {\n this.audioChunks = []\n }\n \n /**\n * \u83B7\u53D6\u7D2F\u79EF\u7684\u97F3\u9891\u6570\u636E\n * \u8FD4\u56DE\u6240\u6709\u5DF2\u63A5\u6536\u7684 chunk\n */\n getAudioChunks(): Buffer[] {\n return [...this.audioChunks]\n }\n}\n", "/**\n * StreamPlayer - \u771F\u6B63\u7684\u8FB9\u6536\u8FB9\u64AD\u6D41\u5F0F\u97F3\u9891\u64AD\u653E\u5668\n * \u63A5\u6536\u97F3\u9891 chunk\uFF0C\u540C\u65F6\u5199\u5165\u4E34\u65F6\u6587\u4EF6\u5E76\u7ACB\u5373\u542F\u52A8\u64AD\u653E\u5668\u64AD\u653E\n */\n\nimport { EventEmitter } from 'events'\nimport { spawn, ChildProcess } from 'child_process'\nimport fs from 'fs'\nimport { createWriteStream, WriteStream } from 'fs'\nimport { tmpdir } from 'os'\nimport { join } from 'path'\n\n/**\n * StreamPlayer Events - \u6D41\u5F0F\u64AD\u653E\u5668\u4E8B\u4EF6\u56DE\u8C03\u63A5\u53E3\n */\nexport interface StreamPlayerEvents {\n onProgress?: (bytesWritten: number) => void\n onStart?: () => void\n onEnd?: () => void\n onError?: (error: Error) => void\n onPause?: () => void\n onResume?: () => void\n onStop?: () => void\n}\n\n/**\n * StreamPlayer Options - \u6D41\u5F0F\u64AD\u653E\u5668\u914D\u7F6E\u9009\u9879\n */\nexport interface StreamPlayerOptions {\n format?: 'mp3' | 'wav' | 'flac'\n events?: StreamPlayerEvents\n}\n\n/**\n * StreamPlayer - \u8FB9\u6536\u8FB9\u64AD\u7684\u6D41\u5F0F\u97F3\u9891\u64AD\u653E\u5668\n * \n * \u7279\u6027\uFF1A\n * - \u5199\u5165\u4E34\u65F6\u6587\u4EF6\u7684\u540C\u65F6\u7ACB\u5373\u542F\u52A8\u64AD\u653E\u5668\n * - \u652F\u6301 pause/resume/stop \u63A7\u5236\n * - \u8DE8\u5E73\u53F0\u652F\u6301\uFF1AmacOS (afplay), Linux (aplay), Windows (PowerShell)\n */\nexport class StreamPlayer extends EventEmitter {\n private tempFile: string = ''\n private writeStream?: WriteStream\n private playerProcess?: ChildProcess\n private _bytesWritten = 0\n private _started = false\n private _paused = false\n private _stopped = false\n private format: 'mp3' | 'wav' | 'flac' = 'mp3'\n private events?: StreamPlayerEvents\n\n constructor(options: StreamPlayerOptions = {}) {\n super()\n this.format = options.format || 'mp3'\n this.events = options.events\n }\n\n /**\n * \u5F00\u59CB\u64AD\u653E\n * \u521B\u5EFA\u4E34\u65F6\u6587\u4EF6\uFF0C\u521B\u5EFA\u5199\u5165\u6D41\uFF0C\u542F\u52A8\u64AD\u653E\u5668\u8FDB\u7A0B\n */\n start(): void {\n if (this._started) {\n return\n }\n\n // \u521B\u5EFA\u4E34\u65F6\u6587\u4EF6\n this.tempFile = join(tmpdir(), `ocosay-stream-${Date.now()}.${this.format}`)\n\n // \u521B\u5EFA\u5199\u5165\u6D41\n this.writeStream = createWriteStream(this.tempFile, { highWaterMark: 64 * 1024 })\n\n this.writeStream.on('error', (error: Error) => {\n this.handleError(error)\n })\n\n this.writeStream.on('finish', () => {\n // \u5199\u5165\u5B8C\u6210\uFF0C\u4F46\u64AD\u653E\u5668\u53EF\u80FD\u8FD8\u5728\u64AD\u653E\n })\n\n // \u542F\u52A8\u64AD\u653E\u5668\u8FDB\u7A0B\n this.startPlayer()\n\n this._started = true\n this._stopped = false\n\n this.events?.onStart?.()\n this.emit('start')\n }\n\n /**\n * \u542F\u52A8\u64AD\u653E\u5668\u8FDB\u7A0B\n */\n private startPlayer(): void {\n const platform = process.platform\n let command: string\n let args: string[]\n\n if (platform === 'darwin') {\n // macOS\n command = 'afplay'\n args = [this.tempFile]\n } else if (platform === 'linux') {\n // Linux\n command = 'aplay'\n args = [this.tempFile]\n } else {\n // Windows - PlaySync is synchronous and blocks the event loop\n // Return error to indicate Windows is not supported for streaming\n this.handleError(new Error('Windows platform is not supported for stream playback. PlaySync() blocks the Node.js event loop.'))\n return\n }\n\n this.playerProcess = spawn(command, args, {\n stdio: 'ignore',\n detached: false\n })\n\n this.playerProcess.on('exit', (code: number | null, signal: string | null) => {\n // \u5982\u679C\u662F\u6B63\u5E38\u7ED3\u675F\u6216\u88AB\u4FE1\u53F7\u7EC8\u6B62\uFF0C\u4E0D\u5F53\u4F5C\u9519\u8BEF\n if (this._stopped) {\n return\n }\n \n if (signal === 'SIGTERM' || signal === 'SIGINT') {\n // \u88AB\u4E3B\u52A8\u505C\u6B62\n return\n }\n\n if (code === 0 || code === null) {\n // \u6B63\u5E38\u64AD\u653E\u7ED3\u675F\n this.events?.onEnd?.()\n this.emit('end')\n } else {\n this.handleError(new Error(`Player exited with code ${code}`))\n }\n })\n\n this.playerProcess.on('error', (error: Error) => {\n this.handleError(error)\n })\n }\n\n /**\n * \u5199\u5165\u97F3\u9891\u6570\u636E\u5757\uFF08\u8FB9\u6536\u8FB9\u5199\uFF09\n * \u5982\u679C\u5C1A\u672A start()\uFF0C\u4F1A\u81EA\u52A8\u8C03\u7528\n */\n write(chunk: Buffer): void {\n // \u5982\u679C\u5DF2\u505C\u6B62\uFF0C\u76F4\u63A5\u5FFD\u7565\n if (this._stopped) {\n return\n }\n\n // \u5982\u679C\u672A\u542F\u52A8\uFF0C\u81EA\u52A8\u542F\u52A8\n if (!this._started) {\n this.start()\n }\n\n // \u5199\u5165\u6570\u636E\u5230\u6587\u4EF6\n if (this.writeStream) {\n const canContinue = this.writeStream.write(chunk)\n \n if (!canContinue) {\n // \u5199\u5165\u7F13\u51B2\u533A\u6EE1\u4E86\uFF0C\u7B49\u5F85 drain \u4E8B\u4EF6\n this.writeStream.once('drain', () => {\n // \u53EF\u4EE5\u7EE7\u7EED\u5199\u5165\n })\n }\n\n this._bytesWritten += chunk.length\n\n this.events?.onProgress?.(this._bytesWritten)\n this.emit('progress', this._bytesWritten)\n }\n }\n\n /**\n * \u7ED3\u675F\u5199\u5165\n * \u5173\u95ED\u5199\u5165\u6D41\uFF0C\u4F46\u4E0D\u6740\u64AD\u653E\u5668\u8FDB\u7A0B\uFF0C\u8BA9\u5B83\u64AD\u5B8C\n */\n end(): void {\n if (this.writeStream) {\n this.writeStream.end()\n this.writeStream = undefined\n }\n }\n\n /**\n * \u505C\u6B62\u64AD\u653E\n * \u6740\u6B7B\u64AD\u653E\u5668\u8FDB\u7A0B\uFF0C\u5220\u9664\u4E34\u65F6\u6587\u4EF6\n */\n stop(): void {\n this._stopped = true\n this._started = false\n this._paused = false\n\n // \u6740\u6B7B\u64AD\u653E\u5668\u8FDB\u7A0B\n if (this.playerProcess) {\n try {\n this.playerProcess.kill('SIGTERM')\n } catch (e) {\n // \u5FFD\u7565\u9519\u8BEF\n }\n this.playerProcess = undefined\n }\n\n // \u5173\u95ED\u5199\u5165\u6D41\n if (this.writeStream) {\n try {\n this.writeStream.destroy()\n } catch (e) {\n // \u5FFD\u7565\u9519\u8BEF\n }\n this.writeStream = undefined\n }\n\n // \u5220\u9664\u4E34\u65F6\u6587\u4EF6\n this.deleteTempFile()\n\n this.events?.onStop?.()\n this.emit('stop')\n }\n\n /**\n * \u6682\u505C\u64AD\u653E\n * \u4F7F\u7528 SIGSTOP \u6682\u505C\u64AD\u653E\u5668\u8FDB\u7A0B\n */\n pause(): void {\n if (!this._started || this._paused || this._stopped) {\n return\n }\n\n if (this.playerProcess) {\n try {\n this.playerProcess.kill('SIGSTOP')\n this._paused = true\n this.events?.onPause?.()\n this.emit('pause')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u6062\u590D\u64AD\u653E\n */\n resume(): void {\n if (!this._paused || this._stopped) {\n return\n }\n\n if (this.playerProcess) {\n try {\n this.playerProcess.kill('SIGCONT')\n this._paused = false\n this.events?.onResume?.()\n this.emit('resume')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u662F\u5426\u5DF2\u542F\u52A8\n */\n isStarted(): boolean {\n return this._started\n }\n\n /**\n * \u662F\u5426\u6682\u505C\n */\n isPaused(): boolean {\n return this._paused\n }\n\n /**\n * \u662F\u5426\u5DF2\u505C\u6B62\n */\n isStopped(): boolean {\n return this._stopped\n }\n\n /**\n * \u83B7\u53D6\u5DF2\u5199\u5165\u7684\u5B57\u8282\u6570\n */\n getBytesWritten(): number {\n return this._bytesWritten\n }\n\n /**\n * \u83B7\u53D6\u4E34\u65F6\u6587\u4EF6\u8DEF\u5F84\n */\n getTempFile(): string {\n return this.tempFile\n }\n\n /**\n * \u5904\u7406\u9519\u8BEF\n */\n private handleError(error: Error): void {\n this.events?.onError?.(error)\n this.emit('error', error)\n }\n\n /**\n * \u5220\u9664\u4E34\u65F6\u6587\u4EF6\n */\n private deleteTempFile(): void {\n if (this.tempFile) {\n try {\n if (fs.existsSync(this.tempFile)) {\n fs.unlinkSync(this.tempFile)\n }\n } catch (e) {\n // \u5FFD\u7565\u5220\u9664\u9519\u8BEF\n }\n this.tempFile = ''\n }\n }\n}\n\nexport default StreamPlayer\n", "import { handleToolCall } from './tools/tts'\nimport { registerProvider, getProvider, listProviders } from './providers/base'\nimport { MiniMaxProvider, MiniMaxConfig } from './providers/minimax'\nimport { Speaker, SpeakerOptions } from './core/speaker'\nimport { TTSError, TTSErrorCode } from './core/types'\nimport { StreamReader } from './core/stream-reader'\nimport { StreamingSynthesizer } from './core/streaming-synthesizer'\nimport { StreamPlayer } from './core/stream-player'\n\nexport const pluginInfo = {\n name: 'ocosay',\n version: '1.0.0',\n description: 'OpenCode TTS \u64AD\u653E\u63D2\u4EF6 - \u652F\u6301 MiniMax TTS',\n author: '',\n license: 'MIT'\n}\n\nlet speaker: Speaker | undefined\nlet streamReader: StreamReader | undefined\nlet streamingSynthesizer: StreamingSynthesizer | undefined\nlet streamPlayer: StreamPlayer | undefined\nlet initialized = false\nlet autoReadEnabled = false\n\nexport interface InitializeOptions {\n defaultProvider?: string\n defaultModel?: 'sync' | 'async' | 'stream'\n defaultVoice?: string\n providers?: {\n minimax?: MiniMaxConfig\n }\n autoRead?: boolean\n streamBufferSize?: number\n streamBufferTimeout?: number\n}\n\nexport async function initialize(config?: InitializeOptions): Promise<void> {\n if (initialized) {\n return\n }\n\n if (config?.providers?.minimax) {\n if (!config.providers.minimax.apiKey) {\n throw new Error('[ocosay] API Key is required. Please set minimax.apiKey in ~/.config/opencode/ocosay.jsonc')\n }\n const minimaxProvider = new MiniMaxProvider(config.providers.minimax)\n registerProvider('minimax', minimaxProvider)\n await minimaxProvider.initialize()\n }\n \n const speakerOptions: SpeakerOptions = {\n defaultProvider: config?.defaultProvider || 'minimax',\n defaultModel: config?.defaultModel || 'stream',\n defaultVoice: config?.defaultVoice\n }\n \n speaker = new Speaker(speakerOptions)\n \n if (config?.autoRead) {\n autoReadEnabled = true\n initializeStreamComponents(config)\n }\n \n initialized = true\n}\n\nfunction initializeStreamComponents(config: InitializeOptions): void {\n const provider = getProvider(config?.defaultProvider || 'minimax')\n \n streamReader = new StreamReader(\n config?.streamBufferSize || 30,\n config?.streamBufferTimeout || 2000\n )\n \n streamingSynthesizer = new StreamingSynthesizer({\n provider,\n voice: config?.defaultVoice,\n speed: 1.0,\n volume: 1.0,\n pitch: 1.0\n })\n \n const playerEvents = {\n onStart: () => {},\n onEnd: () => {},\n onProgress: (bytesWritten: number) => {},\n onError: (error: Error) => console.error('Stream player error:', error),\n onStop: () => {}\n }\n streamPlayer = new StreamPlayer({ events: playerEvents })\n\n const synthesisQueue: string[] = []\n let isSynthesizing = false\n\n async function processQueue(): Promise<void> {\n while (synthesisQueue.length > 0) {\n const text = synthesisQueue.shift()!\n isSynthesizing = true\n try {\n await streamingSynthesizer?.synthesize(text)\n } catch (error) {\n console.error('Synthesize error:', error)\n }\n }\n isSynthesizing = false\n }\n \n streamReader.on('textReady', (text: string) => {\n synthesisQueue.push(text)\n if (!isSynthesizing) {\n processQueue()\n }\n })\n \n streamingSynthesizer.on('chunk', (chunk: Buffer) => {\n if (streamPlayer) {\n streamPlayer.write(chunk)\n }\n })\n \n streamingSynthesizer.on('done', () => {\n if (streamPlayer) {\n streamPlayer.end()\n }\n })\n\n const TuiEventBus = (global as any).__opencode_tuieventbus__\n if (TuiEventBus) {\n const eventBus = new TuiEventBus()\n let messagePartDeltaHandler: ((event: any) => void) | undefined\n let messagePartEndHandler: (() => void) | undefined\n \n messagePartDeltaHandler = (event: any) => {\n if (event?.properties) {\n streamReader?.handleDelta(\n event.sessionId || '',\n event.messageId || '',\n event.partId || '',\n event.properties.delta || ''\n )\n }\n }\n messagePartEndHandler = () => {\n streamReader?.handleEnd()\n }\n eventBus.on('message.part.delta', messagePartDeltaHandler)\n eventBus.on('message.part.end', messagePartEndHandler)\n }\n}\n\nexport function getSpeaker(): Speaker {\n if (!speaker) {\n throw new TTSError(\n 'Plugin not initialized. Call initialize() first.',\n TTSErrorCode.UNKNOWN,\n 'ocosay'\n )\n }\n return speaker\n}\n\nexport function isStreamEnabled(): boolean {\n return streamReader !== undefined && streamingSynthesizer !== undefined && streamPlayer !== undefined\n}\n\nexport function isAutoReadEnabled(): boolean {\n return autoReadEnabled\n}\n\nexport function getStreamStatus(): { isActive: boolean; bytesWritten: number; state: string } {\n if (!streamReader) {\n return { isActive: false, bytesWritten: 0, state: 'not_initialized' }\n }\n return {\n isActive: streamReader.isActive(),\n bytesWritten: streamPlayer?.getBytesWritten() ?? 0,\n state: streamReader.getState()\n }\n}\n\nexport function getStreamReader(): StreamReader | undefined {\n return streamReader\n}\n\nexport function getStreamingSynthesizer(): StreamingSynthesizer | undefined {\n return streamingSynthesizer\n}\n\nexport function getStreamPlayer(): StreamPlayer | undefined {\n return streamPlayer\n}\n\nexport async function destroy(): Promise<void> {\n if (streamReader) {\n streamReader.reset()\n streamReader = undefined\n }\n \n if (streamingSynthesizer) {\n streamingSynthesizer.reset()\n streamingSynthesizer = undefined\n }\n \n if (streamPlayer) {\n await streamPlayer.stop()\n streamPlayer = undefined\n }\n \n if (speaker) {\n await speaker.destroy()\n speaker = undefined\n }\n \n for (const providerName of listProviders()) {\n try {\n getProvider(providerName)?.destroy()\n } catch (e) {}\n }\n \n initialized = false\n autoReadEnabled = false\n}\n\nexport { handleToolCall }\nexport const toolNames = [\n 'tts_speak',\n 'tts_stop',\n 'tts_pause',\n 'tts_resume',\n 'tts_list_voices',\n 'tts_list_providers',\n 'tts_status',\n 'tts_stream_speak',\n 'tts_stream_stop',\n 'tts_stream_status'\n]\n", "import * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\n\n// OcosayConfig \u7C7B\u578B\u5B9A\u4E49\nexport interface OcosayConfig {\n enabled: boolean\n autoPlay: boolean\n autoRead: boolean\n streamMode: boolean\n streamBufferSize: number\n streamBufferTimeout: number\n speed: number\n volume: number\n pitch: number\n providers: {\n minimax: {\n apiKey: string\n baseURL: string\n voiceId: string\n model: 'sync' | 'async' | 'stream'\n ttsModel: string\n audioFormat: 'mp3' | 'wav' | 'flac'\n }\n }\n}\n\n// \u9ED8\u8BA4\u914D\u7F6E\nconst DEFAULT_CONFIG: Omit<OcosayConfig, 'providers'> = {\n enabled: true,\n autoPlay: false,\n autoRead: false,\n streamMode: true,\n streamBufferSize: 30,\n streamBufferTimeout: 2000,\n speed: 1.0,\n volume: 80,\n pitch: 1.0\n}\n\nconst CONFIG_PATH = path.join(os.homedir(), '.config', 'opencode', 'ocosay.jsonc')\n\nexport function generateDefaultConfig(): OcosayConfig {\n return {\n ...DEFAULT_CONFIG,\n providers: {\n minimax: {\n apiKey: '',\n baseURL: 'https://api.minimaxi.com',\n voiceId: 'female-chengshu',\n model: 'stream',\n ttsModel: 'speech-2.8-hd',\n audioFormat: 'mp3'\n }\n }\n }\n}\n\nexport function stripComments(jsonc: string): string {\n let result = ''\n let inString = false\n let stringChar = ''\n let i = 0\n\n while (i < jsonc.length) {\n const char = jsonc[i]\n\n if (!inString && (char === '\"' || char === \"'\" || char === '`')) {\n inString = true\n stringChar = char\n result += char\n i++\n continue\n }\n\n if (inString && char === stringChar && jsonc[i - 1] !== '\\\\') {\n inString = false\n result += char\n i++\n continue\n }\n\n if (inString) {\n result += char\n i++\n continue\n }\n\n if (char === '/' && jsonc[i + 1] === '/') {\n while (i < jsonc.length && jsonc[i] !== '\\n') {\n i++\n }\n continue\n }\n\n if (char === '/' && jsonc[i + 1] === '*') {\n i += 2\n while (i < jsonc.length - 1 && !(jsonc[i] === '*' && jsonc[i + 1] === '/')) {\n i++\n }\n i += 2\n continue\n }\n\n result += char\n i++\n }\n\n return result\n}\n\nexport function mergeWithDefaults(\n loaded: Partial<OcosayConfig>,\n defaults: Omit<OcosayConfig, 'providers'>\n): Omit<OcosayConfig, 'providers'> {\n return {\n enabled: loaded.enabled ?? defaults.enabled,\n autoPlay: loaded.autoPlay ?? defaults.autoPlay,\n autoRead: loaded.autoRead ?? defaults.autoRead,\n streamMode: loaded.streamMode ?? defaults.streamMode,\n streamBufferSize: loaded.streamBufferSize ?? defaults.streamBufferSize,\n streamBufferTimeout: loaded.streamBufferTimeout ?? defaults.streamBufferTimeout,\n speed: loaded.speed ?? defaults.speed,\n volume: loaded.volume ?? defaults.volume,\n pitch: loaded.pitch ?? defaults.pitch\n }\n}\n\nexport function loadOrCreateConfig(): OcosayConfig {\n const configDir = path.dirname(CONFIG_PATH)\n\n if (!fs.existsSync(configDir)) {\n try {\n fs.mkdirSync(configDir, { recursive: true })\n } catch (err) {\n throw new Error(`[ocosay] \u65E0\u6CD5\u521B\u5EFA\u914D\u7F6E\u76EE\u5F55 ${configDir}: ${err}`)\n }\n }\n\n if (!fs.existsSync(CONFIG_PATH)) {\n console.info('[ocosay] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u6B63\u5728\u521B\u5EFA\u9ED8\u8BA4\u914D\u7F6E...')\n const defaultConfig = generateDefaultConfig()\n const configContent = JSON.stringify(defaultConfig, null, 2)\n try {\n fs.writeFileSync(CONFIG_PATH, configContent, 'utf-8')\n try {\n fs.chmodSync(CONFIG_PATH, 0o600)\n } catch (err) {\n console.warn(`[ocosay] \u65E0\u6CD5\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6\u6743\u9650: ${err}`)\n }\n } catch (err) {\n throw new Error(`[ocosay] \u65E0\u6CD5\u5199\u5165\u914D\u7F6E\u6587\u4EF6 ${CONFIG_PATH}: ${err}`)\n }\n console.info(`[ocosay] \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: ${CONFIG_PATH}`)\n console.info('[ocosay] \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u586B\u5165 API Key \u548C Base URL')\n return defaultConfig\n }\n\n try {\n const content = fs.readFileSync(CONFIG_PATH, 'utf-8')\n const stripped = stripComments(content)\n const loaded = JSON.parse(stripped) as Partial<OcosayConfig>\n\n const merged = mergeWithDefaults(loaded, DEFAULT_CONFIG)\n\n return {\n ...merged,\n providers: {\n minimax: {\n apiKey: loaded.providers?.minimax?.apiKey ?? '',\n baseURL: loaded.providers?.minimax?.baseURL ?? '',\n voiceId: loaded.providers?.minimax?.voiceId ?? '',\n model: loaded.providers?.minimax?.model ?? 'stream',\n ttsModel: loaded.providers?.minimax?.ttsModel ?? 'speech-2.8-hd',\n audioFormat: loaded.providers?.minimax?.audioFormat ?? 'mp3'\n }\n }\n }\n } catch (error) {\n console.error('[ocosay] \u914D\u7F6E\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E:', error)\n return generateDefaultConfig()\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { tool } from '@opencode-ai/plugin'\nimport type { Plugin, PluginInput, PluginOptions } from '@opencode-ai/plugin'\nimport { handleToolCall } from './index'\nimport { initialize, destroy } from './index'\nimport { loadOrCreateConfig } from './config'\n\nconst pluginName = 'ocosay'\n\nconst ttsSpeakTool = tool({\n description: '\u5C06\u6587\u672C\u8F6C\u6362\u4E3A\u8BED\u97F3\u5E76\u64AD\u653E',\n args: {\n text: tool.schema.string().describe('\u8981\u8F6C\u6362\u7684\u6587\u672C\u5185\u5BB9'),\n provider: tool.schema.string().optional().describe('TTS \u63D0\u4F9B\u5546\u540D\u79F0'),\n voice: tool.schema.string().optional().describe('\u97F3\u8272 ID'),\n model: tool.schema.enum(['sync', 'async', 'stream']).optional().describe('\u5408\u6210\u6A21\u5F0F'),\n speed: tool.schema.number().optional().describe('\u8BED\u901F 0.5-2.0'),\n volume: tool.schema.number().optional().describe('\u97F3\u91CF 0-100'),\n pitch: tool.schema.number().optional().describe('\u97F3\u8C03 0.5-2.0')\n },\n execute: async (args) => {\n const result = await handleToolCall('tts_speak', args)\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStopTool = tool({\n description: '\u505C\u6B62\u5F53\u524D TTS \u64AD\u653E',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_stop')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsPauseTool = tool({\n description: '\u6682\u505C\u5F53\u524D TTS \u64AD\u653E',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_pause')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsResumeTool = tool({\n description: '\u6062\u590D\u6682\u505C\u7684 TTS \u64AD\u653E',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_resume')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsListVoicesTool = tool({\n description: '\u5217\u51FA\u53EF\u7528\u7684\u97F3\u8272',\n args: {\n provider: tool.schema.string().optional().describe('TTS \u63D0\u4F9B\u5546\u540D\u79F0')\n },\n execute: async (args) => {\n const result = await handleToolCall('tts_list_voices', args)\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsListProvidersTool = tool({\n description: '\u5217\u51FA\u6240\u6709\u5DF2\u6CE8\u518C\u7684 TTS \u63D0\u4F9B\u5546',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_list_providers')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStatusTool = tool({\n description: '\u83B7\u53D6\u5F53\u524D TTS \u64AD\u653E\u72B6\u6001',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_status')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStreamSpeakTool = tool({\n description: '\u542F\u52A8\u6D41\u5F0F\u6717\u8BFB\uFF08\u8C46\u5305\u6A21\u5F0F\uFF09\uFF0C\u8BA2\u9605AI\u56DE\u590D\u5E76\u8FB9\u751F\u6210\u8FB9\u6717\u8BFB',\n args: {\n text: tool.schema.string().optional().describe('\u521D\u59CB\u6587\u672C\uFF08\u53EF\u9009\uFF09'),\n voice: tool.schema.string().optional().describe('\u97F3\u8272ID'),\n model: tool.schema.enum(['sync', 'async', 'stream']).optional().describe('\u5408\u6210\u6A21\u5F0F')\n },\n execute: async (args) => {\n const result = await handleToolCall('tts_stream_speak', args)\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStreamStopTool = tool({\n description: '\u505C\u6B62\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_stream_stop')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return result\n }\n})\n\nconst ttsStreamStatusTool = tool({\n description: '\u83B7\u53D6\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB\u72B6\u6001',\n args: {},\n execute: async () => {\n const result = await handleToolCall('tts_stream_status')\n if (result.success === false) {\n throw new Error(result.error || 'Unknown error')\n }\n return typeof result === 'string' ? result : JSON.stringify(result)\n }\n})\n\nconst OcosayPlugin: Plugin = async (_input: PluginInput, _options?: PluginOptions) => {\n console.info(`${pluginName}: initializing...`)\n\n const config = loadOrCreateConfig()\n\n await initialize({\n autoRead: config.autoRead,\n providers: {\n minimax: {\n apiKey: config.providers.minimax.apiKey,\n baseURL: config.providers.minimax.baseURL || undefined,\n voiceId: config.providers.minimax.voiceId || undefined\n }\n }\n })\n\n return {\n tool: {\n tts_speak: ttsSpeakTool,\n tts_stop: ttsStopTool,\n tts_pause: ttsPauseTool,\n tts_resume: ttsResumeTool,\n tts_list_voices: ttsListVoicesTool,\n tts_list_providers: ttsListProvidersTool,\n tts_status: ttsStatusTool,\n tts_stream_speak: ttsStreamSpeakTool,\n tts_stream_stop: ttsStreamStopTool,\n tts_stream_status: ttsStreamStatusTool\n },\n config: async () => {\n return\n }\n }\n}\n\nexport const server = OcosayPlugin\nexport default OcosayPlugin\n", "/**\n * Speaker - TTS \u7EDF\u4E00\u8C03\u7528\u5165\u53E3\n * \u63D0\u4F9B\u7B80\u6D01\u7684 API \u548C\u4FBF\u6377\u51FD\u6570\n */\n\nimport { EventEmitter } from 'events'\nimport { \n TTSProvider, \n TTSError, \n TTSErrorCode,\n SpeakOptions,\n AudioResult,\n Voice,\n TTSEvent,\n SynthesisModel\n} from './types'\nimport { getProvider, listProviders, hasProvider } from '../providers/base'\nimport { AudioPlayer, PlayerEvents } from './player'\n\nexport interface SpeakerOptions {\n defaultProvider?: string\n defaultModel?: SynthesisModel\n defaultVoice?: string\n onEvent?: (event: TTSEvent, data?: any) => void\n}\n\n/**\n * Speaker - TTS \u7EDF\u4E00\u8C03\u7528\u5165\u53E3\u7C7B\n * \u5C01\u88C5 Provider \u548C Player\uFF0C\u63D0\u4F9B\u7B80\u6D01\u7684 speak/pause/resume/stop API\n */\nexport class Speaker extends EventEmitter {\n private currentProvider?: TTSProvider\n private player?: AudioPlayer\n private currentText?: string\n private isSpeaking = false\n private isPaused = false\n \n constructor(private options: SpeakerOptions = {}) {\n super()\n \n // \u521D\u59CB\u5316\u64AD\u653E\u5668\n const playerEvents: PlayerEvents = {\n onStart: () => this.emit('start', this.currentText),\n onEnd: () => {\n this.isSpeaking = false\n this.emit('end', this.currentText)\n },\n onError: (error) => this.emit('error', error),\n onPause: () => {\n this.isPaused = true\n this.emit('pause')\n },\n onResume: () => {\n this.isPaused = false\n this.emit('resume')\n },\n onStop: () => {\n this.isSpeaking = false\n this.isPaused = false\n this.emit('stop')\n }\n }\n \n this.player = new AudioPlayer(playerEvents)\n }\n \n /**\n * \u8BF4\u8BDD - \u6838\u5FC3\u65B9\u6CD5\n * @param text \u8981\u8BF4\u7684\u6587\u672C\n * @param options \u53EF\u9009\u53C2\u6570\n */\n async speak(\n text: string, \n options: SpeakOptions & { provider?: string } = {}\n ): Promise<void> {\n // \u53C2\u6570\u6821\u9A8C\n if (!text || text.trim().length === 0) {\n throw new TTSError(\n 'Text cannot be empty',\n TTSErrorCode.INVALID_PARAMS,\n 'speaker'\n )\n }\n \n // \u505C\u6B62\u5F53\u524D\u64AD\u653E\n if (this.isSpeaking) {\n await this.stop()\n }\n \n this.isSpeaking = true\n this.currentText = text\n \n try {\n // \u83B7\u53D6 provider\n const providerName = options.provider || this.options.defaultProvider || 'minimax'\n if (!hasProvider(providerName)) {\n throw new TTSError(\n `Provider \"${providerName}\" not found`,\n TTSErrorCode.UNKNOWN,\n 'speaker'\n )\n }\n \n this.currentProvider = getProvider(providerName)\n \n // \u8C03\u7528 provider \u751F\u6210\u97F3\u9891\n const result = await this.currentProvider.speak(text, {\n model: options.model || this.options.defaultModel || 'stream',\n voice: options.voice || this.options.defaultVoice,\n speed: options.speed,\n volume: options.volume,\n pitch: options.pitch,\n sourceVoice: options.sourceVoice\n })\n \n // \u64AD\u653E\u97F3\u9891\n if (this.player) {\n await this.player.play(result.audioData, result.format)\n }\n \n } catch (error) {\n this.isSpeaking = false\n if (error instanceof TTSError) {\n this.emit('error', error)\n throw error\n }\n const ttsError = new TTSError(\n 'Speak failed',\n TTSErrorCode.UNKNOWN,\n 'speaker',\n error\n )\n this.emit('error', ttsError)\n throw ttsError\n }\n }\n \n /**\n * \u6682\u505C\u64AD\u653E\n */\n pause(): void {\n if (this.player && this.isSpeaking && !this.isPaused) {\n this.player.pause()\n }\n }\n \n /**\n * \u6062\u590D\u64AD\u653E\n */\n resume(): void {\n if (this.player && this.isPaused) {\n this.player.resume()\n }\n }\n \n /**\n * \u505C\u6B62\u64AD\u653E\n */\n async stop(): Promise<void> {\n this.isSpeaking = false\n this.isPaused = false\n \n if (this.player) {\n await this.player.stop()\n }\n }\n \n /**\n * \u9500\u6BC1 Speaker\uFF0C\u91CA\u653E\u8D44\u6E90\n */\n async destroy(): Promise<void> {\n this.isSpeaking = false\n this.isPaused = false\n \n if (this.player) {\n await this.player.stop()\n this.player = undefined\n }\n \n this.currentProvider = undefined\n this.currentText = undefined\n }\n \n /**\n * \u5217\u51FA\u53EF\u7528\u97F3\u8272\n */\n async listVoices(providerName?: string): Promise<Voice[]> {\n const name = providerName || this.options.defaultProvider || 'minimax'\n const provider = getProvider(name)\n return provider.listVoices()\n }\n \n /**\n * \u83B7\u53D6 Provider \u80FD\u529B\n */\n getCapabilities(providerName?: string) {\n const name = providerName || this.options.defaultProvider || 'minimax'\n const provider = getProvider(name)\n return provider.getCapabilities()\n }\n \n /**\n * \u83B7\u53D6\u6240\u6709\u5DF2\u6CE8\u518C\u7684 Provider\n */\n getProviders(): string[] {\n return listProviders()\n }\n \n /**\n * \u662F\u5426\u6B63\u5728\u64AD\u653E\n */\n isPlaying(): boolean {\n return this.isSpeaking && !this.isPaused\n }\n \n /**\n * \u662F\u5426\u6682\u505C\n */\n isPausedState(): boolean {\n return this.isPaused\n }\n}\n\n// ============================================================================\n// \u4FBF\u6377\u51FD\u6570 - \u9ED8\u8BA4 Speaker \u5B9E\u4F8B\n// ============================================================================\n\nlet defaultSpeaker: Speaker | undefined\n\n/**\n * \u83B7\u53D6\u9ED8\u8BA4 Speaker \u5B9E\u4F8B\uFF08\u5355\u4F8B\uFF09\n */\nexport function getDefaultSpeaker(): Speaker {\n if (!defaultSpeaker) {\n defaultSpeaker = new Speaker()\n }\n return defaultSpeaker\n}\n\n/**\n * \u8BF4\u8BDD\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport async function speak(\n text: string, \n options?: SpeakOptions & { provider?: string }\n): Promise<void> {\n const speaker = getDefaultSpeaker()\n return speaker.speak(text, options)\n}\n\n/**\n * \u505C\u6B62\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport async function stop(): Promise<void> {\n const speaker = getDefaultSpeaker()\n return speaker.stop()\n}\n\n/**\n * \u6682\u505C\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport function pause(): void {\n const speaker = getDefaultSpeaker()\n speaker.pause()\n}\n\n/**\n * \u6062\u590D\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport function resume(): void {\n const speaker = getDefaultSpeaker()\n speaker.resume()\n}\n\n/**\n * \u5217\u51FA\u97F3\u8272\uFF08\u4FBF\u6377\u51FD\u6570\uFF09\n */\nexport async function listVoices(providerName?: string): Promise<Voice[]> {\n const speaker = getDefaultSpeaker()\n return speaker.listVoices(providerName)\n}\n\nexport default Speaker\n", "/**\n * TTS Core Types\n * \u6838\u5FC3\u7C7B\u578B\u5B9A\u4E49\n */\n\nexport enum TTSErrorCode {\n NETWORK = 'NETWORK',\n AUTH = 'AUTH',\n QUOTA = 'QUOTA',\n INVALID_VOICE = 'INVALID_VOICE',\n INVALID_PARAMS = 'INVALID_PARAMS',\n PLAYER_ERROR = 'PLAYER_ERROR',\n UNKNOWN = 'UNKNOWN'\n}\n\nexport class TTSError extends Error {\n constructor(\n message: string,\n code: TTSErrorCode,\n provider: string,\n details?: unknown\n ) {\n super(message)\n this.name = 'TTSError'\n this.code = code\n this.provider = provider\n this.details = details\n }\n \n code: TTSErrorCode\n provider: string\n details?: unknown\n}\n\nexport interface Voice {\n id: string\n name: string\n language?: string\n gender?: 'male' | 'female' | 'neutral'\n previewUrl?: string\n}\n\nexport interface TTSCapabilities {\n speak: true\n voiceClone?: boolean\n stream?: boolean\n voiceList?: boolean\n sync?: boolean\n async?: boolean\n}\n\nexport type SynthesisModel = 'sync' | 'async' | 'stream'\n\nexport interface SpeakOptions {\n voice?: string\n model?: SynthesisModel\n speed?: number\n volume?: number\n pitch?: number\n sourceVoice?: string\n}\n\nexport interface AudioResult {\n audioData: Buffer | ReadableStream\n sampleRate?: number\n channels?: number\n duration?: number\n format: string\n isStream: boolean\n}\n\nexport type TTSEvent = \n | 'start'\n | 'end'\n | 'error'\n | 'progress'\n | 'pause'\n | 'resume'\n | 'stop'\n\nexport interface SpeakerEvents {\n on(event: 'start', handler: (text: string) => void): void\n on(event: 'end', handler: (text: string) => void): void\n on(event: 'error', handler: (error: TTSError) => void): void\n on(event: 'progress', handler: (progress: { current: number; total: number }) => void): void\n on(event: 'pause', handler: () => void): void\n on(event: 'resume', handler: () => void): void\n on(event: 'stop', handler: () => void): void\n off(event: TTSEvent, handler: Function): void\n}\n\nexport interface TTSProvider {\n name: string\n capabilities: TTSCapabilities\n \n initialize(): Promise<void>\n destroy(): Promise<void>\n \n speak(text: string, options?: SpeakOptions): Promise<AudioResult>\n pause(): Promise<void>\n resume(): Promise<void>\n stop(): Promise<void>\n listVoices(): Promise<Voice[]>\n \n getCapabilities(): TTSCapabilities\n}\n\n// ============================================================================\n// \u914D\u7F6E\u76F8\u5173\u7C7B\u578B\n// ============================================================================\n\nexport interface GlobalConfig {\n defaultProvider: string\n defaultModel?: SynthesisModel\n defaultVoice?: string\n}\n\nexport interface ProviderConfig {\n enabled?: boolean\n apiKey?: string\n [key: string]: unknown\n}\n\nexport interface OcosayConfig {\n enabled?: boolean\n autoPlay?: boolean\n autoRead?: boolean\n streamMode?: boolean\n streamBufferSize?: number\n streamBufferTimeout?: number\n provider?: string\n ttsModel?: string\n baseURL?: string\n speed?: number\n volume?: number\n pitch?: number\n}\n\n// ============================================================================\n// \u6D41\u5F0F\u6717\u8BFB\u76F8\u5173\u7C7B\u578B\n// ============================================================================\n\nexport enum StreamState {\n IDLE = 'idle',\n BUFFERING = 'buffering',\n STREAMING = 'streaming',\n ENDED = 'ended'\n}\n\nexport interface OcosayStreamConfig {\n enabled: boolean\n autoPlay: boolean\n autoRead: boolean\n streamMode: boolean\n streamBufferSize: number\n streamBufferTimeout: number\n provider: string\n voiceId?: string\n ttsModel?: string\n baseURL?: string\n speed?: number\n volume?: number\n pitch?: number\n apiKey?: string\n}\n\nexport interface StreamReaderEvents {\n onTextReady: (text: string) => void\n onStreamStart: () => void\n onStreamEnd: () => void\n onStreamError: (error: TTSError) => void\n}\n\nexport interface StreamingSynthesizerOptions {\n provider: TTSProvider\n voice?: string\n speed?: number\n volume?: number\n pitch?: number\n}\n\nexport interface StreamPlayerOptions {\n format?: 'mp3' | 'wav' | 'flac'\n onProgress?: (bytesReceived: number) => void\n}\n", "/**\n * TTS Provider Base Class and Registry\n * Provider \u57FA\u7C7B\u548C\u6CE8\u518C\u673A\u5236\n */\n\nimport { TTSProvider, TTSError, TTSErrorCode, Voice, TTSCapabilities, SpeakOptions, AudioResult } from '../core/types'\n\n// Provider \u6CE8\u518C\u8868\nconst providers = new Map<string, TTSProvider>()\n\n/**\n * \u6CE8\u518C TTS Provider\n */\nexport function registerProvider(name: string, provider: TTSProvider): void {\n if (providers.has(name)) {\n throw new TTSError(\n `Provider \"${name}\" is already registered`,\n TTSErrorCode.UNKNOWN,\n 'system'\n )\n }\n providers.set(name, provider)\n}\n\n/**\n * \u83B7\u53D6 TTS Provider\n */\nexport function getProvider(name: string): TTSProvider {\n const provider = providers.get(name)\n if (!provider) {\n throw new TTSError(\n `TTS Provider \"${name}\" not found`,\n TTSErrorCode.UNKNOWN,\n 'system'\n )\n }\n return provider\n}\n\n/**\n * \u83B7\u53D6\u6240\u6709\u5DF2\u6CE8\u518C\u7684 Provider \u540D\u79F0\n */\nexport function listProviders(): string[] {\n return Array.from(providers.keys())\n}\n\n/**\n * \u68C0\u67E5 Provider \u662F\u5426\u5DF2\u6CE8\u518C\n */\nexport function hasProvider(name: string): boolean {\n return providers.has(name)\n}\n\n/**\n * \u6CE8\u9500 Provider\n */\nexport function unregisterProvider(name: string): boolean {\n return providers.delete(name)\n}\n\n/**\n * Provider \u62BD\u8C61\u57FA\u7C7B\uFF0C\u63D0\u4F9B\u901A\u7528\u5B9E\u73B0\n */\nexport abstract class BaseTTSProvider implements TTSProvider {\n abstract name: string\n abstract capabilities: TTSCapabilities\n \n protected apiKey?: string\n protected defaultVoice?: string\n protected defaultModel: 'sync' | 'async' | 'stream' = 'stream'\n \n async initialize(): Promise<void> {\n // \u5B50\u7C7B\u53EFoverride\n }\n \n async destroy(): Promise<void> {\n // \u5B50\u7C7B\u53EFoverride\n }\n \n /**\n * \u901A\u7528 speak \u5B9E\u73B0\uFF0C\u5904\u7406\u901A\u7528\u903B\u8F91\n */\n async speak(text: string, options?: SpeakOptions): Promise<AudioResult> {\n if (!text || text.trim().length === 0) {\n throw new TTSError(\n 'Text cannot be empty',\n TTSErrorCode.INVALID_PARAMS,\n this.name\n )\n }\n \n const voice = options?.voice || this.defaultVoice\n const model = options?.model || this.defaultModel\n \n return this.doSpeak(text, voice, model, options)\n }\n \n /**\n * \u5B50\u7C7B\u5B9E\u73B0\u7684\u5B9E\u9645 speak \u903B\u8F91\n */\n protected abstract doSpeak(\n text: string, \n voice: string | undefined, \n model: 'sync' | 'async' | 'stream',\n options?: SpeakOptions\n ): Promise<AudioResult>\n \n pause(): Promise<void> {\n throw new TTSError(\n 'Pause is not supported by this provider',\n TTSErrorCode.UNKNOWN,\n this.name\n )\n }\n \n resume(): Promise<void> {\n throw new TTSError(\n 'Resume is not supported by this provider',\n TTSErrorCode.UNKNOWN,\n this.name\n )\n }\n \n stop(): Promise<void> {\n // \u9ED8\u8BA4\u7A7A\u5B9E\u73B0\n return Promise.resolve()\n }\n \n async listVoices(): Promise<Voice[]> {\n // \u9ED8\u8BA4\u8FD4\u56DE\u7A7A\u6570\u7EC4\uFF0C\u5B50\u7C7B\u53EFoverride\n return []\n }\n \n getCapabilities(): TTSCapabilities {\n return this.capabilities\n }\n \n /**\n * \u9A8C\u8BC1 API Key\n */\n protected validateApiKey(): void {\n if (!this.apiKey) {\n throw new TTSError(\n `API key is required for provider \"${this.name}\"`,\n TTSErrorCode.AUTH,\n this.name\n )\n }\n }\n}\n", "/**\n * Audio Player Module\n * \u97F3\u9891\u64AD\u653E\u5F15\u64CE - \u652F\u6301 pause/resume/stop \u548C\u6D41\u5F0F\u64AD\u653E\n */\n\nimport { EventEmitter } from 'events'\nimport { spawn, ChildProcess } from 'child_process'\nimport fs from 'fs'\nimport { createWriteStream } from 'fs'\nimport { tmpdir } from 'os'\nimport { join } from 'path'\nimport { TTSError, TTSErrorCode } from './types'\n\n/**\n * Player Events - \u64AD\u653E\u4E8B\u4EF6\u56DE\u8C03\u63A5\u53E3\n */\nexport interface PlayerEvents {\n onStart?: () => void\n onEnd?: () => void\n onError?: (error: Error) => void\n onProgress?: (progress: { current: number; total: number }) => void\n onPause?: () => void\n onResume?: () => void\n onStop?: () => void\n}\n\n/**\n * Player \u63A5\u53E3 - \u97F3\u9891\u64AD\u653E\u5668\u6807\u51C6\u63A5\u53E3\n */\nexport interface Player {\n play(audioData: Buffer | ReadableStream, format: string): Promise<void>\n pause(): void\n resume(): void\n stop(): void\n isPlaying(): boolean\n isPaused(): boolean\n}\n\n/**\n * AudioPlayer - \u57FA\u4E8E\u7CFB\u7EDF\u64AD\u653E\u5668\u7684\u97F3\u9891\u64AD\u653E\u5B9E\u73B0\n * \u652F\u6301 macOS (afplay), Linux (aplay), Windows (PowerShell)\n */\nexport class AudioPlayer extends EventEmitter implements Player {\n private _playing = false\n private _paused = false\n private currentProcess?: ChildProcess\n private currentFile?: string\n\n constructor(protected events?: PlayerEvents) {\n super()\n }\n\n /**\n * \u64AD\u653E\u97F3\u9891\n * @param audioData \u97F3\u9891\u6570\u636E (Buffer \u6216 ReadableStream)\n * @param format \u97F3\u9891\u683C\u5F0F (mp3, wav, etc.)\n */\n async play(audioData: Buffer | ReadableStream, format: string): Promise<void> {\n // \u5982\u679C\u6B63\u5728\u64AD\u653E\uFF0C\u5148\u505C\u6B62\n if (this._playing) {\n await this.stop()\n }\n\n this._playing = true\n this._paused = false\n\n try {\n // \u5C06\u97F3\u9891\u6570\u636E\u5199\u5165\u4E34\u65F6\u6587\u4EF6\n const tempFile = join(tmpdir(), `ocosay-${Date.now()}.${format}`)\n this.currentFile = tempFile\n\n if (Buffer.isBuffer(audioData)) {\n fs.writeFileSync(tempFile, audioData)\n } else {\n const writeStream = createWriteStream(tempFile)\n const reader = audioData.getReader()\n \n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n if (value instanceof Uint8Array) {\n writeStream.write(Buffer.from(value))\n }\n }\n writeStream.end()\n } finally {\n reader.releaseLock()\n }\n \n await new Promise<void>((resolve, reject) => {\n writeStream.on('finish', resolve)\n writeStream.on('error', reject)\n })\n }\n\n // \u89E6\u53D1\u5F00\u59CB\u4E8B\u4EF6\n this.events?.onStart?.()\n this.emit('start')\n\n // \u6839\u636E\u683C\u5F0F\u9009\u62E9\u64AD\u653E\u5668\n await this.playFile(tempFile, format)\n\n // \u64AD\u653E\u5B8C\u6210\n this._playing = false\n this.events?.onEnd?.()\n this.emit('end')\n\n // \u6E05\u7406\u4E34\u65F6\u6587\u4EF6\n this.cleanup()\n\n } catch (error: any) {\n this._playing = false\n const ttsError = new TTSError(\n error.message || 'Playback failed',\n TTSErrorCode.PLAYER_ERROR,\n 'player'\n )\n this.events?.onError?.(ttsError)\n this.emit('error', ttsError)\n throw ttsError\n }\n }\n\n /**\n * \u64AD\u653E\u97F3\u9891\u6587\u4EF6\n * \u4F18\u5148\u4F7F\u7528 afplay (macOS), aplay (Linux), \u5426\u5219\u7528 PowerShell (Windows)\n */\n private playFile(filePath: string, format: string): Promise<void> {\n const platform = process.platform\n\n return new Promise((resolve, reject) => {\n let command: string\n let args: string[]\n\n if (platform === 'darwin') {\n // macOS\n command = 'afplay'\n args = [filePath]\n } else if (platform === 'linux') {\n // Linux\n command = 'aplay'\n args = [filePath]\n } else {\n // Windows \u6216\u5176\u4ED6\n command = 'powershell'\n args = ['-c', `(New-Object System.Media.SoundPlayer('${filePath.replace(/\\\\/g, '\\\\\\\\')}')).PlaySync()`]\n }\n\n this.currentProcess = spawn(command, args, {\n stdio: 'ignore',\n detached: false\n })\n\n this.currentProcess.on('exit', (code: number | null, signal: string | null) => {\n // \u5982\u679C\u662F\u88AB\u4FE1\u53F7\u7EC8\u6B62\uFF08\u5982 SIGTERM\uFF09\uFF0C\u4E0D\u5F53\u4F5C\u9519\u8BEF\n if (signal === 'SIGTERM' || signal === 'SIGINT') {\n resolve()\n } else if (code === 0) {\n resolve()\n } else {\n reject(new Error(`Player exited with code ${code}`))\n }\n })\n\n this.currentProcess.on('error', (error: Error) => {\n reject(error)\n })\n })\n }\n\n /**\n * \u6682\u505C\u64AD\u653E\n * \u6CE8\u610F: \u76EE\u524D\u901A\u8FC7 SIGSTOP \u5B9E\u73B0\uFF0C\u771F\u6B63\u7684 pause \u9700\u8981\u652F\u6301\u6682\u505C\u7684\u97F3\u9891\u5E93\n */\n pause(): void {\n if (!this._playing || this._paused) return\n\n if (this.currentProcess) {\n try {\n this.currentProcess.kill('SIGSTOP')\n this._paused = true\n this.events?.onPause?.()\n this.emit('pause')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u6062\u590D\u64AD\u653E\n */\n resume(): void {\n if (!this._playing || !this._paused) return\n\n if (this.currentProcess) {\n try {\n this.currentProcess.kill('SIGCONT')\n this._paused = false\n this.events?.onResume?.()\n this.emit('resume')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u505C\u6B62\u64AD\u653E\n */\n async stop(): Promise<void> {\n this._playing = false\n this._paused = false\n\n if (this.currentProcess) {\n try {\n this.currentProcess.kill('SIGTERM')\n } catch (e) {\n // \u5FFD\u7565\u9519\u8BEF\n }\n this.currentProcess = undefined\n }\n\n this.cleanup()\n\n this.events?.onStop?.()\n this.emit('stop')\n }\n\n /**\n * \u662F\u5426\u6B63\u5728\u64AD\u653E\n */\n isPlaying(): boolean {\n return this._playing\n }\n\n /**\n * \u662F\u5426\u6682\u505C\n */\n isPaused(): boolean {\n return this._paused\n }\n\n /**\n * \u6E05\u7406\u4E34\u65F6\u6587\u4EF6\n */\n private cleanup(): void {\n if (this.currentFile) {\n try {\n if (fs.existsSync(this.currentFile)) {\n fs.unlinkSync(this.currentFile)\n }\n } catch (e) {\n // \u5FFD\u7565\u6E05\u7406\u9519\u8BEF\n }\n this.currentFile = undefined\n }\n }\n}\n\n/**\n * StreamingPlayer - \u6D41\u5F0F\u64AD\u653E\u5668\uFF0C\u652F\u6301\u8FB9\u4E0B\u8F7D\u8FB9\u64AD\u653E\n * \u6CE8\u610F: \u5F53\u524D\u5B9E\u73B0\u662F\u4E0B\u8F7D\u5B8C\u6BD5\u540E\u518D\u64AD\u653E\uFF0ConProgress \u4E8B\u4EF6\u7528\u4E8E\u62A5\u544A\u4E0B\u8F7D\u8FDB\u5EA6\n */\nexport class StreamingPlayer extends AudioPlayer {\n private chunks: Buffer[] = []\n private downloadedSize = 0\n\n constructor(events?: PlayerEvents) {\n super(events)\n }\n\n /**\n * \u6D41\u5F0F\u4E0B\u8F7D\u5E76\u64AD\u653E\n * @param stream \u53EF\u8BFB\u6D41\n * @param format \u97F3\u9891\u683C\u5F0F\n * @param expectedSize \u9884\u671F\u5927\u5C0F\uFF08\u53EF\u9009\uFF09\uFF0C\u7528\u4E8E\u8FDB\u5EA6\u62A5\u544A\n */\n async streamAndPlay(\n stream: ReadableStream,\n format: string,\n expectedSize?: number\n ): Promise<void> {\n const reader = stream.getReader()\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n if (value instanceof Buffer) {\n this.chunks.push(value)\n this.downloadedSize += value.length\n\n // \u89E6\u53D1\u4E0B\u8F7D\u8FDB\u5EA6\n if (expectedSize) {\n this.emit('progress', {\n current: this.downloadedSize,\n total: expectedSize\n })\n this.events?.onProgress?.({\n current: this.downloadedSize,\n total: expectedSize\n })\n }\n }\n }\n\n // \u5408\u5E76\u6240\u6709 chunk \u5E76\u64AD\u653E\n const fullAudio = Buffer.concat(this.chunks)\n await this.play(fullAudio, format)\n\n } finally {\n reader.releaseLock()\n this.chunks = []\n this.downloadedSize = 0\n }\n }\n}\n\nexport default AudioPlayer\n", "/**\n * OpenCode TTS \u5DE5\u5177\u5B9A\u4E49\n * \u7528\u4E8E OpenCode Plugin \u6CE8\u518C\n */\n\nimport { speak, stop, pause, resume, listVoices, getDefaultSpeaker } from '../core/speaker'\nimport { TTSError, TTSErrorCode } from '../core/types'\nimport { \n isStreamEnabled, \n isAutoReadEnabled,\n getStreamStatus, \n getStreamReader, \n getStreamingSynthesizer,\n getStreamPlayer \n} from '../index'\n\n/**\n * OpenCode TTS \u5DE5\u5177\u5B9A\u4E49\n * \u7528\u4E8E OpenCode Plugin \u6CE8\u518C\n */\nexport const ttsTools = [\n {\n name: 'tts_speak',\n description: '\u5C06\u6587\u672C\u8F6C\u6362\u4E3A\u8BED\u97F3\u5E76\u64AD\u653E',\n input: {\n type: 'object',\n properties: {\n text: { \n type: 'string', \n description: '\u8981\u8F6C\u6362\u7684\u6587\u672C\u5185\u5BB9' \n },\n provider: { \n type: 'string', \n description: 'TTS \u63D0\u4F9B\u5546\u540D\u79F0',\n default: 'minimax'\n },\n voice: { \n type: 'string', \n description: '\u97F3\u8272 ID' \n },\n model: { \n type: 'string', \n enum: ['sync', 'async', 'stream'],\n description: '\u5408\u6210\u6A21\u5F0F',\n default: 'stream'\n },\n speed: { \n type: 'number', \n description: '\u8BED\u901F 0.5-2.0' \n },\n volume: { \n type: 'number', \n description: '\u97F3\u91CF 0-100' \n },\n pitch: { \n type: 'number', \n description: '\u97F3\u8C03 0.5-2.0' \n }\n },\n required: ['text']\n }\n },\n {\n name: 'tts_stop',\n description: '\u505C\u6B62\u5F53\u524D TTS \u64AD\u653E'\n },\n {\n name: 'tts_pause',\n description: '\u6682\u505C\u5F53\u524D TTS \u64AD\u653E'\n },\n {\n name: 'tts_resume',\n description: '\u6062\u590D\u6682\u505C\u7684 TTS \u64AD\u653E'\n },\n {\n name: 'tts_list_voices',\n description: '\u5217\u51FA\u53EF\u7528\u7684\u97F3\u8272',\n input: {\n type: 'object',\n properties: {\n provider: { \n type: 'string', \n description: 'TTS \u63D0\u4F9B\u5546\u540D\u79F0',\n default: 'minimax'\n }\n }\n }\n },\n {\n name: 'tts_list_providers',\n description: '\u5217\u51FA\u6240\u6709\u5DF2\u6CE8\u518C\u7684 TTS \u63D0\u4F9B\u5546'\n },\n {\n name: 'tts_status',\n description: '\u83B7\u53D6\u5F53\u524D TTS \u64AD\u653E\u72B6\u6001',\n output: {\n type: 'object',\n properties: {\n isPlaying: { type: 'boolean' },\n isPaused: { type: 'boolean' }\n }\n }\n },\n {\n name: 'tts_stream_speak',\n description: '\u542F\u52A8\u6D41\u5F0F\u6717\u8BFB\uFF08\u8C46\u5305\u6A21\u5F0F\uFF09\uFF0C\u8BA2\u9605AI\u56DE\u590D\u5E76\u8FB9\u751F\u6210\u8FB9\u6717\u8BFB',\n input: {\n type: 'object',\n properties: {\n text: { \n type: 'string', \n description: '\u521D\u59CB\u6587\u672C\uFF08\u53EF\u9009\uFF09' \n },\n voice: { \n type: 'string', \n description: '\u97F3\u8272ID' \n },\n model: { \n type: 'string', \n enum: ['sync', 'async', 'stream'], \n default: 'stream' \n }\n }\n }\n },\n {\n name: 'tts_stream_stop',\n description: '\u505C\u6B62\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB'\n },\n {\n name: 'tts_stream_status',\n description: '\u83B7\u53D6\u5F53\u524D\u6D41\u5F0F\u6717\u8BFB\u72B6\u6001',\n output: {\n type: 'object',\n properties: {\n isActive: { type: 'boolean' },\n bytesWritten: { type: 'number' },\n state: { type: 'string' }\n }\n }\n }\n]\n\n/**\n * \u5DE5\u5177\u6267\u884C\u5904\u7406\u5668\n */\nexport async function handleToolCall(\n toolName: string, \n args?: Record<string, any>\n): Promise<any> {\n try {\n switch (toolName) {\n case 'tts_speak':\n await speak(args?.text, {\n provider: args?.provider,\n voice: args?.voice,\n model: args?.model,\n speed: args?.speed,\n volume: args?.volume,\n pitch: args?.pitch\n })\n return { success: true, message: 'Speech completed' }\n \n case 'tts_stop':\n await stop()\n return { success: true, message: 'Stopped' }\n \n case 'tts_pause':\n pause()\n return { success: true, message: 'Paused' }\n \n case 'tts_resume':\n resume()\n return { success: true, message: 'Resumed' }\n \n case 'tts_list_voices':\n const voices = await listVoices(args?.provider as string | undefined)\n return { success: true, voices }\n \n case 'tts_list_providers':\n const speaker = getDefaultSpeaker()\n const providers = speaker.getProviders()\n return { success: true, providers }\n \n case 'tts_status':\n const s = getDefaultSpeaker()\n return {\n success: true,\n isPlaying: s.isPlaying(),\n isPaused: s.isPausedState()\n }\n \n case 'tts_stream_speak':\n if (!isAutoReadEnabled()) {\n throw new TTSError(\n 'Stream mode is not enabled. autoRead must be enabled in configuration to use tts_stream_speak.',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n }\n if (!isStreamEnabled()) {\n throw new TTSError(\n 'Stream components not initialized. Please initialize with autoRead enabled.',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n }\n const streamReader = getStreamReader()\n const synthesizer = getStreamingSynthesizer()\n if (streamReader && synthesizer) {\n streamReader.start()\n if (args?.text) {\n synthesizer.synthesize(args.text)\n }\n return { success: true, message: 'Stream speak started' }\n }\n throw new TTSError(\n 'Stream components not available',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n \n case 'tts_stream_stop':\n if (!isStreamEnabled()) {\n throw new TTSError(\n 'Stream mode is not enabled. Please enable autoRead in configuration.',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n }\n const player = getStreamPlayer()\n if (player) {\n player.stop()\n return { success: true, message: 'Stream stopped' }\n }\n throw new TTSError(\n 'Stream player not available',\n TTSErrorCode.UNKNOWN,\n 'tts_stream'\n )\n \n case 'tts_stream_status':\n if (!isStreamEnabled()) {\n return {\n success: true,\n isActive: false,\n bytesWritten: 0,\n state: 'not_initialized'\n }\n }\n return {\n success: true,\n ...getStreamStatus()\n }\n \n default:\n throw new TTSError(\n `Unknown tool: ${toolName}`,\n TTSErrorCode.UNKNOWN,\n 'tools'\n )\n }\n } catch (error) {\n if (error instanceof TTSError) {\n return {\n success: false,\n error: error.message,\n code: error.code,\n provider: error.provider\n }\n }\n return {\n success: false,\n error: String(error)\n }\n }\n}\n", "/**\n * MiniMax TTS Provider\n * \u652F\u6301 T2A v2 (\u540C\u6B65/\u6D41\u5F0FHTTP)\u3001T2A Async v2 (\u5F02\u6B65HTTP\u8F6E\u8BE2)\n * \u7AEF\u70B9\u53EF\u914D\u7F6E: baseURL (\u9ED8\u8BA4 https://api.minimaxi.com)\n */\n\nimport { BaseTTSProvider } from './base'\nimport {\n TTSError,\n TTSErrorCode,\n AudioResult,\n Voice,\n SpeakOptions\n} from '../core/types'\nimport axios, { AxiosInstance } from 'axios'\nimport { WebSocket } from 'ws'\n\nexport interface MiniMaxConfig {\n apiKey: string\n baseURL?: string\n voiceId?: string\n model?: 'sync' | 'async' | 'stream'\n ttsModel?: string\n audioFormat?: 'mp3' | 'wav' | 'flac'\n speed?: number\n volume?: number\n pitch?: number\n groupId?: string\n}\n\n/**\n * MiniMax TTS Provider\n * \u5B98\u7F51: https://www.minimax.io/\n * API\u6587\u6863: https://www.minimaxi.com/document/T2A\n */\nexport class MiniMaxProvider extends BaseTTSProvider {\n name = 'minimax'\n capabilities = {\n speak: true,\n stream: true,\n sync: true,\n async: true,\n voiceList: true,\n voiceClone: true\n } as const\n\n private config: MiniMaxConfig\n private httpClient: AxiosInstance\n private wsConnection?: WebSocket\n private currentAudioData: Buffer[] = []\n private audioFormat: 'mp3' | 'wav' | 'flac' = 'mp3'\n\n constructor(config: MiniMaxConfig) {\n super()\n this.config = config\n this.apiKey = config.apiKey\n this.defaultVoice = config.voiceId\n this.defaultModel = config.model || 'stream'\n this.audioFormat = config.audioFormat || 'mp3'\n\n this.httpClient = axios.create({\n baseURL: this.config.baseURL || 'https://api.minimaxi.com',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n },\n timeout: 30000\n })\n }\n\n async initialize(): Promise<void> {\n this.validateApiKey()\n }\n\n async destroy(): Promise<void> {\n if (this.wsConnection) {\n this.wsConnection.close()\n this.wsConnection = undefined\n }\n }\n\n protected async doSpeak(\n text: string,\n voice: string | undefined,\n model: 'sync' | 'async' | 'stream',\n options?: SpeakOptions\n ): Promise<AudioResult> {\n this.validateApiKey()\n\n switch (model) {\n case 'stream':\n return this.streamingSpeak(text, voice, options)\n case 'sync':\n return this.syncSpeak(text, voice, options)\n case 'async':\n return this.asyncSpeak(text, voice, options)\n default:\n return this.streamingSpeak(text, voice, options)\n }\n }\n\n /**\n * \u6D41\u5F0F\u5408\u6210 (HTTP) - T2A v2 with stream: true\n */\n private async streamingSpeak(\n text: string,\n voice: string | undefined,\n options?: SpeakOptions\n ): Promise<AudioResult> {\n try {\n const voiceId = voice || this.defaultVoice || 'male-qn-qingse'\n const speed = options?.speed || this.config.speed || 1.0\n const vol = options?.volume !== undefined ? options.volume / 10 : (this.config.volume !== undefined ? this.config.volume / 10 : 1.0)\n const pitch = options?.pitch !== undefined ? Math.round((options.pitch - 1) * 12) : (this.config.pitch !== undefined ? Math.round((this.config.pitch - 1) * 12) : 0)\n\n const response = await this.httpClient.post('/v1/t2a_v2', {\n model: this.config.ttsModel || 'speech-2.8-hd',\n text,\n stream: true,\n voice_setting: {\n voice_id: voiceId,\n speed: speed,\n vol: vol,\n pitch: pitch\n },\n audio_setting: {\n sample_rate: 32000,\n bitrate: 128000,\n format: this.audioFormat,\n channel: 1\n }\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n },\n responseType: 'stream'\n })\n\n const stream = response.data\n const audioChunks: Buffer[] = []\n\n return new Promise((resolve, reject) => {\n stream.on('data', (chunk: Buffer) => {\n try {\n const lines = chunk.toString().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data:')) {\n const data = JSON.parse(line.slice(5))\n if (data.data?.audio) {\n audioChunks.push(Buffer.from(data.data.audio, 'hex'))\n }\n if (data.data?.status === 2) {\n const fullAudio = Buffer.concat(audioChunks)\n resolve({\n audioData: fullAudio,\n format: this.audioFormat,\n isStream: true,\n duration: this.estimateDuration(fullAudio.length)\n })\n }\n }\n }\n } catch (e) {\n audioChunks.push(chunk)\n }\n })\n\n stream.on('error', (err: any) => {\n reject(new TTSError(\n 'Stream error',\n TTSErrorCode.NETWORK,\n this.name,\n err\n ))\n })\n\n stream.on('end', () => {\n if (audioChunks.length > 0) {\n const fullAudio = Buffer.concat(audioChunks)\n resolve({\n audioData: fullAudio,\n format: this.audioFormat,\n isStream: true,\n duration: this.estimateDuration(fullAudio.length)\n })\n }\n })\n })\n } catch (error: any) {\n if (error instanceof TTSError) throw error\n throw this.mapError(error)\n }\n }\n\n /**\n * \u540C\u6B65\u5408\u6210 (HTTP) - T2A v2\n * API: POST https://api.minimax.io/v1/t2a_v2\n */\n private async syncSpeak(\n text: string,\n voice: string | undefined,\n options?: SpeakOptions\n ): Promise<AudioResult> {\n try {\n const voiceId = voice || this.defaultVoice || 'male-qn-qingse'\n const speed = options?.speed || this.config.speed || 1.0\n const vol = options?.volume !== undefined ? options.volume / 10 : (this.config.volume !== undefined ? this.config.volume / 10 : 1.0)\n const pitch = options?.pitch !== undefined ? Math.round((options.pitch - 1) * 12) : (this.config.pitch !== undefined ? Math.round((this.config.pitch - 1) * 12) : 0)\n\n const response = await this.httpClient.post('/v1/t2a_v2', {\n model: this.config.ttsModel || 'speech-2.8-hd',\n text,\n stream: false,\n output_format: 'hex',\n voice_setting: {\n voice_id: voiceId,\n speed: speed,\n vol: vol,\n pitch: pitch\n },\n audio_setting: {\n sample_rate: 32000,\n bitrate: 128000,\n format: this.audioFormat,\n channel: 1\n }\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n }\n })\n\n if (response.data.base_resp?.status_code !== 0) {\n throw new TTSError(\n response.data.base_resp?.status_msg || 'API request failed',\n TTSErrorCode.UNKNOWN,\n this.name,\n response.data.base_resp\n )\n }\n\n const audioHex = response.data.data?.audio\n if (!audioHex) {\n throw new TTSError(\n 'No audio data in response',\n TTSErrorCode.UNKNOWN,\n this.name\n )\n }\n\n const audioBuffer = Buffer.from(audioHex, 'hex')\n\n return {\n audioData: audioBuffer,\n format: this.audioFormat,\n isStream: false,\n duration: response.data.extra_info?.audio_length \n ? response.data.extra_info.audio_length / 1000 \n : this.estimateDuration(audioBuffer.length)\n }\n } catch (error: any) {\n if (error instanceof TTSError) throw error\n throw this.mapError(error)\n }\n }\n\n /**\n * \u5F02\u6B65\u5408\u6210 (\u8F6E\u8BE2) - T2A Async v2\n */\n private async asyncSpeak(\n text: string,\n voice: string | undefined,\n options?: SpeakOptions\n ): Promise<AudioResult> {\n try {\n const voiceId = voice || this.defaultVoice || 'male-qn-qingse'\n const speed = options?.speed || this.config.speed || 1.0\n const vol = options?.volume !== undefined ? options.volume / 10 : (this.config.volume !== undefined ? this.config.volume / 10 : 1.0)\n const pitch = options?.pitch !== undefined ? Math.round((options.pitch - 1) * 12) : (this.config.pitch !== undefined ? Math.round((this.config.pitch - 1) * 12) : 0)\n\n const createResponse = await this.httpClient.post('/v1/t2a_async_v2', {\n model: this.config.ttsModel || 'speech-2.8-hd',\n text,\n voice_setting: {\n voice_id: voiceId,\n speed: speed,\n vol: vol,\n pitch: pitch\n },\n audio_setting: {\n sample_rate: 32000,\n bitrate: 128000,\n format: this.audioFormat,\n channel: 1\n }\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n }\n })\n\n const taskId = createResponse.data.task_id\n if (!taskId) {\n throw new TTSError(\n 'No task_id in async response',\n TTSErrorCode.UNKNOWN,\n this.name,\n createResponse.data\n )\n }\n\n let attempts = 0\n const maxAttempts = 60\n\n while (attempts < maxAttempts) {\n await this.delay(2000)\n\n const statusResponse = await this.httpClient.get(\n `/v1/query/t2a_async_query_v2?task_id=${taskId}`,\n {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n }\n }\n )\n\n if (statusResponse.data.status === 'success') {\n const fileId = statusResponse.data.file_id\n if (!fileId) {\n throw new TTSError(\n 'No file_id in async response',\n TTSErrorCode.UNKNOWN,\n this.name,\n statusResponse.data\n )\n }\n\n const downloadResponse = await this.httpClient.get(\n `/v1/files/retrieve_content?file_id=${fileId}`,\n { \n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n },\n responseType: 'arraybuffer'\n }\n )\n\n return {\n audioData: Buffer.from(downloadResponse.data),\n format: this.audioFormat,\n isStream: false,\n duration: 0\n }\n }\n\n if (statusResponse.data.status === 'failed') {\n throw new TTSError(\n 'Async TTS task failed',\n TTSErrorCode.UNKNOWN,\n this.name,\n statusResponse.data\n )\n }\n\n attempts++\n }\n\n throw new TTSError(\n 'Async TTS task timeout',\n TTSErrorCode.NETWORK,\n this.name\n )\n } catch (error: any) {\n if (error instanceof TTSError) throw error\n throw this.mapError(error)\n }\n }\n\n /**\n * \u97F3\u8272\u514B\u9686 - \u4F7F\u7528\u53C2\u8003\u97F3\u9891\u514B\u9686\u58F0\u97F3\n */\n async voiceClone(audioUrl: string, text: string, voice?: string): Promise<AudioResult> {\n this.validateApiKey()\n\n try {\n const response = await this.httpClient.post('/v1/t2a_v2/voice_clone', {\n audio_url: audioUrl,\n text,\n voice_id: voice || 'custom_clone'\n }, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json'\n },\n responseType: 'arraybuffer'\n })\n\n return {\n audioData: Buffer.from(response.data),\n format: this.audioFormat,\n isStream: false,\n duration: this.estimateDuration(response.data.length)\n }\n } catch (error: any) {\n throw this.mapError(error)\n }\n }\n\n /**\n * \u83B7\u53D6\u97F3\u8272\u5217\u8868\n */\n async listVoices(): Promise<Voice[]> {\n this.validateApiKey()\n\n try {\n const response = await this.httpClient.get('/v1/t2a/voices', {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n }\n })\n\n return response.data.voices.map((v: any) => ({\n id: v.voice_id,\n name: v.name,\n language: v.language,\n gender: v.gender\n }))\n } catch (error: any) {\n // \u5982\u679CAPI\u8C03\u7528\u5931\u8D25\uFF0C\u8FD4\u56DE\u9884\u5B9A\u4E49\u97F3\u8272\u5217\u8868\n return MINIMAX_VOICES\n }\n }\n\n /**\n * \u9519\u8BEF\u6620\u5C04\n */\n private mapError(error: any): TTSError {\n if (error.response) {\n const status = error.response.status\n const code =\n status === 401 ? TTSErrorCode.AUTH :\n status === 429 ? TTSErrorCode.QUOTA :\n status >= 500 ? TTSErrorCode.NETWORK :\n TTSErrorCode.UNKNOWN\n\n return new TTSError(\n error.response.data?.message || 'API request failed',\n code,\n this.name,\n error.response.data\n )\n }\n\n if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {\n return new TTSError(\n 'Network error: Unable to connect to MiniMax API',\n TTSErrorCode.NETWORK,\n this.name,\n error.message\n )\n }\n\n return new TTSError(\n error.message || 'Unknown error',\n TTSErrorCode.UNKNOWN,\n this.name,\n error\n )\n }\n\n /**\n * \u5EF6\u8FDF\u8F85\u52A9\u51FD\u6570\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n /**\n * \u4F30\u7B97\u97F3\u9891\u65F6\u957F\n * \u57FA\u4E8E 32kbps MP3 \u4F30\u7B97\n */\n private estimateDuration(bytes: number): number {\n return (bytes * 8) / (32000 * 60)\n }\n}\n\n/**\n * MiniMax \u9884\u5B9A\u4E49\u97F3\u8272\u5217\u8868\n * \u5B98\u65B9\u97F3\u8272ID\u53C2\u8003\n */\nexport const MINIMAX_VOICES: Voice[] = [\n { id: 'male-qn-qingse', name: '\u9752\u5E74\u6E05\u6F88', language: 'zh-CN', gender: 'male' },\n { id: 'male-qn-qingse_2', name: '\u9752\u5E74\u6E05\u6F88v2', language: 'zh-CN', gender: 'male' },\n { id: 'female-shaonv', name: '\u5C11\u5973', language: 'zh-CN', gender: 'female' },\n { id: 'male-baiming', name: '\u6210\u719F\u7537\u58F0', language: 'zh-CN', gender: 'male' },\n { id: 'female-tianmei', name: '\u751C\u7F8E\u5973\u58F0', language: 'zh-CN', gender: 'female' },\n { id: 'male-zhongnan', name: '\u4E2D\u5E74\u7537\u58F0', language: 'zh-CN', gender: 'male' },\n { id: 'female-yujie', name: '\u5FA1\u59D0\u97F3', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-xiaoao', name: '\u9752\u5E74\u8C6A\u723D', language: 'zh-CN', gender: 'male' },\n { id: 'female-shandian', name: '\u751C\u5FC3\u5C0F\u5A18', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-buke', name: '\u9752\u5E74\u4F4E\u6C89', language: 'zh-CN', gender: 'male' },\n { id: 'male-qn-wenlv', name: '\u6587\u7EFF\u9752\u5E74', language: 'zh-CN', gender: 'male' },\n { id: 'female-tianmei-2', name: '\u751C\u7F8E\u5973\u58F0v2', language: 'zh-CN', gender: 'female' },\n { id: 'female-yujie-2', name: '\u5FA1\u59D0\u97F3v2', language: 'zh-CN', gender: 'female' },\n { id: 'male-shaonian', name: '\u5C11\u5E74\u97F3', language: 'zh-CN', gender: 'male' },\n { id: 'female-yunv', name: '\u6E29\u67D4\u5973\u58F0', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-jingdian', name: '\u7ECF\u5178\u7537\u58F0', language: 'zh-CN', gender: 'male' },\n { id: 'male-qn-kuang\u91CE', name: '\u72C2\u91CE\u9752\u5E74', language: 'zh-CN', gender: 'male' },\n { id: 'female-yujie-old', name: '\u4F18\u96C5\u4F4E\u6C89', language: 'zh-CN', gender: 'female' },\n { id: 'female-tianmei-old', name: '\u751C\u7F8E\u5973\u5B69', language: 'zh-CN', gender: 'female' },\n { id: 'male-qn-taohua', name: '\u6843\u82B1\u9752\u5E74', language: 'zh-CN', gender: 'male' }\n]\n", "/**\n * StreamReader - \u6D41\u5F0F\u6587\u672C\u7F13\u51B2\u4E0E\u53E5\u5B50\u8FB9\u754C\u68C0\u6D4B\n * \n * \u529F\u80FD\uFF1A\n * - \u8BA2\u9605 TuiEventBus \u7684 message.part.delta \u4E8B\u4EF6\n * - \u7F13\u51B2\u533A\u6EE1\u6216\u9047\u5230\u53E5\u5B50\u7ED3\u675F\u7B26\u65F6\u89E6\u53D1 textReady \u4E8B\u4EF6\n * - \u652F\u6301\u8D85\u65F6\u5F3A\u5236\u53D1\u9001\n */\n\nimport { EventEmitter } from 'events'\nimport { StreamState, TTSError, TTSErrorCode } from './types'\n\nexport class StreamReader extends EventEmitter {\n private state: StreamState = StreamState.IDLE\n private buffer: string = ''\n private sessionID?: string\n private messageID?: string\n private partID?: string\n private timeoutHandle?: NodeJS.Timeout\n \n constructor(\n private bufferSize: number = 30,\n private bufferTimeout: number = 2000\n ) {\n super()\n }\n\n /**\n * \u542F\u52A8\u6D41\u5F0F\u76D1\u542C\n * \u5C06\u72B6\u6001\u4ECE IDLE \u5207\u6362\u5230 BUFFERING\uFF0C\u5F00\u59CB\u76D1\u542C\u4E8B\u4EF6\n */\n start(): void {\n if (this.state === StreamState.IDLE) {\n this.state = StreamState.BUFFERING\n this.emit('streamStart')\n }\n }\n \n /**\n * \u5904\u7406 message.part.delta \u4E8B\u4EF6\n */\n handleDelta(sessionID: string, messageID: string, partID: string, delta: string): void {\n if (this.state === StreamState.IDLE) {\n this.state = StreamState.BUFFERING\n this.sessionID = sessionID\n this.messageID = messageID\n this.partID = partID\n this.emit('streamStart')\n }\n \n this.buffer += delta\n this.resetTimeout()\n \n if (this.shouldFlush()) {\n this.flushBuffer()\n }\n }\n \n /**\n * \u5904\u7406\u6D41\u7ED3\u675F\n */\n handleEnd(): void {\n if (this.state === StreamState.ENDED) {\n return\n }\n if (this.buffer.length > 0) {\n this.flushBuffer()\n }\n this.state = StreamState.ENDED\n this.clearTimeout()\n this.emit('streamEnd')\n }\n \n /**\n * \u5904\u7406\u9519\u8BEF\n */\n handleError(error: TTSError): void {\n this.clearTimeout()\n this.state = StreamState.IDLE\n this.buffer = ''\n this.emit('streamError', error)\n }\n \n /**\n * \u91CD\u7F6E\u7F13\u51B2\u5668\n */\n reset(): void {\n this.state = StreamState.IDLE\n this.buffer = ''\n this.sessionID = undefined\n this.messageID = undefined\n this.partID = undefined\n this.clearTimeout()\n }\n \n /**\n * \u5224\u65AD\u662F\u5426\u5E94\u8BE5\u5237\u65B0\u7F13\u51B2\u533A\n * \u6761\u4EF6\uFF1A\n * 1. \u5305\u542B\u53E5\u5B50\u7ED3\u675F\u7B26\uFF08\u4EFB\u4F55\u957F\u5EA6\uFF09\n * 2. \u7F13\u51B2\u533A\u957F\u5EA6 >= bufferSize\n */\n private shouldFlush(): boolean {\n // \u53E5\u5B50\u7ED3\u675F\u6807\u8BB0\uFF1A\u3002\uFF01\uFF1F.!?\u2026\u2026\uFF08\u4E2D\u6587\u53E5\u53F7\u3001\u611F\u53F9\u53F7\u3001\u95EE\u53F7\u3001\u7701\u7565\u53F7\uFF09\n const sentenceEnd = /[\u3002\uFF01\uFF1F.!?]|\u2026\u2026/\n if (sentenceEnd.test(this.buffer)) {\n return true\n }\n // \u7F13\u51B2\u533A\u8FBE\u5230\u9608\u503C\n if (this.buffer.length >= this.bufferSize) {\n return true\n }\n return false\n }\n \n /**\n * \u5237\u65B0\u7F13\u51B2\u533A\uFF0C\u53D1\u9001textReady\u4E8B\u4EF6\n */\n private flushBuffer(): void {\n const text = this.buffer.trim()\n if (text.length > 0) {\n this.emit('textReady', text)\n }\n this.buffer = ''\n this.resetTimeout()\n }\n \n /**\n * \u91CD\u7F6E\u8D85\u65F6\u8BA1\u65F6\u5668\n */\n private resetTimeout(): void {\n this.clearTimeout()\n this.timeoutHandle = setTimeout(() => {\n if (this.buffer.length > 0) {\n this.flushBuffer()\n }\n }, this.bufferTimeout)\n }\n \n /**\n * \u6E05\u9664\u8D85\u65F6\u8BA1\u65F6\u5668\n */\n private clearTimeout(): void {\n if (this.timeoutHandle) {\n clearTimeout(this.timeoutHandle)\n this.timeoutHandle = undefined\n }\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u72B6\u6001\n */\n getState(): StreamState {\n return this.state\n }\n \n /**\n * \u68C0\u67E5\u6D41\u662F\u5426\u5904\u4E8E\u6D3B\u8DC3\u72B6\u6001\n */\n isActive(): boolean {\n return this.state === StreamState.BUFFERING\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u7F13\u51B2\u533A\u5185\u5BB9\n */\n getBuffer(): string {\n return this.buffer\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u4F1A\u8BDDID\n */\n getSessionID(): string | undefined {\n return this.sessionID\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u6D88\u606FID\n */\n getMessageID(): string | undefined {\n return this.messageID\n }\n \n /**\n * \u83B7\u53D6\u5F53\u524D\u5206\u5757ID\n */\n getPartID(): string | undefined {\n return this.partID\n }\n}\n", "/**\n * StreamingSynthesizer - \u6D41\u5F0F\u5408\u6210\u5668\n * \n * \u529F\u80FD\uFF1A\n * - \u63A5\u6536 StreamReader \u53D1\u6765\u7684\u6587\u672C\uFF08\u901A\u8FC7 synthesize \u65B9\u6CD5\uFF09\n * - \u8C03\u7528 TTSProvider \u7684\u6D41\u5F0F\u5408\u6210\u63A5\u53E3\n * - \u5C06\u8FD4\u56DE\u7684\u97F3\u9891 chunk \u4F20\u9012\u7ED9\u4E0B\u6E38\uFF08StreamPlayer\uFF09\n * \n * \u6570\u636E\u6D41\uFF1A\n * StreamReader.textReady \u2192 StreamingSynthesizer.synthesize() \u2192 StreamPlayer (\u8FB9\u6536\u8FB9\u64AD)\n */\n\nimport { EventEmitter } from 'events'\nimport { TTSProvider, TTSError, TTSErrorCode, StreamingSynthesizerOptions, AudioResult } from './types'\n\nexport interface StreamingSynthesizerEvents {\n on(event: 'chunk', handler: (chunk: Buffer) => void): void\n on(event: 'error', handler: (error: TTSError) => void): void\n on(event: 'done', handler: () => void): void\n}\n\nexport class StreamingSynthesizer extends EventEmitter {\n private audioChunks: Buffer[] = []\n \n constructor(private options: StreamingSynthesizerOptions) {\n super()\n }\n \n /**\n * \u53D1\u9001\u6587\u672C\u7247\u6BB5\u8FDB\u884C\u5408\u6210\n * \u8C03\u7528 provider.speak() \u5E76\u5904\u7406\u8FD4\u56DE\u7684\u97F3\u9891\u6D41\n */\n async synthesize(text: string): Promise<void> {\n if (!text || text.trim().length === 0) {\n return\n }\n \n try {\n const result = await this.options.provider.speak(text, {\n model: 'stream',\n voice: this.options.voice,\n speed: this.options.speed,\n volume: this.options.volume,\n pitch: this.options.pitch\n })\n \n await this.processAudioResult(result)\n \n this.emit('done')\n } catch (error) {\n const ttsError = error instanceof TTSError \n ? error \n : new TTSError(\n error instanceof Error ? error.message : 'Synthesis failed',\n 'UNKNOWN' as TTSErrorCode,\n this.options.provider.name,\n error\n )\n this.emit('error', ttsError)\n }\n }\n \n /**\n * \u5904\u7406 AudioResult\uFF0C\u6839\u636E audioData \u7C7B\u578B\u8FDB\u884C\u76F8\u5E94\u5904\u7406\n */\n private async processAudioResult(result: AudioResult): Promise<void> {\n if (result.isStream && result.audioData instanceof ReadableStream) {\n // \u6D41\u5F0F\u6570\u636E\uFF1AReadableStream\n await this.processReadableStream(result.audioData)\n } else if (Buffer.isBuffer(result.audioData)) {\n // \u975E\u6D41\u5F0F\u6570\u636E\uFF1ABuffer\n this.emitChunk(result.audioData)\n }\n }\n \n /**\n * \u5904\u7406 ReadableStream\uFF0C\u9010chunk emit\n */\n private async processReadableStream(stream: ReadableStream): Promise<void> {\n const reader = stream.getReader()\n \n try {\n while (true) {\n const { done, value } = await reader.read()\n \n if (done) {\n break\n }\n \n if (value) {\n const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value)\n this.emitChunk(chunk)\n }\n }\n } finally {\n reader.releaseLock()\n }\n }\n \n /**\n * emit chunk \u5E76\u7D2F\u79EF\n */\n private emitChunk(chunk: Buffer): void {\n this.audioChunks.push(chunk)\n this.emit('chunk', chunk)\n }\n \n /**\n * \u91CD\u7F6E\u72B6\u6001\n * \u6E05\u7A7A\u7D2F\u79EF\u7684\u97F3\u9891\u6570\u636E\n */\n reset(): void {\n this.audioChunks = []\n }\n \n /**\n * \u83B7\u53D6\u7D2F\u79EF\u7684\u97F3\u9891\u6570\u636E\n * \u8FD4\u56DE\u6240\u6709\u5DF2\u63A5\u6536\u7684 chunk\n */\n getAudioChunks(): Buffer[] {\n return [...this.audioChunks]\n }\n}\n", "/**\n * StreamPlayer - \u771F\u6B63\u7684\u8FB9\u6536\u8FB9\u64AD\u6D41\u5F0F\u97F3\u9891\u64AD\u653E\u5668\n * \u63A5\u6536\u97F3\u9891 chunk\uFF0C\u540C\u65F6\u5199\u5165\u4E34\u65F6\u6587\u4EF6\u5E76\u7ACB\u5373\u542F\u52A8\u64AD\u653E\u5668\u64AD\u653E\n */\n\nimport { EventEmitter } from 'events'\nimport { spawn, ChildProcess } from 'child_process'\nimport fs from 'fs'\nimport { createWriteStream, WriteStream } from 'fs'\nimport { tmpdir } from 'os'\nimport { join } from 'path'\n\n/**\n * StreamPlayer Events - \u6D41\u5F0F\u64AD\u653E\u5668\u4E8B\u4EF6\u56DE\u8C03\u63A5\u53E3\n */\nexport interface StreamPlayerEvents {\n onProgress?: (bytesWritten: number) => void\n onStart?: () => void\n onEnd?: () => void\n onError?: (error: Error) => void\n onPause?: () => void\n onResume?: () => void\n onStop?: () => void\n}\n\n/**\n * StreamPlayer Options - \u6D41\u5F0F\u64AD\u653E\u5668\u914D\u7F6E\u9009\u9879\n */\nexport interface StreamPlayerOptions {\n format?: 'mp3' | 'wav' | 'flac'\n events?: StreamPlayerEvents\n}\n\n/**\n * StreamPlayer - \u8FB9\u6536\u8FB9\u64AD\u7684\u6D41\u5F0F\u97F3\u9891\u64AD\u653E\u5668\n * \n * \u7279\u6027\uFF1A\n * - \u5199\u5165\u4E34\u65F6\u6587\u4EF6\u7684\u540C\u65F6\u7ACB\u5373\u542F\u52A8\u64AD\u653E\u5668\n * - \u652F\u6301 pause/resume/stop \u63A7\u5236\n * - \u8DE8\u5E73\u53F0\u652F\u6301\uFF1AmacOS (afplay), Linux (aplay), Windows (PowerShell)\n */\nexport class StreamPlayer extends EventEmitter {\n private tempFile: string = ''\n private writeStream?: WriteStream\n private playerProcess?: ChildProcess\n private _bytesWritten = 0\n private _started = false\n private _paused = false\n private _stopped = false\n private format: 'mp3' | 'wav' | 'flac' = 'mp3'\n private events?: StreamPlayerEvents\n\n constructor(options: StreamPlayerOptions = {}) {\n super()\n this.format = options.format || 'mp3'\n this.events = options.events\n }\n\n /**\n * \u5F00\u59CB\u64AD\u653E\n * \u521B\u5EFA\u4E34\u65F6\u6587\u4EF6\uFF0C\u521B\u5EFA\u5199\u5165\u6D41\uFF0C\u542F\u52A8\u64AD\u653E\u5668\u8FDB\u7A0B\n */\n start(): void {\n if (this._started) {\n return\n }\n\n // \u521B\u5EFA\u4E34\u65F6\u6587\u4EF6\n this.tempFile = join(tmpdir(), `ocosay-stream-${Date.now()}.${this.format}`)\n\n // \u521B\u5EFA\u5199\u5165\u6D41\n this.writeStream = createWriteStream(this.tempFile, { highWaterMark: 64 * 1024 })\n\n this.writeStream.on('error', (error: Error) => {\n this.handleError(error)\n })\n\n this.writeStream.on('finish', () => {\n // \u5199\u5165\u5B8C\u6210\uFF0C\u4F46\u64AD\u653E\u5668\u53EF\u80FD\u8FD8\u5728\u64AD\u653E\n })\n\n // \u542F\u52A8\u64AD\u653E\u5668\u8FDB\u7A0B\n this.startPlayer()\n\n this._started = true\n this._stopped = false\n\n this.events?.onStart?.()\n this.emit('start')\n }\n\n /**\n * \u542F\u52A8\u64AD\u653E\u5668\u8FDB\u7A0B\n */\n private startPlayer(): void {\n const platform = process.platform\n let command: string\n let args: string[]\n\n if (platform === 'darwin') {\n // macOS\n command = 'afplay'\n args = [this.tempFile]\n } else if (platform === 'linux') {\n // Linux\n command = 'aplay'\n args = [this.tempFile]\n } else {\n // Windows - PlaySync is synchronous and blocks the event loop\n // Return error to indicate Windows is not supported for streaming\n this.handleError(new Error('Windows platform is not supported for stream playback. PlaySync() blocks the Node.js event loop.'))\n return\n }\n\n this.playerProcess = spawn(command, args, {\n stdio: 'ignore',\n detached: false\n })\n\n this.playerProcess.on('exit', (code: number | null, signal: string | null) => {\n // \u5982\u679C\u662F\u6B63\u5E38\u7ED3\u675F\u6216\u88AB\u4FE1\u53F7\u7EC8\u6B62\uFF0C\u4E0D\u5F53\u4F5C\u9519\u8BEF\n if (this._stopped) {\n return\n }\n \n if (signal === 'SIGTERM' || signal === 'SIGINT') {\n // \u88AB\u4E3B\u52A8\u505C\u6B62\n return\n }\n\n if (code === 0 || code === null) {\n // \u6B63\u5E38\u64AD\u653E\u7ED3\u675F\n this.events?.onEnd?.()\n this.emit('end')\n } else {\n this.handleError(new Error(`Player exited with code ${code}`))\n }\n })\n\n this.playerProcess.on('error', (error: Error) => {\n this.handleError(error)\n })\n }\n\n /**\n * \u5199\u5165\u97F3\u9891\u6570\u636E\u5757\uFF08\u8FB9\u6536\u8FB9\u5199\uFF09\n * \u5982\u679C\u5C1A\u672A start()\uFF0C\u4F1A\u81EA\u52A8\u8C03\u7528\n */\n write(chunk: Buffer): void {\n // \u5982\u679C\u5DF2\u505C\u6B62\uFF0C\u76F4\u63A5\u5FFD\u7565\n if (this._stopped) {\n return\n }\n\n // \u5982\u679C\u672A\u542F\u52A8\uFF0C\u81EA\u52A8\u542F\u52A8\n if (!this._started) {\n this.start()\n }\n\n // \u5199\u5165\u6570\u636E\u5230\u6587\u4EF6\n if (this.writeStream) {\n const canContinue = this.writeStream.write(chunk)\n \n if (!canContinue) {\n // \u5199\u5165\u7F13\u51B2\u533A\u6EE1\u4E86\uFF0C\u7B49\u5F85 drain \u4E8B\u4EF6\n this.writeStream.once('drain', () => {\n // \u53EF\u4EE5\u7EE7\u7EED\u5199\u5165\n })\n }\n\n this._bytesWritten += chunk.length\n\n this.events?.onProgress?.(this._bytesWritten)\n this.emit('progress', this._bytesWritten)\n }\n }\n\n /**\n * \u7ED3\u675F\u5199\u5165\n * \u5173\u95ED\u5199\u5165\u6D41\uFF0C\u4F46\u4E0D\u6740\u64AD\u653E\u5668\u8FDB\u7A0B\uFF0C\u8BA9\u5B83\u64AD\u5B8C\n */\n end(): void {\n if (this.writeStream) {\n this.writeStream.end()\n this.writeStream = undefined\n }\n }\n\n /**\n * \u505C\u6B62\u64AD\u653E\n * \u6740\u6B7B\u64AD\u653E\u5668\u8FDB\u7A0B\uFF0C\u5220\u9664\u4E34\u65F6\u6587\u4EF6\n */\n stop(): void {\n this._stopped = true\n this._started = false\n this._paused = false\n\n // \u6740\u6B7B\u64AD\u653E\u5668\u8FDB\u7A0B\n if (this.playerProcess) {\n try {\n this.playerProcess.kill('SIGTERM')\n } catch (e) {\n // \u5FFD\u7565\u9519\u8BEF\n }\n this.playerProcess = undefined\n }\n\n // \u5173\u95ED\u5199\u5165\u6D41\n if (this.writeStream) {\n try {\n this.writeStream.destroy()\n } catch (e) {\n // \u5FFD\u7565\u9519\u8BEF\n }\n this.writeStream = undefined\n }\n\n // \u5220\u9664\u4E34\u65F6\u6587\u4EF6\n this.deleteTempFile()\n\n this.events?.onStop?.()\n this.emit('stop')\n }\n\n /**\n * \u6682\u505C\u64AD\u653E\n * \u4F7F\u7528 SIGSTOP \u6682\u505C\u64AD\u653E\u5668\u8FDB\u7A0B\n */\n pause(): void {\n if (!this._started || this._paused || this._stopped) {\n return\n }\n\n if (this.playerProcess) {\n try {\n this.playerProcess.kill('SIGSTOP')\n this._paused = true\n this.events?.onPause?.()\n this.emit('pause')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u6062\u590D\u64AD\u653E\n */\n resume(): void {\n if (!this._paused || this._stopped) {\n return\n }\n\n if (this.playerProcess) {\n try {\n this.playerProcess.kill('SIGCONT')\n this._paused = false\n this.events?.onResume?.()\n this.emit('resume')\n } catch (e) {\n // \u5982\u679C kill \u5931\u8D25\uFF0C\u5FFD\u7565\n }\n }\n }\n\n /**\n * \u662F\u5426\u5DF2\u542F\u52A8\n */\n isStarted(): boolean {\n return this._started\n }\n\n /**\n * \u662F\u5426\u6682\u505C\n */\n isPaused(): boolean {\n return this._paused\n }\n\n /**\n * \u662F\u5426\u5DF2\u505C\u6B62\n */\n isStopped(): boolean {\n return this._stopped\n }\n\n /**\n * \u83B7\u53D6\u5DF2\u5199\u5165\u7684\u5B57\u8282\u6570\n */\n getBytesWritten(): number {\n return this._bytesWritten\n }\n\n /**\n * \u83B7\u53D6\u4E34\u65F6\u6587\u4EF6\u8DEF\u5F84\n */\n getTempFile(): string {\n return this.tempFile\n }\n\n /**\n * \u5904\u7406\u9519\u8BEF\n */\n private handleError(error: Error): void {\n this.events?.onError?.(error)\n this.emit('error', error)\n }\n\n /**\n * \u5220\u9664\u4E34\u65F6\u6587\u4EF6\n */\n private deleteTempFile(): void {\n if (this.tempFile) {\n try {\n if (fs.existsSync(this.tempFile)) {\n fs.unlinkSync(this.tempFile)\n }\n } catch (e) {\n // \u5FFD\u7565\u5220\u9664\u9519\u8BEF\n }\n this.tempFile = ''\n }\n }\n}\n\nexport default StreamPlayer\n", "import { handleToolCall } from './tools/tts'\nimport { registerProvider, getProvider, listProviders } from './providers/base'\nimport { MiniMaxProvider, MiniMaxConfig } from './providers/minimax'\nimport { Speaker, SpeakerOptions } from './core/speaker'\nimport { TTSError, TTSErrorCode } from './core/types'\nimport { StreamReader } from './core/stream-reader'\nimport { StreamingSynthesizer } from './core/streaming-synthesizer'\nimport { StreamPlayer } from './core/stream-player'\n\nexport const pluginInfo = {\n name: 'ocosay',\n version: '1.0.0',\n description: 'OpenCode TTS \u64AD\u653E\u63D2\u4EF6 - \u652F\u6301 MiniMax TTS',\n author: '',\n license: 'MIT'\n}\n\nlet speaker: Speaker | undefined\nlet streamReader: StreamReader | undefined\nlet streamingSynthesizer: StreamingSynthesizer | undefined\nlet streamPlayer: StreamPlayer | undefined\nlet initialized = false\nlet autoReadEnabled = false\n\nexport interface InitializeOptions {\n defaultProvider?: string\n defaultModel?: 'sync' | 'async' | 'stream'\n defaultVoice?: string\n providers?: {\n minimax?: MiniMaxConfig\n }\n autoRead?: boolean\n streamBufferSize?: number\n streamBufferTimeout?: number\n}\n\nexport async function initialize(config?: InitializeOptions): Promise<void> {\n if (initialized) {\n return\n }\n\n if (config?.providers?.minimax) {\n if (!config.providers.minimax.apiKey) {\n throw new Error('[ocosay] API Key is required. Please set minimax.apiKey in ~/.config/opencode/ocosay.jsonc')\n }\n const minimaxProvider = new MiniMaxProvider(config.providers.minimax)\n registerProvider('minimax', minimaxProvider)\n await minimaxProvider.initialize()\n }\n \n const speakerOptions: SpeakerOptions = {\n defaultProvider: config?.defaultProvider || 'minimax',\n defaultModel: config?.defaultModel || 'stream',\n defaultVoice: config?.defaultVoice\n }\n \n speaker = new Speaker(speakerOptions)\n \n if (config?.autoRead) {\n autoReadEnabled = true\n initializeStreamComponents(config)\n }\n \n initialized = true\n}\n\nfunction initializeStreamComponents(config: InitializeOptions): void {\n const provider = getProvider(config?.defaultProvider || 'minimax')\n \n streamReader = new StreamReader(\n config?.streamBufferSize || 30,\n config?.streamBufferTimeout || 2000\n )\n \n streamingSynthesizer = new StreamingSynthesizer({\n provider,\n voice: config?.defaultVoice,\n speed: 1.0,\n volume: 1.0,\n pitch: 1.0\n })\n \n const playerEvents = {\n onStart: () => {},\n onEnd: () => {},\n onProgress: (bytesWritten: number) => {},\n onError: (error: Error) => console.error('Stream player error:', error),\n onStop: () => {}\n }\n streamPlayer = new StreamPlayer({ events: playerEvents })\n\n const synthesisQueue: string[] = []\n let isSynthesizing = false\n\n async function processQueue(): Promise<void> {\n while (synthesisQueue.length > 0) {\n const text = synthesisQueue.shift()!\n isSynthesizing = true\n try {\n await streamingSynthesizer?.synthesize(text)\n } catch (error) {\n console.error('Synthesize error:', error)\n }\n }\n isSynthesizing = false\n }\n \n streamReader.on('textReady', (text: string) => {\n synthesisQueue.push(text)\n if (!isSynthesizing) {\n processQueue()\n }\n })\n \n streamingSynthesizer.on('chunk', (chunk: Buffer) => {\n if (streamPlayer) {\n streamPlayer.write(chunk)\n }\n })\n \n streamingSynthesizer.on('done', () => {\n if (streamPlayer) {\n streamPlayer.end()\n }\n })\n\n const TuiEventBus = (global as any).__opencode_tuieventbus__\n if (TuiEventBus) {\n const eventBus = new TuiEventBus()\n let messagePartDeltaHandler: ((event: any) => void) | undefined\n let messagePartEndHandler: (() => void) | undefined\n \n messagePartDeltaHandler = (event: any) => {\n if (event?.properties) {\n streamReader?.handleDelta(\n event.sessionId || '',\n event.messageId || '',\n event.partId || '',\n event.properties.delta || ''\n )\n }\n }\n messagePartEndHandler = () => {\n streamReader?.handleEnd()\n }\n eventBus.on('message.part.delta', messagePartDeltaHandler)\n eventBus.on('message.part.end', messagePartEndHandler)\n }\n}\n\nexport function getSpeaker(): Speaker {\n if (!speaker) {\n throw new TTSError(\n 'Plugin not initialized. Call initialize() first.',\n TTSErrorCode.UNKNOWN,\n 'ocosay'\n )\n }\n return speaker\n}\n\nexport function isStreamEnabled(): boolean {\n return streamReader !== undefined && streamingSynthesizer !== undefined && streamPlayer !== undefined\n}\n\nexport function isAutoReadEnabled(): boolean {\n return autoReadEnabled\n}\n\nexport function getStreamStatus(): { isActive: boolean; bytesWritten: number; state: string } {\n if (!streamReader) {\n return { isActive: false, bytesWritten: 0, state: 'not_initialized' }\n }\n return {\n isActive: streamReader.isActive(),\n bytesWritten: streamPlayer?.getBytesWritten() ?? 0,\n state: streamReader.getState()\n }\n}\n\nexport function getStreamReader(): StreamReader | undefined {\n return streamReader\n}\n\nexport function getStreamingSynthesizer(): StreamingSynthesizer | undefined {\n return streamingSynthesizer\n}\n\nexport function getStreamPlayer(): StreamPlayer | undefined {\n return streamPlayer\n}\n\nexport async function destroy(): Promise<void> {\n if (streamReader) {\n streamReader.reset()\n streamReader = undefined\n }\n \n if (streamingSynthesizer) {\n streamingSynthesizer.reset()\n streamingSynthesizer = undefined\n }\n \n if (streamPlayer) {\n await streamPlayer.stop()\n streamPlayer = undefined\n }\n \n if (speaker) {\n await speaker.destroy()\n speaker = undefined\n }\n \n for (const providerName of listProviders()) {\n try {\n getProvider(providerName)?.destroy()\n } catch (e) {}\n }\n \n initialized = false\n autoReadEnabled = false\n}\n\nexport { handleToolCall }\nexport const toolNames = [\n 'tts_speak',\n 'tts_stop',\n 'tts_pause',\n 'tts_resume',\n 'tts_list_voices',\n 'tts_list_providers',\n 'tts_status',\n 'tts_stream_speak',\n 'tts_stream_stop',\n 'tts_stream_status'\n]\n", "import * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\n\n// OcosayConfig \u7C7B\u578B\u5B9A\u4E49\nexport interface OcosayConfig {\n enabled: boolean\n autoPlay: boolean\n autoRead: boolean\n streamMode: boolean\n streamBufferSize: number\n streamBufferTimeout: number\n speed: number\n volume: number\n pitch: number\n providers: {\n minimax: {\n apiKey: string\n baseURL: string\n voiceId: string\n model: 'sync' | 'async' | 'stream'\n ttsModel: string\n audioFormat: 'mp3' | 'wav' | 'flac'\n }\n }\n}\n\n// \u9ED8\u8BA4\u914D\u7F6E\nconst DEFAULT_CONFIG: Omit<OcosayConfig, 'providers'> = {\n enabled: true,\n autoPlay: false,\n autoRead: false,\n streamMode: true,\n streamBufferSize: 30,\n streamBufferTimeout: 2000,\n speed: 1.0,\n volume: 80,\n pitch: 1.0\n}\n\nconst CONFIG_PATH = path.join(os.homedir(), '.config', 'opencode', 'ocosay.jsonc')\n\nexport function generateDefaultConfig(): OcosayConfig {\n return {\n ...DEFAULT_CONFIG,\n providers: {\n minimax: {\n apiKey: '',\n baseURL: 'https://api.minimaxi.com',\n voiceId: 'female-chengshu',\n model: 'stream',\n ttsModel: 'speech-2.8-hd',\n audioFormat: 'mp3'\n }\n }\n }\n}\n\nexport function stripComments(jsonc: string): string {\n let result = ''\n let inString = false\n let stringChar = ''\n let i = 0\n\n while (i < jsonc.length) {\n const char = jsonc[i]\n\n if (!inString && (char === '\"' || char === \"'\" || char === '`')) {\n inString = true\n stringChar = char\n result += char\n i++\n continue\n }\n\n if (inString && char === stringChar && jsonc[i - 1] !== '\\\\') {\n inString = false\n result += char\n i++\n continue\n }\n\n if (inString) {\n result += char\n i++\n continue\n }\n\n if (char === '/' && jsonc[i + 1] === '/') {\n while (i < jsonc.length && jsonc[i] !== '\\n') {\n i++\n }\n continue\n }\n\n if (char === '/' && jsonc[i + 1] === '*') {\n i += 2\n while (i < jsonc.length - 1 && !(jsonc[i] === '*' && jsonc[i + 1] === '/')) {\n i++\n }\n i += 2\n continue\n }\n\n result += char\n i++\n }\n\n return result\n}\n\nexport function mergeWithDefaults(\n loaded: Partial<OcosayConfig>,\n defaults: Omit<OcosayConfig, 'providers'>\n): Omit<OcosayConfig, 'providers'> {\n return {\n enabled: loaded.enabled ?? defaults.enabled,\n autoPlay: loaded.autoPlay ?? defaults.autoPlay,\n autoRead: loaded.autoRead ?? defaults.autoRead,\n streamMode: loaded.streamMode ?? defaults.streamMode,\n streamBufferSize: loaded.streamBufferSize ?? defaults.streamBufferSize,\n streamBufferTimeout: loaded.streamBufferTimeout ?? defaults.streamBufferTimeout,\n speed: loaded.speed ?? defaults.speed,\n volume: loaded.volume ?? defaults.volume,\n pitch: loaded.pitch ?? defaults.pitch\n }\n}\n\n/**\n * \u89E3\u6790\u914D\u7F6E\u503C\uFF0C\u652F\u6301 {env:VAR_NAME} \u683C\u5F0F\u7684\u73AF\u5883\u53D8\u91CF\u5F15\u7528\n */\nfunction resolveEnvValue(value: string | undefined): string {\n if (!value) return ''\n if (value.startsWith('{env:') && value.endsWith('}')) {\n const envVar = value.slice(5, -1)\n return process.env[envVar] || ''\n }\n return value\n}\n\nexport function loadOrCreateConfig(): OcosayConfig {\n const configDir = path.dirname(CONFIG_PATH)\n\n if (!fs.existsSync(configDir)) {\n try {\n fs.mkdirSync(configDir, { recursive: true })\n } catch (err) {\n throw new Error(`[ocosay] \u65E0\u6CD5\u521B\u5EFA\u914D\u7F6E\u76EE\u5F55 ${configDir}: ${err}`)\n }\n }\n\n if (!fs.existsSync(CONFIG_PATH)) {\n console.info('[ocosay] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u6B63\u5728\u521B\u5EFA\u9ED8\u8BA4\u914D\u7F6E...')\n const defaultConfig = generateDefaultConfig()\n const configContent = JSON.stringify(defaultConfig, null, 2)\n try {\n fs.writeFileSync(CONFIG_PATH, configContent, 'utf-8')\n try {\n fs.chmodSync(CONFIG_PATH, 0o600)\n } catch (err) {\n console.warn(`[ocosay] \u65E0\u6CD5\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6\u6743\u9650: ${err}`)\n }\n } catch (err) {\n throw new Error(`[ocosay] \u65E0\u6CD5\u5199\u5165\u914D\u7F6E\u6587\u4EF6 ${CONFIG_PATH}: ${err}`)\n }\n console.info(`[ocosay] \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: ${CONFIG_PATH}`)\n console.info('[ocosay] \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u586B\u5165 API Key \u548C Base URL')\n return defaultConfig\n }\n\n try {\n const content = fs.readFileSync(CONFIG_PATH, 'utf-8')\n const stripped = stripComments(content)\n const loaded = JSON.parse(stripped) as Partial<OcosayConfig>\n\n const merged = mergeWithDefaults(loaded, DEFAULT_CONFIG)\n\n return {\n ...merged,\n providers: {\n minimax: {\n apiKey: resolveEnvValue(loaded.providers?.minimax?.apiKey),\n baseURL: resolveEnvValue(loaded.providers?.minimax?.baseURL),\n voiceId: loaded.providers?.minimax?.voiceId ?? '',\n model: loaded.providers?.minimax?.model ?? 'stream',\n ttsModel: loaded.providers?.minimax?.ttsModel ?? 'speech-2.8-hd',\n audioFormat: loaded.providers?.minimax?.audioFormat ?? 'mp3'\n }\n }\n }\n } catch (error) {\n console.error('[ocosay] \u914D\u7F6E\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E:', error)\n return generateDefaultConfig()\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["EventEmitter", "EventEmitter", "speaker", "speaker", "providers", "streamReader", "EventEmitter", "EventEmitter", "EventEmitter", "EventEmitter", "EventEmitter", "spawn", "fs", "createWriteStream", "tmpdir", "join", "fs"]
|
|
7
7
|
}
|