@@ -67,52 +67,135 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
6767 [ setApiConfigurationField ] ,
6868 )
6969
70- const onMessage = useCallback ( ( event : MessageEvent ) => {
71- const message : ExtensionMessage = event . data
72-
73- switch ( message . type ) {
74- case "ollamaModels" :
75- {
76- const newModels = message . ollamaModels ?? { }
77- setOllamaModels ( newModels )
70+ // Helper function to translate backend messages
71+ const translateMessage = useCallback (
72+ ( msg : string ) : string => {
73+ if ( ! msg ) return msg
74+
75+ // Successfully connected to Ollama at {url}
76+ const successMatch = msg . match ( / ^ S u c c e s s f u l l y c o n n e c t e d t o O l l a m a a t ( .+ ) $ / )
77+ if ( successMatch ) {
78+ return t ( "settings:providers.ollama.messages.connectionSuccess" , { baseUrl : successMatch [ 1 ] } )
79+ }
80+
81+ // Invalid URL: {url}
82+ const invalidUrlMatch = msg . match ( / ^ I n v a l i d U R L : ( .+ ) $ / )
83+ if ( invalidUrlMatch ) {
84+ return t ( "settings:providers.ollama.messages.connectionInvalidUrl" , { baseUrl : invalidUrlMatch [ 1 ] } )
85+ }
86+
87+ // Cannot connect to Ollama at {url}. Make sure Ollama is running.
88+ const refusedMatch = msg . match ( / ^ C a n n o t c o n n e c t t o O l l a m a a t ( .+ ) \. M a k e s u r e O l l a m a i s r u n n i n g \. $ / )
89+ if ( refusedMatch ) {
90+ return t ( "settings:providers.ollama.messages.connectionRefused" , { baseUrl : refusedMatch [ 1 ] } )
91+ }
92+
93+ // Connection to Ollama timed out. Check if the URL is correct and Ollama is accessible.
94+ if ( msg . includes ( "Connection to Ollama timed out" ) ) {
95+ return t ( "settings:providers.ollama.messages.connectionTimeout" )
96+ }
97+
98+ // Network error connecting to Ollama. Check your network connection.
99+ if ( msg . includes ( "Network error connecting to Ollama" ) ) {
100+ return t ( "settings:providers.ollama.messages.connectionNetworkError" )
101+ }
102+
103+ // Ollama returned error: {status} {statusText}
104+ const httpErrorMatch = msg . match ( / ^ O l l a m a r e t u r n e d e r r o r : ( \d + ) ( .+ ) $ / )
105+ if ( httpErrorMatch ) {
106+ return t ( "settings:providers.ollama.messages.connectionHttpError" , {
107+ status : httpErrorMatch [ 1 ] ,
108+ statusText : httpErrorMatch [ 2 ] ,
109+ } )
110+ }
111+
112+ // Failed to connect: {error}
113+ const failedMatch = msg . match ( / ^ F a i l e d t o c o n n e c t : ( .+ ) $ / )
114+ if ( failedMatch ) {
115+ return t ( "settings:providers.ollama.messages.connectionFailed" , { error : failedMatch [ 1 ] } )
116+ }
117+
118+ // Error testing connection: {error}
119+ const testErrorMatch = msg . match ( / ^ E r r o r t e s t i n g c o n n e c t i o n : ( .+ ) $ / )
120+ if ( testErrorMatch ) {
121+ return t ( "settings:providers.ollama.messages.connectionTestError" , { error : testErrorMatch [ 1 ] } )
122+ }
123+
124+ // Found {count} model(s) with tools support ({total} total)
125+ const refreshSuccessMatch = msg . match ( / ^ F o u n d ( \d + ) m o d e l \( s \) w i t h t o o l s s u p p o r t \( ( \d + ) t o t a l \) $ / )
126+ if ( refreshSuccessMatch ) {
127+ return t ( "settings:providers.ollama.messages.refreshSuccess" , {
128+ count : refreshSuccessMatch [ 1 ] ,
129+ total : refreshSuccessMatch [ 2 ] ,
130+ } )
131+ }
132+
133+ // No models found. Make sure Ollama is running and has models installed.
134+ if ( msg === "No models found. Make sure Ollama is running and has models installed." ) {
135+ return t ( "settings:providers.ollama.messages.refreshNoModels" )
136+ }
137+
138+ // Failed to refresh models: {error}
139+ const refreshFailedMatch = msg . match ( / ^ F a i l e d t o r e f r e s h m o d e l s : ( .+ ) $ / )
140+ if ( refreshFailedMatch ) {
141+ return t ( "settings:providers.ollama.messages.refreshFailed" , { error : refreshFailedMatch [ 1 ] } )
142+ }
143+
144+ // Unknown message - return as is
145+ return msg
146+ } ,
147+ [ t ] ,
148+ )
149+
150+ const onMessage = useCallback (
151+ ( event : MessageEvent ) => {
152+ const message : ExtensionMessage = event . data
153+
154+ switch ( message . type ) {
155+ case "ollamaModels" :
156+ {
157+ const newModels = message . ollamaModels ?? { }
158+ setOllamaModels ( newModels )
159+ if ( message . ollamaModelsWithTools ) {
160+ setModelsWithTools ( message . ollamaModelsWithTools )
161+ }
162+ setModelsWithoutTools ( message . modelsWithoutTools ?? [ ] )
163+ }
164+ break
165+ case "ollamaConnectionTestResult" :
166+ setTestResult ( {
167+ success : message . success ?? false ,
168+ message : translateMessage ( message . message ?? "Unknown error" ) ,
169+ durationMs : message . durationMs ,
170+ } )
171+ setTestingConnection ( false )
172+ if ( testResultTimerRef . current ) {
173+ clearTimeout ( testResultTimerRef . current )
174+ }
175+ testResultTimerRef . current = setTimeout ( ( ) => setTestResult ( null ) , 5000 )
176+ break
177+ case "ollamaModelsRefreshResult" :
178+ setRefreshResult ( {
179+ success : message . success ?? false ,
180+ message : translateMessage ( message . message ?? "Unknown error" ) ,
181+ durationMs : message . durationMs ,
182+ } )
183+ setRefreshingModels ( false )
78184 if ( message . ollamaModelsWithTools ) {
79185 setModelsWithTools ( message . ollamaModelsWithTools )
80186 }
81- setModelsWithoutTools ( message . modelsWithoutTools ?? [ ] )
82- }
83- break
84- case "ollamaConnectionTestResult" :
85- setTestResult ( {
86- success : message . success ?? false ,
87- message : message . message ?? "Unknown error" ,
88- durationMs : message . durationMs ,
89- } )
90- setTestingConnection ( false )
91- if ( testResultTimerRef . current ) {
92- clearTimeout ( testResultTimerRef . current )
93- }
94- testResultTimerRef . current = setTimeout ( ( ) => setTestResult ( null ) , 5000 )
95- break
96- case "ollamaModelsRefreshResult" :
97- setRefreshResult ( {
98- success : message . success ?? false ,
99- message : message . message ?? "Unknown error" ,
100- durationMs : message . durationMs ,
101- } )
102- setRefreshingModels ( false )
103- if ( message . ollamaModelsWithTools ) {
104- setModelsWithTools ( message . ollamaModelsWithTools )
105- }
106- if ( message . modelsWithoutTools ) {
107- setModelsWithoutTools ( message . modelsWithoutTools )
108- }
109- if ( refreshResultTimerRef . current ) {
110- clearTimeout ( refreshResultTimerRef . current )
111- }
112- refreshResultTimerRef . current = setTimeout ( ( ) => setRefreshResult ( null ) , 5000 )
113- break
114- }
115- } , [ ] )
187+ if ( message . modelsWithoutTools ) {
188+ setModelsWithoutTools ( message . modelsWithoutTools )
189+ }
190+ if ( refreshResultTimerRef . current ) {
191+ clearTimeout ( refreshResultTimerRef . current )
192+ }
193+ refreshResultTimerRef . current = setTimeout ( ( ) => setRefreshResult ( null ) , 5000 )
194+ break
195+ }
196+ } ,
197+ [ translateMessage ] ,
198+ )
116199
117200 const handleTestConnection = useCallback ( ( ) => {
118201 setTestingConnection ( true )
@@ -201,7 +284,9 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
201284 } `} >
202285 < div > { testResult . message } </ div >
203286 { testResult . durationMs !== undefined && (
204- < div className = "text-xs mt-1 opacity-80" > Completed in { testResult . durationMs } ms</ div >
287+ < div className = "text-xs mt-1 opacity-80" >
288+ { t ( "settings:providers.ollama.completedIn" , { duration : testResult . durationMs } ) }
289+ </ div >
205290 ) }
206291 </ div >
207292 ) }
@@ -239,7 +324,9 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
239324 } `} >
240325 < div > { refreshResult . message } </ div >
241326 { refreshResult . durationMs !== undefined && (
242- < div className = "text-xs mt-1 opacity-80" > Completed in { refreshResult . durationMs } ms</ div >
327+ < div className = "text-xs mt-1 opacity-80" >
328+ { t ( "settings:providers.ollama.completedIn" , { duration : refreshResult . durationMs } ) }
329+ </ div >
243330 ) }
244331 </ div >
245332 ) }
@@ -274,20 +361,22 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
274361 < thead >
275362 < tr className = "border-b border-vscode-foreground/10" >
276363 < th className = "text-left py-2 px-3 font-medium text-vscode-foreground" >
277- Model Name
364+ { t ( "settings:providers.ollama.table.modelName" ) }
365+ </ th >
366+ < th className = "text-left py-2 px-3 font-medium text-vscode-foreground" >
367+ { t ( "settings:providers.ollama.table.context" ) }
278368 </ th >
279369 < th className = "text-left py-2 px-3 font-medium text-vscode-foreground" >
280- Context
370+ { t ( "settings:providers.ollama.table.size" ) }
281371 </ th >
282- < th className = "text-left py-2 px-3 font-medium text-vscode-foreground" > Size</ th >
283372 < th className = "text-left py-2 px-3 font-medium text-vscode-foreground" >
284- Quantization
373+ { t ( "settings:providers.ollama.table.quantization" ) }
285374 </ th >
286375 < th className = "text-left py-2 px-3 font-medium text-vscode-foreground" >
287- Family
376+ { t ( "settings:providers.ollama.table.family" ) }
288377 </ th >
289378 < th className = "text-left py-2 px-3 font-medium text-vscode-foreground" >
290- Images
379+ { t ( "settings:providers.ollama.table.images" ) }
291380 </ th >
292381 </ tr >
293382 </ thead >
@@ -297,10 +386,10 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
297386 if ( ! bytes ) return "-"
298387 const gb = bytes / ( 1024 * 1024 * 1024 )
299388 if ( gb >= 1 ) {
300- return `${ gb . toFixed ( 1 ) } GB `
389+ return `${ gb . toFixed ( 1 ) } ${ t ( "settings:providers.ollama.table.sizeFormatting.gb" ) } `
301390 }
302391 const mb = bytes / ( 1024 * 1024 )
303- return `${ mb . toFixed ( 1 ) } MB `
392+ return `${ mb . toFixed ( 1 ) } ${ t ( "settings:providers.ollama.table.sizeFormatting.mb" ) } `
304393 }
305394 return (
306395 < tr
@@ -326,7 +415,9 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
326415 { model . family || "-" }
327416 </ td >
328417 < td className = "py-2 px-3 text-vscode-descriptionForeground" >
329- { model . supportsImages ? "Yes" : "No" }
418+ { model . supportsImages
419+ ? t ( "settings:providers.ollama.table.yes" )
420+ : t ( "settings:providers.ollama.table.no" ) }
330421 </ td >
331422 </ tr >
332423 )
0 commit comments