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>
4.3 KiB
4.3 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
プロジェクト概要
Python (FastAPI) バックエンド + Vue 3 (TypeScript) フロントエンドのチャットアプリ。
LLM は LiteLLM 経由で OpenAI / Anthropic / Ollama など任意のプロバイダーを統一 API で扱い、会話履歴とメモリは SQLite に永続化する。
コマンド
バックエンド
Set-Location backend
# 依存インストール (SSL プロキシ環境では --native-tls が必要)
uv sync --native-tls
# 開発サーバー起動
uv run uvicorn app.main:app --reload
# テスト
pytest
pytest tests/test_chat.py # 単一ファイル
フロントエンド
Set-Location frontend
# 依存インストール
npm install
# 開発サーバー起動 (port 5173)
npm run dev
# ビルド
npm run build
# 型チェック
npm run type-check
環境設定
Set-Location backend
Copy-Item .env.example .env
# .env を編集して API キーとモデル名を設定
アーキテクチャ
詳細は docs/architecture.md を参照。
frontend (Vue3 + Pinia, :5173)
↕ REST + SSE (Vite proxy)
backend (FastAPI, :8000)
├── app/api/ チャット・メモリ・ログ のルーター
├── app/core/ LLM ラッパー・メモリロジック・設定
└── app/db/ SQLAlchemy モデル・DB 接続
↕
SQLite (playchat.db) + LiteLLM → 任意の LLM
メモリ機構
- 短期: セッション内の全メッセージをコンテキストに含める
- 長期: メッセージ数が
MEMORY_SUMMARIZE_THRESHOLD(デフォルト 20)を超えると古い半分を LLM で要約 →memoriesテーブルに保存 → 次回以降のシステムプロンプトに注入
SSE ストリーミング
POST /chat/stream が SSE を返す。イベント種別: session_id(新規セッション ID)/ chunk(テキスト断片)/ done(完了)/ error(エラー)。
フロントは src/api/client.ts の streamChat() で fetch + ReadableStream により受信し、messages.value[msgIdx] を reactive proxy 経由で更新する。
Markdown レンダリング
アシスタントメッセージは marked + DOMPurify でレンダリング。ストリーミング中の未閉じコードフェンスは自動補完してから描画する(MarkdownContent.vue)。
モデル切替
.env の DEFAULT_MODEL またはリクエストの model フィールドで指定。
ローカル Ollama は ollama/llama3 形式、OLLAMA_API_BASE でエンドポイントを設定。
DEBUG=true で LiteLLM の詳細ログが有効になる。
ローカル開発環境メモ
- このマシンでは PostgreSQL がポート 8080 で起動している(本アプリの
DATABASE_URLには使用していないが、ポート競合時は確認すること) - このマシンには TLS 監視プロキシらしき設定があり、環境変数
SSLKEYLOGFILEが名前付きパイプ(nllMonFltProxy)を指している。これが原因でlitellm(OpenSSL を直接ロード)やpyright(内部で Node.js サブプロセスを起動)がOPENSSL_Uplinkエラーでクラッシュすることがある。発生した場合は当該コマンド実行時のみSSLKEYLOGFILEを unset すると回避できるRemove-Item Env:\SSLKEYLOGFILE uv run pyright
環境変数(backend/.env)
| 変数 | デフォルト | 説明 |
|---|---|---|
DEFAULT_MODEL |
gpt-5.4 |
デフォルト LLM モデル |
DATABASE_URL |
sqlite:///./playchat.db |
DB 接続先 |
MEMORY_SUMMARIZE_THRESHOLD |
20 |
長期メモリ化するメッセージ数の閾値 |
CORS_ORIGINS |
http://localhost:5173 |
許可する CORS オリジン |
DEBUG |
false |
LiteLLM デバッグログの有効化 |
OPENAI_API_KEY |
— | OpenAI API キー |
ANTHROPIC_API_KEY |
— | Anthropic API キー |
OLLAMA_API_BASE |
http://localhost:11434 |
Ollama エンドポイント |
SITE_PASSWORD |
— | サイト全体を保護する共有パスワード(未設定なら無認証) |
SESSION_SECRET_KEY |
起動毎に自動生成 | ログインセッション Cookie の署名鍵 |