feat: agent_worker DeepSeek fallback & Sprint 003 spec
Deploy t-youtube / Build & Deploy (push) Successful in 1m48s
Deploy t-youtube / Build & Deploy (push) Successful in 1m48s
This commit is contained in:
+30
-6
@@ -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}")
|
||||
|
||||
Reference in New Issue
Block a user