2b0abad68e
Add a single-session AI flow alongside program generation: describe a
workout in plain words and get a ready-to-log workout back — exercises
with suggested weights, target reps, and set counts grounded in the
user's recent history. The suggestion can be inline-edited or refined
by sending a follow-up instruction back to the model, then "Use this
workout" pre-fills the normal New Workout form (nothing persists until
the user saves through the regular path).
Why reuse, not fork: the existing program-generation spine (detached
background runner, SSE streaming, lenient-JSON preview, 5 providers,
history context, library name->id mapping) already does the hard parts.
A new AIGeneration.kind discriminant ("program" | "workout", default
"program" via boot-time guarded ALTER) selects the parser and keeps the
ephemeral workout rows out of the program-shaped AI history. Refine is a
fresh generation seeded with the prior suggestion (validated through the
same schema before it re-enters the prompt).
Hand-off is sessionStorage -> /main/workouts/new?from=ai -> AiWorkoutPrefill,
which expands each suggestion into N sets and maps effort by cardio-ness
(Gear for cardio, RPE for strength). EditWorkoutData.id is now optional so
the prefill CREATEs rather than PATCHing a nonexistent id. The AI suggests
each weight in that exercise's effective logging unit (the library JSON
carries a per-exercise unit) so the stored number and unit never diverge.
Built + sideloaded to immense-voyage.local as 1.2.0:6; on-box ALTER and
non-root launch confirmed via start-cli. tsc clean (app + packaging),
251 tests pass, next build + s9pk build succeed.
33 lines
1.4 KiB
TypeScript
33 lines
1.4 KiB
TypeScript
import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk'
|
|
|
|
/**
|
|
* v1.2.0:6 — AI "generate today's workout" (2026-06-19).
|
|
*
|
|
* A new AI flow alongside program generation: describe a single session in
|
|
* plain words and get a ready-to-log workout back — exercises with suggested
|
|
* weights + target reps + set counts grounded in recent history. Inline-edit
|
|
* it, send a follow-up to refine it via the model, then "Use this workout" to
|
|
* pre-fill the normal New Workout form (nothing persists until you save).
|
|
*
|
|
* Reuses the existing generation spine (detached runner / SSE / lenient JSON /
|
|
* providers / history context) via a new AIGeneration.kind discriminant
|
|
* ("program" | "workout"). Single-workout rows are ephemeral and excluded from
|
|
* the program-shaped AI history.
|
|
*
|
|
* Additive schema change: the new AIGeneration.kind column (default "program")
|
|
* is added by the boot-time guarded ALTER in docker_entrypoint.sh, so this
|
|
* migration stays empty like every other column add. Existing rows read as
|
|
* "program"; no data changes.
|
|
*/
|
|
export const v_1_2_0_6 = VersionInfo.of({
|
|
version: '1.2.0:6',
|
|
releaseNotes: {
|
|
en_US:
|
|
'New: AI "Today\'s workout". Describe a session in plain words and get a ready-to-log workout with suggested weights and reps from your history. Edit it, refine it with the AI, then pre-fill the workout log. No data changes.',
|
|
},
|
|
migrations: {
|
|
up: async () => {},
|
|
down: IMPOSSIBLE,
|
|
},
|
|
})
|