fix: Liste verfügbarer Ollama-Modelle in Einstellungen anzeigen (closes #103)
This commit is contained in:
parent
ac61d8f38f
commit
87a303c933
4 changed files with 107 additions and 0 deletions
|
|
@ -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-08 – Fix: KI-Verbindungstest mit Diagnoseinformationen (Issue #55)
|
## 2026-06-08 – Fix: KI-Verbindungstest mit Diagnoseinformationen (Issue #55)
|
||||||
|
|
||||||
- **`LlmService`:** Neue Methode `testConnection()` gibt detaillierte Diagnose zurück (cURL-Fehlernummer/-meldung, HTTP-Code, Antwortzeit, verfügbare Modelle)
|
- **`LlmService`:** Neue Methode `testConnection()` gibt detaillierte Diagnose zurück (cURL-Fehlernummer/-meldung, HTTP-Code, Antwortzeit, verfügbare Modelle)
|
||||||
|
|
|
||||||
|
|
@ -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
|
public function generate(string $prompt): string
|
||||||
{
|
{
|
||||||
return match($this->mode) {
|
return match($this->mode) {
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,32 @@
|
||||||
— Kein LLM-Provider konfiguriert (Auto-Discovery localhost:11434 fehlgeschlagen)
|
— Kein LLM-Provider konfiguriert (Auto-Discovery localhost:11434 fehlgeschlagen)
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</p>
|
</p>
|
||||||
|
<?php if ($reachable && $llm->getMode() === 'ollama'):
|
||||||
|
$availableModels = $llm->getAvailableModels();
|
||||||
|
$configModel = $llm->getModel();
|
||||||
|
$visionModel = $llm->getVisionModel();
|
||||||
|
?>
|
||||||
|
<?php if (!empty($availableModels)): ?>
|
||||||
|
<div class="text-sm" style="margin:0 0 .5rem 1.75rem;color:#374151">
|
||||||
|
Verfügbare Modelle:
|
||||||
|
<ul style="margin:.25rem 0 0 1.25rem;padding:0">
|
||||||
|
<?php foreach ($availableModels as $availableModel): ?>
|
||||||
|
<li>
|
||||||
|
<?= $h($availableModel) ?>
|
||||||
|
<?php if ($availableModel === $configModel): ?>
|
||||||
|
<span class="text-muted">(Standard)</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($availableModel === $visionModel): ?>
|
||||||
|
<span class="text-muted">(Vision)</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<p class="text-sm text-muted" style="margin:0 0 .5rem 1.75rem">Keine Modelle gefunden.</p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endif; ?>
|
||||||
<div style="margin-left:1.75rem;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap">
|
<div style="margin-left:1.75rem;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap">
|
||||||
<button type="button" class="btn btn-secondary btn-sm" id="btn-llm-test">Verbindung testen</button>
|
<button type="button" class="btn btn-secondary btn-sm" id="btn-llm-test">Verbindung testen</button>
|
||||||
<span id="llm-test-result" style="font-size:.8rem"></span>
|
<span id="llm-test-result" style="font-size:.8rem"></span>
|
||||||
|
|
|
||||||
32
tests/44_LlmAvailableModelsTest.php
Normal file
32
tests/44_LlmAvailableModelsTest.php
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Steuerkram\Services\LlmService;
|
||||||
|
|
||||||
|
class LlmAvailableModelsTest extends TestCase
|
||||||
|
{
|
||||||
|
protected string $testName = 'Test 44: LLM verfügbare Modelle abfragen';
|
||||||
|
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$llm = new LlmService();
|
||||||
|
|
||||||
|
$mode = $llm->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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue