From c7a873bcf907f6e97dc557f4ee8f01852095f2a2 Mon Sep 17 00:00:00 2001 From: Hare Date: Mon, 27 Apr 2026 13:25:16 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=BB=E3=82=B0=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=81=AE=E3=82=BB=E3=83=83=E3=82=B7=E3=83=A7=E3=83=B3=E6=B0=B8?= =?UTF-8?q?=E7=B6=9A=E5=8C=96=E3=83=81=E3=82=B1=E3=83=83=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 2 ++ tickets/session-log-segments.md | 37 ++++++++++++++++++++++++++++++++ tickets/tui-input-queue.md | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 tickets/session-log-segments.md create mode 100644 tickets/tui-input-queue.md diff --git a/TODO.md b/TODO.md index bc3158f6..f3b87de7 100644 --- a/TODO.md +++ b/TODO.md @@ -8,8 +8,10 @@ - [ ] TUI 拡充 - [ ] フルスクリーン化によるオーバーホール → [tickets/tui-fullscreen-overhaul.md](tickets/tui-fullscreen-overhaul.md) - [ ] 新しい Pod を spawn する UI の設計 → [tickets/tui-pod-spawn-ui.md](tickets/tui-pod-spawn-ui.md) + - [ ] Run 中の入力キューイング → [tickets/tui-input-queue.md](tickets/tui-input-queue.md) - [ ] サブミット入力 - [ ] TUI 補完 + 型付き atom 化 → [tickets/submit-tui-completion.md](tickets/submit-tui-completion.md) + - [ ] セッションログの Segment 保持 → [tickets/session-log-segments.md](tickets/session-log-segments.md) - [ ] メモリ機構 - [ ] ファイル形式 + Linter 土台 → [tickets/memory-file-format.md](tickets/memory-file-format.md) - [ ] memory / Knowledge 検索ツール → [tickets/memory-search-tools.md](tickets/memory-search-tools.md) diff --git a/tickets/session-log-segments.md b/tickets/session-log-segments.md new file mode 100644 index 00000000..1f0e9c11 --- /dev/null +++ b/tickets/session-log-segments.md @@ -0,0 +1,37 @@ +# セッションログの Segment 保持 + +## 背景 + +`submit-segment-protocol` で `Method::Run` / `Event::UserMessage` は `Vec` を運ぶようになり、TUI では paste を `[Clipboard #N | X chars, Y lines]` のラベルチップとして再描画できる。一方でセッション復元経路は worker の history(`Item::user_message(text)`)からしか情報を拾えず、`crates/tui/src/app.rs` の `restore_history` は user message を `vec![Segment::text(text)]` 1 個に潰して復元している。 + +つまり「ライブで届いた `Event::UserMessage` では paste チップが見える / 同じセッションを開き直すと潰れたテキストになる」という非対称が残っている。今後 paste 部分を context から prune する話(後続チケット)にも segment 単位の永続化が前提になるため、ここで土台を入れたい。 + +LLM 側の入力は flatten 済み文字列のままで良い(worker / llm-client 層は変更しない)。永続化と client 復元経路にだけ segment を残す。 + +## 要件 + +- セッションログに user message の元 `Vec` を残す。worker の `Item` 表現や LLM 送信 payload は変更しない(`flatten_segments` の結果を引き続き食わせる)。 +- 復元経路で client が segments を取り戻せるようにする。最低限、TUI の `restore_history` が paste segment を典型の magenta `[Clipboard #N | ...]` チップとして再構築できること。 +- forward compat: 旧フォーマット(segments を持たないログ行)を読んでも panic / parse error にならず、従来通り text 1 個の segment として復元できること。 +- 現行の compaction / fork / restore のフローを壊さない。 + +## 範囲外 + +- paste prune(segment メタデータを使って context から落とす話)。別チケットで扱う。 +- FileRef / KnowledgeRef / WorkflowInvoke の resolve 結果の永続化。これらは resolver 実装チケット側の責務。 +- worker / llm-client 層の API 変更。 + +## 完了条件 + +- セッションログに segment 情報が persist される(新規セッションから書かれる行は segments を含む)。 +- TUI で paste を含むメッセージを送信 → セッションを開き直す → magenta チップが復元される。 +- segments を持たない旧ログ行も正常に restore でき、テキスト 1 segment として表示される。 +- 既存ビルド・テストを壊さない。新フォーマットに対する round-trip テスト 1 本は追加する。 + +## 参照 + +- `tickets/submit-segment-protocol.md`(前提) +- `crates/session-store/src/session_log.rs`(`LogEntry::UserInput`) +- `crates/session-store/src/session.rs`(`restore`, `RestoredState`) +- `crates/tui/src/app.rs`(`restore_history` — 現状 segment を捨てている地点) +- `crates/protocol/src/lib.rs`(`Segment`) diff --git a/tickets/tui-input-queue.md b/tickets/tui-input-queue.md new file mode 100644 index 00000000..58cfca21 --- /dev/null +++ b/tickets/tui-input-queue.md @@ -0,0 +1,38 @@ +# TUI: Run 中の入力キューイング + +## 背景 + +Pod は `Method::Run` を Run 中に受け取ると `AlreadyRunning` で即座に拒否する設計(1 turn = 1 message)。これはプログラマティックなクライアント(pod_cli、Pod 間通信の `sendToPod`)にとっては自然な契約だが、TUI で人間が操作している場合、「現ターンが終わるのを待って次を投げる」ためにユーザーが目視で完了を待つ必要があり、テンポが悪い。 + +「次のターンが終わり次第すぐに投げる」を可能にしたい。 + +## 方針 + +**プロトコルには載せず、TUI クライアント側でキューを持つ。** + +理由: + +- キューイングは人間が連続入力する TUI 固有の都合。pod_cli や Pod 間通信は 1 turn = 1 message が自然で、不要な抽象を背負わせない。 +- キュー上のメッセージは「まだ送信していないユーザー入力」であり、送信前のキャンセル・編集が自然にできるべき。これは TUI ローカル状態で扱うのが素直。 +- Pod controller / protocol への変更が不要。他クライアントへの影響ゼロ。 + +## 要件 + +- Run 中に Enter で送信した入力は TUI 内のキューに積まれる(即座に Pod に送信されない)。 +- 現在の Run が `RunEnd` で終了したら、キュー先頭を `Method::Run` として送信する。 +- キューに積まれた状態がユーザーから見える(積まれていることが分かる UI 表現)。 +- キュー内のメッセージは送信前にキャンセル・編集できる。 +- Pause 中の Resume 入力との関係を整理する(Resume はキューイングではなく即座に発火、で良いはず)。 +- キャンセル(`Method::Cancel`)が走った場合、キューをどう扱うかを決める(破棄が妥当と思われるが要検討)。 + +## 完了条件 + +- TUI で Run 中に入力を送信すると、現ターン終了直後に自動で次が投げられる。 +- 積まれた状態と、送信前のキャンセル・編集ができる。 +- pod プロトコルや pod crate に変更が入っていない。 + +## 範囲外 + +- 複数 Pod 間でのキュー共有・転送 +- キューの永続化(TUI 再起動をまたぐ保存) +- キュー内メッセージの優先度・並び替え(FIFO で十分)