Built-ins

sound Plugin

使用 FED 模型目录统一提供 ASR 语音识别、TTS 语音合成和 chat 入站自动转写

sound Plugin

sound 是统一的语音能力 plugin。它从 FED 模型目录发现支持 asrtts 的模型,并通过 City AI Service 完成真实调用。

sound 不下载或运行本地语音模型,也不依赖 Python、Whisper、Piper 等本地推理环境。本地音频文件只会被读取并转换成 data URL,然后发送给 FED。

创建 plugin

import { SoundPlugin } from "@downcity/plugins";

const sound = new SoundPlugin({
  list_models: async () => {
    const catalog = await city.ai.listModels();
    return catalog.all().filter((model) =>
      model.modalities.includes("asr") || model.modalities.includes("tts")
    );
  },
  asr: (input) => city.ai.asr(input),
  tts: (input) => city.ai.tts(input),
});

Actions

models

列出 FED 中支持语音能力的模型:

plugin_call({
  plugin: "sound",
  action: "models",
  payload: { capability: "asr" },
});

capability 可为 asrtts。不传时返回支持任意一种语音能力的模型,模型的 modalities 字段说明其具体能力。

asr

使用 FED ASR 模型转写音频:

plugin_call({
  plugin: "sound",
  action: "asr",
  payload: {
    model: "asr-model-id",
    audio_path: "./input.wav",
  },
});

音频来源必须提供以下一种:

  • audio_path:本地绝对路径或相对 Agent 项目根目录的路径
  • url:远程音频 URL
  • data_url:data URL 音频内容

结果采用与 AI SDK TranscriptionResult 对齐的可序列化核心字段:

{
  text: string;
  segments?: Array<{
    text: string;
    startSecond: number;
    endSecond: number;
  }>;
  language?: string;
  durationInSeconds?: number;
}

tts

使用 FED TTS 模型生成语音:

plugin_call({
  plugin: "sound",
  action: "tts",
  payload: {
    model: "tts-model-id",
    text: "欢迎回来",
    voice: "alloy",
    format: "mp3",
  },
});

TTS 返回 AI SDK UIMessage。音频使用 file part 表示,Agent 会统一把资源保存到项目资源目录并附加到 assistant 消息。

默认模型

可以分别配置默认 ASR 与 TTS 模型:

new SoundPlugin({
  default_asr_model: "asr-model-id",
  default_tts_model: "tts-model-id",
  list_models,
  asr,
  tts,
});

未配置默认模型且 action 未传 model 时,调用会失败并提示先读取 sound.models,不会隐式选择模型。

自动转写 chat 语音

auto_asr: true 会在 chat 入站阶段自动转写 voice / audio 附件。自动路径无法交互选择模型,因此必须同时配置 default_asr_model

new SoundPlugin({
  auto_asr: true,
  default_asr_model: "asr-model-id",
  list_models,
  asr,
  tts,
});

转写文本会作为 <voice src="...">...</voice> 追加到用户正文。单个附件转写失败不会阻断 chat 主链路。