78 lines
2.5 KiB
Go
78 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
cryptorand "crypto/rand"
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// ASR-only subset of the reference configuration. No LLM/TTS fields are imported.
|
|
type agentCfg struct {
|
|
BailianKey, BailianWssBaseURL string
|
|
VolcAppKey, VolcAppID, VolcAccessToken, VolcResourceID, VolcWS string
|
|
}
|
|
|
|
type config struct {
|
|
bailianKey, bailianBase, funASRKey, funASRBase string
|
|
volcAppKey, volcAppID, volcToken, volcResourceID, volcWS string
|
|
}
|
|
|
|
func env(key, fallback string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func loadConfig() config {
|
|
key := os.Getenv("BAILIAN_API_KEY")
|
|
return config{
|
|
bailianKey: key,
|
|
bailianBase: env("BAILIAN_WS", "wss://dashscope.aliyuncs.com/api-ws/v1/inference/"),
|
|
funASRKey: env("FUNASR_API_KEY", key),
|
|
funASRBase: env("FUNASR_WS", "wss://dashscope.aliyuncs.com/api-ws/v1/inference/"),
|
|
volcAppKey: os.Getenv("VOLC_APP_KEY"), volcAppID: os.Getenv("VOLC_APP_ID"),
|
|
volcToken: os.Getenv("VOLC_ACCESS_TOKEN"),
|
|
volcResourceID: env("VOLC_RESOURCE_ID", "volc.bigasr.sauc.duration"),
|
|
volcWS: env("VOLC_WS", "wss://openspeech.bytedance.com/api/v3/sauc/bigmodel"),
|
|
}
|
|
}
|
|
|
|
func validateConfig(token, origin string, cfg config) error {
|
|
if len(token) < 32 || strings.HasPrefix(token, "CHANGE_ME") {
|
|
return errors.New("ASR_WEB_TOKEN must be at least 32 characters and not a placeholder")
|
|
}
|
|
for _, r := range token {
|
|
if !(r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-' || r == '_') {
|
|
return errors.New("ASR_WEB_TOKEN must use URL-safe alphanumeric characters")
|
|
}
|
|
}
|
|
if origin != "" {
|
|
u, err := url.Parse(origin)
|
|
if err != nil || (u.Scheme != "https" && u.Scheme != "http") || u.Host == "" || u.User != nil || u.Path != "" || u.RawQuery != "" || u.Fragment != "" {
|
|
return errors.New("PUBLIC_ORIGIN must be an exact http(s) origin without a path")
|
|
}
|
|
}
|
|
for _, endpoint := range []string{cfg.bailianBase, cfg.funASRBase, cfg.volcWS} {
|
|
u, err := url.Parse(endpoint)
|
|
if err != nil || u.Scheme != "wss" || u.Host == "" || u.User != nil {
|
|
return errors.New("provider endpoints must use wss without embedded credentials")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func uuid() (string, error) {
|
|
b := make([]byte, 16)
|
|
count, err := cryptorand.Read(b)
|
|
if err != nil || count != len(b) {
|
|
return "", errors.New("secure random unavailable")
|
|
}
|
|
b[6] = b[6]&15 | 64
|
|
b[8] = b[8]&63 | 128
|
|
return fmt.Sprintf("%x-%x-%x-%x-%x", b[:4], b[4:6], b[6:8], b[8:10], b[10:]), nil
|
|
}
|