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>
This commit is contained in:
+105
-31
@@ -3,47 +3,121 @@
|
||||
## 全体構成
|
||||
|
||||
```
|
||||
フロントエンド (Vue 3 + TypeScript + Vite, port 5173)
|
||||
↕ REST / SSE
|
||||
バックエンド (FastAPI + Python, port 8000)
|
||||
↕
|
||||
フロントエンド (Vue 3 + TypeScript + Vite, :5173)
|
||||
↕ REST + SSE (Vite dev proxy 経由)
|
||||
バックエンド (FastAPI + Python, :8000)
|
||||
↕ SQLAlchemy
|
||||
SQLite (playchat.db)
|
||||
↕
|
||||
LiteLLM → OpenAI / Anthropic / Ollama (任意のLLM)
|
||||
↕ LiteLLM
|
||||
OpenAI / Anthropic / Ollama など任意の LLM
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## バックエンド
|
||||
|
||||
### エントリーポイント
|
||||
`app/main.py` — FastAPI インスタンス作成、CORS 設定、DB 初期化、ルーター登録。
|
||||
### ディレクトリ構成
|
||||
|
||||
### ルーター
|
||||
| ファイル | エンドポイント | 役割 |
|
||||
```
|
||||
backend/
|
||||
├── app/
|
||||
│ ├── main.py # FastAPI インスタンス、CORS、ルーター登録、DB初期化
|
||||
│ ├── api/
|
||||
│ │ ├── chat.py # チャット・セッション関連エンドポイント
|
||||
│ │ ├── memory.py # 長期メモリ参照・削除
|
||||
│ │ └── logs.py # API ログ参照・削除
|
||||
│ ├── core/
|
||||
│ │ ├── config.py # .env 読み込み・定数定義
|
||||
│ │ ├── llm.py # LiteLLM ラッパー(ストリーミング・ログ記録)
|
||||
│ │ └── memory.py # メモリ読み書きロジック(要約・コンテキスト生成)
|
||||
│ └── db/
|
||||
│ ├── database.py # SQLite 接続・セッションファクトリ・テーブル自動作成
|
||||
│ └── models.py # SQLAlchemy モデル定義
|
||||
└── pyproject.toml
|
||||
```
|
||||
|
||||
### DB テーブル
|
||||
|
||||
| テーブル | 主なカラム | 用途 |
|
||||
|---|---|---|
|
||||
| `app/api/chat.py` | `POST /chat/stream` | SSE でストリーミング応答 |
|
||||
| `app/api/chat.py` | `GET /chat/sessions` | セッション一覧 |
|
||||
| `app/api/chat.py` | `DELETE /chat/sessions/{id}` | セッション削除 |
|
||||
| `app/api/memory.py` | `GET /memory/{session_id}` | メモリ一覧 |
|
||||
| `app/api/memory.py` | `DELETE /memory/{id}` | メモリ削除 |
|
||||
| `sessions` | id (UUID), title, model, created_at, updated_at | チャットセッション |
|
||||
| `messages` | id, session_id, role, content, created_at | 会話メッセージ(短期メモリ) |
|
||||
| `memories` | id, session_id, summary, embedding_json, created_at | 要約による長期メモリ |
|
||||
| `api_logs` | id, session_id, model, request_json, response_text, error, latency_ms, created_at | LLM API 呼び出しログ |
|
||||
|
||||
### メモリ機構
|
||||
- **短期メモリ**: セッション内のすべてのメッセージをコンテキストとして送信
|
||||
- **長期メモリ**: メッセージ数が `MEMORY_SUMMARIZE_THRESHOLD`(デフォルト20) を超えると古い半分をLLMで要約し `memories` テーブルに保存
|
||||
- 要約はシステムメッセージとして次回以降のコンテキスト先頭に注入される
|
||||
### メモリ機構(`core/memory.py`)
|
||||
|
||||
### LLM 接続
|
||||
`app/core/llm.py` が LiteLLM を薄くラップ。モデル名は `DEFAULT_MODEL` 環境変数で制御。
|
||||
ローカルの Ollama は `ollama/llama3` のように `ollama/` プレフィックスで指定。
|
||||
1. **短期メモリ**: セッション内の全 `messages` をコンテキストとして送信
|
||||
2. **長期メモリ**: メッセージ数が `MEMORY_SUMMARIZE_THRESHOLD`(デフォルト 20)を超えると、古い半分を LLM で要約して `memories` に保存しメッセージを削除
|
||||
3. **コンテキスト合成**: `get_context_messages()` が `memories` の要約をシステムメッセージとして先頭に付加し、残存メッセージと結合して返す
|
||||
|
||||
### LLM 呼び出し(`core/llm.py`)
|
||||
|
||||
- `stream_chat()` / `complete()` が LiteLLM を薄くラップ
|
||||
- `_log_context` で呼び出しを囲み、成功・失敗どちらも `api_logs` テーブルに記録
|
||||
- `DEBUG=true` で `litellm._turn_on_debug()` が有効になり詳細ログが出力される
|
||||
|
||||
### SSE ストリーミング(`api/chat.py`)
|
||||
|
||||
`POST /chat/stream` は `StreamingResponse` で以下のイベントを順番に送出する:
|
||||
|
||||
```
|
||||
data: {"type":"session_id","value":"<uuid>"} # 新規セッション時のみ
|
||||
data: {"type":"chunk","value":"テキスト断片"} # 0回以上
|
||||
data: {"type":"done"} # 正常完了
|
||||
data: {"type":"error","value":"エラー内容"} # 例外発生時
|
||||
```
|
||||
|
||||
バッファリング防止のため `Cache-Control: no-cache` と `X-Accel-Buffering: no` を付与する。
|
||||
|
||||
---
|
||||
|
||||
## フロントエンド
|
||||
|
||||
### 状態管理
|
||||
`src/stores/chat.ts` (Pinia) が全状態を保持:
|
||||
- `sessions` — バックエンドから取得したセッション一覧
|
||||
- `messages` — 現在セッションの表示用メッセージ配列
|
||||
- `isStreaming` — SSE 受信中フラグ
|
||||
- `selectedModel` — UI で選択中のモデル
|
||||
### ディレクトリ構成
|
||||
|
||||
### SSE ストリーミング
|
||||
`src/api/client.ts` の `streamChat()` が fetch + ReadableStream で SSE を受信。
|
||||
チャンクは3種類: `session_id`(新規セッションID通知)、`chunk`(テキスト断片)、`done`(完了)。
|
||||
```
|
||||
frontend/src/
|
||||
├── api/
|
||||
│ └── client.ts # fetch ラッパー・SSE クライアント・型定義
|
||||
├── stores/
|
||||
│ └── chat.ts # Pinia ストア(全アプリ状態)
|
||||
├── components/
|
||||
│ ├── SessionList.vue # セッション一覧サイドバー
|
||||
│ ├── ChatWindow.vue # メッセージ表示エリア
|
||||
│ ├── MessageInput.vue # 入力欄・送信
|
||||
│ ├── ModelSelector.vue # LLM モデル切替セレクト
|
||||
│ ├── MarkdownContent.vue # marked + DOMPurify によるレンダリング
|
||||
│ ├── LogViewer.vue # API ログ閲覧パネル
|
||||
│ └── ToastList.vue # エラートースト通知
|
||||
└── App.vue # ルートレイアウト
|
||||
```
|
||||
|
||||
### 状態管理(`stores/chat.ts`)
|
||||
|
||||
| 状態 | 型 | 説明 |
|
||||
|---|---|---|
|
||||
| `sessions` | `SessionInfo[]` | セッション一覧 |
|
||||
| `currentSessionId` | `string \| null` | 選択中セッション |
|
||||
| `messages` | `Message[]` | 表示中メッセージ |
|
||||
| `isStreaming` | `boolean` | SSE 受信中フラグ |
|
||||
| `selectedModel` | `string` | 選択中 LLM モデル |
|
||||
| `toasts` | `Toast[]` | エラー通知キュー |
|
||||
|
||||
### SSE 受信フロー
|
||||
|
||||
1. `sendMessage()` がユーザーメッセージと空のアシスタントメッセージを `messages` に追加
|
||||
2. `streamChat()` が fetch + ReadableStream で SSE を受信
|
||||
3. `chunk` イベント受信のたびに `messages.value[msgIdx].content` を更新(Vue reactive proxy 経由)
|
||||
4. `done` で `pending` フラグを解除
|
||||
5. `error` / ネットワークエラーは `error` フラグを立て赤バブル表示 + トースト通知
|
||||
|
||||
### Markdown レンダリング(`MarkdownContent.vue`)
|
||||
|
||||
- アシスタントメッセージのみ `marked` で HTML に変換後 `DOMPurify` でサニタイズ
|
||||
- ストリーミング中(`pending=true`)は未閉じのコードフェンス(` ``` `)を自動補完してから描画
|
||||
|
||||
### Vite プロキシ設定
|
||||
|
||||
`/chat`、`/memory`、`/logs`、`/health` を `http://localhost:8000` に転送。
|
||||
`/chat` は SSE バッファリング無効化のため `configure` で `x-accel-buffering: no` を付与。
|
||||
|
||||
Reference in New Issue
Block a user