From 69891ae6fd1acb80fd4f9f4c4ee0142e4bddbf05 Mon Sep 17 00:00:00 2001 From: Aleksandar Sredojevi Date: Fri, 5 Jun 2026 11:49:33 -0400 Subject: [PATCH] Improve Ollama request timeout settings --- README.md | 2 +- scripts/ai.py | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index de1485c..4f4b616 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ I38 includes an integrated AI assistant accessible through ratpoison mode with t The AI assistant stores its configuration in `~/.config/stormux/I38/ai.conf` using XDG directory standards. Settings include: - AI provider selection (Claude Code or Ollama) -- Ollama model selection and host configuration +- Ollama model selection, host configuration, and request timeout - Action confirmation preferences - Voice input/output settings - Wake word customization diff --git a/scripts/ai.py b/scripts/ai.py index 925b405..c6746ac 100755 --- a/scripts/ai.py +++ b/scripts/ai.py @@ -218,6 +218,7 @@ class AiConfig: 'ollama_model': 'llama2', 'ollama_vision_model': 'llava', 'ollama_host': 'http://localhost:11434', + 'ollama_timeout': '60', 'codex_model': 'gpt-5.1-codex', 'codex_profile': '', 'confirm_actions': 'true', @@ -249,8 +250,9 @@ class AiConfig: class OllamaInterface: """Interface for Ollama AI provider""" - def __init__(self, host='http://localhost:11434'): + def __init__(self, host='http://localhost:11434', timeout=60): self.host = host + self.timeout = max(1, int(timeout)) self.model_details_cache = {} def get_models(self): @@ -382,7 +384,7 @@ class OllamaInterface: return f"Error reading image: {str(e)}" response = requests.post(f'{self.host}/api/generate', - json=data, timeout=60) # Longer timeout for image processing + json=data, timeout=self.timeout) if response.status_code == 200: return response.json().get('response', 'No response received') else: @@ -600,7 +602,8 @@ class AiAssistant(Gtk.Window): self.config = AiConfig() self.claudeInterface = ClaudeCodeInterface() self.codexInterface = CodexCliInterface() - self.ollamaInterface = OllamaInterface(self.config.get('ollama_host')) + self.ollamaInterface = OllamaInterface(self.config.get('ollama_host'), + self.config.get('ollama_timeout')) self.windowContext = WindowContext() self.launchWindowId = self.windowContext.get_focused_window_id() self.voiceRecognition = VoiceRecognition(self.config) @@ -972,6 +975,20 @@ class AiAssistant(Gtk.Window): self.hostEntry.get_accessible().set_description("URL of the Ollama service") hostLabel.set_mnemonic_widget(self.hostEntry) ollamaBox.pack_start(self.hostEntry, False, False, 0) + + # Ollama request timeout + ollamaTimeoutLabel = Gtk.Label("Ollama _timeout (seconds):") + ollamaTimeoutLabel.set_use_underline(True) + ollamaTimeoutLabel.set_alignment(0, 0.5) + ollamaBox.pack_start(ollamaTimeoutLabel, False, False, 0) + + self.ollamaTimeoutSpin = Gtk.SpinButton.new_with_range(1, 3600, 1) + self.ollamaTimeoutSpin.set_value(int(self.config.get('ollama_timeout', '60'))) + self.ollamaTimeoutSpin.set_can_focus(True) + self.ollamaTimeoutSpin.get_accessible().set_name("Ollama request timeout") + self.ollamaTimeoutSpin.get_accessible().set_description("How long to wait for Ollama requests in seconds") + ollamaTimeoutLabel.set_mnemonic_widget(self.ollamaTimeoutSpin) + ollamaBox.pack_start(self.ollamaTimeoutSpin, False, False, 0) self.ollamaFrame.add(ollamaBox) vbox.pack_start(self.ollamaFrame, False, False, 0) @@ -1305,7 +1322,8 @@ class AiAssistant(Gtk.Window): """Handle refresh models button click""" # Update host if changed new_host = self.hostEntry.get_text() - self.ollamaInterface = OllamaInterface(new_host) + self.ollamaInterface = OllamaInterface(new_host, + int(self.ollamaTimeoutSpin.get_value())) self.refresh_ollama_models() def on_save_settings(self, widget): @@ -1318,8 +1336,11 @@ class AiAssistant(Gtk.Window): self.config.set('provider', 'ollama') self.config.set('ollama_host', self.hostEntry.get_text()) + self.config.set('ollama_timeout', str(int(self.ollamaTimeoutSpin.get_value()))) self.config.set('codex_model', self.codexModelEntry.get_text().strip()) self.config.set('codex_profile', self.codexProfileEntry.get_text().strip()) + self.ollamaInterface = OllamaInterface(self.config.get('ollama_host'), + self.config.get('ollama_timeout')) # Save selected text model for radio in self.textModelRadios: