From 9e7f4740a2a09dae72deb3f32dce14647a11d4e0 Mon Sep 17 00:00:00 2001 From: Jordy Versmissen Date: Mon, 24 Nov 2025 13:22:13 +0100 Subject: [PATCH] Use more general AI settings so other providers are also supported --- js/main.js | 23 +++++++++++++---------- js/modules/ai.js | 16 +++++++++------- panel.html | 17 ++++++++--------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/js/main.js b/js/main.js index 5c8051a..0ac92d1 100644 --- a/js/main.js +++ b/js/main.js @@ -330,8 +330,9 @@ function setupAIFeatures() { const settingsBtn = document.getElementById('settings-btn'); const settingsModal = document.getElementById('settings-modal'); const saveSettingsBtn = document.getElementById('save-settings-btn'); - const anthropicApiKeyInput = document.getElementById('anthropic-api-key'); - const anthropicModelSelect = document.getElementById('anthropic-model'); + const aiBaseUrlInput = document.getElementById('ai-base-url'); + const aiApiKeyInput = document.getElementById('ai-api-key'); + const aiModelInput = document.getElementById('ai-model'); const aiMenuBtn = document.getElementById('ai-menu-btn'); const aiMenuDropdown = document.getElementById('ai-menu-dropdown'); const explainBtn = document.getElementById('explain-btn'); @@ -342,9 +343,10 @@ function setupAIFeatures() { if (settingsBtn) { settingsBtn.addEventListener('click', () => { - const { apiKey, model } = getAISettings(); - anthropicApiKeyInput.value = apiKey; - if (anthropicModelSelect) anthropicModelSelect.value = model; + const { baseUrl, apiKey, model } = getAISettings(); + aiApiKeyInput.value = apiKey; + aiBaseUrlInput.value = baseUrl; + aiModelInput.value = model; settingsModal.style.display = 'block'; }); @@ -352,11 +354,12 @@ function setupAIFeatures() { if (saveSettingsBtn) { saveSettingsBtn.addEventListener('click', () => { - const key = anthropicApiKeyInput.value.trim(); - const model = anthropicModelSelect ? anthropicModelSelect.value : 'claude-3-5-sonnet-20241022'; + const baseUrl = aiBaseUrlInput.value.trim(); + const key = aiApiKeyInput.value.trim(); + const model = aiModelInput.value.trim(); if (key) { - saveAISettings(key, model); + saveAISettings(baseUrl, key, model); } alert('Settings saved!'); @@ -377,7 +380,7 @@ function setupAIFeatures() { } const handleAIRequest = async (promptPrefix, content) => { - const { apiKey, model } = getAISettings(); + const { baseUrl, apiKey, model } = getAISettings(); if (!apiKey) { alert('Please configure your Anthropic API Key in Settings first.'); settingsModal.style.display = 'block'; @@ -388,7 +391,7 @@ function setupAIFeatures() { explanationContent.innerHTML = '
Generating...
'; try { - await streamExplanationFromClaude(apiKey, model, promptPrefix + "\n\n" + content, (text) => { + await streamExplanationFromClaude(baseUrl, apiKey, model, promptPrefix + "\n\n" + content, (text) => { if (typeof marked !== 'undefined') { explanationContent.innerHTML = marked.parse(text); } else { diff --git a/js/modules/ai.js b/js/modules/ai.js index 611c561..777ff99 100644 --- a/js/modules/ai.js +++ b/js/modules/ai.js @@ -2,20 +2,22 @@ export function getAISettings() { return { - apiKey: localStorage.getItem('anthropic_api_key') || '', - model: localStorage.getItem('anthropic_model') || 'claude-3-5-sonnet-20241022' + baseUrl: localStorage.getItem('ai_base_url') || 'https://api.anthropic.com', + apiKey: localStorage.getItem('ai_api_key') || '', + model: localStorage.getItem('ai_model') || 'claude-3-5-sonnet-20241022' }; } -export function saveAISettings(apiKey, model) { - localStorage.setItem('anthropic_api_key', apiKey); - localStorage.setItem('anthropic_model', model); +export function saveAISettings(baseUrl, apiKey, model) { + localStorage.setItem('ai_base_url', baseUrl); + localStorage.setItem('ai_api_key', apiKey); + localStorage.setItem('ai_model', model); } -export async function streamExplanationFromClaude(apiKey, model, request, onUpdate) { +export async function streamExplanationFromClaude(baseUrl, apiKey, model, request, onUpdate) { const systemPrompt = "You are an expert security researcher and web developer. Explain the following HTTP request in detail, highlighting interesting parameters, potential security implications, and what this request is likely doing. Be concise but thorough."; - const response = await fetch('https://api.anthropic.com/v1/messages', { + const response = await fetch(baseUrl + '/v1/messages', { method: 'POST', headers: { 'x-api-key': apiKey, diff --git a/panel.html b/panel.html index b3283b6..44710c1 100644 --- a/panel.html +++ b/panel.html @@ -355,18 +355,17 @@

Settings