diff --git a/AGENTS.md b/AGENTS.md index dfe59f3..1f51484 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,8 +49,8 @@ skill 或其他脚本应通过上述命令定位资源,避免硬编码 `~/work ```bash mytoolkit env set secrets.api_keys.ark -mytoolkit env set secrets.api_keys.volc_tts # TTS 新版 API Key(X-Api-Key) -mytoolkit env set secrets.volcengine.app_id # STT 旧版应用凭证 +mytoolkit env set secrets.api_keys.volc_tts # TTS/STT 新版 API Key(X-Api-Key,推荐) +mytoolkit env set secrets.volcengine.app_id # 旧版应用凭证(回退用) mytoolkit env set secrets.volcengine.access_token mytoolkit env list # 查看所有 key mytoolkit env export # 导出为 shell export 语句 @@ -80,7 +80,7 @@ mytoolkit voice tts "文本" -v zh_female_xiaohe_uranus_bigtts --format mp3 --sp ### 语音识别 (STT) -豆包录音文件识别极速版(flash ASR),STT 仍用旧版 `secrets.volcengine.app_id` / `access_token`(TTS 已改用 `secrets.api_keys.volc_tts`): +豆包录音文件识别极速版(flash ASR),STT 优先用新版 **API Key**(`secrets.api_keys.volc_tts`,`X-Api-Key` 鉴权,与 TTS 同一个 key),旧版 `secrets.volcengine.app_id` / `access_token` 仅作回退: ```bash mytoolkit voice stt -i clip.webm diff --git a/mytoolkit/api/asr.py b/mytoolkit/api/asr.py index 095a017..450837d 100644 --- a/mytoolkit/api/asr.py +++ b/mytoolkit/api/asr.py @@ -126,13 +126,19 @@ def transcribe_flash( token: str, audio_path: str | Path, *, + api_key: str | None = None, uid: str | None = None, timeout_sec: float = 60.0, hotwords: Sequence[str] | None = None, history: Sequence[str] | None = None, scene_hints: Sequence[str] | None = None, ) -> str: - """Transcribe a local audio file via Doubao flash ASR. Returns text.""" + """Transcribe a local audio file via Doubao flash ASR. Returns text. + + ``api_key`` (new-console X-Api-Key) is preferred; without it the legacy + App ID + Access Token pair (``X-Api-App-Key`` / ``X-Api-Access-Key``) + is used. + """ path = Path(audio_path) if not path.is_file(): raise FileNotFoundError(str(path)) @@ -143,12 +149,15 @@ def transcribe_flash( headers = { "Content-Type": "application/json", - "X-Api-App-Key": appid, - "X-Api-Access-Key": token, "X-Api-Resource-Id": _RESOURCE_ID, "X-Api-Request-Id": str(uuid.uuid4()), "X-Api-Sequence": "-1", } + if api_key: + headers["X-Api-Key"] = api_key + else: + headers["X-Api-App-Key"] = appid + headers["X-Api-Access-Key"] = token request_body: dict[str, Any] = { "model_name": "bigmodel", "enable_itn": True, @@ -162,7 +171,7 @@ def transcribe_flash( request_body["corpus"] = corpus body = { - "user": {"uid": uid or appid}, + "user": {"uid": uid or appid or "xiaohe"}, "audio": { "data": base64.b64encode(audio_bytes).decode("ascii"), "format": fmt, diff --git a/mytoolkit/commands/voice.py b/mytoolkit/commands/voice.py index c355aac..7f51177 100644 --- a/mytoolkit/commands/voice.py +++ b/mytoolkit/commands/voice.py @@ -22,10 +22,10 @@ _FORMAT_CHOICES = ["mp3", "wav", "pcm"] def _get_credentials(): - """Get Volcengine appid + access_token (STT, legacy TTS). + """Get legacy Volcengine appid + access_token (STT/TTS fallback). - STT still uses the legacy appid/token app auth; the newer X-Api-Key path is - TTS-only and lives in ``_get_tts_credentials``. + The new-console X-Api-Key (``secrets.api_keys.volc_tts``) is preferred for + both TTS and STT; the legacy appid/token pair survives as fallback. """ appid = config.resolve_key("secrets.volcengine.app_id", "VOLC_APPID") access_token = config.resolve_key( @@ -36,8 +36,8 @@ def _get_credentials(): return appid, access_token -def _get_tts_credentials() -> dict: - """TTS credentials from config (new api_key preferred). +def _get_voice_credentials() -> dict: + """TTS/STT credentials from config (new api_key preferred). Newer X-Api-Key auth (``secrets.api_keys.volc_tts`` / ``VOLC_TTS_API_KEY``) takes precedence; legacy appid + access_token is the fallback. @@ -61,7 +61,7 @@ def _synthesize_sync( output_path: str, ) -> str: """Synchronous wrapper around async TTS.""" - creds = _get_tts_credentials() + creds = _get_voice_credentials() if not creds: raise click.UsageError( "Volcengine TTS credentials not set. Run:\n" @@ -164,11 +164,22 @@ def tts_cmd(text, file, speaker, fmt, speed, output): @handle_errors def stt_cmd(input_path, output, history_file, hotword, correct): """使用豆包/火山引擎极速 ASR 将语音转为文本。""" - appid, access_token = _get_credentials() - if not appid or not access_token: + creds = _get_voice_credentials() + if not creds: raise click.UsageError( - "Volcengine credentials not set. Run:\n" - " mytoolkit env set secrets.volcengine.app_id \n" + "Volcengine ASR credentials not set. Run:\n" + " mytoolkit env set secrets.api_keys.volc_tts \n" + " (or legacy) mytoolkit env set secrets.volcengine.app_id \n" + " mytoolkit env set secrets.volcengine.access_token " + ) + api_key = creds.get("api_key") + appid = creds.get("appid", "") + access_token = creds.get("token", "") + if not api_key and not (appid and access_token): + raise click.UsageError( + "Volcengine ASR credentials not set. Run:\n" + " mytoolkit env set secrets.api_keys.volc_tts \n" + " (or legacy) mytoolkit env set secrets.volcengine.app_id \n" " mytoolkit env set secrets.volcengine.access_token " ) history = None @@ -185,6 +196,7 @@ def stt_cmd(input_path, output, history_file, hotword, correct): appid, access_token, input_path, + api_key=api_key, history=history, hotwords=hotwords, )