Files
life-echo/api/app/core/dependencies.py
Kevin 07979bfb09 feat(api): use Tencent ASR flash with 16k_zh_large and dev transcript logs
Replace CreateRecTask polling with recording-file flash API, add TENCENT_APP_ID,
remove server-side pydub slicing, and log ASR recognition text at INFO in development.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 11:28:22 +08:00

180 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
全局共享依赖:
- 认证get_current_user / get_optional_user
- Port DI factoryget_sms_sender / get_llm_provider / get_tts_provider / ...
"""
from functools import lru_cache
from typing import Optional
from fastapi import Depends
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.config import settings
from app.core.eval_judge_spec import EvalJudgeLlmSpec, EvalJudgeProvider
from app.core.runtime_constants import asr_defaults, llm_defaults, misc_defaults, tts_defaults
from app.features.memoir.constants import memoir
from app.ports.asr import ASRProvider
from app.ports.embedding import EmbeddingProvider
from app.ports.image_gen import ImageGenerator
from app.ports.llm import LLMProvider
from app.ports.sms import SmsSender
from app.ports.storage import ObjectStorage
from app.ports.tts import TTSProvider
# ── Port DI factories ───────────────────────────────────────
@lru_cache
def get_sms_sender() -> SmsSender:
from app.adapters.sms.tencent import TencentSmsSender
return TencentSmsSender(
secret_id=settings.tencent_secret_id,
secret_key=settings.tencent_secret_key,
sdk_app_id=settings.tencent_sms_sdk_app_id,
sign_name=settings.tencent_sms_sign_name,
template_id=settings.tencent_sms_template_id,
template_param_count=misc_defaults.tencent_sms_template_param_count,
)
@lru_cache
def get_llm_provider() -> LLMProvider:
from app.adapters.llm.deepseek import DeepSeekLLMProvider
api_key = settings.deepseek_api_key or ""
base_url = llm_defaults.deepseek_base_url or ""
model = llm_defaults.deepseek_model or "deepseek-v4-flash"
return DeepSeekLLMProvider(
api_key=api_key,
base_url=base_url,
model=model,
temperature=llm_defaults.temperature,
extra_body={
"thinking": {
"type": "enabled" if llm_defaults.deepseek_thinking_enabled else "disabled"
}
},
)
@lru_cache
def get_llm_provider_fast() -> LLMProvider:
"""快档位:与默认共用密钥与 base_url仅模型名可单独配置。"""
fast = (llm_defaults.fast_model or "").strip()
if not fast:
return get_llm_provider()
from app.adapters.llm.deepseek import DeepSeekLLMProvider
api_key = settings.deepseek_api_key or ""
base_url = llm_defaults.deepseek_base_url or ""
return DeepSeekLLMProvider(
api_key=api_key,
base_url=base_url,
model=fast,
temperature=llm_defaults.temperature,
extra_body={
"thinking": {
"type": "enabled" if llm_defaults.deepseek_thinking_enabled else "disabled"
}
},
)
@lru_cache
def get_tts_provider() -> TTSProvider:
if tts_defaults.provider == "tencent":
from app.adapters.tts.tencent_tts import TencentTTSProvider
return TencentTTSProvider(
secret_id=settings.tencent_secret_id,
secret_key=settings.tencent_secret_key,
voice_type=tts_defaults.voice_type,
codec=tts_defaults.codec,
voice_type_en=tts_defaults.voice_type_en,
)
from app.adapters.tts.openai_tts import OpenAITTSProvider
return OpenAITTSProvider(api_key="")
@lru_cache
def get_asr_provider() -> ASRProvider:
from app.adapters.asr.tencent_asr import TencentASRProvider
return TencentASRProvider(
secret_id=settings.tencent_secret_id,
secret_key=settings.tencent_secret_key,
app_id=settings.tencent_app_id,
engine_type=asr_defaults.engine_type,
request_timeout_seconds=asr_defaults.request_timeout_seconds,
)
@lru_cache
def get_image_generator() -> ImageGenerator:
from app.adapters.image_gen.liblib import LiblibImageGenerator
return LiblibImageGenerator(
access_key=settings.liblib_access_key,
secret_key=settings.liblib_secret_key,
base_url=misc_defaults.liblib_base_url,
template_uuid=settings.liblib_template_uuid,
poll_interval=memoir.image_poll_interval,
max_attempts=memoir.image_max_attempts,
)
@lru_cache
def get_object_storage() -> ObjectStorage:
from app.adapters.storage.tencent_cos import TencentCosStorage
return TencentCosStorage(
secret_id=settings.tencent_secret_id,
secret_key=settings.tencent_secret_key,
region=misc_defaults.tencent_cos_region,
bucket=settings.tencent_cos_bucket,
base_url=settings.tencent_cos_base_url,
token="",
)
@lru_cache
def get_embedding_provider() -> EmbeddingProvider:
from app.adapters.embedding.zhipu import ZhipuEmbeddingProvider
return ZhipuEmbeddingProvider(
api_key=settings.zhipu_api_key,
base_url=llm_defaults.embedding_base_url or None,
model=llm_defaults.embedding_model,
)
# Re-export auth deps for backward compatibility
from app.core.auth_deps import get_current_user, get_optional_user # noqa: F401
# ── Eval judge ───────────────────────────────────────────────
def build_eval_judge_llm_spec(
provider: EvalJudgeProvider = "zhipu",
judge_model: str | None = None,
) -> EvalJudgeLlmSpec | None:
"""按供应商装配 ChatOpenAI密钥缺失时返回 Nonellm 为 None"""
from app.adapters.llm.deepseek_eval_judge import build_deepseek_eval_judge_spec
from app.adapters.llm.zhipu_eval_judge import build_zhipu_eval_judge_spec
if provider == "deepseek":
return build_deepseek_eval_judge_spec(judge_model)
return build_zhipu_eval_judge_spec(judge_model)
def get_eval_judge_langchain_llm():
"""兼容:等价于智谱供应商下的 `build_eval_judge_llm_spec(\"zhipu\", None).llm`。"""
spec = build_eval_judge_llm_spec("zhipu", None)
return spec.llm if spec else None