Add a read-only view of backend/knowledge_base/**.md so the files that get
injected into the system prompt can be inspected from the GUI:
- GET /api/kb/files lists the Markdown files (title, preview, size, mtime and
whether the file is already embedded), GET /api/kb/file returns one in full.
Paths are resolved against the knowledge base directory and rejected unless
they stay inside it and end in .md.
- KnowledgeBasePanel.vue groups the files by folder (collapsible, so web_search
can be folded away), filters by title/path/preview and renders the selected
file with MarkdownContent.
The header had grown to four side panel toggles, so collapse them into one
menu: panels.ts now holds the list of panels along with the component each one
renders, App.vue picks it with <component :is>, and SidePanelMenu.vue shows the
active panel on its button. Re-picking the open panel (or "パネルを閉じる")
closes it; a click outside or Esc closes just the menu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a note_pages table backing a tabbed notes panel where the user and
the model can both read and write. Only page titles (plus a short
preview) are injected into the system prompt on every turn; full page
content is kept out of context and fetched on demand via a read_note
tool, with write_note letting the model append to, replace, or create a
page.
Generalizes llm.resolve_web_search into resolve_tool_calls so the
tool-calling loop handles web_search and the new note tools through one
path. The chat stream emits a notes_updated SSE event when the model
edits a note so the frontend panel can refresh; local edits are tracked
as dirty and never clobbered by that refresh.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Chat/memory/logs/models APIs were reachable without any auth even
though the app is deployed publicly behind Caddy HTTPS; only the
settings screen had a password. Add an optional SITE_PASSWORD-backed
session cookie gate in front of everything (settings included, on
top of its existing SETTINGS_PASSWORD), with a matching login screen
on the frontend. Stays fully backward compatible: with SITE_PASSWORD
unset the app behaves exactly as before.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 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>
Introduces websearch.py (Tavily) + knowledge.py to ground chat responses
in search results, tagging.py to tag user and assistant messages via LLM
and pick related topics for the Discord useless-tips job, and
word_memory.py to track recent conversation nouns (surfaced in the new
WordPool.vue sidebar) used to pick tip topics close to a related tag.
- Cache the latest fetched tomorrow weather and expose it via /api/system/weather/latest
- Add a header Clock widget showing date/time plus the cached weather summary
- Redirect useless-talk mentions from the weather bot to the useless-tips webhook
- Switch Bedrock auth from bearer token to standard IAM access key/secret
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>