Skip to content

Commit b0072ec

Browse files
author
Antonio Maiolo
authored
fix(app): show setup wizard when configured Ollama model is missing (#46)
1 parent c187deb commit b0072ec

3 files changed

Lines changed: 63 additions & 9 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"think-app": patch
3+
---
4+
5+
fix(app): show setup wizard when configured Ollama model is missing
6+
7+
Fixes #44
8+
9+
Previously, if Ollama was installed and running but the configured chat model (e.g., llama3.2) wasn't downloaded, the app would skip the setup wizard and fail when trying to chat.
10+
11+
Now the app checks if the configured model is actually available before skipping the setup wizard. Also improved the model download progress to show user-friendly status messages instead of raw layer hashes.

app/src/App.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ function App() {
106106
setAppState("ai_setup");
107107
return;
108108
}
109+
110+
// Check if the configured model is actually downloaded
111+
const modelsRes = await apiFetch("/api/settings/models?provider=ollama");
112+
const modelsData = await modelsRes.json();
113+
114+
// Check if current_model exists in the available models list
115+
const hasConfiguredModel = modelsData.models?.some(
116+
(m: { name: string }) =>
117+
m.name === modelsData.current_model ||
118+
m.name.startsWith(modelsData.current_model + ":")
119+
);
120+
121+
if (!hasConfiguredModel) {
122+
// Configured model not downloaded - show setup wizard
123+
setAppState("ai_setup");
124+
return;
125+
}
109126
}
110127
} catch {
111128
// If checks fail, proceed to app (don't block on check failure)

app/src/SetupWizard.tsx

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ function WizardLayout({ title, children }: { title?: string; children: React.Rea
5656
);
5757
}
5858

59+
const formatPullStatus = (status: string): string => {
60+
if (status.startsWith('pulling manifest')) return 'Preparing download...';
61+
if (status.startsWith('pulling ')) return 'Downloading model...';
62+
if (status.startsWith('verifying')) return 'Verifying download...';
63+
if (status.startsWith('writing')) return 'Finalizing...';
64+
if (status === 'success') return 'Complete!';
65+
return status;
66+
};
67+
5968
export default function SetupWizard({ onComplete }: Props) {
6069
const [step, setStep] = useState<SetupStep>('check');
6170
const [progress, setProgress] = useState(0);
@@ -85,7 +94,7 @@ export default function SetupWizard({ onComplete }: Props) {
8594
setProgress(data.progress);
8695
}
8796
if (data.status) {
88-
setStatusText(data.status);
97+
setStatusText(formatPullStatus(data.status));
8998
}
9099
});
91100

@@ -112,17 +121,34 @@ export default function SetupWizard({ onComplete }: Props) {
112121
if (res.ok) {
113122
const data = await res.json();
114123
const models = data.models?.map((m: { name: string }) => m.name) || [];
124+
const hasChatModel = models.some((n: string) => n.startsWith('llama3.2'));
115125
const hasEmbedding = models.some((n: string) => n.startsWith('mxbai-embed-large'));
116126

117-
if (!hasEmbedding && window.electronAPI) {
127+
if ((!hasChatModel || !hasEmbedding) && window.electronAPI) {
118128
setStep('pulling');
119-
setProgress(0);
120-
setStatusText('Downloading embedding model...');
121-
const result = await window.electronAPI.pullModel('mxbai-embed-large');
122-
if (!result.success) {
123-
setError(result.error || 'Embedding model download failed');
124-
setStep('choose');
125-
return;
129+
130+
// Pull chat model if missing
131+
if (!hasChatModel) {
132+
setProgress(0);
133+
setStatusText('Downloading chat model...');
134+
const chatResult = await window.electronAPI.pullModel('llama3.2');
135+
if (!chatResult.success) {
136+
setError(chatResult.error || 'Chat model download failed');
137+
setStep('choose');
138+
return;
139+
}
140+
}
141+
142+
// Pull embedding model if missing
143+
if (!hasEmbedding) {
144+
setProgress(0);
145+
setStatusText('Downloading embedding model...');
146+
const embedResult = await window.electronAPI.pullModel('mxbai-embed-large');
147+
if (!embedResult.success) {
148+
setError(embedResult.error || 'Embedding model download failed');
149+
setStep('choose');
150+
return;
151+
}
126152
}
127153
}
128154

0 commit comments

Comments
 (0)