Build a local AI feature
Add a deterministic fallback
Preserve the application value when local inference is unavailable by generating a truthful result from source data.
The fallback should not pretend to be another AI model.
Build the sentence directly from fields the application already trusts:
function fallbackSummary(activity) {
return {
summary: `You focused for ${activity.focusMinutes} minutes and completed ${activity.completedTasks} tasks.`,
confidence: 'high',
}
}
Call the model inside a narrow wrapper. Return the validated model result on success and the deterministic result on expected local failures.
Do not hide programming errors. A misspelled variable or invalid application state should fail a test, not quietly look like an Ollama outage. Reserve the fallback for runtime conditions you genuinely expect in production.
The interface can label generated text when that distinction matters. It does not need to interrupt the user every time the optional enhancement falls back. A small “generated” badge is enough when transparency is a requirement.
This pattern is useful for summaries, labels, suggestions, and other features where the original data remains valuable by itself. The user came for the activity record, not for poetry.
Compare the fallback output against the schema the model uses. Same keys, same types, same max length rules. That lets one UI path render both outcomes without branching all over the codebase.
I test fallbacks by stopping Ollama and running the same button click. If the screen still updates with truthful numbers from the record, the boundary holds.
When the model returns extra facts not present in the input, reject and fall back too. Truthfulness beats fluent hallucination every time for this feature.
Try this on your own project: write one unit test that calls fallbackSummary with the sample activity and asserts the exact string. That test should never call the network.
Lesson completed