Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 15x 15x 15x 15x 15x 15x 15x 15x | import type { WorkoutAdaptationContext } from '../model-provider.js';
/**
* System prompt for workout adaptation.
*
* Handles three adaptation kinds:
* - not_feeling_it: reduce volume/intensity for a low-energy day
* - exercise_substitution: swap out a specific exercise for equipment/preference reasons
* - pain_reported: modify or remove exercises that aggravate reported pain
*/
export function adaptWorkoutPrompt(context: WorkoutAdaptationContext): string {
const { kind, context_description, current_exercises, completed_sets } = context;
const kindGuidance: Record<typeof kind, string> = {
not_feeling_it: `The athlete is NOT FEELING IT today. This is valid input. Adapt the workout to:
- Reduce total volume by approximately 30-40% (fewer sets, not fewer exercises)
- Lower target weights to approximately 70-80% of prescribed values
- Maintain movement pattern variety — don't cut entire patterns
- Keep the session structure intact but make it more manageable
- Tone is supportive: honour the athlete's intuition`,
exercise_substitution: `The athlete needs to SUBSTITUTE an exercise. Adapt the workout to:
- Replace the problematic exercise with a biomechanically similar alternative
- Maintain the same movement pattern(s) in the replacement
- Match the rep/set/rest structure of the original where possible
- If context describes which exercise to replace, target that specifically`,
pain_reported: `The athlete has REPORTED PAIN. Safety is the absolute priority:
- Remove or significantly modify any exercise that may aggravate the reported area
- Provide a brief safety note in the explanation (recommend consulting a professional if persistent)
- Substitute with pain-free alternatives that maintain training stimulus where possible
- Err on the side of caution — it is better to undertrain than to cause injury`,
};
const completedNote =
completed_sets > 0
? `The athlete has already completed ${completed_sets} sets. Preserve completed work in the adapted plan.`
: 'The workout has not yet started.';
// Sanitize athlete-supplied text to prevent prompt injection:
// strip markdown headings and cap length
const sanitizedDescription = context_description
? context_description
.replace(/#{1,6}\s/g, '') // strip markdown headings
.replace(/\n{2,}/g, '\n') // collapse multiple newlines
.slice(0, 500)
: null;
const descriptionNote = sanitizedDescription
? `\n## Athlete's Description\n"${sanitizedDescription}"`
: '';
const exerciseList = current_exercises
.map(
(ex, i) =>
`${i + 1}. ${ex.exercise_name} (${ex.movement_patterns.join('/')}, ${ex.sets.length} sets)`,
)
.join('\n');
return `You are an expert strength and conditioning coach adapting a workout in real time.
## Adaptation Type: ${kind.replace(/_/g, ' ').toUpperCase()}
${kindGuidance[kind]}
${descriptionNote}
## Current Workout (${current_exercises.length} exercises)
${exerciseList}
## Completion Status
${completedNote}
## Output Requirements
Use the submit_adapted_workout tool to return the adapted workout. Include:
- prescribed_exercises: the full modified exercise list (including already-completed exercises unchanged)
- explanation: a brief, empathetic explanation of what changed and why (1-3 sentences)
The explanation will be shown directly to the athlete — keep it supportive and clear.`;
}
|