predict_race
Predict finish times for standard race distances by applying the Riegel formula to a known race result.
Instructions
Predict race finish times using the Riegel formula based on a known race result
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| known_distance | Yes | Known race distance: "5k", "10k", "half", "marathon", or km value | |
| known_time | Yes | Known race time in H:MM:SS or MM:SS format | |
| target_distance | No | Target distance to predict (defaults to showing all standard distances) |
Implementation Reference
- index.js:277-301 (handler)The main handler function for the predict_race tool. It receives known_distance, known_time, and optional target_distance, resolves them using helper functions, computes predictions using the Riegel formula and VO2max estimation, and returns formatted race predictions.
async ({ known_distance, known_time, target_distance }) => { const distKm = resolveDistance(known_distance); const timeSecs = timeToSeconds(known_time); const vo2max = estimateVO2max(distKm, timeSecs); const targets = target_distance ? [{ name: target_distance, km: resolveDistance(target_distance) }] : [ { name: '5K', km: 5 }, { name: '10K', km: 10 }, { name: 'Half Marathon', km: 21.0975 }, { name: 'Marathon', km: 42.195 }, ]; let text = `Based on ${known_distance} in ${known_time}:\n\nEstimated VO2max: ${vo2max.toFixed(1)} ml/kg/min\n\nPredictions:\n`; targets.forEach(t => { const predicted = predictTime(distKm, timeSecs, t.km); const pace = predicted / t.km; text += `- ${t.name}: ${secondsToTime(predicted)} (pace: ${secondsToPace(pace)}/km)\n`; }); text += `\nNote: Predictions assume equivalent training for the target distance. Use RunDida's Race Time Predictor for more details: ${BASE_URL}/tools/race-time-predictor/`; return { content: [{ type: 'text', text }] }; } ); - index.js:271-276 (schema)Input schema for predict_race using Zod: known_distance (string, required), known_time (string, required), target_distance (string, optional).
'Predict race finish times using the Riegel formula based on a known race result', { known_distance: z.string().describe('Known race distance: "5k", "10k", "half", "marathon", or km value'), known_time: z.string().describe('Known race time in H:MM:SS or MM:SS format'), target_distance: z.string().optional().describe('Target distance to predict (defaults to showing all standard distances)'), }, - index.js:269-301 (registration)Registration of the 'predict_race' tool via server.tool() with name, description, schema, and handler function.
server.tool( 'predict_race', 'Predict race finish times using the Riegel formula based on a known race result', { known_distance: z.string().describe('Known race distance: "5k", "10k", "half", "marathon", or km value'), known_time: z.string().describe('Known race time in H:MM:SS or MM:SS format'), target_distance: z.string().optional().describe('Target distance to predict (defaults to showing all standard distances)'), }, async ({ known_distance, known_time, target_distance }) => { const distKm = resolveDistance(known_distance); const timeSecs = timeToSeconds(known_time); const vo2max = estimateVO2max(distKm, timeSecs); const targets = target_distance ? [{ name: target_distance, km: resolveDistance(target_distance) }] : [ { name: '5K', km: 5 }, { name: '10K', km: 10 }, { name: 'Half Marathon', km: 21.0975 }, { name: 'Marathon', km: 42.195 }, ]; let text = `Based on ${known_distance} in ${known_time}:\n\nEstimated VO2max: ${vo2max.toFixed(1)} ml/kg/min\n\nPredictions:\n`; targets.forEach(t => { const predicted = predictTime(distKm, timeSecs, t.km); const pace = predicted / t.km; text += `- ${t.name}: ${secondsToTime(predicted)} (pace: ${secondsToPace(pace)}/km)\n`; }); text += `\nNote: Predictions assume equivalent training for the target distance. Use RunDida's Race Time Predictor for more details: ${BASE_URL}/tools/race-time-predictor/`; return { content: [{ type: 'text', text }] }; } ); - index.js:72-74 (helper)The predictTime function implements the Riegel formula (exponential scaling) used to predict race finish times.
function predictTime(knownDist, knownTimeSecs, targetDist, exponent = 1.06) { return knownTimeSecs * Math.pow(targetDist / knownDist, exponent); } - index.js:78-85 (helper)The estimateVO2max function (Jack Daniels method) used to estimate VO2max from a known race result.
function estimateVO2max(distKm, timeSecs) { const timeMin = timeSecs / 60; const velocity = distKm * 1000 / timeMin; // meters per minute const pctVO2max = 0.8 + 0.1894393 * Math.exp(-0.012778 * timeMin) + 0.2989558 * Math.exp(-0.1932605 * timeMin); const vo2 = -4.60 + 0.182258 * velocity + 0.000104 * velocity * velocity; return vo2 / pctVO2max; }