159 lines
7.2 KiB
HTML
159 lines
7.2 KiB
HTML
{{define "content"}}
|
|
<h2>Настройки нейросетей</h2>
|
|
<div class="card">
|
|
<form id="ai-form">
|
|
<label>Провайдер:</label>
|
|
<select id="provider" name="provider">
|
|
<option value="ollama">Ollama (локальная)</option>
|
|
<option value="chatgpt">ChatGPT (OpenAI)</option>
|
|
<option value="gigachat">GigaChat (Сбер)</option>
|
|
</select>
|
|
|
|
<div id="ollama-fields" class="provider-fields">
|
|
<label>Endpoint:</label>
|
|
<input type="text" id="endpoint" name="endpoint" placeholder="http://localhost:11434">
|
|
<label>Модель:</label>
|
|
<input type="text" id="model" name="model" placeholder="llama2, mistral, ...">
|
|
</div>
|
|
<div id="chatgpt-fields" class="provider-fields" style="display:none;">
|
|
<label>API Key:</label>
|
|
<input type="password" id="api_key" name="api_key" placeholder="sk-...">
|
|
<label>Модель:</label>
|
|
<input type="text" id="model_gpt" name="model_gpt" placeholder="gpt-3.5-turbo">
|
|
</div>
|
|
<div id="gigachat-fields" class="provider-fields" style="display:none;">
|
|
<label>Client ID:</label>
|
|
<input type="text" id="client_id" name="client_id" placeholder="ваш client_id">
|
|
<label>Client Secret:</label>
|
|
<input type="password" id="client_secret" name="client_secret" placeholder="ваш client_secret">
|
|
<label>Endpoint (опционально):</label>
|
|
<input type="text" id="endpoint_giga" name="endpoint_giga" placeholder="https://gigachat.devices.sberbank.ru/api/v1">
|
|
<label>Модель (опционально):</label>
|
|
<input type="text" id="model_giga" name="model_giga" placeholder="GigaChat">
|
|
</div>
|
|
|
|
<label>Системный промпт (префикс):</label>
|
|
<textarea id="system_prompt" name="system_prompt" rows="3">ты в чате твитча, ответь одним предложением.</textarea>
|
|
|
|
<button type="submit">Сохранить</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Тестирование</h3>
|
|
<input type="text" id="test-prompt" placeholder="Введите вопрос для нейросети" style="width: 70%;">
|
|
<button id="test-btn">Отправить</button>
|
|
<div id="test-result" class="test-result-block"></div>
|
|
</div>
|
|
|
|
<script>
|
|
const providerSelect = document.getElementById('provider');
|
|
const ollamaFields = document.getElementById('ollama-fields');
|
|
const chatgptFields = document.getElementById('chatgpt-fields');
|
|
const gigachatFields = document.getElementById('gigachat-fields');
|
|
|
|
function showProviderFields() {
|
|
const prov = providerSelect.value;
|
|
ollamaFields.style.display = 'none';
|
|
chatgptFields.style.display = 'none';
|
|
gigachatFields.style.display = 'none';
|
|
if (prov === 'ollama') ollamaFields.style.display = 'block';
|
|
else if (prov === 'chatgpt') chatgptFields.style.display = 'block';
|
|
else if (prov === 'gigachat') gigachatFields.style.display = 'block';
|
|
}
|
|
providerSelect.addEventListener('change', showProviderFields);
|
|
|
|
async function loadConfig() {
|
|
const res = await fetch('/api/ai/config');
|
|
const cfg = await res.json();
|
|
providerSelect.value = cfg.provider || 'ollama';
|
|
document.getElementById('endpoint').value = cfg.endpoint || '';
|
|
document.getElementById('model').value = cfg.model || '';
|
|
document.getElementById('api_key').value = cfg.api_key || '';
|
|
document.getElementById('model_gpt').value = cfg.model || '';
|
|
document.getElementById('client_id').value = cfg.client_id || '';
|
|
document.getElementById('client_secret').value = cfg.client_secret || '';
|
|
document.getElementById('endpoint_giga').value = cfg.endpoint || '';
|
|
document.getElementById('model_giga').value = cfg.model || '';
|
|
document.getElementById('system_prompt').value = cfg.system_prompt || 'ты в чате твитча, ответь одним предложением.';
|
|
showProviderFields();
|
|
}
|
|
|
|
document.getElementById('ai-form').addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const provider = providerSelect.value;
|
|
let apiKey = '', endpoint = '', model = '', clientId = '', clientSecret = '';
|
|
if (provider === 'ollama') {
|
|
endpoint = document.getElementById('endpoint').value;
|
|
model = document.getElementById('model').value;
|
|
} else if (provider === 'chatgpt') {
|
|
apiKey = document.getElementById('api_key').value;
|
|
model = document.getElementById('model_gpt').value;
|
|
} else if (provider === 'gigachat') {
|
|
clientId = document.getElementById('client_id').value;
|
|
clientSecret = document.getElementById('client_secret').value;
|
|
endpoint = document.getElementById('endpoint_giga').value;
|
|
model = document.getElementById('model_giga').value;
|
|
}
|
|
const systemPrompt = document.getElementById('system_prompt').value;
|
|
const body = {
|
|
provider,
|
|
api_key: apiKey,
|
|
endpoint,
|
|
model,
|
|
system_prompt: systemPrompt,
|
|
client_id: clientId,
|
|
client_secret: clientSecret
|
|
};
|
|
try {
|
|
const res = await fetch('/api/ai/config', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body)
|
|
});
|
|
if (res.ok) {
|
|
alert('Настройки сохранены');
|
|
await loadConfig();
|
|
} else {
|
|
const err = await res.text();
|
|
alert('Ошибка сохранения: ' + err);
|
|
}
|
|
} catch (err) {
|
|
alert('Ошибка соединения: ' + err.message);
|
|
}
|
|
});
|
|
|
|
document.getElementById('test-btn').addEventListener('click', async () => {
|
|
const prompt = document.getElementById('test-prompt').value;
|
|
if (!prompt) return;
|
|
try {
|
|
const res = await fetch('/api/ai/test', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ prompt })
|
|
});
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
document.getElementById('test-result').innerHTML = `<strong>Ответ:</strong> ${escapeHtml(data.answer)}`;
|
|
} else {
|
|
const err = await res.text();
|
|
document.getElementById('test-result').innerHTML = `<span style="color:red;">Ошибка: ${escapeHtml(err)}</span>`;
|
|
}
|
|
} catch (err) {
|
|
document.getElementById('test-result').innerHTML = `<span style="color:red;">Ошибка соединения: ${err.message}</span>`;
|
|
}
|
|
});
|
|
|
|
function escapeHtml(str) {
|
|
if (!str) return '';
|
|
return str.replace(/[&<>]/g, function(m) {
|
|
if (m === '&') return '&';
|
|
if (m === '<') return '<';
|
|
if (m === '>') return '>';
|
|
return m;
|
|
});
|
|
}
|
|
|
|
loadConfig();
|
|
</script>
|
|
{{end}} |