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 125 126 | import type { PrescribedExercise, MovementPattern, SessionType } from '@strengthsys/shared';
// ── AI Tier Distinction ─────────────────────────────────────
/**
* Simple tier: low-stakes, model-agnostic tasks (review questions,
* notifications, adherence messages).
*
* Complex tier: high-stakes tasks requiring creativity within constraints
* (workout generation, adaptation, replanning).
*/
export type ModelTier = 'simple' | 'complex';
// ── Context Types ───────────────────────────────────────────
export interface WorkoutGenerationContext {
athlete_id: string;
block_id: string;
session_type: SessionType;
time_cap_minutes: number;
rep_range_low: number;
rep_range_high: number;
rest_seconds_target: number;
is_deload: boolean;
available_equipment: string[];
movement_pattern_history: Partial<Record<MovementPattern, number>>;
familiar_exercises: string[];
constraints: string[];
previous_violations?: Array<{ rule: string; message: string }>;
/** True if athlete has a minimal profile with system-assigned defaults */
is_sparse_profile?: boolean;
}
export interface WorkoutAdaptationContext {
workout_id: string;
athlete_id: string;
kind: 'not_feeling_it' | 'exercise_substitution' | 'pain_reported';
context_description: string | null;
current_exercises: PrescribedExercise[];
completed_sets: number;
}
export interface ReviewContext {
athlete_id: string;
workout_id?: string;
block_id?: string;
cycle_id?: string;
scope: 'workout' | 'block' | 'cycle';
/** 'system_default' if schedule was auto-assigned, 'athlete_specified' if athlete chose */
schedule_source?: 'system_default' | 'athlete_specified';
/** True if any of the athlete's training locations has source = system_default */
has_system_default_location?: boolean;
/** True if athlete has at least one active goal */
has_active_goals?: boolean;
}
export interface NarrativeContext {
athlete_id: string;
timeframe: 'recent' | 'block' | 'cycle' | 'all_time';
}
// ── Response Types ──────────────────────────────────────────
export interface WorkoutPlan {
prescribed_exercises: PrescribedExercise[];
}
export interface AdaptedWorkout {
prescribed_exercises: PrescribedExercise[];
explanation: string;
}
export interface ReviewPrompt {
question: string;
options: string[] | null;
kind: 'standard' | 'profile_enrichment' | 'goal_refinement' | 'goal_discovery';
}
// ── AI Interaction Logging ──────────────────────────────────
export interface AIInteraction {
athlete_id: string;
action_type: string;
context_sent: unknown;
response_received: unknown;
tools_called: string[];
tool_results: unknown[];
/** Per-call details for computation tools — used to populate computation_tool_calls rows. */
tool_call_details?: Array<{
tool_name: string;
input_parameters: unknown;
output_result: unknown;
called_at: string; // ISO timestamp
}>;
duration_ms: number;
}
// ── Model Provider Interface ────────────────────────────────
/**
* Model-agnostic interface for AI-powered operations.
* Implementations can wrap Claude, OpenAI, or any other provider.
*
* All methods return the AI response alongside an AIInteraction log
* entry for audit purposes.
*/
export interface ModelProvider {
readonly tier: ModelTier;
generateWorkout(
context: WorkoutGenerationContext,
): Promise<{ result: WorkoutPlan; interaction: AIInteraction }>;
adaptWorkout(
context: WorkoutAdaptationContext,
): Promise<{ result: AdaptedWorkout; interaction: AIInteraction }>;
generateReviewQuestions(
context: ReviewContext,
): Promise<{ result: ReviewPrompt[]; interaction: AIInteraction }>;
generateNarrative(
context: NarrativeContext,
): Promise<{ result: string; interaction: AIInteraction }>;
}
|