# 通知設計書 36-Select an agent and model

## 概要

本ドキュメントは、OpenCodeアプリケーションにおける「Select an agent and model（エージェントとモデルを選択）」トースト通知の設計仕様を定義する。

### 本通知の処理概要

ユーザーがプロンプトを送信しようとした際に、エージェントまたはモデルが選択されていない場合にバリデーションエラーとしてトースト通知を表示する機能である。

**業務上の目的・背景**：OpenCodeでは、AIエージェントとLLMモデルの組み合わせでプロンプトを処理する。ユーザーがプロンプトを送信する前に、適切なエージェント（コード生成、レビューなど）とモデル（GPT-4、Claude等）を選択する必要がある。この選択が行われていない状態でプロンプト送信を試みた場合、処理を続行できないため、ユーザーに選択を促す通知が必要となる。この通知により、ユーザーはプロンプト送信前に必要な設定が不足していることを認識し、適切な選択を行うことができる。

**通知の送信タイミング**：ユーザーがプロンプト入力欄からプロンプトを送信しようとした時点で、`currentModel` または `currentAgent` が未設定（null/undefined）の場合に通知が発生する。

**通知の受信者**：プロンプト送信を試みたユーザー本人のみが受信する。アプリ内のトースト通知であり、外部への送信は行わない。

**通知内容の概要**：タイトルとして「Select an agent and model」（日本語：「エージェントとモデルを選択」）が表示され、説明文として「Choose an agent and model before sending a prompt.」（日本語：「プロンプトを送信する前にエージェントとモデルを選択してください。」）が表示される。

**期待されるアクション**：ユーザーはプロンプト入力画面のエージェント選択UIとモデル選択UIを使用して、適切なエージェントとモデルを選択する。その後、再度プロンプトを送信する。

## 通知種別

トースト通知（アプリ内通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（UIスレッド上で即時表示） |
| 優先度 | 中 |
| リトライ | 無し（UIトーストのため） |

### 送信先決定ロジック

操作を実行したユーザーのブラウザ/デスクトップアプリ画面に表示される。特別な送信先決定ロジックは不要。

## 通知テンプレート

### トースト通知の場合

| 項目 | 内容 |
|-----|------|
| バリアント | default |
| アイコン | なし |
| 持続性 | 非持続（自動消去） |

### 本文テンプレート

```
タイトル: Select an agent and model
説明: Choose an agent and model before sending a prompt.
```

日本語の場合:
```
タイトル: エージェントとモデルを選択
説明: プロンプトを送信する前にエージェントとモデルを選択してください。
```

### 添付ファイル

なし（トースト通知のため添付ファイルは非対応）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| title | 通知タイトル | i18n: `prompt.toast.modelAgentRequired.title` | Yes |
| description | 説明文 | i18n: `prompt.toast.modelAgentRequired.description` | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | プロンプト送信実行 | `!currentModel \|\| !currentAgent` | モデルまたはエージェントが未選択の場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| currentModel && currentAgent | 両方が選択されている場合は通知されない（正常処理へ進む） |
| 空のプロンプト | テキストが空で画像もコメントもない場合は、この通知の前に処理が中断される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがプロンプト送信を実行] --> B{テキスト/画像/コメントあり?}
    B -->|No| C[処理中断・通知なし]
    B -->|Yes| D{currentModel && currentAgent?}
    D -->|Yes| E[正常処理へ - セッション作成等]
    D -->|No| F[showToast - バリデーション通知表示]
    F --> G[return - 処理中断]
    C --> H[終了]
    E --> H
    G --> H
```

## データベース参照・更新仕様

### 参照テーブル一覧

本通知はフロントエンド側のUI通知であり、直接的なデータベース参照は行わない。

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| N/A | - | フロントエンドの状態チェックのため |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| N/A | - | 通知表示自体はデータベース更新を伴わない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| バリデーションエラー | エージェント/モデル未選択 | 本通知を表示し、ユーザーに選択を促す |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | N/A（バリデーションエラーのため） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（ユーザー操作に応じて即時表示）

## セキュリティ考慮事項

- バリデーション通知のみであり、機密情報は含まれない
- ユーザーの設定状態に関する情報のみを通知

## 備考

- この通知はプロンプト送信処理の初期段階で発生するバリデーションエラー
- 通知後は `return` で処理が中断され、プロンプトは送信されない
- ユーザーは設定を修正後、再度プロンプト送信を試みる必要がある

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

プロンプト送信処理の入力構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | submit.ts | `packages/app/src/components/prompt-input/submit.ts` | createPromptSubmit関数の構造（53行目以降） |
| 1-2 | submit.ts | `packages/app/src/components/prompt-input/submit.ts` | local.model.current() と local.agent.current() の使用 |
| 1-3 | en.ts | `packages/app/src/i18n/en.ts` | 280-281行目の `prompt.toast.modelAgentRequired.*` キーを確認 |

**読解のコツ**: `useLocal()` フックから取得した `local.model.current()` と `local.agent.current()` がそれぞれ現在選択されているモデルとエージェントを返す。

#### Step 2: エントリーポイントを理解する

プロンプト送信処理のバリデーションを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | submit.ts | `packages/app/src/components/prompt-input/submit.ts` | handleSubmit関数内のバリデーション（115-136行目） |

**主要処理フロー**:
1. **115-116行目**: event.preventDefault()とプロンプト取得
2. **123-126行目**: 空のプロンプトチェック（このチェックが先に実行される）
3. **128-129行目**: currentModel と currentAgent の取得
4. **130-136行目**: **バリデーションとshowToast呼び出し（本通知の発生箇所）**

#### Step 3: ローカル状態管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | submit.ts | `packages/app/src/components/prompt-input/submit.ts` | useLocal()フックの使用（58行目） |

**主要処理フロー**:
- **58行目**: `const local = useLocal()` - ローカル状態の取得
- **128-129行目**: `local.model.current()` と `local.agent.current()` でモデル/エージェントの現在値を取得

### プログラム呼び出し階層図

```
submit.ts::createPromptSubmit()
    │
    └─ handleSubmit(event)
           │
           ├─ prompt.current() → テキスト取得
           │
           ├─ [空チェック] → 空なら処理中断
           │
           ├─ local.model.current() → currentModel
           │
           ├─ local.agent.current() → currentAgent
           │
           └─ [!currentModel || !currentAgent]
                  │
                  └─ showToast({
                         title: "prompt.toast.modelAgentRequired.title",
                         description: "prompt.toast.modelAgentRequired.description"
                     })
                     │
                     └─ return（処理中断）
```

### データフロー図

```
[入力]                    [処理]                              [出力]

ユーザー操作          handleSubmit関数                 バリデーション通知
(送信ボタン) ───▶    local.model.current() ───▶    null/undefined チェック
                    local.agent.current()                    │
                            │                                ▼
                      [いずれか未設定]              showToast()
                            │                    「Select an agent and model」
                            ▼
                      return（処理中断）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| submit.ts | `packages/app/src/components/prompt-input/submit.ts` | ソース | プロンプト送信処理とバリデーション |
| toast.tsx | `packages/ui/src/components/toast.tsx` | ソース | showToast関数 |
| en.ts | `packages/app/src/i18n/en.ts` | 設定 | 英語の国際化メッセージ定義 |
| ja.ts | `packages/app/src/i18n/ja.ts` | 設定 | 日本語の国際化メッセージ定義 |
