ITADN

feat: TTS usage v1.5 — upstream-precise (elevenlabs header, gemini usageMetadata)

#1427Closedisamu 创建于 2026-06-18
enhancement
I
isamucommented
Part of #1415. Follow-up from #1420 research. ## What For the two TTS providers that DO expose per-call billing info, capture it precisely instead of relying on input length. ### ElevenLabs (`tts_elevenlabs_agent.ts`) ElevenLabs returns a `character-cost` HTTP header on every successful TTS call. Currently we discard the `Response` after `arrayBuffer()` so the header is dropped. Refactor: ```ts const response = await fetch(...); // ... existing ok check const charactersBilled = Number(response.headers.get("character-cost") ?? 0); const requestId = response.headers.get("request-id") ?? undefined; const arrayBuffer = await response.arrayBuffer(); const buffer = Buffer.from(arrayBuffer); return { buffer, usage: { provider: "elevenlabs", model: usedModel, charactersBilled, // exact billed amount (already 0.5-1 per char depending on model) inputChars: text.length, // for cross-check / fallback requestId, cached: false, }, }; ``` ### Gemini TTS (`tts_gemini_agent.ts`) `response.usageMetadata` is available (verified in `@google/genai/dist/genai.d.ts` → `GenerateContentResponseUsageMetadata`). ```ts return { buffer: await pcmToMp3(rawPcm, sampleRate), usage: { provider: "gemini", model: usedModel, inputTokens: response.usageMetadata?.promptTokenCount, outputTokens: response.usageMetadata?.candidatesTokenCount, totalTokens: response.usageMetadata?.totalTokenCount, cached: false, }, }; ``` This mirrors the pattern used in #1418 (`image_genai_agent`). ## UsageRecord shape impact `UsageRecord` already supports `inputTokens` / `outputTokens` / `totalTokens` / `inputChars`. Add an optional `charactersBilled?: number` field for ElevenLabs precision (or fold into a generic `charges?` map — open question). Surface the decision in this issue's PR. ## Acceptance - [ ] ElevenLabs agent reads `character-cost` / `request-id` headers - [ ] Gemini TTS agent extracts `usageMetadata` - [ ] `UsageRecord` extended (or decision recorded for why not) - [ ] Callback wiring (sharing the pattern from #1419) - [ ] Tests with mocked HTTP / mocked Gemini response ## Dependencies - #1416 (UsageCollector foundation) - Research closed via #1420
关闭于 2026-06-20 0 条评论