@downcity/plugins 1.0.56 → 1.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/bin/BuiltinPlugins.d.ts.map +1 -1
  2. package/bin/BuiltinPlugins.js +0 -6
  3. package/bin/BuiltinPlugins.js.map +1 -1
  4. package/bin/asr/Plugin.d.ts +67 -7
  5. package/bin/asr/Plugin.d.ts.map +1 -1
  6. package/bin/asr/Plugin.js +229 -461
  7. package/bin/asr/Plugin.js.map +1 -1
  8. package/bin/asr/types/AsrPlugin.d.ts +114 -0
  9. package/bin/asr/types/AsrPlugin.d.ts.map +1 -0
  10. package/bin/asr/types/AsrPlugin.js +10 -0
  11. package/bin/asr/types/AsrPlugin.js.map +1 -0
  12. package/bin/auth/types/AuthPlugin.d.ts +12 -16
  13. package/bin/auth/types/AuthPlugin.d.ts.map +1 -1
  14. package/bin/auth/types/AuthPlugin.js +9 -13
  15. package/bin/auth/types/AuthPlugin.js.map +1 -1
  16. package/bin/chat/ChatPlugin.d.ts +37 -6
  17. package/bin/chat/ChatPlugin.d.ts.map +1 -1
  18. package/bin/chat/ChatPlugin.js +58 -80
  19. package/bin/chat/ChatPlugin.js.map +1 -1
  20. package/bin/chat/Index.d.ts +4 -1
  21. package/bin/chat/Index.d.ts.map +1 -1
  22. package/bin/chat/Index.js +2 -1
  23. package/bin/chat/Index.js.map +1 -1
  24. package/bin/chat/channels/Configuration.d.ts +1 -1
  25. package/bin/chat/channels/Configuration.js +1 -1
  26. package/bin/chat/channels/RuntimeChannel.d.ts +145 -0
  27. package/bin/chat/channels/RuntimeChannel.d.ts.map +1 -0
  28. package/bin/chat/channels/RuntimeChannel.js +148 -0
  29. package/bin/chat/channels/RuntimeChannel.js.map +1 -0
  30. package/bin/chat/runtime/ChatAuthorizationRuntime.d.ts +22 -0
  31. package/bin/chat/runtime/ChatAuthorizationRuntime.d.ts.map +1 -0
  32. package/bin/chat/runtime/ChatAuthorizationRuntime.js +189 -0
  33. package/bin/chat/runtime/ChatAuthorizationRuntime.js.map +1 -0
  34. package/bin/chat/runtime/ChatChannelActions.d.ts.map +1 -1
  35. package/bin/chat/runtime/ChatChannelActions.js +19 -9
  36. package/bin/chat/runtime/ChatChannelActions.js.map +1 -1
  37. package/bin/chat/runtime/ChatChannelConfig.d.ts +2 -18
  38. package/bin/chat/runtime/ChatChannelConfig.d.ts.map +1 -1
  39. package/bin/chat/runtime/ChatChannelConfig.js +2 -73
  40. package/bin/chat/runtime/ChatChannelConfig.js.map +1 -1
  41. package/bin/chat/runtime/ChatChannelCore.d.ts +22 -1
  42. package/bin/chat/runtime/ChatChannelCore.d.ts.map +1 -1
  43. package/bin/chat/runtime/ChatChannelCore.js +5 -5
  44. package/bin/chat/runtime/ChatChannelCore.js.map +1 -1
  45. package/bin/chat/runtime/ChatPluginActionRegistry.js +1 -1
  46. package/bin/chat/runtime/ChatPluginActionRegistry.js.map +1 -1
  47. package/bin/chat/runtime/PluginPoints.d.ts +3 -3
  48. package/bin/chat/runtime/PluginPoints.js +3 -3
  49. package/bin/chat/types/ChannelStatus.d.ts +1 -1
  50. package/bin/chat/types/ChatPluginOptions.d.ts +76 -0
  51. package/bin/chat/types/ChatPluginOptions.d.ts.map +1 -0
  52. package/bin/chat/types/ChatPluginOptions.js +10 -0
  53. package/bin/chat/types/ChatPluginOptions.js.map +1 -0
  54. package/bin/image/ImagePlugin.d.ts +1 -1
  55. package/bin/image/ImagePlugin.d.ts.map +1 -1
  56. package/bin/image/ImagePlugin.js +23 -5
  57. package/bin/image/ImagePlugin.js.map +1 -1
  58. package/bin/index.d.ts +6 -3
  59. package/bin/index.d.ts.map +1 -1
  60. package/bin/index.js +2 -2
  61. package/bin/index.js.map +1 -1
  62. package/bin/skill/Action.d.ts.map +1 -1
  63. package/bin/skill/Action.js +2 -2
  64. package/bin/skill/Action.js.map +1 -1
  65. package/bin/skill/Command.js +5 -5
  66. package/bin/skill/Command.js.map +1 -1
  67. package/bin/skill/Plugin.js +1 -1
  68. package/bin/skill/Plugin.js.map +1 -1
  69. package/bin/skill/runtime/Discovery.d.ts +4 -4
  70. package/bin/skill/runtime/Discovery.d.ts.map +1 -1
  71. package/bin/skill/runtime/Discovery.js +5 -5
  72. package/bin/skill/runtime/Discovery.js.map +1 -1
  73. package/bin/skill/runtime/Paths.d.ts +1 -5
  74. package/bin/skill/runtime/Paths.d.ts.map +1 -1
  75. package/bin/skill/runtime/Paths.js +1 -9
  76. package/bin/skill/runtime/Paths.js.map +1 -1
  77. package/bin/skill/runtime/Prompt.d.ts +2 -2
  78. package/bin/skill/runtime/Prompt.d.ts.map +1 -1
  79. package/bin/skill/runtime/Prompt.js +3 -3
  80. package/bin/skill/runtime/Prompt.js.map +1 -1
  81. package/bin/skill/runtime/Store.d.ts +2 -2
  82. package/bin/skill/runtime/Store.d.ts.map +1 -1
  83. package/bin/skill/runtime/Store.js.map +1 -1
  84. package/bin/skill/runtime/SystemProvider.js +4 -4
  85. package/bin/skill/runtime/SystemProvider.js.map +1 -1
  86. package/bin/skill/runtime/Types.d.ts +3 -3
  87. package/bin/skill/runtime/Types.d.ts.map +1 -1
  88. package/bin/skill/types/{ClaudeSkill.d.ts → SkillDefinition.d.ts} +4 -4
  89. package/bin/skill/types/SkillDefinition.d.ts.map +1 -0
  90. package/bin/skill/types/{ClaudeSkill.js → SkillDefinition.js} +2 -2
  91. package/bin/skill/types/SkillDefinition.js.map +1 -0
  92. package/bin/skill/types/SkillPlugin.d.ts +2 -2
  93. package/bin/skill/types/SkillPlugin.d.ts.map +1 -1
  94. package/bin/tts/Plugin.d.ts +53 -6
  95. package/bin/tts/Plugin.d.ts.map +1 -1
  96. package/bin/tts/Plugin.js +197 -474
  97. package/bin/tts/Plugin.js.map +1 -1
  98. package/bin/tts/types/TtsPlugin.d.ts +63 -102
  99. package/bin/tts/types/TtsPlugin.d.ts.map +1 -1
  100. package/bin/tts/types/TtsPlugin.js +4 -3
  101. package/bin/tts/types/TtsPlugin.js.map +1 -1
  102. package/bin/web/PROMPT.d.ts +1 -1
  103. package/bin/web/PROMPT.d.ts.map +1 -1
  104. package/bin/web/PROMPT.js +1 -1
  105. package/bin/web/PROMPT.js.map +1 -1
  106. package/bin/web/Plugin.d.ts +66 -5
  107. package/bin/web/Plugin.d.ts.map +1 -1
  108. package/bin/web/Plugin.js +126 -450
  109. package/bin/web/Plugin.js.map +1 -1
  110. package/bin/web/WebPromptAssets.d.ts +1 -9
  111. package/bin/web/WebPromptAssets.d.ts.map +1 -1
  112. package/bin/web/WebPromptAssets.js +1 -11
  113. package/bin/web/WebPromptAssets.js.map +1 -1
  114. package/bin/web/runtime/Install.d.ts +19 -0
  115. package/bin/web/runtime/Install.d.ts.map +1 -0
  116. package/bin/web/runtime/Install.js +178 -0
  117. package/bin/web/runtime/Install.js.map +1 -0
  118. package/bin/web/types/WebPlugin.d.ts +38 -109
  119. package/bin/web/types/WebPlugin.d.ts.map +1 -1
  120. package/bin/web/types/WebPlugin.js +5 -7
  121. package/bin/web/types/WebPlugin.js.map +1 -1
  122. package/bin/workboard/Plugin.d.ts +23 -3
  123. package/bin/workboard/Plugin.d.ts.map +1 -1
  124. package/bin/workboard/Plugin.js +66 -85
  125. package/bin/workboard/Plugin.js.map +1 -1
  126. package/package.json +2 -2
  127. package/src/BuiltinPlugins.ts +0 -6
  128. package/src/asr/Plugin.ts +264 -483
  129. package/src/asr/types/AsrPlugin.ts +118 -0
  130. package/src/auth/types/AuthPlugin.ts +12 -17
  131. package/src/chat/ChatPlugin.ts +92 -89
  132. package/src/chat/Index.ts +18 -1
  133. package/src/chat/channels/Configuration.ts +1 -1
  134. package/src/chat/channels/RuntimeChannel.ts +264 -0
  135. package/src/chat/runtime/ChatAuthorizationRuntime.ts +229 -0
  136. package/src/chat/runtime/ChatChannelActions.ts +24 -9
  137. package/src/chat/runtime/ChatChannelConfig.ts +2 -100
  138. package/src/chat/runtime/ChatChannelCore.ts +20 -8
  139. package/src/chat/runtime/ChatPluginActionRegistry.ts +1 -1
  140. package/src/chat/runtime/PluginPoints.ts +3 -3
  141. package/src/chat/types/ChannelStatus.ts +1 -1
  142. package/src/chat/types/ChatPluginOptions.ts +79 -0
  143. package/src/image/ImagePlugin.ts +23 -5
  144. package/src/index.ts +29 -6
  145. package/src/skill/Action.ts +10 -7
  146. package/src/skill/Command.ts +5 -5
  147. package/src/skill/Plugin.ts +1 -1
  148. package/src/skill/runtime/Discovery.ts +14 -11
  149. package/src/skill/runtime/Paths.ts +1 -13
  150. package/src/skill/runtime/Prompt.ts +5 -5
  151. package/src/skill/runtime/Store.ts +6 -3
  152. package/src/skill/runtime/SystemProvider.ts +4 -4
  153. package/src/skill/runtime/Types.ts +3 -3
  154. package/src/skill/types/{ClaudeSkill.ts → SkillDefinition.ts} +3 -3
  155. package/src/skill/types/SkillPlugin.ts +2 -2
  156. package/src/tts/Plugin.ts +225 -492
  157. package/src/tts/types/TtsPlugin.ts +67 -102
  158. package/src/web/PROMPT.ts +1 -1
  159. package/src/web/PROMPT.ts.txt +32 -6
  160. package/src/web/Plugin.ts +119 -453
  161. package/src/web/WebPromptAssets.ts +1 -13
  162. package/src/web/runtime/Install.ts +241 -0
  163. package/src/web/types/WebPlugin.ts +38 -114
  164. package/src/workboard/Plugin.ts +80 -95
  165. package/bin/asr/Config.d.ts +0 -43
  166. package/bin/asr/Config.d.ts.map +0 -1
  167. package/bin/asr/Config.js +0 -107
  168. package/bin/asr/Config.js.map +0 -1
  169. package/bin/asr/Dependency.d.ts +0 -77
  170. package/bin/asr/Dependency.d.ts.map +0 -1
  171. package/bin/asr/Dependency.js +0 -238
  172. package/bin/asr/Dependency.js.map +0 -1
  173. package/bin/asr/InboundAugment.d.ts +0 -17
  174. package/bin/asr/InboundAugment.d.ts.map +0 -1
  175. package/bin/asr/InboundAugment.js +0 -47
  176. package/bin/asr/InboundAugment.js.map +0 -1
  177. package/bin/asr/ModelCatalog.d.ts +0 -29
  178. package/bin/asr/ModelCatalog.d.ts.map +0 -1
  179. package/bin/asr/ModelCatalog.js +0 -25
  180. package/bin/asr/ModelCatalog.js.map +0 -1
  181. package/bin/auth/Plugin.d.ts +0 -17
  182. package/bin/auth/Plugin.d.ts.map +0 -1
  183. package/bin/auth/Plugin.js +0 -199
  184. package/bin/auth/Plugin.js.map +0 -1
  185. package/bin/chat/ChatPluginTypes.d.ts +0 -122
  186. package/bin/chat/ChatPluginTypes.d.ts.map +0 -1
  187. package/bin/chat/ChatPluginTypes.js +0 -10
  188. package/bin/chat/ChatPluginTypes.js.map +0 -1
  189. package/bin/skill/types/ClaudeSkill.d.ts.map +0 -1
  190. package/bin/skill/types/ClaudeSkill.js.map +0 -1
  191. package/bin/tts/Dependency.d.ts +0 -90
  192. package/bin/tts/Dependency.d.ts.map +0 -1
  193. package/bin/tts/Dependency.js +0 -344
  194. package/bin/tts/Dependency.js.map +0 -1
  195. package/bin/tts/PluginSupport.d.ts +0 -25
  196. package/bin/tts/PluginSupport.d.ts.map +0 -1
  197. package/bin/tts/PluginSupport.js +0 -72
  198. package/bin/tts/PluginSupport.js.map +0 -1
  199. package/bin/tts/runtime/Catalog.d.ts +0 -21
  200. package/bin/tts/runtime/Catalog.d.ts.map +0 -1
  201. package/bin/tts/runtime/Catalog.js +0 -90
  202. package/bin/tts/runtime/Catalog.js.map +0 -1
  203. package/bin/tts/runtime/DependencyInstaller.d.ts +0 -143
  204. package/bin/tts/runtime/DependencyInstaller.d.ts.map +0 -1
  205. package/bin/tts/runtime/DependencyInstaller.js +0 -261
  206. package/bin/tts/runtime/DependencyInstaller.js.map +0 -1
  207. package/bin/tts/runtime/Installer.d.ts +0 -89
  208. package/bin/tts/runtime/Installer.d.ts.map +0 -1
  209. package/bin/tts/runtime/Installer.js +0 -188
  210. package/bin/tts/runtime/Installer.js.map +0 -1
  211. package/bin/tts/runtime/Paths.d.ts +0 -20
  212. package/bin/tts/runtime/Paths.d.ts.map +0 -1
  213. package/bin/tts/runtime/Paths.js +0 -32
  214. package/bin/tts/runtime/Paths.js.map +0 -1
  215. package/bin/tts/runtime/Synthesizer.d.ts +0 -44
  216. package/bin/tts/runtime/Synthesizer.d.ts.map +0 -1
  217. package/bin/tts/runtime/Synthesizer.js +0 -363
  218. package/bin/tts/runtime/Synthesizer.js.map +0 -1
  219. package/bin/tts/types/Tts.d.ts +0 -91
  220. package/bin/tts/types/Tts.d.ts.map +0 -1
  221. package/bin/tts/types/Tts.js +0 -9
  222. package/bin/tts/types/Tts.js.map +0 -1
  223. package/bin/voice/Config.d.ts +0 -43
  224. package/bin/voice/Config.d.ts.map +0 -1
  225. package/bin/voice/Config.js +0 -104
  226. package/bin/voice/Config.js.map +0 -1
  227. package/bin/voice/Dependency.d.ts +0 -77
  228. package/bin/voice/Dependency.d.ts.map +0 -1
  229. package/bin/voice/Dependency.js +0 -237
  230. package/bin/voice/Dependency.js.map +0 -1
  231. package/bin/voice/InboundAugment.d.ts +0 -17
  232. package/bin/voice/InboundAugment.d.ts.map +0 -1
  233. package/bin/voice/InboundAugment.js +0 -47
  234. package/bin/voice/InboundAugment.js.map +0 -1
  235. package/bin/voice/ModelCatalog.d.ts +0 -29
  236. package/bin/voice/ModelCatalog.d.ts.map +0 -1
  237. package/bin/voice/ModelCatalog.js +0 -25
  238. package/bin/voice/ModelCatalog.js.map +0 -1
  239. package/bin/voice/runtime/Catalog.d.ts +0 -18
  240. package/bin/voice/runtime/Catalog.d.ts.map +0 -1
  241. package/bin/voice/runtime/Catalog.js +0 -61
  242. package/bin/voice/runtime/Catalog.js.map +0 -1
  243. package/bin/voice/runtime/DependencyInstaller.d.ts +0 -145
  244. package/bin/voice/runtime/DependencyInstaller.d.ts.map +0 -1
  245. package/bin/voice/runtime/DependencyInstaller.js +0 -309
  246. package/bin/voice/runtime/DependencyInstaller.js.map +0 -1
  247. package/bin/voice/runtime/Installer.d.ts +0 -94
  248. package/bin/voice/runtime/Installer.d.ts.map +0 -1
  249. package/bin/voice/runtime/Installer.js +0 -200
  250. package/bin/voice/runtime/Installer.js.map +0 -1
  251. package/bin/voice/runtime/Paths.d.ts +0 -8
  252. package/bin/voice/runtime/Paths.d.ts.map +0 -1
  253. package/bin/voice/runtime/Paths.js +0 -26
  254. package/bin/voice/runtime/Paths.js.map +0 -1
  255. package/bin/voice/runtime/Transcriber.d.ts +0 -57
  256. package/bin/voice/runtime/Transcriber.d.ts.map +0 -1
  257. package/bin/voice/runtime/Transcriber.js +0 -329
  258. package/bin/voice/runtime/Transcriber.js.map +0 -1
  259. package/bin/voice/types/Voice.d.ts +0 -58
  260. package/bin/voice/types/Voice.d.ts.map +0 -1
  261. package/bin/voice/types/Voice.js +0 -9
  262. package/bin/voice/types/Voice.js.map +0 -1
  263. package/bin/voice/types/VoicePlugin.d.ts +0 -190
  264. package/bin/voice/types/VoicePlugin.d.ts.map +0 -1
  265. package/bin/voice/types/VoicePlugin.js +0 -9
  266. package/bin/voice/types/VoicePlugin.js.map +0 -1
  267. package/bin/web/Dependency.d.ts +0 -10
  268. package/bin/web/Dependency.d.ts.map +0 -1
  269. package/bin/web/Dependency.js +0 -10
  270. package/bin/web/Dependency.js.map +0 -1
  271. package/bin/web/PROMPT.agent-browser.d.ts +0 -7
  272. package/bin/web/PROMPT.agent-browser.d.ts.map +0 -1
  273. package/bin/web/PROMPT.agent-browser.js +0 -8
  274. package/bin/web/PROMPT.agent-browser.js.map +0 -1
  275. package/bin/web/PROMPT.web-access.d.ts +0 -7
  276. package/bin/web/PROMPT.web-access.d.ts.map +0 -1
  277. package/bin/web/PROMPT.web-access.js +0 -8
  278. package/bin/web/PROMPT.web-access.js.map +0 -1
  279. package/bin/web/runtime/Config.d.ts +0 -21
  280. package/bin/web/runtime/Config.d.ts.map +0 -1
  281. package/bin/web/runtime/Config.js +0 -79
  282. package/bin/web/runtime/Config.js.map +0 -1
  283. package/bin/web/runtime/Source.d.ts +0 -29
  284. package/bin/web/runtime/Source.d.ts.map +0 -1
  285. package/bin/web/runtime/Source.js +0 -209
  286. package/bin/web/runtime/Source.js.map +0 -1
  287. package/src/asr/Config.ts +0 -138
  288. package/src/asr/Dependency.ts +0 -336
  289. package/src/asr/InboundAugment.ts +0 -59
  290. package/src/asr/ModelCatalog.ts +0 -43
  291. package/src/auth/Plugin.ts +0 -237
  292. package/src/chat/ChatPluginTypes.ts +0 -126
  293. package/src/tts/Dependency.ts +0 -473
  294. package/src/tts/PluginSupport.ts +0 -85
  295. package/src/tts/runtime/Catalog.ts +0 -97
  296. package/src/tts/runtime/DependencyInstaller.ts +0 -436
  297. package/src/tts/runtime/Installer.ts +0 -297
  298. package/src/tts/runtime/Paths.ts +0 -39
  299. package/src/tts/runtime/Synthesizer.ts +0 -480
  300. package/src/tts/types/Tts.ts +0 -99
  301. package/src/voice/Config.ts +0 -135
  302. package/src/voice/Dependency.ts +0 -329
  303. package/src/voice/InboundAugment.ts +0 -59
  304. package/src/voice/ModelCatalog.ts +0 -43
  305. package/src/voice/runtime/Catalog.ts +0 -68
  306. package/src/voice/runtime/DependencyInstaller.ts +0 -505
  307. package/src/voice/runtime/Installer.ts +0 -324
  308. package/src/voice/runtime/Paths.ts +0 -26
  309. package/src/voice/runtime/Transcriber.ts +0 -467
  310. package/src/voice/types/Voice.ts +0 -68
  311. package/src/voice/types/VoicePlugin.ts +0 -194
  312. package/src/web/Dependency.ts +0 -17
  313. package/src/web/PROMPT.agent-browser.ts +0 -9
  314. package/src/web/PROMPT.agent-browser.ts.txt +0 -17
  315. package/src/web/PROMPT.web-access.ts +0 -9
  316. package/src/web/PROMPT.web-access.ts.txt +0 -13
  317. package/src/web/runtime/Config.ts +0 -105
  318. package/src/web/runtime/Source.ts +0 -257
package/bin/tts/Plugin.js CHANGED
@@ -1,491 +1,214 @@
1
1
  /**
2
- * TTS Plugin。
2
+ * TtsPlugin:文本转语音插件。
3
3
  *
4
4
  * 关键点(中文)
5
- * - TTS Plugin 现在自己内聚本地模型与 Python 依赖,不再依赖 console 模型池。
6
- * - Console 只通过 setup / action 与插件交互,保持极简统一。
5
+ * - TTS 能力通过 constructor 注入,推荐传入 `city.ai.tts`。
6
+ * - plugin 不负责本地模型、Python 依赖、provider 或项目配置。
7
+ * - action 返回 AI SDK UIMessage,音频 file part 会由 plugin tool bridge 统一落盘到资源目录。
7
8
  */
8
9
  import { BasePlugin } from "@downcity/agent/internal/plugin/core/BasePlugin.js";
9
- import { isPluginEnabled } from "@downcity/agent/internal/plugin/core/Activation.js";
10
- import { writeProjectPluginEnabled } from "@downcity/agent/internal/plugin/core/ProjectConfigStore.js";
11
- import { checkTtsSynthesizer, installTtsSynthesizer, listTtsModelOptions, readTtsPluginConfig, writeTtsPluginConfig, } from "../tts/Dependency.js";
12
- import { resolveTtsModelId } from "../tts/runtime/Catalog.js";
13
- import { synthesizeSpeechFile } from "../tts/runtime/Synthesizer.js";
14
- import { getBooleanOpt, getNumberOpt, getStringOpt, toJsonObject, } from "../tts/PluginSupport.js";
15
- function createTtsPluginDefinition(plugin) {
10
+ const DEFAULT_TTS_PLUGIN_NAME = "tts";
11
+ const DEFAULT_TTS_PLUGIN_TITLE = "TTS";
12
+ const DEFAULT_TTS_PLUGIN_DESCRIPTION = "Synthesize speech through an injected TTS function and return assistant audio file parts.";
13
+ const DEFAULT_MEDIA_TYPE = "audio/wav";
14
+ const DEFAULT_FILENAME = "speech.wav";
15
+ /**
16
+ * 判断值是否为普通对象。
17
+ */
18
+ function to_record(value) {
19
+ if (!value || typeof value !== "object" || Array.isArray(value))
20
+ return null;
21
+ return value;
22
+ }
23
+ /**
24
+ * 归一化 action payload。
25
+ */
26
+ function normalize_tts_payload(payload) {
27
+ const record = to_record(payload ?? {});
28
+ if (!record) {
29
+ throw new TypeError("TtsPlugin.synthesize payload must be an object");
30
+ }
31
+ const text = typeof record.text === "string" ? record.text.trim() : "";
32
+ if (!text) {
33
+ throw new Error("TtsPlugin.synthesize requires text");
34
+ }
16
35
  return {
17
- name: "tts",
18
- title: "Text To Speech",
19
- description: "Generates local speech audio files from plain text through an installed TTS model, then returns a reusable audio file tag for downstream sending.",
20
- config: {
21
- plugin: "tts",
22
- scope: "project",
23
- defaultValue: {
24
- provider: "local",
25
- modelId: "qwen3-tts-0.6b",
26
- format: "wav",
27
- speed: 1,
28
- },
29
- },
30
- setup: {
31
- mode: "install-configure",
32
- title: "安装语音合成",
33
- description: "选择模型后直接完成模型下载、独立运行环境准备与配置写入。",
34
- fields: [
35
- {
36
- key: "modelId",
37
- label: "模型",
38
- type: "select",
39
- required: true,
40
- sourceAction: "models",
41
- },
42
- {
43
- key: "format",
44
- label: "输出格式",
45
- type: "select",
46
- required: true,
47
- options: [
48
- { label: "WAV", value: "wav" },
49
- { label: "FLAC", value: "flac" },
50
- ],
51
- },
52
- ],
53
- primaryAction: "install",
54
- statusAction: "status",
55
- },
56
- usage: {
57
- title: "配置语音合成",
58
- description: "设置当前 agent 默认使用的语音模型与输出参数。",
59
- fields: [
60
- {
61
- key: "modelId",
62
- label: "默认模型",
63
- type: "select",
64
- required: true,
65
- sourceAction: "models",
66
- },
67
- {
68
- key: "format",
69
- label: "输出格式",
70
- type: "select",
71
- required: true,
72
- options: [
73
- { label: "WAV", value: "wav", description: "兼容性最好,适合绝大多数渠道。" },
74
- { label: "FLAC", value: "flac", description: "体积更小,适合存档或传输。" },
75
- ],
76
- },
77
- {
78
- key: "speed",
79
- label: "默认语速",
80
- type: "number",
81
- placeholder: "1",
82
- description: "1 为正常语速,可按需要设置为 0.8、1.2 等。",
83
- },
84
- {
85
- key: "language",
86
- label: "默认语言提示",
87
- type: "string",
88
- placeholder: "auto / zh / en",
89
- },
90
- {
91
- key: "voice",
92
- label: "默认音色",
93
- type: "string",
94
- placeholder: "可选音色 ID",
95
- },
96
- ],
97
- saveAction: "configure",
98
- statusAction: "status",
99
- },
100
- async availability(context) {
101
- if (!isPluginEnabled({ plugin, context })) {
102
- return {
103
- enabled: false,
104
- available: false,
105
- reasons: ["tts plugin disabled in project config"],
106
- };
107
- }
108
- const dependencyStatus = await checkTtsSynthesizer(context);
109
- return {
110
- enabled: true,
111
- available: dependencyStatus.available,
112
- reasons: dependencyStatus.reasons,
113
- };
114
- },
115
- actions: {
116
- status: {
117
- allowWhenDisabled: true,
118
- command: {
119
- description: "查看 tts plugin 当前状态",
120
- mapInput() {
121
- return {};
122
- },
123
- },
124
- execute: async ({ context }) => {
125
- const config = readTtsPluginConfig(context);
126
- const availability = await plugin.availability(context);
127
- const synthesizer = await checkTtsSynthesizer(context);
128
- return {
129
- success: true,
130
- data: {
131
- plugin: toJsonObject(config) || {},
132
- availability: {
133
- enabled: availability.enabled,
134
- available: availability.available,
135
- reasons: availability.reasons,
136
- },
137
- synthesizer: {
138
- available: synthesizer.available,
139
- reasons: synthesizer.reasons,
140
- details: synthesizer.details || null,
141
- },
142
- },
143
- };
144
- },
145
- },
146
- doctor: {
147
- allowWhenDisabled: true,
148
- command: {
149
- description: "检查 tts plugin 依赖状态",
150
- mapInput() {
151
- return {};
152
- },
153
- },
154
- execute: async ({ context }) => {
155
- const result = await checkTtsSynthesizer(context);
156
- return {
157
- success: true,
158
- data: {
159
- available: result.available,
160
- reasons: result.reasons,
161
- details: result.details || null,
162
- },
163
- };
164
- },
165
- },
166
- models: {
167
- allowWhenDisabled: true,
168
- command: {
169
- description: "列出可用于 tts 的本地模型",
170
- mapInput() {
171
- return {};
172
- },
173
- },
174
- execute: async () => {
175
- return {
176
- success: true,
177
- data: {
178
- options: listTtsModelOptions(),
179
- },
180
- };
181
- },
182
- },
183
- install: {
184
- allowWhenDisabled: true,
185
- command: {
186
- description: "安装 tts 语音合成依赖",
187
- configure(command) {
188
- command
189
- .argument("[models...]")
190
- .option("--active-model <modelId>", "安装完成后设为当前模型")
191
- .option("--models-dir <path>", "模型目录(可选)")
192
- .option("--python <bin>", "Python 可执行文件(默认 python3)")
193
- .option("--no-install-deps", "跳过依赖安装")
194
- .option("--force", "强制覆盖已存在资源")
195
- .option("--hf-token <token>", "HuggingFace token(可选)")
196
- .option("--format <format>", "默认输出格式(wav/flac)");
197
- },
198
- mapInput({ args, opts }) {
199
- return {
200
- modelIds: args,
201
- ...(getStringOpt(opts, "activeModel")
202
- ? { activeModel: getStringOpt(opts, "activeModel") }
203
- : {}),
204
- ...(getStringOpt(opts, "modelsDir")
205
- ? { modelsDir: getStringOpt(opts, "modelsDir") }
206
- : {}),
207
- ...(getStringOpt(opts, "python")
208
- ? { pythonBin: getStringOpt(opts, "python") }
209
- : {}),
210
- installDeps: getBooleanOpt(opts, "installDeps", true),
211
- force: getBooleanOpt(opts, "force", false),
212
- ...(getStringOpt(opts, "hfToken")
213
- ? { hfToken: getStringOpt(opts, "hfToken") }
214
- : {}),
215
- ...(getStringOpt(opts, "format")
216
- ? { format: getStringOpt(opts, "format") }
217
- : {}),
218
- };
219
- },
220
- },
221
- execute: async ({ context, payload }) => {
222
- const result = await installTtsSynthesizer({
223
- context,
224
- input: payload && typeof payload === "object" && !Array.isArray(payload)
225
- ? payload
226
- : undefined,
227
- });
228
- return {
229
- success: result.success,
230
- ...(result.message ? { message: result.message } : {}),
231
- ...(result.details !== undefined ? { data: result.details } : {}),
232
- ...(result.success ? {} : { error: result.message || "install failed" }),
233
- };
234
- },
235
- },
236
- configure: {
237
- allowWhenDisabled: true,
238
- execute: async ({ context, payload }) => {
239
- const payloadObject = payload && typeof payload === "object" && !Array.isArray(payload)
240
- ? payload
241
- : {};
242
- const { enabled: _ignoredEnabled, ...patch } = payloadObject;
243
- const current = readTtsPluginConfig(context);
244
- const next = {
245
- ...current,
246
- ...patch,
247
- };
248
- await writeTtsPluginConfig({
249
- context,
250
- value: next,
251
- });
252
- return {
253
- success: true,
254
- data: {
255
- plugin: toJsonObject(next) || {},
256
- },
257
- };
258
- },
259
- },
260
- on: {
261
- allowWhenDisabled: true,
262
- command: {
263
- description: "启用 tts plugin,并可选安装本地依赖",
264
- configure(command) {
265
- command
266
- .argument("[models...]")
267
- .option("--active-model <modelId>", "安装完成后设为当前模型")
268
- .option("--models-dir <path>", "模型目录(可选)")
269
- .option("--python <bin>", "Python 可执行文件(默认 python3)")
270
- .option("--no-install", "仅启用 plugin,不安装依赖")
271
- .option("--no-install-deps", "跳过依赖安装")
272
- .option("--force", "强制覆盖已存在资源")
273
- .option("--hf-token <token>", "HuggingFace token(可选)")
274
- .option("--format <format>", "默认输出格式(wav/flac)");
275
- },
276
- mapInput({ args, opts }) {
277
- return {
278
- modelIds: args,
279
- ...(getStringOpt(opts, "activeModel")
280
- ? { activeModel: getStringOpt(opts, "activeModel") }
281
- : {}),
282
- ...(getStringOpt(opts, "modelsDir")
283
- ? { modelsDir: getStringOpt(opts, "modelsDir") }
284
- : {}),
285
- ...(getStringOpt(opts, "python")
286
- ? { pythonBin: getStringOpt(opts, "python") }
287
- : {}),
288
- install: getBooleanOpt(opts, "install", true),
289
- installDeps: getBooleanOpt(opts, "installDeps", true),
290
- force: getBooleanOpt(opts, "force", false),
291
- ...(getStringOpt(opts, "hfToken")
292
- ? { hfToken: getStringOpt(opts, "hfToken") }
293
- : {}),
294
- ...(getStringOpt(opts, "format")
295
- ? { format: getStringOpt(opts, "format") }
296
- : {}),
297
- };
298
- },
299
- },
300
- execute: async ({ context, payload }) => {
301
- await writeProjectPluginEnabled({
302
- pluginName: "tts",
303
- enabled: true,
304
- context,
305
- });
306
- if (payload.install !== false) {
307
- const installResult = await installTtsSynthesizer({
308
- context,
309
- input: payload && typeof payload === "object" && !Array.isArray(payload)
310
- ? payload
311
- : undefined,
312
- });
313
- if (!installResult.success) {
314
- return {
315
- success: false,
316
- error: installResult.message || "tts dependency install failed",
317
- message: installResult.message || "tts dependency install failed",
318
- };
319
- }
320
- }
321
- return {
322
- success: true,
323
- data: {
324
- plugin: toJsonObject(readTtsPluginConfig(context)) || {},
325
- },
326
- };
327
- },
328
- },
329
- off: {
330
- command: {
331
- description: "关闭 tts plugin",
332
- mapInput() {
333
- return {};
334
- },
335
- },
336
- execute: async ({ context }) => {
337
- await writeProjectPluginEnabled({
338
- pluginName: "tts",
339
- enabled: false,
340
- context,
341
- });
342
- return {
343
- success: true,
344
- data: {
345
- plugin: toJsonObject(readTtsPluginConfig(context)) || {},
346
- },
347
- };
348
- },
36
+ ...record,
37
+ text,
38
+ };
39
+ }
40
+ /**
41
+ * 判断返回值是否已经是 AI SDK UIMessage。
42
+ */
43
+ function is_ui_message_result(value) {
44
+ const record = to_record(value);
45
+ return Boolean(record && Array.isArray(record.parts));
46
+ }
47
+ /**
48
+ * 读取简单音频结果中的 URL。
49
+ */
50
+ function read_audio_url(record) {
51
+ const url = typeof record.url === "string"
52
+ ? record.url.trim()
53
+ : typeof record.data_url === "string"
54
+ ? record.data_url.trim()
55
+ : typeof record.audio_path === "string"
56
+ ? record.audio_path.trim()
57
+ : "";
58
+ if (!url) {
59
+ throw new TypeError("TtsPlugin tts function must return a UIMessage or { url | data_url | audio_path }");
60
+ }
61
+ return url;
62
+ }
63
+ /**
64
+ * 把简单音频结果归一为 UIMessage。
65
+ */
66
+ function simple_audio_to_ui_message(result) {
67
+ const record = to_record(result);
68
+ if (!record) {
69
+ throw new TypeError("TtsPlugin tts function returned an invalid result");
70
+ }
71
+ const url = read_audio_url(record);
72
+ const media_type = typeof record.media_type === "string" && record.media_type.trim()
73
+ ? record.media_type.trim()
74
+ : DEFAULT_MEDIA_TYPE;
75
+ const filename = typeof record.filename === "string" && record.filename.trim()
76
+ ? record.filename.trim()
77
+ : DEFAULT_FILENAME;
78
+ const text = typeof record.text === "string" ? record.text.trim() : "";
79
+ return {
80
+ id: `tts:${Date.now()}`,
81
+ role: "assistant",
82
+ parts: [
83
+ ...(text ? [{ type: "text", text }] : []),
84
+ {
85
+ type: "file",
86
+ mediaType: media_type,
87
+ filename,
88
+ url,
349
89
  },
350
- use: {
351
- allowWhenDisabled: true,
352
- command: {
353
- description: "切换 tts 当前模型",
354
- configure(command) {
355
- command.argument("<modelId>");
356
- },
357
- mapInput({ args }) {
358
- const modelId = String(args[0] || "").trim();
359
- if (!modelId) {
360
- throw new Error("modelId is required");
361
- }
362
- return {
363
- modelId,
364
- };
365
- },
366
- },
367
- execute: async ({ context, payload }) => {
368
- const modelId = String(payload.modelId || "").trim();
369
- const resolvedModelId = resolveTtsModelId(modelId);
370
- if (!resolvedModelId) {
371
- return {
372
- success: false,
373
- error: `Unsupported tts model: ${modelId}`,
374
- message: `Unsupported tts model: ${modelId}`,
375
- };
376
- }
377
- const nextConfig = await writeTtsPluginConfig({
378
- context,
379
- value: {
380
- ...readTtsPluginConfig(context),
381
- modelId: resolvedModelId,
382
- },
383
- });
90
+ ],
91
+ };
92
+ }
93
+ /**
94
+ * 校验并归一化 TTS 返回结果。
95
+ */
96
+ function normalize_tts_result(result) {
97
+ if (is_ui_message_result(result)) {
98
+ return result;
99
+ }
100
+ return simple_audio_to_ui_message(result);
101
+ }
102
+ /**
103
+ * Agent TTS 插件。
104
+ */
105
+ export class TtsPlugin extends BasePlugin {
106
+ /**
107
+ * 当前 plugin 稳定名称。
108
+ */
109
+ name;
110
+ /**
111
+ * 插件标题。
112
+ */
113
+ title;
114
+ /**
115
+ * 插件说明。
116
+ */
117
+ description;
118
+ tts;
119
+ language;
120
+ voice;
121
+ format;
122
+ constructor(options) {
123
+ super();
124
+ const name = String(options.name || DEFAULT_TTS_PLUGIN_NAME).trim();
125
+ if (!name) {
126
+ throw new Error("TtsPlugin requires a non-empty name");
127
+ }
128
+ if (typeof options.tts !== "function") {
129
+ throw new Error("TtsPlugin requires a tts function");
130
+ }
131
+ this.name = name;
132
+ this.title = String(options.title || DEFAULT_TTS_PLUGIN_TITLE).trim();
133
+ this.description = String(options.description || DEFAULT_TTS_PLUGIN_DESCRIPTION).trim();
134
+ this.tts = options.tts;
135
+ this.language =
136
+ typeof options.language === "string" && options.language.trim()
137
+ ? options.language.trim()
138
+ : undefined;
139
+ this.voice =
140
+ typeof options.voice === "string" && options.voice.trim()
141
+ ? options.voice.trim()
142
+ : undefined;
143
+ this.format =
144
+ typeof options.format === "string" && options.format.trim()
145
+ ? options.format.trim()
146
+ : undefined;
147
+ }
148
+ /**
149
+ * TTS 插件给模型的使用说明。
150
+ */
151
+ system(_context) {
152
+ return [
153
+ "# TTS Plugin",
154
+ "",
155
+ "Use this plugin when the user asks to create spoken audio, voice output, narration, or a reusable audio file.",
156
+ "Do not call it for ordinary text replies unless the user explicitly wants audio.",
157
+ "",
158
+ "Call through `plugin_call`:",
159
+ "",
160
+ "```ts",
161
+ "plugin_call({",
162
+ ` plugin: "${this.name}",`,
163
+ ' action: "synthesize",',
164
+ " payload: {",
165
+ ' text: "...",',
166
+ " },",
167
+ "});",
168
+ "```",
169
+ "",
170
+ "Payload rules:",
171
+ "- `text` is required.",
172
+ "- Optional fields: `language`, `voice`, `format`, `speed`, `provider_options`.",
173
+ "- The returned audio file part is saved under project `.downcity/resources` and attached to the final assistant message automatically.",
174
+ ].join("\n");
175
+ }
176
+ /**
177
+ * 执行一次 TTS 合成。
178
+ */
179
+ async synthesize(input) {
180
+ const result = await this.tts({
181
+ ...(this.language ? { language: this.language } : {}),
182
+ ...(this.voice ? { voice: this.voice } : {}),
183
+ ...(this.format ? { format: this.format } : {}),
184
+ ...input,
185
+ });
186
+ return normalize_tts_result(result);
187
+ }
188
+ /**
189
+ * 显式 action 集合。
190
+ */
191
+ actions = {
192
+ synthesize: {
193
+ execute: async ({ payload }) => {
194
+ try {
195
+ const input = normalize_tts_payload(payload);
196
+ const message = await this.synthesize(input);
384
197
  return {
385
198
  success: true,
386
- data: {
387
- plugin: toJsonObject(nextConfig) || {},
388
- },
199
+ data: message,
200
+ message: "speech synthesized",
389
201
  };
390
- },
391
- },
392
- synthesize: {
393
- command: {
394
- description: "将文本生成语音文件",
395
- configure(command) {
396
- command
397
- .argument("<text>")
398
- .option("--model <modelId>", "语音模型 ID")
399
- .option("--language <language>", "语言提示(可选,例如 zh / en)")
400
- .option("--voice <voice>", "音色 ID(可选)")
401
- .option("--format <format>", "输出格式(wav/flac)")
402
- .option("--speed <speed>", "语速倍率", Number)
403
- .option("--output <path>", "输出文件路径或目录(可选)");
404
- },
405
- mapInput({ args, opts }) {
406
- const text = String(args[0] || "").trim();
407
- if (!text) {
408
- throw new Error("text is required");
409
- }
410
- return {
411
- text,
412
- ...(getStringOpt(opts, "model")
413
- ? { modelId: getStringOpt(opts, "model") }
414
- : {}),
415
- ...(getStringOpt(opts, "language")
416
- ? { language: getStringOpt(opts, "language") }
417
- : {}),
418
- ...(getStringOpt(opts, "voice")
419
- ? { voice: getStringOpt(opts, "voice") }
420
- : {}),
421
- ...(getStringOpt(opts, "format")
422
- ? { format: getStringOpt(opts, "format") }
423
- : {}),
424
- ...(typeof getNumberOpt(opts, "speed") === "number"
425
- ? { speed: getNumberOpt(opts, "speed") }
426
- : {}),
427
- ...(getStringOpt(opts, "output")
428
- ? { output: getStringOpt(opts, "output") }
429
- : {}),
430
- };
431
- },
432
- },
433
- execute: async ({ context, payload }) => {
434
- const pluginStatus = await plugin.availability(context);
435
- if (!pluginStatus.enabled || !pluginStatus.available) {
436
- return {
437
- success: false,
438
- error: pluginStatus.reasons[0] || "tts plugin unavailable",
439
- message: pluginStatus.reasons[0] || "tts plugin unavailable",
440
- };
441
- }
442
- const input = payload && typeof payload === "object" && !Array.isArray(payload)
443
- ? payload
444
- : {};
445
- const result = await synthesizeSpeechFile({
446
- context,
447
- config: readTtsPluginConfig(context),
448
- input,
449
- });
202
+ }
203
+ catch (error) {
450
204
  return {
451
- success: true,
452
- data: {
453
- outputPath: result.outputPath,
454
- fileTag: result.fileTag,
455
- bytes: result.bytes,
456
- ...(result.stderrSummary ? { stderr: result.stderrSummary } : {}),
457
- },
205
+ success: false,
206
+ error: String(error),
207
+ message: String(error),
458
208
  };
459
- },
209
+ }
460
210
  },
461
211
  },
462
- system(context) {
463
- if (!isPluginEnabled({ plugin, context })) {
464
- return "";
465
- }
466
- return [
467
- "# TTS Plugin",
468
- "The agent can call the tts plugin to synthesize speech audio from plain text.",
469
- "Typical usage flow:",
470
- "1. Check availability with the `status` action when you need to confirm whether the plugin and model are ready.",
471
- "2. Generate audio with the `synthesize` action.",
472
- "3. Optionally override synthesis parameters in the action payload: `voice`, `language`, `format`, `speed`, and `output`.",
473
- "Use the `tts.synthesize` action when the user asks to generate spoken audio or a reusable audio file tag.",
474
- "A successful synthesis returns a local output path and a reusable `<file type=\"audio\">...</file>` tag for downstream sending.",
475
- "If the Python runner prints non-fatal stderr, the command still succeeds and returns that stderr summary as extra context.",
476
- "Example: `plugin_call({ plugin: \"tts\", action: \"synthesize\", payload: { text: \"你好,欢迎来到 Downcity\", format: \"wav\" } })`",
477
- ].join("\n");
478
- },
479
212
  };
480
213
  }
481
- /**
482
- * TtsPlugin:文本转语音插件。
483
- */
484
- export class TtsPlugin extends BasePlugin {
485
- name = "tts";
486
- constructor() {
487
- super();
488
- Object.assign(this, createTtsPluginDefinition(this));
489
- }
490
- }
491
214
  //# sourceMappingURL=Plugin.js.map