Files
Avtex/app/server/api/ai/coach.post.ts
T

171 lines
11 KiB
TypeScript

import { requireAuth } from '~/server/utils/auth'
import { generateAIResponse } from '~/server/utils/ai'
export default defineEventHandler(async (event) => {
const user = requireAuth(event)
const body = await readBody(event)
const { action, text, model } = body
if (!action || !text) {
throw createError({ statusCode: 400, message: 'Action and text are required' })
}
console.log(`[AI Coach] action=${action} userId=${user.id}`)
try {
if (action === 'smart') {
const systemPrompt = `You are an expert executive coach. Your job is to transform any vague goal or statement into a high-quality, fully detailed S.M.A.R.T. goal. Keep your response in Russian.
Use Markdown headers for each element: Specific (Конкретная), Measurable (Измеримая), Achievable (Достижимая), Relevant (Значимая), Time-bound (Ограниченная во времени).
For Measurable, include a clear checklist with markdown checkboxes (- [ ]) for metrics. At the end, write a brief, inspiring summary.`
const prompt = `Пожалуйста, преобразуй следующую цель в формат S.M.A.R.T.
Исходная цель: "${text}"`
const result = await generateAIResponse(prompt, systemPrompt, model)
return { success: true, result }
} else if (action === 'grow') {
const systemPrompt = `You are a professional business coach. Your job is to perform a structured coaching analysis of the user's problem or goal using the G.R.O.W. framework. Keep all content in Russian.
You must return the response strictly as a JSON object with the following keys:
{
"goal": "Markdown text. Description of the reformulated Goal (G) starting with # 🎯 Цель (Goal).\\n\\nAnswer these questions:\\n- Какой именно цели я хочу достичь?\\n- Какой результат я хочу получить?\\n- Почему достижение этой цели важно?",
"options": "Markdown text. Options & Obstacles (O) starting with # 🚧 Варианты (Options).\\n\\nAnswer these questions:\\n- Что именно я могу изменить?\\n- Какие ресурсы мне нужны?\\n- Кто мне может помочь?\\n- А что еще?\\nInclude a checkbox list (- [ ]).",
"reality": "Markdown text. Description of the current Situation/Reality (R) starting with # 🔍 Реальность (Reality).\\n\\nAnswer these questions:\\n- Какова текущая ситуация?\\n- Какие препятствия я вижу?\\n- Что мне мешает начать?\\n- Какие у меня уже есть ресурсы?",
"wayForward": "Markdown text. Action Plan / Way Forward (W) starting with # 🏁 План действий (Way Forward).\\n\\nAnswer these questions:\\n- Какие самые важные действия необходимо предпринять?\\n- Что я сделаю в первую очередь? Какие сроки?\\nInclude a checkbox list (- [ ])."
}
Do NOT include any markdown code blocks (like \`\`\`json) or any extra text before or after the JSON. Return only the JSON object.`
const prompt = `Проведи GROW-коучинг анализ для следующей проблемы/цели: "${text}"`
const aiResponse = await generateAIResponse(prompt, systemPrompt, model)
// Robust JSON extraction
let jsonText = aiResponse.trim()
if (jsonText.startsWith('```json')) {
jsonText = jsonText.substring(7)
} else if (jsonText.startsWith('```')) {
jsonText = jsonText.substring(3)
}
if (jsonText.endsWith('```')) {
jsonText = jsonText.substring(0, jsonText.length - 3)
}
jsonText = jsonText.trim()
try {
const parsed = JSON.parse(jsonText)
return { success: true, result: parsed }
} catch (parseErr) {
console.error('Failed to parse AI G.R.O.W. JSON response:', aiResponse)
// Fallback: if JSON parsing fails, wrap the text into fields
return {
success: true,
result: {
goal: `# 🎯 Цель (Goal)\n\n${text}`,
reality: `# 🔍 Реальность (Reality)\n\nНе удалось автоматически разбить ответ AI на JSON. Вот оригинальный ответ:\n\n${aiResponse}`,
options: `# 🚧 Варианты\n\n- Рассмотреть альтернативные пути решения вручную`,
wayForward: `# 🏁 План действий\n\n- [ ] Детализировать шаги вручную`
}
}
}
} else if (action === 'dilts') {
const systemPrompt = `You are a professional life and business coach. Your job is to perform a structured analysis of the user's goal or situation using Robert Dilts' Logical Levels (Пирамида логических уровней Дилтса). Keep all content in Russian.
You must return the response strictly as a JSON object with the following keys:
{
"mission": "Markdown text starting with # 🌟 Миссия (Mission).\\n\\nAnswer these questions:\\n- Ради кого?\\n- Кому еще это важно?\\n(Уровень БЫТЬ)",
"identity": "Markdown text starting with # 👤 Идентичность (Identity).\\n\\nAnswer these questions:\\n- Кто я?",
"values": "Markdown text starting with # 💎 Ценности (Values).\\n\\nAnswer these questions:\\n- Почему это важно?",
"skills": "Markdown text starting with # 🧠 Навыки (Skills).\\n\\nAnswer these questions:\\n- Как? Каким образом?",
"actions": "Markdown text starting with # 🎬 Действия (Actions).\\n\\nAnswer these questions:\\n- Что делать? (Уровень ДЕЛАТЬ)",
"environment": "Markdown text starting with # 🌍 Окружение (Environment).\\n\\nAnswer these questions:\\n- Где? Когда? С кем? (Уровень ИМЕТЬ)"
}
Do NOT include any markdown code blocks (like \`\`\`json) or any extra text before or after the JSON. Return only the JSON object.`
const prompt = `Проведи коучинговый анализ по логическим уровням Дилтса для следующего запроса: "${text}"`
const aiResponse = await generateAIResponse(prompt, systemPrompt, model)
// Robust JSON extraction
let jsonText = aiResponse.trim()
if (jsonText.startsWith('```json')) {
jsonText = jsonText.substring(7)
} else if (jsonText.startsWith('```')) {
jsonText = jsonText.substring(3)
}
if (jsonText.endsWith('```')) {
jsonText = jsonText.substring(0, jsonText.length - 3)
}
jsonText = jsonText.trim()
try {
const parsed = JSON.parse(jsonText)
return { success: true, result: parsed }
} catch (parseErr) {
console.error('Failed to parse AI Dilts JSON response:', aiResponse)
// Fallback
return {
success: true,
result: {
mission: `# 🌟 Миссия (Mission)\n\nРади кого? Кому еще это важно? (Уровень БЫТЬ)\n\n${text}`,
identity: `# 👤 Идентичность (Identity)\n\nКто я?`,
values: `# 💎 Ценности (Values)\n\nПочему это важно?`,
skills: `# 🧠 Навыки (Skills)\n\nКак? Каким образом?`,
actions: `# 🎬 Действия (Actions)\n\nЧто делать? (Уровень ДЕЛАТЬ)\n\nНе удалось автоматически разбить ответ AI на JSON:\n\n${aiResponse}`,
environment: `# 🌍 Окружение (Environment)\n\nГде? Когда? С кем? (Уровень ИМЕТЬ)`
}
}
}
} else if (action === 'eisenhower') {
const systemPrompt = `You are a professional productivity expert. Your job is to analyze the user's tasks or list of ideas and prioritize them using the Eisenhower Matrix (Матрица Эйзенхауэра). Keep all content in Russian.
You must return the response strictly as a JSON object with the following keys:
{
"q1": "Markdown text starting with # 🔥 Важно и Срочно (Do First).\\n\\nIdentify tasks that are both urgent and important. Focus on crises, deadlines, and crucial problems.",
"q2": "Markdown text starting with # ⚡ Важно, но Несрочно (Schedule).\\n\\nIdentify tasks that are important but not urgent. Focus on long-term planning, personal growth, and relationships.",
"q3": "Markdown text starting with # 🧊 Неважно, но Срочно (Delegate).\\n\\nIdentify tasks that are urgent but not important. Focus on interruptions, minor meetings, and tasks that can be delegated.",
"q4": "Markdown text starting with # 💤 Неважно и Несрочно (Eliminate).\\n\\nIdentify tasks that are neither urgent nor important. Focus on time-wasting activities, distractions, and low-value tasks."
}
Do NOT include any markdown code blocks (like \`\`\`json) or any extra text before or after the JSON. Return only the JSON object.`
const prompt = `Распредели следующие задачи/цели по квадрантам Матрицы Эйзенхауэра: "${text}"`
const aiResponse = await generateAIResponse(prompt, systemPrompt, model)
// Robust JSON extraction
let jsonText = aiResponse.trim()
if (jsonText.startsWith('```json')) {
jsonText = jsonText.substring(7)
} else if (jsonText.startsWith('```')) {
jsonText = jsonText.substring(3)
}
if (jsonText.endsWith('```')) {
jsonText = jsonText.substring(0, jsonText.length - 3)
}
jsonText = jsonText.trim()
try {
const parsed = JSON.parse(jsonText)
return { success: true, result: parsed }
} catch (parseErr) {
console.error('Failed to parse AI Eisenhower JSON response:', aiResponse)
// Fallback
return {
success: true,
result: {
q1: `# 🔥 Важно и Срочно (Do First)\n\n- [ ] Срочные приоритетные задачи\n\n${text}`,
q2: `# ⚡ Важно, но Несрочно (Schedule)\n\n- [ ] Задачи планирования`,
q3: `# 🧊 Неважно, но Срочно (Delegate)\n\n- [ ] Задачи для делегирования\n\nНе удалось разобрать ответ ИИ:\n\n${aiResponse}`,
q4: `# 💤 Неважно и Несрочно (Eliminate)\n\n- [ ] Задачи, которые можно отложить`
}
}
}
} else {
throw createError({ statusCode: 400, message: `Unsupported action: ${action}` })
}
} catch (err: any) {
console.error('[AI Coach Error]:', err)
throw createError({
statusCode: 500,
message: err.message || 'AI coach generation failed'
})
}
})