Files
octopus/myproject/integrations/models/ai_services/openrouter.py

95 lines
3.4 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.
from django.db import models
from integrations.models.base import BaseIntegration, IntegrationType
from django.core.exceptions import ValidationError
from integrations.fields import EncryptedCharField
def validate_temperature(value):
"""Валидатор для температуры, принимает значения от 0 до 2"""
if value < 0 or value > 2:
raise ValidationError('Температура должна быть в диапазоне 0.0-2.0')
# Список доступных моделей OpenRouter (бесплатные)
OPENROUTER_MODEL_CHOICES = [
('xiaomi/mimo-v2-flash:free', 'Xiaomi MIMO v2 Flash (Бесплатная)'),
('mistralai/devstral-2512:free', 'Mistral Devstral 2512 (Бесплатная)'),
('z-ai/glm-4.5-air:free', 'Z.AI GLM-4.5 Air (Бесплатная)'),
('qwen/qwen3-coder:free', 'Qwen 3 Coder (Бесплатная)'),
]
# Предустановленные значения температуры
OPENROUTER_TEMPERATURE_CHOICES = [
(0.1, '0.1 - Очень консервативно'),
(0.3, '0.3 - Консервативно'),
(0.5, '0.5 - Умеренно'),
(0.7, '0.7 - Баланс (по умолчанию)'),
(1.0, '1.0 - Креативно'),
(1.5, '1.5 - Очень креативно'),
(2.0, '2.0 - Максимальная креативность'),
]
class AIIntegration(BaseIntegration):
"""
Базовая модель для интеграций с ИИ-сервисами
"""
class Meta:
abstract = True
class OpenRouterIntegration(AIIntegration):
"""
Интеграция с OpenRouter.ai
"""
integration_type = IntegrationType.AI_SERVICE
api_key = EncryptedCharField(
max_length=500,
blank=True,
verbose_name="API ключ",
help_text="Ключ для доступа к API OpenRouter (шифруется в БД)"
)
api_url = models.URLField(
max_length=500,
default="https://openrouter.ai/api/v1",
verbose_name="URL API",
help_text="URL для обращения к API OpenRouter (обычно https://openrouter.ai/api/v1)"
)
model_name = models.CharField(
max_length=100,
default="xiaomi/mimo-v2-flash:free",
choices=OPENROUTER_MODEL_CHOICES,
verbose_name="Название модели",
help_text="Название используемой модели OpenRouter"
)
temperature = models.FloatField(
default=0.7,
choices=OPENROUTER_TEMPERATURE_CHOICES,
validators=[validate_temperature],
verbose_name="Температура",
help_text="Параметр температуры для генерации (0.0-2.0)"
)
max_tokens = models.IntegerField(
default=1000,
verbose_name="Макс. токенов",
help_text="Максимальное количество токенов в ответе"
)
class Meta:
verbose_name = "Интеграция OpenRouter"
verbose_name_plural = "Интеграции OpenRouter"
@property
def is_configured(self) -> bool:
return bool(self.api_key)
def clean(self):
super().clean()
if self.temperature < 0 or self.temperature > 2:
raise ValidationError({'temperature': 'Температура должна быть в диапазоне 0.0-2.0'})