from rest_framework import serializers class AskRequestSerializer(serializers.Serializer): conversationId = serializers.CharField(required=False, allow_null=True, allow_blank=True) lessonId = serializers.CharField(required=False, allow_null=True, allow_blank=True) chapterId = serializers.CharField(required=False, allow_null=True, allow_blank=True) gradeId = serializers.IntegerField(required=False, allow_null=True) questionId = serializers.CharField(required=False, allow_null=True, allow_blank=True) # metadataِ retrieval برای لایه‌ی RAG (اپ rag): برای زدن به دیتای واقعیِ # کتاب‌ها در Qdrant باید subject (مثلاً «علوم تجربی») + gradeId + lessonNumber # همگی مطابقِ دادهٔ موجود ارسال بشن؛ اگه نباشن، پاسخ به‌صورتِ تدریسِ عمومی # (بدونِ استناد به کتاب) تولید می‌شه. در ادامه‌ی همون مکالمه لازم نیست # دوباره فرستاده بشن (روی Conversation ذخیره می‌شن). subject = serializers.CharField(required=False, allow_null=True, allow_blank=True) # جزءِ «پایه» در نامِ collectionِ Qdrant (مثلاً «ششم»). اگه بیاد مستقیم # استفاده می‌شه؛ اگه نه، از روی gradeId و content.Grade.title / نگاشتِ # RAG_GRADE_TITLE_OVERRIDES ساخته می‌شه. grade = serializers.CharField(required=False, allow_null=True, allow_blank=True) lessonNumber = serializers.IntegerField(required=False, allow_null=True) # سقفِ طول: کلِ متن به مدلِ پولی می‌رود؛ بی‌سقف، یک درخواستِ صدهزار نویسه‌ای # به‌تنهایی هزینه‌ی صدها سوالِ عادی را داشت. userQuestion = serializers.CharField(max_length=2000) stream = serializers.BooleanField(required=False, default=False) class UsedChunkSerializer(serializers.Serializer): title = serializers.CharField(allow_blank=True) summary = serializers.CharField() class AskResponseSerializer(serializers.Serializer): conversationId = serializers.CharField() messageId = serializers.CharField() answer = serializers.CharField() suggestedFollowUps = serializers.ListField(child=serializers.CharField()) remainingQuota = serializers.IntegerField() # تکه‌های درسیِ بازیابی‌شده از Qdrant که پاسخ بر پایه‌شون ساخته شده؛ # خالی یعنی retrieval انجام نشده (نبودِ subject/lessonNumber یا خاموش‌بودنِ RAG). usedChunks = UsedChunkSerializer(many=True, required=False, default=list) # فقط وقتی DEBUG=True: از کدام collection/فصل چانک‌ها برداشته شد (بازبینیِ داخلی). retrievalDebug = serializers.DictField(required=False) class MessageSerializer(serializers.Serializer): messageId = serializers.CharField() role = serializers.CharField() text = serializers.CharField() class ConversationMessagesResponseSerializer(serializers.Serializer): conversationId = serializers.CharField() lessonId = serializers.CharField(allow_null=True) messages = MessageSerializer(many=True) class FeedbackRequestSerializer(serializers.Serializer): isHelpful = serializers.BooleanField() # اختیاری: «چرا». تنها چیزی که از خودِ 👍/👎 درنمی‌آید و برای اصلاحِ # پرامپت واقعاً به کار می‌آید. reason = serializers.CharField(max_length=300, required=False, allow_blank=True) class FeedbackResponseSerializer(serializers.Serializer): success = serializers.BooleanField()