What it is, and what it is not
The AI Coach is a chat screen that can query your local database while it answers. It is not a hosted service, and no API key ships with the app. If you never configure a provider, the feature simply does not exist for you and everything else works unchanged.
When you send a message, the conversation plus whatever the tools returned goes to the provider you chose. That provider's privacy policy and retention rules apply. This is the one part of the app where your training data deliberately leaves the device, and it only happens when you use it.
Setting up a provider
Go to Settings → Configure AI. Any
OpenAI-compatible endpoint works: the app normalises the base URL to end
in /v1, fetches the available models from the provider and
sorts them for you.
- Providers
- As many as you like, each with a name, base URL, token, model list and a selected model. One is active at a time.
- Reasoning effort
- Per model: automatic, low, medium or high. Automatic omits the parameter entirely.
- System prompt
- Editable, so you can set the coach's personality and priorities.
- Context mode
- Minimal, standard or full: how much of the summary snapshot is attached to each turn.
- Response style
- Concise, balanced or detailed.
- Display
- Show message timestamps, and auto-expand tool details so you can watch what it queried.
Where your token lives
Provider tokens are written to platform secure storage, keyed per provider. They are deliberately kept out of the app database, out of logs, out of prompts and out of backups, so exporting your journal and handing the file to someone else cannot leak a key.
Transport details
- Requests go to
POST {baseUrl}/chat/completions. - A 180-second timeout, with a single retry on timeout.
- Compatibility is adjusted automatically: if a provider rejects temperature, reasoning effort or a forced tool choice, the app drops or downgrades that parameter and retries rather than failing.
- No streaming, and no token or cost tracking. Answers arrive complete.
What gets sent
The request is deliberately structured so that the expensive, unchanging part stays identical across turns, which is what lets a provider cache it.
- A static system prefix: your editable prompt, plus two fixed policies that are not editable: one requiring the model to consult tools for facts about you instead of relying on memory, and one requiring approval before any routine change. Keeping those out of the editable prompt means a custom personality cannot talk its way past the approval requirement.
- One dynamic block containing a small JSON snapshot of your data, an optional summary of older messages in the thread, and an optional hint line about which tools are probably relevant.
- The conversation, with older tool transcripts dropped from the request once a final answer exists; they stay in your history for you to read.
The snapshot
The injected snapshot is counts and availability, not content. It holds totals: workouts, sets, total volume, exercises, routines, body measurements, active goals, recorded runs, bike sessions, run plans, current streak, and, in standard or full mode, which domains have recent data (sleep nights in the last week, nutrition days, workouts and weight entries in the last month, and so on). The date is day-granular on purpose.
No individual entries are dumped into the prompt. Every specific fact the coach states has to come from a tool call, which is exactly why the tool list below matters.
If a query returns too much, the version sent to the model is trimmed and wrapped with a note telling it to narrow the query. The message stored in your history keeps the full payload, so the app can still show you everything it read.
The tool catalog
The full catalog is offered on every round. The relevance hint never filters it; a hint that guesses wrong cannot stop the model from reaching the tool it actually needs.
Read-only tools
These execute directly against your database, with no confirmation step.
| Area | Tools |
|---|---|
| Workouts |
list_recent_workouts, get_workout_history,
get_workout_detail, get_training_summary
|
| Exercises |
list_exercises, get_exercise_detail,
get_exercise_history,
get_exercise_personal_records
|
| Volume & trend |
get_weekly_volume_breakdown,
get_progress_trend
|
| Routines | list_routines, get_routine_detail |
| Body | list_body_measurements |
| Cardio & plans |
get_cardio_summary, list_run_activities,
get_run_activity_detail, get_run_progress,
get_run_achievements, list_run_plans,
get_run_plan_detail, get_run_schedule
|
| Goals |
list_goals, get_goal_progress_history
|
| Sleep |
get_sleep_summary,
get_sleep_night_detail,
get_sleep_history, get_sleep_profile
|
| Nutrition |
get_nutrition_summary,
get_nutrition_diary_day,
get_nutrition_history,
get_micronutrient_summary,
search_food_library, get_food_detail,
list_saved_meals,
get_saved_meal_detail,
get_nutrition_profile
|
| Cross-domain analysis |
analyze_sleep_performance,
analyze_nutrition_body_trend,
get_weekly_recovery_trend
|
Proposal tools
Two tools express an intent to change something. Neither one writes.
propose_routine_change- Builds a routine proposal and stores it for review. Preparing a proposal never mutates a routine. When you approve it, the app revalidates the proposal against the current state of your data and applies it inside a single transaction, so a proposal built against a routine you have since edited fails loudly instead of overwriting your changes.
propose_manual_food_creation- Produces an editable draft. Approving it opens the manual food form pre-filled; the food exists only after you press save yourself.
No AI response can write domain data without explicit user approval. That rule is enforced in the fixed part of the prompt, in the tool registry, and in the code that applies a proposal: three independent places, so changing the personality prompt cannot weaken it.
Images
You can attach an image to a message when the model supports vision. The main built-in use is the food label photo flow: photograph a nutrition label and get a food draft to review. The request carries a note that images are user-provided content and that details must not be invented; a blurry label should produce blanks, not plausible numbers.
Threads and history
Conversations are stored locally with a history screen for older threads. Older messages in a long thread are condensed into a summary for the request, while the full messages stay readable in the app. Tool calls are shown inline so you can expand any of them and see exactly what was queried and what came back.
What it is good at
Questions that need several queries stitched together, which is tedious to do by hand across screens:
- "Has my bench actually progressed this quarter, or just my volume?"
- "Compare my weeks with under six hours of sleep against the rest."
- "Which exercises have I not trained in a month?"
- "Am I hitting protein on training days specifically?"
- "Is my long run keeping up with the plan's weekly distance?"
Expand the tool calls in the message. Because every claim about your data is supposed to come from a tool result, you can usually see immediately whether the model misread the numbers or the numbers themselves are what surprised you.