Add GUI settings panel for API keys, model presets, and embedding model
- Add a password-protected /api/settings endpoint (HTTP Basic auth, backend/app/core/auth.py) backed by a DB-stored allowlist of connection settings (OPENAI_API_KEY, ANTHROPIC_API_KEY, AWS creds, OLLAMA_API_BASE, TAVILY_API_KEY, LOCAL_KB_EMBEDDING_MODEL). Saved values override .env and apply immediately via os.environ, so Lightsail deployments no longer need SSH + `.env` edits to rotate keys. Values are always returned masked to the frontend. - Replace ModelSelector.vue's hardcoded model list with a DB-backed /api/models CRUD API (read is public, writes reuse the settings password) so the chat model dropdown can be edited from the GUI; seed it once with the previous hardcoded presets on first boot. - Fix local_knowledge.py reading LOCAL_KB_EMBEDDING_MODEL once at import time instead of per-call, which would have silently ignored GUI/DB overrides for the embedding model. - Add SettingsPanel.vue (API keys + model management UI) and document the new SETTINGS_PASSWORD env var in .env.example and the Lightsail deploy guide. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,28 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { useChatStore } from '../stores/chat'
|
||||
import { useSettingsStore } from '../stores/settings'
|
||||
|
||||
const store = useChatStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
const presets = [
|
||||
{ label: 'GPT-5.5', value: 'gpt-5.5' },
|
||||
{ label: 'GPT-5.4', value: 'gpt-5.4' },
|
||||
{ label: 'GPT-5.4 mini', value: 'gpt-5.4-mini' },
|
||||
{ label: 'Claude Sonnet 4.6', value: 'claude-sonnet-4-6' },
|
||||
{ label: 'Claude Haiku 4.5', value: 'claude-haiku-4-5-20251001' },
|
||||
{ label: 'Ollama llama3', value: 'ollama/llama3' },
|
||||
{ label: 'Ollama Gemma4', value: 'ollama/gemma4' },
|
||||
{ label: 'Gemma 4 12B (llama-server)', value: 'gpt-3.5-turbo' },
|
||||
{ label: 'Claude Sonnet 4.6 (Bedrock)', value: 'bedrock/jp.anthropic.claude-sonnet-4-6' },
|
||||
{ label: 'Llama 3 70B (Bedrock)', value: 'bedrock/meta.llama3-70b-instruct-v1:0' },
|
||||
{ label: 'Nova 2 Lite (Bedrock)', value: 'bedrock/jp.amazon.nova-2-lite-v1:0' },
|
||||
]
|
||||
// 選択中のモデルがプリセット一覧に無い場合(削除された/カスタム値)も表示が壊れないよう、
|
||||
// その場で追加のoptionとして補う。
|
||||
const options = computed(() => {
|
||||
const presets = settingsStore.modelPresets
|
||||
if (presets.some((p) => p.value === store.selectedModel)) return presets
|
||||
return [...presets, { id: -1, label: store.selectedModel, value: store.selectedModel }]
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
settingsStore.loadModelPresets()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="model-selector">
|
||||
<label>モデル</label>
|
||||
<select v-model="store.selectedModel">
|
||||
<option v-for="p in presets" :key="p.value" :value="p.value">{{ p.label }}</option>
|
||||
<option v-for="p in options" :key="p.value" :value="p.value">{{ p.label }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user