feat: phase1 platform upgrade with moderation, dev payments, admin panel and landing updates
This commit is contained in:
@ -137,53 +137,50 @@ export class OpenRouterProvider {
|
||||
model: string
|
||||
): Promise<ClarifyingQuestions> {
|
||||
log.request('generateClarifyingQuestions', model);
|
||||
log.info(`User prompt: "${prompt.substring(0, 100)}${prompt.length > 100 ? '...' : ''}"`);
|
||||
|
||||
const systemPrompt = `Ты - эксперт по созданию образовательных курсов.
|
||||
Пользователь хочет создать курс. Твоя задача - задать уточняющие вопросы,
|
||||
чтобы лучше понять его потребности и создать максимально релевантный курс.
|
||||
log.info(`Using structured onboarding quiz for prompt: "${prompt.substring(0, 120)}${prompt.length > 120 ? '...' : ''}"`);
|
||||
|
||||
Сгенерируй 3-5 вопросов. Обязательно включи вопрос про объём курса (важно для длины):
|
||||
- Короткий (3-4 главы, по 2-4 урока — только введение в тему)
|
||||
- Средний (5-7 глав, по 4-6 уроков — полноценное покрытие)
|
||||
- Длинный / полный (7-12 глав, по 5-8 уроков — глубокое погружение, рекомендуемый вариант для серьёзного обучения)
|
||||
const structured = {
|
||||
questions: [
|
||||
{
|
||||
id: 'q_audience',
|
||||
question: 'Для кого курс?',
|
||||
type: 'single_choice',
|
||||
options: ['Новички', 'Middle', 'Продвинутые'],
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'q_format',
|
||||
question: 'Формат курса?',
|
||||
type: 'single_choice',
|
||||
options: ['Теория', 'Практика', 'Смешанный'],
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'q_goal',
|
||||
question: 'Основная цель курса?',
|
||||
type: 'single_choice',
|
||||
options: ['Освоить профессию', 'Подготовиться к экзамену', 'Для себя'],
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'q_volume',
|
||||
question: 'Какой объём курса нужен?',
|
||||
type: 'single_choice',
|
||||
options: ['Короткий (3-4 главы)', 'Средний (5-7 глав)', 'Полный (7-12 глав)'],
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'q_notes',
|
||||
question: 'Есть ли дополнительные пожелания по структуре, заданиям и кейсам?',
|
||||
type: 'text',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
Остальные вопросы: целевая аудитория, глубина материала, специфические темы.
|
||||
|
||||
Ответь в формате JSON.`;
|
||||
|
||||
return this.withRetry(async () => {
|
||||
const response = await this.client.chat.completions.create({
|
||||
model,
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: `Запрос пользователя: "${prompt}"` },
|
||||
],
|
||||
response_format: { type: 'json_object' },
|
||||
temperature: 0.7,
|
||||
});
|
||||
|
||||
log.response('generateClarifyingQuestions', {
|
||||
prompt: response.usage?.prompt_tokens,
|
||||
completion: response.usage?.completion_tokens,
|
||||
});
|
||||
|
||||
const content = response.choices[0].message.content;
|
||||
log.debug('Raw AI response:', content);
|
||||
|
||||
if (!content) {
|
||||
log.error('Empty response from AI');
|
||||
throw new Error('Empty response from AI');
|
||||
}
|
||||
|
||||
const parsed = JSON.parse(content);
|
||||
const validated = ClarifyingQuestionsSchema.parse(parsed);
|
||||
|
||||
log.success(`Generated ${validated.questions.length} clarifying questions`);
|
||||
log.info('Questions:', validated.questions.map(q => q.question));
|
||||
|
||||
return validated;
|
||||
}, 'generateClarifyingQuestions');
|
||||
const validated = ClarifyingQuestionsSchema.parse(structured);
|
||||
log.success(`Generated ${validated.questions.length} structured onboarding questions`);
|
||||
return validated;
|
||||
}
|
||||
|
||||
async generateCourseOutline(
|
||||
@ -225,9 +222,22 @@ export class OpenRouterProvider {
|
||||
"tags": ["тег1", "тег2"]
|
||||
}`;
|
||||
|
||||
const audience = String(answers.q_audience || '').trim();
|
||||
const format = String(answers.q_format || '').trim();
|
||||
const goal = String(answers.q_goal || '').trim();
|
||||
const volume = String(answers.q_volume || '').trim();
|
||||
const notes = String(answers.q_notes || '').trim();
|
||||
|
||||
const userMessage = `Запрос: "${prompt}"
|
||||
|
||||
Ответы пользователя на уточняющие вопросы:
|
||||
Структурированные ответы:
|
||||
- Аудитория: ${audience || 'не указано'}
|
||||
- Формат: ${format || 'не указано'}
|
||||
- Цель: ${goal || 'не указано'}
|
||||
- Объём: ${volume || 'не указано'}
|
||||
- Доп. пожелания: ${notes || 'нет'}
|
||||
|
||||
Сырой набор ответов:
|
||||
${Object.entries(answers)
|
||||
.map(([key, value]) => `- ${key}: ${Array.isArray(value) ? value.join(', ') : value}`)
|
||||
.join('\n')}`;
|
||||
|
||||
Reference in New Issue
Block a user