feat: agent_worker DeepSeek fallback & Sprint 003 spec
Deploy t-youtube / Build & Deploy (push) Successful in 1m48s

This commit is contained in:
Gan, Jimmy
2026-07-11 16:09:29 +08:00
parent 40a2666e55
commit 757c4b29c8
4 changed files with 117 additions and 7 deletions
+30 -6
View File
@@ -13,8 +13,12 @@ import db
log = logging.getLogger(__name__)
QWEN_BASE_URL = os.environ.get("QWEN_BASE_URL", "http://localhost:8080")
# LLM config: use local Qwen if QWEN_BASE_URL set, otherwise fall back to DeepSeek
QWEN_BASE_URL = os.environ.get("QWEN_BASE_URL", "")
QWEN_MODEL = os.environ.get("QWEN_MODEL", "current")
DEEPSEEK_API_KEY = os.environ.get("DEEPSEEK_API_KEY", "")
DEEPSEEK_BASE_URL = "https://api.deepseek.com"
DEEPSEEK_MODEL = os.environ.get("DEEPSEEK_MODEL", "deepseek-chat")
POLL_INTERVAL = int(os.environ.get("AGENT_POLL_INTERVAL", "30"))
MAX_CONCURRENT = int(os.environ.get("AGENT_MAX_CONCURRENT", "3"))
SYSTEM_PROMPT = os.environ.get(
@@ -27,8 +31,8 @@ SYSTEM_PROMPT = os.environ.get(
semaphore = asyncio.Semaphore(MAX_CONCURRENT)
async def _call_qwen(prompt: str, video_title: str, video_context: str) -> str:
"""Call the local Qwen27B API with video context + user prompt."""
async def _call_llm(prompt: str, video_title: str, video_context: str) -> str:
"""Call local Qwen or DeepSeek API with video context + user prompt."""
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{
@@ -45,11 +49,27 @@ async def _call_qwen(prompt: str, video_title: str, video_context: str) -> str:
https_proxy = os.environ.get("HTTPS_PROXY") or os.environ.get("https_proxy")
proxies = http_proxy or https_proxy
if QWEN_BASE_URL:
# Use local Qwen
base_url = QWEN_BASE_URL
model = QWEN_MODEL
headers = {}
log.debug("Using local Qwen at %s", base_url)
elif DEEPSEEK_API_KEY:
# Fall back to DeepSeek cloud
base_url = DEEPSEEK_BASE_URL
model = DEEPSEEK_MODEL
headers = {"Authorization": f"Bearer {DEEPSEEK_API_KEY}"}
log.debug("Using DeepSeek cloud API")
else:
raise RuntimeError("No LLM configured: set QWEN_BASE_URL or DEEPSEEK_API_KEY")
async with httpx.AsyncClient(proxy=proxies, timeout=180) as client:
resp = await client.post(
f"{QWEN_BASE_URL}/v1/chat/completions",
f"{base_url}/v1/chat/completions",
headers=headers,
json={
"model": QWEN_MODEL,
"model": model,
"messages": messages,
"max_tokens": 2048,
"temperature": 0.3,
@@ -60,6 +80,10 @@ async def _call_qwen(prompt: str, video_title: str, video_context: str) -> str:
return data["choices"][0]["message"]["content"]
# Backward compat alias
_call_qwen = _call_llm
async def _process_item(item: dict) -> None:
"""Process a single agent_queue item."""
video_id = item["video_id"]
@@ -102,7 +126,7 @@ async def _process_item(item: dict) -> None:
video_context = "\n\n".join(context_parts) if context_parts else "No additional context available."
try:
result = await _call_qwen(user_prompt, video["title"], video_context)
result = await _call_llm(user_prompt, video["title"], video_context)
status = "done"
except Exception as e:
log.warning(f"Qwen API call failed for item {item['id']}: {e}")