Files
octopus/myproject/integrations/models/ai_services/openrouter.py
Andrey Smakotin 5ec5ee48d4 feat(integrations): add dynamic OpenRouter model loading
- Remove hardcoded OPENROUTER_MODEL_CHOICES from openrouter.py
- Add API endpoint /integrations/openrouter/models/ to fetch models dynamically
- Models loaded from OpenRouter API with free models (':free') at top
- Update OpenRouterIntegration model_name field (remove choices, blank=True)
- Add async buildForm() with dynamic_choices support
- Show asterisks (********) for saved API keys with helpful placeholder

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:16:12 +03:00

87 lines
3.0 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_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=200,
default="",
blank=True,
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'})