Files
WhatsAppCentralizado/services/flow-engine/app/nodes/ai.py
Claude AI a6c2e67c6a refactor(ai): replace OpenAI with DeepSeek API
- Update config.py with DEEPSEEK_API_KEY, DEEPSEEK_MODEL, DEEPSEEK_BASE_URL
- Update ai.py to use DeepSeek endpoint (OpenAI-compatible)
- Update docker-compose.yml environment variables
2026-01-29 22:05:10 +00:00

118 lines
4.0 KiB
Python

from typing import Any, Optional
import httpx
from app.config import get_settings
from app.context import FlowContext
from app.nodes.base import NodeExecutor
settings = get_settings()
class AIResponseExecutor(NodeExecutor):
"""Generate AI response using DeepSeek API"""
async def execute(
self, config: dict, context: FlowContext, session: Any
) -> Optional[str]:
prompt = context.interpolate(config.get("prompt", ""))
system_prompt = config.get("system_prompt", "Eres un asistente útil.")
output_variable = config.get("output_variable", "_ai_response")
max_tokens = config.get("max_tokens", 500)
temperature = config.get("temperature", 0.7)
if not settings.DEEPSEEK_API_KEY:
context.set("_ai_error", "DeepSeek API key not configured")
return "error"
if not prompt:
return "error"
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt},
]
if config.get("include_history", False):
history = context.get("_conversation_history") or []
messages = (
[{"role": "system", "content": system_prompt}]
+ history
+ [{"role": "user", "content": prompt}]
)
async with httpx.AsyncClient() as client:
response = await client.post(
f"{settings.DEEPSEEK_BASE_URL}/v1/chat/completions",
headers={
"Authorization": f"Bearer {settings.DEEPSEEK_API_KEY}",
"Content-Type": "application/json",
},
json={
"model": settings.DEEPSEEK_MODEL,
"messages": messages,
"max_tokens": max_tokens,
"temperature": temperature,
},
timeout=30,
)
if response.status_code != 200:
context.set("_ai_error", response.text)
return "error"
data = response.json()
ai_response = data["choices"][0]["message"]["content"]
context.set(output_variable, ai_response)
return "success"
class AISentimentExecutor(NodeExecutor):
"""Analyze sentiment of user message using DeepSeek"""
async def execute(
self, config: dict, context: FlowContext, session: Any
) -> Optional[str]:
text = context.get(config.get("variable", "")) or context.message.get(
"content", ""
)
output_variable = config.get("output_variable", "_sentiment")
if not settings.DEEPSEEK_API_KEY or not text:
return "neutral"
async with httpx.AsyncClient() as client:
response = await client.post(
f"{settings.DEEPSEEK_BASE_URL}/v1/chat/completions",
headers={
"Authorization": f"Bearer {settings.DEEPSEEK_API_KEY}",
"Content-Type": "application/json",
},
json={
"model": settings.DEEPSEEK_MODEL,
"messages": [
{
"role": "system",
"content": "Analyze the sentiment. Reply with only one word: positive, negative, or neutral",
},
{"role": "user", "content": text},
],
"max_tokens": 10,
"temperature": 0,
},
timeout=15,
)
if response.status_code != 200:
return "neutral"
data = response.json()
sentiment = data["choices"][0]["message"]["content"].lower().strip()
context.set(output_variable, sentiment)
if "positive" in sentiment:
return "positive"
if "negative" in sentiment:
return "negative"
return "neutral"