142 lines
5.5 KiB
Python
142 lines
5.5 KiB
Python
"""
|
||
AI module for Perplexity API integration.
|
||
Sends user queries and receives AI responses.
|
||
"""
|
||
|
||
import requests
|
||
from config import PERPLEXITY_API_KEY, PERPLEXITY_MODEL, PERPLEXITY_API_URL
|
||
|
||
|
||
# System prompt for the AI
|
||
SYSTEM_PROMPT = """Ты — Александр, умный голосовой ассистент с человеческим поведением.
|
||
Веди себя как живой человек: будь дружелюбным, естественным и немного эмоциональным, где это уместно.
|
||
Твоя главная цель — помогать пользователю и поддерживать интересный диалог.
|
||
Отвечай кратко и по существу, на русском языке.
|
||
Избегай длинных списков, сложного форматирования и спецсимволов, так как твои ответы озвучиваются голосом.
|
||
Пиши в разговорном стиле, как при живом общении, но не забывай о вежливости и правильности твоих ответов.
|
||
ВАЖНО: Не используй в ответах панибратские или сленговые приветствия и обращения, такие как "Эй", "Хэй", "Слушай" в начале фразы и подобные."""
|
||
|
||
TRANSLATION_SYSTEM_PROMPT = """You are a translation engine.
|
||
Translate from {source} to {target}.
|
||
Return only the translated text, without quotes, comments, or explanations."""
|
||
|
||
|
||
def ask_ai(messages_history: list) -> str:
|
||
"""
|
||
Send a message history to Perplexity AI and get a response.
|
||
|
||
Args:
|
||
messages_history: List of dictionaries with role and content
|
||
e.g., [{"role": "user", "content": "Hi"}]
|
||
|
||
Returns:
|
||
AI response text
|
||
"""
|
||
if not messages_history:
|
||
return "Извините, я не расслышал вашу команду."
|
||
|
||
# Extract the last user message for logging
|
||
last_user_message = next(
|
||
(m["content"] for m in reversed(messages_history) if m["role"] == "user"),
|
||
"Unknown",
|
||
)
|
||
print(f"🤖 Запрос к AI: {last_user_message}")
|
||
|
||
headers = {
|
||
"Authorization": f"Bearer {PERPLEXITY_API_KEY}",
|
||
"Content-Type": "application/json",
|
||
}
|
||
|
||
# Prepend system prompt to the history
|
||
messages = [{"role": "system", "content": SYSTEM_PROMPT}] + list(messages_history)
|
||
|
||
payload = {
|
||
"model": PERPLEXITY_MODEL,
|
||
"messages": messages,
|
||
"max_tokens": 500,
|
||
"temperature": 1.0,
|
||
}
|
||
|
||
try:
|
||
response = requests.post(
|
||
PERPLEXITY_API_URL, headers=headers, json=payload, timeout=30
|
||
)
|
||
response.raise_for_status()
|
||
|
||
data = response.json()
|
||
ai_response = data["choices"][0]["message"]["content"]
|
||
print(f"💬 Ответ AI: {ai_response[:100]}...")
|
||
return ai_response
|
||
|
||
except requests.exceptions.Timeout:
|
||
return "Извините, сервер не отвечает. Попробуйте позже."
|
||
except requests.exceptions.RequestException as e:
|
||
print(f"❌ Ошибка API: {e}")
|
||
return "Произошла ошибка при обращении к AI. Попробуйте ещё раз."
|
||
except (KeyError, IndexError) as e:
|
||
print(f"❌ Ошибка парсинга ответа: {e}")
|
||
return "Не удалось обработать ответ от AI."
|
||
|
||
|
||
def translate_text(text: str, source_lang: str, target_lang: str) -> str:
|
||
"""
|
||
Translate text using Perplexity AI.
|
||
|
||
Args:
|
||
text: Text to translate
|
||
source_lang: Source language code ("ru" or "en")
|
||
target_lang: Target language code ("ru" or "en")
|
||
|
||
Returns:
|
||
Translated text
|
||
"""
|
||
if not text:
|
||
return "Извините, я не расслышал текст для перевода."
|
||
|
||
lang_names = {"ru": "Russian", "en": "English"}
|
||
source_name = lang_names.get(source_lang, source_lang)
|
||
target_name = lang_names.get(target_lang, target_lang)
|
||
|
||
print(f"🌍 Перевод: {source_name} -> {target_name}: {text[:60]}...")
|
||
|
||
headers = {
|
||
"Authorization": f"Bearer {PERPLEXITY_API_KEY}",
|
||
"Content-Type": "application/json",
|
||
}
|
||
|
||
messages = [
|
||
{
|
||
"role": "system",
|
||
"content": TRANSLATION_SYSTEM_PROMPT.format(
|
||
source=source_name, target=target_name
|
||
),
|
||
},
|
||
{"role": "user", "content": text},
|
||
]
|
||
|
||
payload = {
|
||
"model": PERPLEXITY_MODEL,
|
||
"messages": messages,
|
||
"max_tokens": 400,
|
||
"temperature": 0.2,
|
||
}
|
||
|
||
try:
|
||
response = requests.post(
|
||
PERPLEXITY_API_URL, headers=headers, json=payload, timeout=30
|
||
)
|
||
response.raise_for_status()
|
||
|
||
data = response.json()
|
||
ai_response = data["choices"][0]["message"]["content"]
|
||
return ai_response.strip()
|
||
|
||
except requests.exceptions.Timeout:
|
||
return "Извините, сервер не отвечает. Попробуйте позже."
|
||
except requests.exceptions.RequestException as e:
|
||
print(f"❌ Ошибка API перевода: {e}")
|
||
return "Произошла ошибка при переводе. Попробуйте ещё раз."
|
||
except (KeyError, IndexError) as e:
|
||
print(f"❌ Ошибка парсинга ответа перевода: {e}")
|
||
return "Не удалось обработать перевод."
|