[Wake/VAD/STT 与 Live runtime]:完成真实重复语音运行,包含云端ASR/TTS开关、run-live和临时上下文测试
This commit is contained in:
@@ -11,7 +11,7 @@ class AppConfig:
|
||||
wake_word: str = "小杰小杰"
|
||||
sample_rate: int = 16000
|
||||
channels: int = 1
|
||||
llm_base_url: str = "https://newapi.mkbk.shop"
|
||||
llm_base_url: str = "https://token-plan-cn.xiaomimimo.com/v1"
|
||||
llm_api_key: str | None = None
|
||||
llm_model: str = "gpt-5.4-mini"
|
||||
llm_api_style: str = "chat_completions"
|
||||
@@ -20,6 +20,10 @@ class AppConfig:
|
||||
audio_output_device: str | None = None
|
||||
asset_dir: Path = Path("assets/pet")
|
||||
log_dir: Path = Path("logs")
|
||||
speech_provider: str = "cloud"
|
||||
asr_model: str = "mimo-v2.5-asr"
|
||||
tts_model: str = "mimo-v2.5-tts"
|
||||
tts_voice: str = "alloy"
|
||||
speech_models_dir: Path = Path("models")
|
||||
context_max_messages: int = 12
|
||||
context_max_chars: int = 12000
|
||||
@@ -36,7 +40,7 @@ class AppConfig:
|
||||
wake_word=get("WAKE_WORD", "小杰小杰") or "小杰小杰",
|
||||
sample_rate=int(get("SAMPLE_RATE", "16000") or "16000"),
|
||||
channels=int(get("CHANNELS", "1") or "1"),
|
||||
llm_base_url=(get("LLM_BASE_URL", "https://newapi.mkbk.shop") or "").rstrip("/"),
|
||||
llm_base_url=(get("LLM_BASE_URL", "https://token-plan-cn.xiaomimimo.com/v1") or "").rstrip("/"),
|
||||
llm_api_key=get("LLM_API_KEY"),
|
||||
llm_model=get("LLM_MODEL", "gpt-5.4-mini") or "gpt-5.4-mini",
|
||||
llm_api_style=get("LLM_API_STYLE", "chat_completions") or "chat_completions",
|
||||
@@ -45,6 +49,10 @@ class AppConfig:
|
||||
audio_output_device=get("AUDIO_OUTPUT_DEVICE"),
|
||||
asset_dir=Path(get("ASSET_DIR", "assets/pet") or "assets/pet"),
|
||||
log_dir=Path(get("LOG_DIR", "logs") or "logs"),
|
||||
speech_provider=(get("SPEECH_PROVIDER", "cloud") or "cloud").lower(),
|
||||
asr_model=get("ASR_MODEL", "mimo-v2.5-asr") or "mimo-v2.5-asr",
|
||||
tts_model=get("TTS_MODEL", "mimo-v2.5-tts") or "mimo-v2.5-tts",
|
||||
tts_voice=get("TTS_VOICE", "alloy") or "alloy",
|
||||
speech_models_dir=Path(get("SPEECH_MODELS_DIR", "models") or "models"),
|
||||
context_max_messages=int(get("CONTEXT_MAX_MESSAGES", "12") or "12"),
|
||||
context_max_chars=int(get("CONTEXT_MAX_CHARS", "12000") or "12000"),
|
||||
@@ -96,6 +104,16 @@ class AppConfig:
|
||||
"startup",
|
||||
)
|
||||
)
|
||||
if self.speech_provider not in {"cloud", "local"}:
|
||||
errors.append(
|
||||
ProviderError(
|
||||
ErrorCode.CONFIG_MISSING_VALUE,
|
||||
"OWNER_SPEECH_PROVIDER must be cloud or local",
|
||||
False,
|
||||
"config",
|
||||
"startup",
|
||||
)
|
||||
)
|
||||
if not self.llm_base_url.startswith(("http://", "https://")):
|
||||
errors.append(
|
||||
ProviderError(
|
||||
@@ -108,6 +126,13 @@ class AppConfig:
|
||||
)
|
||||
return errors
|
||||
|
||||
def api_url(self, path: str) -> str:
|
||||
normalized = path if path.startswith("/") else f"/{path}"
|
||||
base = self.llm_base_url.rstrip("/")
|
||||
if base.endswith("/v1") and normalized.startswith("/v1/"):
|
||||
return base + normalized[3:]
|
||||
return base + normalized
|
||||
|
||||
|
||||
def parse_dotenv(path: Path) -> dict[str, str]:
|
||||
if not path.exists():
|
||||
|
||||
Reference in New Issue
Block a user