mirror of
https://github.com/suitenumerique/docs.git
synced 2026-09-18 15:50:21 +02:00
✨(backend) add ai_proxy
Add AI proxy to handle AI related requests to the AI service.
This commit is contained in:
@@ -833,6 +833,41 @@ class AITranslateSerializer(serializers.Serializer):
|
||||
return value
|
||||
|
||||
|
||||
class AIProxySerializer(serializers.Serializer):
|
||||
"""Serializer for AI proxy requests."""
|
||||
|
||||
messages = serializers.ListField(
|
||||
required=True,
|
||||
child=serializers.DictField(
|
||||
child=serializers.CharField(required=True),
|
||||
),
|
||||
allow_empty=False,
|
||||
)
|
||||
model = serializers.CharField(required=True)
|
||||
|
||||
def validate_messages(self, messages):
|
||||
"""Validate messages structure."""
|
||||
# Ensure each message has the required fields
|
||||
for message in messages:
|
||||
if (
|
||||
not isinstance(message, dict)
|
||||
or "role" not in message
|
||||
or "content" not in message
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"Each message must have 'role' and 'content' fields"
|
||||
)
|
||||
|
||||
return messages
|
||||
|
||||
def validate_model(self, value):
|
||||
"""Validate model value is the same than settings.AI_MODEL"""
|
||||
if value != settings.AI_MODEL:
|
||||
raise serializers.ValidationError(f"{value} is not a valid model")
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class MoveDocumentSerializer(serializers.Serializer):
|
||||
"""
|
||||
Serializer for validating input data to move a document within the tree structure.
|
||||
|
||||
@@ -475,6 +475,9 @@ class DocumentViewSet(
|
||||
Returns: JSON response with the translated text.
|
||||
Throttled by: AIDocumentRateThrottle, AIUserRateThrottle.
|
||||
|
||||
12. **AI Proxy**: Proxy an AI request to an external AI service.
|
||||
Example: POST /api/v1.0/documents/<resource_id>/ai-proxy
|
||||
|
||||
### Ordering: created_at, updated_at, is_favorite, title
|
||||
|
||||
Example:
|
||||
@@ -1832,6 +1835,31 @@ class DocumentViewSet(
|
||||
|
||||
return drf.response.Response(body, status=drf.status.HTTP_200_OK)
|
||||
|
||||
@drf.decorators.action(
|
||||
detail=True,
|
||||
methods=["post"],
|
||||
name="Proxy AI requests to the AI provider",
|
||||
url_path="ai-proxy",
|
||||
throttle_classes=[utils.AIDocumentRateThrottle, utils.AIUserRateThrottle],
|
||||
)
|
||||
def ai_proxy(self, request, *args, **kwargs):
|
||||
"""
|
||||
POST /api/v1.0/documents/<resource_id>/ai-proxy
|
||||
Proxy AI requests to the configured AI provider.
|
||||
This endpoint forwards requests to the AI provider and returns the complete response.
|
||||
"""
|
||||
# Check permissions first
|
||||
self.get_object()
|
||||
|
||||
if not settings.AI_FEATURE_ENABLED:
|
||||
raise ValidationError("AI feature is not enabled.")
|
||||
|
||||
serializer = serializers.AIProxySerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
response = AIService().proxy(request.data)
|
||||
return drf.response.Response(response, status=drf.status.HTTP_200_OK)
|
||||
|
||||
@drf.decorators.action(
|
||||
detail=True,
|
||||
methods=["post"],
|
||||
|
||||
Reference in New Issue
Block a user