diff --git a/Changes.md b/Changes.md index fe6877f..9a58765 100644 --- a/Changes.md +++ b/Changes.md @@ -2,6 +2,11 @@ --- +## 2026-06-11 – Feature: Liste verfügbarer Ollama-Modelle in den Einstellungen (Issue #103) + +- **`LlmService`:** Neue Methode `getAvailableModels()` fragt `/api/tags` ab und liefert die Namen aller lokal verfügbaren Ollama-Modelle; neue Getter `getMode()`, `getModel()`, `getVisionModel()` +- **Einstellungsseite:** Im KI-Abschnitt wird bei erreichbarem Ollama-Provider die Liste der verfügbaren Modelle angezeigt, das konfigurierte Standard- und Vision-Modell sind markiert + ## 2026-06-11 – Feature: CSV-Importformat aus „Neue Direktverbindung"-Dialog anlegen (Issue #102) - **`bank/fints.php`:** Neue Auswahl „+ CSV-Importformat…" im Anbieter-Dropdown des „Neue Direktverbindung"-Dialogs; zeigt Felder für Trennzeichen, Anführungszeichen, Datumsformat, Dezimal-/Tausendertrennzeichen, Headerzeile und übersprungene Zeilen diff --git a/src/Services/LlmService.php b/src/Services/LlmService.php index a41cd29..b7870f9 100644 --- a/src/Services/LlmService.php +++ b/src/Services/LlmService.php @@ -45,6 +45,50 @@ class LlmService }; } + public function getMode(): ?string + { + return $this->mode; + } + + public function getModel(): string + { + return $this->model; + } + + public function getVisionModel(): string + { + return $this->visionModel; + } + + /** + * Fragt beim Ollama-Server die Liste der lokal verfügbaren Modelle ab. + * Gibt ein leeres Array zurück, wenn kein Ollama-Provider konfiguriert ist + * oder der Server nicht erreichbar ist. + * + * @return string[] + */ + public function getAvailableModels(): array + { + if ($this->mode !== 'ollama') return []; + + $url = $this->url . '/api/tags'; + $ch = curl_init($url); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 3, + CURLOPT_CONNECTTIMEOUT => 2, + ]); + $response = curl_exec($ch); + $errno = curl_errno($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($errno !== 0 || $code < 200 || $code >= 300 || !$response) return []; + + $data = json_decode($response, true); + return array_column($data['models'] ?? [], 'name'); + } + public function generate(string $prompt): string { return match($this->mode) { diff --git a/src/Views/settings/form.php b/src/Views/settings/form.php index b558032..e800398 100644 --- a/src/Views/settings/form.php +++ b/src/Views/settings/form.php @@ -269,6 +269,32 @@ — Kein LLM-Provider konfiguriert (Auto-Discovery localhost:11434 fehlgeschlagen)

+ getMode() === 'ollama'): + $availableModels = $llm->getAvailableModels(); + $configModel = $llm->getModel(); + $visionModel = $llm->getVisionModel(); + ?> + +
+ Verfügbare Modelle: + +
+ +

Keine Modelle gefunden.

+ +
diff --git a/tests/44_LlmAvailableModelsTest.php b/tests/44_LlmAvailableModelsTest.php new file mode 100644 index 0000000..c2649f8 --- /dev/null +++ b/tests/44_LlmAvailableModelsTest.php @@ -0,0 +1,32 @@ +getMode(); + $this->assert( + $mode === null || $mode === 'ollama' || $mode === 'openai', + 'getMode() liefert null, ollama oder openai' + ); + + $models = $llm->getAvailableModels(); + $this->assert(is_array($models), 'getAvailableModels() liefert ein Array'); + + if ($mode !== 'ollama') { + $this->assert(empty($models), 'Ohne Ollama-Provider ist die Modell-Liste leer'); + } + + if ($mode !== null) { + $this->assertNotEmpty($llm->getModel(), 'getModel() liefert konfiguriertes Modell'); + } + } +}