You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
3.1 KiB
72 lines
3.1 KiB
"""Генерация черновика теста из извлечённого текста (порт части `documentGenService.js`).""" |
|
from __future__ import annotations |
|
|
|
from .draft_validator import ( |
|
parse_json_from_llm_text, |
|
validate_and_normalize_draft, |
|
) |
|
from .llm_client import LlmError, chat_completion_text_content, get_llm_config |
|
|
|
|
|
MAX_EXTRACT_CHARS = 14000 |
|
|
|
|
|
def generation_for_import_document(extracted_text: str) -> dict: |
|
text = (extracted_text or '').strip() |
|
if not text: |
|
return { |
|
'available': False, |
|
'message': 'Нет извлечённого текста — нечего передавать в модель.', |
|
} |
|
cfg = get_llm_config() |
|
if cfg is None: |
|
return { |
|
'available': False, |
|
'message': ( |
|
'Автогенерация выключена: задайте DEEPSEEK_API_KEY или OPENAI_API_KEY ' |
|
'в .env. Превью текста ниже — можно вставить вручную.' |
|
), |
|
'textPreview': text[:4000], |
|
} |
|
if len(text) > MAX_EXTRACT_CHARS: |
|
slice_ = text[:MAX_EXTRACT_CHARS] + '\n\n[…фрагмент обрезан для API]' |
|
else: |
|
slice_ = text |
|
try: |
|
system = ( |
|
'Ты помощник для составления тестов. Отвечай ТОЛЬКО одним JSON-объектом ' |
|
'без пояснений. Схема: {"title": string, "description"?: string, ' |
|
'"questions": array}. Каждый вопрос: {"text", "hasMultipleAnswers": boolean, ' |
|
'"options": [{"text", "isCorrect": boolean}, ...]}. Минимум 2 варианта. ' |
|
'Для одиночного выбора ровно один isCorrect: true. ' |
|
'Текст и формулировки — на русском, по содержанию входного материала.' |
|
) |
|
user = ( |
|
'Составь тест с вопросами с одним или несколькими правильными ответами ' |
|
'на основе текста:\n\n' + slice_ |
|
) |
|
raw = chat_completion_text_content(cfg, system, user, 0.25) |
|
parsed = parse_json_from_llm_text(raw) |
|
draft = validate_and_normalize_draft(parsed) |
|
return { |
|
'available': True, |
|
'message': ( |
|
f'Сгенерировано: «{draft["title"]}», вопросов: ' |
|
f'{len(draft["questions"])}. Нажмите «Применить сгенерированный черновик».' |
|
), |
|
'draft': draft, |
|
} |
|
except LlmError as e: |
|
return { |
|
'available': False, |
|
'message': f'Генерация не удалась: {e}', |
|
'errorCode': e.code, |
|
'textPreview': text[:4000], |
|
} |
|
except Exception as e: |
|
return { |
|
'available': False, |
|
'message': f'Генерация не удалась: {e}', |
|
'errorCode': 'unknown', |
|
'textPreview': text[:4000], |
|
}
|
|
|