- Add prompt column to ai_settings (migration) - AiSetting: DEFAULT_PROMPT constant + getActivePrompt() (falls back to default if empty) - ProcessNailPolishImage: reads prompt from DB instead of hardcoded - Admin view: textarea to edit prompt, shows active prompt, reset-to-default link Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
101 lines
5.0 KiB
PHP
101 lines
5.0 KiB
PHP
@extends('layouts.app')
|
||
|
||
@section('title', 'KI-Einstellungen – NeoNail DB')
|
||
|
||
@section('content')
|
||
|
||
<div class="page-hero mb-4">
|
||
<h1><i class="fas fa-robot me-2"></i>KI-Einstellungen</h1>
|
||
<p>Ollama-Konfiguration für den automatischen Foto-Import</p>
|
||
</div>
|
||
|
||
<div class="row g-4">
|
||
<div class="col-lg-7">
|
||
<div class="card">
|
||
<div class="card-header"><i class="fas fa-cog me-2"></i>Ollama Verbindung</div>
|
||
<div class="card-body p-4">
|
||
<form method="POST" action="{{ route('admin.ai.update') }}">
|
||
@csrf
|
||
@method('PUT')
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label" for="ollama_url">Ollama URL <span class="text-danger">*</span></label>
|
||
<input type="url" class="form-control @error('ollama_url') is-invalid @enderror"
|
||
id="ollama_url" name="ollama_url"
|
||
value="{{ old('ollama_url', $ai->ollama_url) }}"
|
||
placeholder="http://192.168.30.172:11434">
|
||
@error('ollama_url')
|
||
<div class="invalid-feedback">{{ $message }}</div>
|
||
@enderror
|
||
<div class="form-text">URL des Ollama-Containers/Servers ohne abschließenden Slash.</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label" for="ollama_model">Modell <span class="text-danger">*</span></label>
|
||
<input type="text" class="form-control @error('ollama_model') is-invalid @enderror"
|
||
id="ollama_model" name="ollama_model"
|
||
value="{{ old('ollama_model', $ai->ollama_model) }}"
|
||
placeholder="llama3.2-vision">
|
||
@error('ollama_model')
|
||
<div class="invalid-feedback">{{ $message }}</div>
|
||
@enderror
|
||
<div class="form-text">Muss ein Vision-fähiges Modell sein (z.B. <code>llama3.2-vision</code>, <code>llava</code>).</div>
|
||
</div>
|
||
|
||
<div class="mb-4">
|
||
<label class="form-label" for="prompt">
|
||
Erkennungs-Prompt
|
||
<span class="badge bg-secondary ms-1" style="font-size:.65rem;">optional</span>
|
||
</label>
|
||
<textarea class="form-control @error('prompt') is-invalid @enderror"
|
||
id="prompt" name="prompt" rows="12"
|
||
placeholder="Leer lassen für Standard-Prompt"
|
||
style="font-family: monospace; font-size: .82rem;">{{ old('prompt', $ai->prompt) }}</textarea>
|
||
@error('prompt')
|
||
<div class="invalid-feedback">{{ $message }}</div>
|
||
@enderror
|
||
<div class="form-text">
|
||
Leer lassen um den Standard-Prompt zu verwenden.
|
||
<a href="#" onclick="resetPrompt(); return false;">Standard-Prompt einfügen</a>
|
||
</div>
|
||
<div class="mt-2 p-3" style="background:#f9fafb; border-radius:10px; border:1px solid #e5e7eb;">
|
||
<p style="font-size:.75rem; color:#6b7280; margin:0 0 6px; font-weight:600;">AKTUELL AKTIVER PROMPT:</p>
|
||
<pre style="font-size:.75rem; color:#374151; margin:0; white-space:pre-wrap; word-break:break-word;">{{ $ai->getActivePrompt() }}</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="submit" class="btn btn-primary">
|
||
<i class="fas fa-save me-2"></i>Speichern
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-lg-5">
|
||
<div class="card">
|
||
<div class="card-header"><i class="fas fa-info-circle me-2"></i>Queue Worker</div>
|
||
<div class="card-body p-3">
|
||
<p style="font-size:.83rem; color:#374151; margin-bottom:10px;">
|
||
Jobs werden über die <strong>Datenbank-Queue</strong> verarbeitet. Auf dem Server muss dauerhaft ein Worker laufen:
|
||
</p>
|
||
<code style="display:block; background:#f3f4f6; padding:10px 12px; border-radius:8px; font-size:.78rem; white-space:pre-wrap;">php artisan queue:work \
|
||
--timeout=180 \
|
||
--tries=2 \
|
||
--sleep=3</code>
|
||
<p style="font-size:.78rem; color:#9ca3af; margin-top:10px; margin-bottom:0;">
|
||
Empfohlen: Als Supervisor-Dienst einrichten, damit der Worker nach Crashes neu startet.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
@section('scripts')
|
||
<script>
|
||
function resetPrompt() {
|
||
document.getElementById('prompt').value = @json(\App\Models\AiSetting::DEFAULT_PROMPT);
|
||
}
|
||
</script>
|
||
@endsection
|