d3ro-voice/server/supabase/functions/_shared/provider-key.ts
Yun Chan 0273c6abaa
All checks were successful
ci / 정본·보안·린트·타입·테스트 (push) Successful in 52s
ci / 모바일 린트·타입·Jest (push) Successful in 41s
ci / Supabase Edge Functions + Cloudflare Worker (push) Successful in 22s
ci / .NET API 서버 테스트 (push) Successful in 14s
deploy-site / deploy (push) Successful in 41s
ci / 워크스페이스 빌드 검증 (push) Successful in 36s
fix(edge): stop short clips waiting a minute on the NAS and make the OpenAI STT fallback usable
A five-second phone recording took over a minute: stt-proxy waited up to
60 s for the self-hosted gateway, whose GPU endpoint was off and whose NAS CPU
Whisper needs 30-90 s per clip. With a direct provider configured the gateway
now gets 5 s plus the clip length (30 s cap).

The direct OpenAI fallback never produced a result. The production key held
characters that are not valid in an HTTP header, so every request threw while
being built; provider keys are now stripped of BOM/zero-width characters and a
still-invalid key counts as not configured. whisper-1 verbose_json reports the
language by name, which the result contract rejected; names now map to codes.
Fail-closed responses list each provider's failure (status or error class,
no secrets) so an outage can be diagnosed without log access.
2026-09-27 18:02:14 +09:00

22 lines
992 B
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Provider API keys read from function secrets.
//
// A secret pasted from a Windows file or a rich-text source can carry a BOM,
// zero-width characters or surrounding whitespace. Such a value is not a valid
// HTTP header ByteString, so every request built with it throws before leaving
// the function — the OpenAI STT fallback failed this way on every call until
// 2026-09-27 ("headers of RequestInit is not a valid ByteString"). Strip the
// invisible characters; anything still outside printable ASCII is treated as
// not configured, so the provider is skipped instead of failing each request.
const INVISIBLE = /[​-‍⁠ \s]/g
const PRINTABLE_ASCII = /^[\x21-\x7E]+$/
export function sanitizeProviderKey(raw: string | undefined | null): string {
if (!raw) return ''
const value = raw.replace(INVISIBLE, '')
return PRINTABLE_ASCII.test(value) ? value : ''
}
export function readProviderKey(name: string): string {
return sanitizeProviderKey(Deno.env.get(name))
}