Full implementation from spec: ZNC/IRC client with TLS, Ollama LLM backend, per-user SQLite conversation memory, and Flask web admin portal with 7 pages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
80 lines
3.0 KiB
HTML
80 lines
3.0 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}LLM Settings — IRC Bot Portal{% endblock %}
|
|
{% block content %}
|
|
<h1>LLM Settings</h1>
|
|
|
|
{% for e in errors %}
|
|
<div class="alert alert-error">{{ e }}</div>
|
|
{% endfor %}
|
|
|
|
<form method="post" class="settings-form">
|
|
<div class="section">
|
|
<h2>Ollama Backend</h2>
|
|
<div class="field-row">
|
|
<label>Host</label>
|
|
<input type="text" name="ollama_host" value="{{ cfg.get('ollama_host', '192.168.2.10') }}" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Port</label>
|
|
<input type="number" name="ollama_port" value="{{ cfg.get('ollama_port', 11434) }}" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Model</label>
|
|
<input type="text" name="ollama_model" value="{{ cfg.get('ollama_model', 'llama3.1') }}" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Temperature</label>
|
|
<input type="number" name="ollama_temperature" value="{{ cfg.get('ollama_temperature', 0.7) }}" step="0.05" min="0" max="2" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Token Limit (num_predict)</label>
|
|
<input type="number" name="ollama_num_predict" value="{{ cfg.get('ollama_num_predict', 120) }}" min="1" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Context Size (num_ctx tokens)</label>
|
|
<input type="number" name="ollama_num_ctx" value="{{ cfg.get('ollama_num_ctx', 2048) }}" min="512" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Response Timeout (seconds)</label>
|
|
<input type="number" name="response_timeout_seconds" value="{{ cfg.get('response_timeout_seconds', 30) }}" min="5" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>Response Handling</h2>
|
|
<div class="field-row">
|
|
<label>System Prompt</label>
|
|
<textarea name="system_prompt" rows="4">{{ cfg.get('system_prompt', '') }}</textarea>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Max Response Length (chars)</label>
|
|
<input type="number" name="max_response_length" value="{{ cfg.get('max_response_length', 400) }}" min="50" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Channel Context Window (messages)</label>
|
|
<input type="number" name="context_window" value="{{ cfg.get('context_window', 5) }}" min="0" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h2>Persistent Memory</h2>
|
|
<div class="field-row">
|
|
<label>Memory Enabled</label>
|
|
<input type="checkbox" name="memory_enabled" {% if cfg.get('memory_enabled', True) %}checked{% endif %}>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Memory Depth (exchanges)</label>
|
|
<input type="number" name="memory_history_limit" value="{{ cfg.get('memory_history_limit', 8) }}" min="0" required>
|
|
</div>
|
|
<div class="field-row">
|
|
<label>Memory Max Age (days, 0=forever)</label>
|
|
<input type="number" name="memory_max_age_days" value="{{ cfg.get('memory_max_age_days', 90) }}" min="0" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="actions">
|
|
<button type="submit" class="btn btn-primary">Save & Apply</button>
|
|
</div>
|
|
</form>
|
|
{% endblock %}
|