diff --git a/components/AICoach.tsx b/components/AICoach.tsx index 25c667e..6bc4c95 100644 --- a/components/AICoach.tsx +++ b/components/AICoach.tsx @@ -29,7 +29,7 @@ const AICoach: React.FC = ({ history, lang }) => { useEffect(() => { try { - const chat = createFitnessChat(history); + const chat = createFitnessChat(history, lang); if (chat) { chatSessionRef.current = chat; } else { @@ -108,8 +108,8 @@ const AICoach: React.FC = ({ history, lang }) => { {messages.map((msg) => (
{msg.text}
diff --git a/server/src/routes/ai.ts b/server/src/routes/ai.ts index 8bbd109..b5dc6e6 100644 --- a/server/src/routes/ai.ts +++ b/server/src/routes/ai.ts @@ -5,7 +5,7 @@ import jwt from 'jsonwebtoken'; const router = express.Router(); const JWT_SECRET = process.env.JWT_SECRET || 'secret'; const API_KEY = process.env.API_KEY; -const MODEL_ID = 'gemini-1.5-flash'; +const MODEL_ID = 'gemini-2.0-flash'; const authenticate = (req: any, res: any, next: any) => { const token = req.headers.authorization?.split(' ')[1]; @@ -35,11 +35,11 @@ router.post('/chat', async (req, res) => { const { systemInstruction, userMessage } = req.body; const model = ai.getGenerativeModel({ - model: MODEL_ID, - systemInstruction + model: MODEL_ID }); - const result = await model.generateContent(userMessage); + const prompt = `${systemInstruction}\n\nUser: ${userMessage}`; + const result = await model.generateContent(prompt); const response = result.response.text(); res.json({ response }); diff --git a/services/geminiService.ts b/services/geminiService.ts index 326708d..141998d 100644 --- a/services/geminiService.ts +++ b/services/geminiService.ts @@ -1,7 +1,7 @@ import { WorkoutSession } from '../types'; import { api } from './api'; -export const createFitnessChat = (history: WorkoutSession[]): any => { +export const createFitnessChat = (history: WorkoutSession[], lang: 'en' | 'ru' = 'ru'): any => { // The original returned a Chat object. // Now we need to return something that behaves like it or refactor the UI. // The UI likely calls `chat.sendMessage(msg)`. @@ -9,12 +9,12 @@ export const createFitnessChat = (history: WorkoutSession[]): any => { // Summarize data to reduce token count while keeping relevant context const summary = history.slice(0, 10).map(s => ({ - date: new Date(s.startTime).toLocaleDateString('ru-RU'), + date: new Date(s.startTime).toLocaleDateString(lang === 'ru' ? 'ru-RU' : 'en-US'), userWeight: s.userBodyWeight, - exercises: s.sets.map(set => `${set.exerciseName}: ${set.weight ? set.weight + 'кг' : ''}${set.reps ? ' x ' + set.reps + 'повт' : ''} ${set.distanceMeters ? set.distanceMeters + 'м' : ''}`).join(', ') + exercises: s.sets.map(set => `${set.exerciseName}: ${set.weight ? set.weight + (lang === 'ru' ? 'кг' : 'kg') : ''}${set.reps ? ' x ' + set.reps + (lang === 'ru' ? 'повт' : 'reps') : ''} ${set.distanceMeters ? set.distanceMeters + (lang === 'ru' ? 'м' : 'm') : ''}`).join(', ') })); - const systemInstruction = ` + const systemInstruction = lang === 'ru' ? ` Ты — опытный и поддерживающий фитнес-тренер. Твоя задача — анализировать тренировки пользователя и давать краткие, полезные советы на русском языке. @@ -25,6 +25,18 @@ export const createFitnessChat = (history: WorkoutSession[]): any => { Если пользователь спрашивает о прогрессе, используй эти данные. Отвечай емко, мотивирующе. Избегай длинных лекций, если не просили. + ` : ` + You are an experienced and supportive fitness coach. + Your task is to analyze the user's workouts and provide concise, helpful advice in English. + + Consider the user's weight (userWeight in json), if provided, when analyzing progress in bodyweight exercises. + + Here are the user's last 10 workouts (in JSON format): + ${JSON.stringify(summary)} + + If the user asks about progress, use this data. + Answer concisely and motivationally. Avoid long lectures unless asked. + ALWAYS answer in the language the user speaks to you, defaulting to English if unsure. `; return { @@ -34,6 +46,7 @@ export const createFitnessChat = (history: WorkoutSession[]): any => { userMessage }); return { + text: res.response, response: { text: () => res.response }