Commit Graph
19 Commits
Author SHA1 Message Date
colcaroliandClaude Opus 5 762026aa2c Drop optional lightningcss entries from the frontend lockfile
npm install(npm 11 / Node 24)を実行した際の再解決で、lightningcss と
その各プラットフォーム向けバイナリ、detect-libc のエントリが外れた。
いずれも vite の optional な peer 依存で、実際には使われていない。

package.json は変更しておらず、追加・バージョン更新も無い(286行の削除のみ)。
この状態で npm run type-check(vue-tsc)が通ることは確認済み。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:57:30 +09:00
colcaroliandClaude Opus 5 2ee7238afb Archive summarized messages instead of deleting them
要約で長期メモリに移したメッセージをDBから物理削除していたため、
一度要約されると人間も内容を確認できなくなっていた。削除をやめ、
messages に archived_at(要約に取り込まれた時刻)と memory_id
(どの要約に取り込まれたか)を持たせる。

モデルからは従来どおり見えない:
- get_context_messages() がアーカイブ済みを除外する
- maybe_summarize() の閾値判定も現役メッセージだけを数える
  (ここを除外し忘れると件数が減らず再要約が繰り返される)
- backfill_tags() もアーカイブ済みは対象外にする

人間からは確認できる:
- GET /chat/sessions/{id}/messages がアーカイブ済みも archived_at
  付きで返す。export/import もアーカイブ状態を保持する
- チャット画面では半透明で表示し、最後のアーカイブ済みメッセージの
  直後に「ここから先がモデルに渡る」区切り線を出す

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:33:18 +09:00
colcaroliandClaude Opus 5 be3af44891 Store timestamps as UTC-aware and slim the knowledge context to headlines
タイムゾーン:
SQLite の DATETIME は tzinfo を保存できず、DateTime(timezone=True) を
指定してもバインド時に捨てられるため、API のレスポンスがオフセット無しの
ISO 文字列になりフロントがローカル時刻として誤解していた。UtcDateTime
(TypeDecorator) を追加し、書き込み時は naive な UTC に正規化、読み出し時は
UTC の aware として返すようにする。格納フォーマットは変わらないので既存
データはそのまま正しく解釈でき、マイグレーションは不要。
コンテナは TZ 未設定で UTC だったため、天気通知の cron 時刻・深夜スキップ
判定・「明日」の日付計算が9時間ずれていた。TZ=Asia/Tokyo を指定し、slim
イメージに無い tzdata を導入する。

蓄積知識:
層1が最新15件の要約全文を毎リクエスト無条件に注入しており、同じ内容が
ローカルKB(層3)にも保存されているため重複していた。層1を「クエリ+
一行要約」の目次に変え、本文は read_knowledge ツールで読み出す形にする。
一行要約は要約生成時の既存 LLM 呼び出しに相乗りするので呼び出し回数は
増えない。headline を持たない既存エントリは本文の先頭行から導出する。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:22:59 +09:00
colcaroliandClaude Opus 5 8b2231ea97 Add drag-and-drop reordering for note tabs, and a user-facing guide
Tabs can now be dragged to reorder within a group and to move between
sections in one gesture: dropping on a tab's left/right half inserts
before/after it and adopts that tab's section, while a dedicated zone
past the last group ungroups and appends at the end. A blue indicator
line shows the drop position while dragging.

core/notes.reorder() takes the full new page-id order computed
client-side (NotePanel.vue has the reactive list already) rather than
recomputing positions server-side, validates it against the current
page-id set, sets the moved page's section, then renumbers position.
POST /api/notes/reorder exposes it.

Also adds docs/notes-guide.md, an end-user walkthrough of the shared
notes panel (pages, sections, drag-and-drop, AI interaction) — the
existing docs were all developer-facing specs with no operating
instructions for the feature itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 07:27:38 +09:00
colcaroliandClaude Opus 5 1c21fc3406 Add section grouping to shared note tabs
Notes can now be clustered into named sections in the tab bar: each tab
gets a 🏷 button to assign it to a section, and clicking a section's
label renames (or, given an empty name, ungroups) every page in it.

note_pages gains a `section` column. Since the app has no migration
framework, database.py adds the column to existing SQLite files at
startup via PRAGMA table_info + ALTER TABLE. core/notes.set_section()
keeps same-section pages contiguous by renumbering position whenever a
page's section changes, so the tab bar and the AI-facing title list
(now grouped under "## section" headings) can both treat "adjacent" as
"same group" without a separate ordering field.

Also fixes a bug in the tab rename input: ref="renameInput" sits inside
a nested v-for, which Vue 3 binds as an array rather than a single
element, so renameInput.value?.select() was throwing on every rename.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 00:28:36 +09:00
colcaroli b1350eb8bc Merge pull request 'Feature/shared notes' (#1) from feature/shared-notes into main
Reviewed-on: #1
2026-08-18 16:29:56 +00:00
colcaroliandClaude Opus 5 a08b1785a4 Add shared notes with tabbed pages editable by user and AI
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>
2026-08-19 01:27:31 +09:00
colcaroliandClaude Opus 5 ef588d99d8 Add session export/import as JSON
Sessions can now be downloaded as a JSON file containing the session
metadata and every message with its tags, and re-imported as a new
session from that same format.

GET /chat/sessions/{id}/export streams the session as a file download.
POST /chat/sessions/import validates the roles, then recreates the
session under a fresh UUID so importing never collides with an existing
session. The sidebar gets a per-row download button and an import button
that feeds a hidden file input.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 01:22:08 +09:00
colcaroliandClaude Sonnet 5 1ad8b130c7 Add site-wide login gate protecting the whole app
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>
2026-08-18 23:04:01 +09:00
colcaroli 002282a8b7 Fix MemoryMonitor blank on GPU-less deployments
gpu_memory_percent is serialized as JSON null (not omitted) when no
GPU is present, but the template checked `!== undefined`, which is
true for null too. Calling .toFixed() on that null then threw during
render, blanking the whole widget instead of just hiding the GPU row.
Only showed up on GPU-less hosts like a Lightsail instance, not on
this dev machine which has a GPU.
2026-08-18 21:48:38 +09:00
colcaroli 20cb449f76 Add Caddy for automatic HTTPS in front of the frontend/backend stack
Caddy now owns ports 80/443 and reverse-proxies to the frontend
container (which was publishing 80 itself, conflicting with Caddy),
handling Let's Encrypt certificate issuance/renewal automatically.
Fix the Caddyfile's upstream name (it referenced a nonexistent "app"
service instead of "frontend") and update the Lightsail deploy guide's
HTTPS section to match this setup instead of the old manual-certbot
approach.
2026-08-18 21:22:53 +09:00
colcaroli db98677838 Disable eager bytecode compilation in backend Dockerfile
UV_COMPILE_BYTECODE=1 made `uv sync` bytecode-compile every package
upfront, including janome's large sysdic/connections1.py dictionary
file, which times out after 60s on smaller build machines (e.g. a
Lightsail instance). Modules now compile lazily on first import
instead, which has no functional effect.
2026-08-18 07:27:57 +09:00
colcaroliandClaude Sonnet 5 d207537b53 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>
2026-08-18 01:27:08 +09:00
colcaroliandClaude Sonnet 5 8e01458bb2 Add Docker/Lightsail deployment, web search summarization, and fix vite peer dep
- Add backend/frontend Dockerfiles, nginx reverse proxy config, and
  docker-compose.yml to run the app on AWS Lightsail; document the setup
  in docs/deploy-lightsail.md. Fix a .gitignore path anchoring bug that
  left backend/knowledge_base/web_search/ untracked instead of ignored.
- Summarize web search results into structured Markdown via LLM before
  saving them to the local knowledge base, and support regenerating
  existing entries from their source URLs (backend/app/core/memory_kb).
- Downgrade vite to ^6 to match @vitejs/plugin-vue's peer dependency
  range, fixing a failing `npm ci` (found while testing the Docker build).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 02:45:09 +09:00
colcaroli 347230e3c8 Reorganize core into subpackages, add local KB, ruff/pyright tooling
- Split backend/app/core into weather/, discord/, memory_kb/, search/
  subpackages by responsibility, keeping config.py and llm.py as the
  shared foundation; updated all import sites accordingly.
- Add local Markdown knowledge base support (local_knowledge.py,
  knowledge_base/fgo.md, LOCAL_KB_* settings) that embeds and injects
  relevant docs into the system prompt by topic similarity.
- Add ruff and pyright as backend dev dependencies with basic config
  in pyproject.toml for linting and type checking.
- Document local machine quirks in CLAUDE.md (Postgres on port 8080,
  SSLKEYLOGFILE breaking litellm/pyright via OPENSSL_Uplink crashes).
- Add backend/run_dev.ps1 dev launcher and docs/discord-bot.md.
2026-06-21 11:44:11 +09:00
colcaroli 234ebba103 Add web search knowledge base, message tagging, and word-memory tip topics
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.
2026-06-20 18:06:06 +09:00
colcaroliandClaude Sonnet 4.6 4e837d1419 Add weather caching, useless-tip redirect, clock widget, and IAM Bedrock auth
- 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>
2026-06-20 15:15:11 +09:00
colcaroliandClaude Sonnet 4.6 4a08ba29fa Add system memory monitoring, Bedrock support, and Discord integrations
- Add CPU/GPU memory monitoring endpoint and frontend widget
- Add Amazon Bedrock model support (API key / inference profiles) plus model selector entries
- Add Discord weather/laundry notification job (JMA forecast + LLM-generated message)
- Add Discord bot that replies to mentions via the configured LLM, with weather-aware context
- Add scheduled "useless tips" job with separate webhook and quiet-hours skip
- Switch FastAPI startup to lifespan handler, log viewer, markdown rendering, and toast UI additions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 00:59:38 +09:00
colcaroli 903d34761c initial_commit 2026-06-01 20:16:53 +09:00