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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 29x 29x 29x 2x 29x 29x 29x 34x 29x 29x 17x 29x 17x 29x 29x | import type { WorkoutGenerationContext } from '../model-provider.js';
/**
* System prompt for workout generation.
*
* Guides Claude to produce creative, personalised programming within
* periodisation constraints (deload behavior, movement pattern balance,
* rep ranges, time caps, equipment availability).
*/
export function generateWorkoutPrompt(context: WorkoutGenerationContext): string {
const {
session_type,
time_cap_minutes,
rep_range_low,
rep_range_high,
rest_seconds_target,
is_deload,
available_equipment,
movement_pattern_history,
familiar_exercises,
constraints,
previous_violations,
is_sparse_profile,
} = context;
const deloadGuidance = is_deload
? `
## Deload Week
This is a DELOAD session. Reduce training stress significantly:
- Use 2 working sets per exercise (not 3+)
- Target weights approximately 40-60% of normal working weights
- Keep RPE below 7 on all sets
- Prioritise movement quality and recovery`
: '';
const violationWarning =
previous_violations && previous_violations.length > 0
? `
## Previous Violations to Avoid
The previous workout generation attempt had these violations. Do NOT repeat them:
${previous_violations.map((v) => `- ${v.rule}: ${v.message}`).join('\n')}`
: '';
const sparseProfileGuidance = is_sparse_profile
? `
## Sparse Profile Note
This athlete has a minimal profile with system-assigned defaults. Programme conservatively:
- Stick to foundational, well-known exercises
- Prefer moderate intensity (RPE 6-7)
- Include clear form cues in exercise notes
- Keep the session straightforward — this may be their first structured programme`
: '';
const historyEntries = Object.entries(movement_pattern_history);
const patternHistoryText =
historyEntries.length > 0
? historyEntries.map(([pattern, count]) => `- ${pattern}: ${count} recent sets`).join('\n')
: '- No recent history available';
const equipmentText =
available_equipment.length > 0 ? available_equipment.join(', ') : 'bodyweight only';
// Sanitize athlete-editable constraint text to prevent prompt injection
const sanitizeConstraint = (c: string) =>
c.replace(/#{1,6}\s/g, '').replace(/\n{2,}/g, '\n').slice(0, 200);
const constraintsText =
constraints.length > 0
? constraints.map((c) => `- ${sanitizeConstraint(c)}`).join('\n')
: '- No special constraints';
const familiarText =
familiar_exercises.length > 0
? familiar_exercises.join(', ')
: 'No exercise history available';
return `You are an expert strength and conditioning coach generating a personalised workout session.
## Session Parameters
- Session type: ${session_type}
- Time cap: ${time_cap_minutes} minutes
- Rep range: ${rep_range_low}–${rep_range_high} reps per set
- Rest target: ${rest_seconds_target} seconds between sets
${deloadGuidance}
## Available Equipment
${equipmentText}
## Movement Pattern Balance
Balance training across movement patterns (squat, hinge, push, pull). Avoid over-concentrating on one pattern. Recent training history:
${patternHistoryText}
## Athlete Familiarity
Exercises the athlete knows well (prioritise these): ${familiarText}
## Constraints
${constraintsText}
${violationWarning}${sparseProfileGuidance}
## Output Requirements
Use the submit_workout_plan tool to return the final workout. Do NOT output JSON directly.
Before building the plan, call lookup_exercises for each movement pattern you intend to programme.
Use only the id values returned by lookup_exercises as exercise_id — never invent exercise_id values.
Lookups are scoped to the athlete's available equipment (listed above).
Each prescribed exercise must include:
- exercise_id: UUID returned by lookup_exercises — must be from the library, not invented
- exercise_name: human-readable name (from the lookup_exercises result)
- order: sequence number (1-based)
- sets: array of SetPrescription objects with target_weight_kg, target_reps, target_rpe, rest_seconds
- is_warmup: false for working sets
- is_backup: true for exercises that can substitute if equipment is unavailable
- notes: optional coaching cue or null
- movement_patterns: array of patterns this exercise trains
## Validation Rules
Before submitting, use validate_session to check your workout passes safety checks:
1. No single movement pattern should exceed 45% of total set count
2. Estimated workout time must not exceed the time cap by more than 3 minutes
Use estimate_workout_time to check timing. If validate_session returns violations, redesign and re-check before submitting.`;
}
|