feat(desktop): TODO/Schedule で Claude model と effort を指定可能に (closes #235)#245
feat(desktop): TODO/Schedule で Claude model と effort を指定可能に (closes #235)#245
Conversation
) TODO セッションとスケジュールの作成時に `--model` / `--effort` を 選べるようにした。これまではモデル・思考量の固定値で動いており、 VSCode の公式 Claude Code 拡張のような調整手段がなかった。 - TodoModal / ScheduleEditorDialog / 設定タブに共通ピッカーを追加 - supervisor が per-session の model / effort を CLI 引数に展開 - 設定タブに既定値を用意し、新規作成フォームにシードされる - DB: todo_sessions / todo_schedules に claude_model / claude_effort を追加
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 39 minutes and 49 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughこのプルリクエストは、TodoエージェントシステムにClaudeモデルと試行努力レベルの設定機能を追加します。データベーススキーマを拡張し、バックエンドの永続化層・オーケストレーション層・TRPC APIを更新し、新しいUIコンポーネントをフロントエンドに統合することで、ユーザーがスケジュール・セッション・デフォルト設定ごとにClaudeの実行パラメータを指定できるようにします。 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsx (1)
119-136:⚠️ Potential issue | 🟡 Minor新規スケジュール作成時にグローバル既定値がシードされていません。
TodoModal 側では
todoSettings.defaultClaudeModel/defaultClaudeEffortを初期値として反映していますが、この Dialog の新規作成ブランチではDEFAULT_SENTINELに固定されています。PR 概要の「new forms are seeded from those defaults」に反しており、スケジュール作成画面を開くと既定値が効かない UX になります。electronTrpc.todoAgent.settings.getを取得して TodoModal と同様にシードする実装が一貫します。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsx` around lines 119 - 136, The new-schedule branch in ScheduleEditorDialog is seeding Claude model/effort with DEFAULT_SENTINEL instead of the user's global defaults; update the "else" new-item initialization to read the todo settings (via electronTrpc.todoAgent.settings.get or the same prop/state TodoModal uses) and call setClaudeModel(todoSettings.defaultClaudeModel) and setClaudeEffort(todoSettings.defaultClaudeEffort) (falling back to DEFAULT_SENTINEL only if those settings are undefined), ensuring the new form fields are seeded consistently with the global defaults.
🧹 Nitpick comments (4)
apps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/ClaudeRuntimePicker.tsx (1)
62-62:cnの単一引数呼び出しは冗長です。
cn("flex flex-col gap-1.5")は条件分岐もクラス合成もないため、直接className="flex flex-col gap-1.5"で十分です。細かいですが、cn利用箇所の意図が分かりやすくなります。♻️ Proposed fix
- <div className={cn("flex flex-col gap-1.5")}> + <div className="flex flex-col gap-1.5">🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/ClaudeRuntimePicker.tsx` at line 62, Replace the redundant single-argument cn call on the div in ClaudeRuntimePicker (the JSX element with className={cn("flex flex-col gap-1.5")}) with a plain string literal className; i.e., change className={cn("flex flex-col gap-1.5")} to className="flex flex-col gap-1.5" so the intent is clearer and unnecessary helper usage is removed.apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsx (1)
25-34: tsconfig のエイリアス利用を検討してください。
../../../../ClaudeRuntimePickerの 4 階層を上る相対パスは、ファイルを別階層へ移動したときに壊れやすいです。renderer/features/todo-agent/ClaudeRuntimePickerなど、tsconfig で定義済みのエイリアスに寄せると保守しやすくなります。As per coding guidelines, "Use aliases as defined intsconfig.jsonwhen possible".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsx` around lines 25 - 34, The import uses a fragile deep relative path; update the import of ClaudeRuntimePicker and its symbols (ClaudeRuntimePicker, DEFAULT_SENTINEL, ClaudeModelPick, ClaudeEffortPick, fromPersistedEffort, fromPersistedModel, toPersistedEffort, toPersistedModel) to use the tsconfig path alias instead of "../../../../ClaudeRuntimePicker" (e.g., the alias that maps to the renderer/features/todo-agent/ClaudeRuntimePicker), and ensure your tsconfig/paths is configured and tests/build still resolve the new alias.apps/desktop/src/main/todo-agent/types.ts (1)
28-39: 固定モデル名のハードコードは陳腐化しやすい点に注意。
claude-opus-4-7/claude-sonnet-4-6/claude-haiku-4-5-20251001は CLI 側の実モデル名に依存しており、新リリースのたびにこの enum と UI ラベル(claudeRuntimeOptions.ts)の両方を更新する必要があります。PR 記述にもある通り model×effort の互換性検証はアプリ側で行わないため、古い固定名を選んだユーザーは起動時に Claude CLI 側でセッション失敗します。最低限、固定名に関しては「使えなくなる可能性がある」旨の注意を UI の description か README に残し、エイリアス(
opus/sonnet/haiku)の使用を推奨しておくと運用が楽です。コード上の対応は不要ですが、supervisor 側で spawn 失敗時のエラーメッセージに「モデル名が無効な可能性があります」のヒントを含めることを検討してください。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/main/todo-agent/types.ts` around lines 28 - 39, The hardcoded Claude model names (CLAUDE_MODEL_OPTIONS / TodoClaudeModel / todoClaudeModelSchema) can become invalid across CLI releases; update the UI description and repository README to warn users that concrete model strings (e.g., "claude-opus-4-7") may break and recommend using the stable aliases ("opus", "sonnet", "haiku") instead, and also add a hint in the supervisor/error path (where spawn/session failures are logged) to mention that an invalid model name could be the cause so users know to try the alias or update the model string.apps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/claudeRuntimeOptions.ts (1)
19-22:DEFAULT_SENTINELが将来のモデル/effort 値と衝突しないことを保証する型レベルのガードを検討。
"__default__"は現状のCLAUDE_MODEL_OPTIONS/CLAUDE_EFFORT_OPTIONSと衝突しませんが、将来誰かが options に"__default__"を追加すると、ClaudeModelPickのユニオンが縮退して静かにバグります。以下のような静的アサートを 1 行足しておくと安全です。♻️ 提案
export const DEFAULT_SENTINEL = "__default__" as const; +// Compile-time guard: sentinel must not collide with any real option. +type _AssertSentinelUnique = + typeof DEFAULT_SENTINEL extends TodoClaudeModel | TodoClaudeEffort + ? never + : true;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/claudeRuntimeOptions.ts` around lines 19 - 22, DEFAULT_SENTINEL が将来の options 値と衝突してユニオンが縮退しないよう、型レベルのガードを追加してください: 具体的には DEFAULT_SENTINEL、ClaudeModelPick、ClaudeEffortPick を用いるファイルで CLAUDE_MODEL_OPTIONS と CLAUDE_EFFORT_OPTIONS に対してコンパイル時の否定的アサーション(conditional type / never を用いた静的チェック)を追加し、DEFAULT_SENTINEL がいずれの options 値にも割り当てられないことを保証してください(エラーが出るようにして将来の衝突を防ぐ)。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@apps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/claudeRuntimeOptions.ts`:
- Around line 134-150: fromPersistedModel and fromPersistedEffort silently map
unknown persisted strings to DEFAULT_SENTINEL; update both functions to emit a
warning when they encounter a persisted value not present in
CLAUDE_MODEL_OPTIONS / CLAUDE_EFFORT_OPTIONS (e.g., call console.warn or the
shared logger) including the offending persisted value and which function
detected it, and keep returning DEFAULT_SENTINEL; optionally add an overload or
callback parameter to surface this event to callers (TodoModal /
ScheduleEditorDialog / PresetsDialog) if they need to notify users.
In
`@apps/desktop/src/renderer/features/todo-agent/TodoManager/PresetsDialog/PresetsDialog.tsx`:
- Around line 119-130: The current useEffect unconditionally overwrites all
local fields whenever settings changes, which will clobber user edits during
background refetch; update the effect in PresetsDialog to only sync settings
when the form is not dirty or only on initial mount: add a dirty flag (or an
initialized ref) and wrap the
setMaxIter/setMaxMin/setMaxConcurrent/setRetentionDays/setDefaultModel/setDefaultEffort
calls inside an if (!dirty) / if (!initialized) check, or change the effect to
run only once on mount and provide separate explicit sync logic for saves/loads
so in-progress edits are preserved (refer to useEffect, settings, and the setter
functions named above).
In `@apps/desktop/src/renderer/features/todo-agent/TodoModal/TodoModal.tsx`:
- Around line 87-103: The effect re-seeds state whenever todoSettings updates,
which can overwrite a user-selected DEFAULT_SENTINEL; modify the useEffect
containing setClaudeModel and setClaudeEffort so it only runs once on initial
mount or only on the first arrival of todoSettings (e.g., track a seeded flag
via useRef or detect that todoSettings was previously undefined) instead of on
every todoSettings change; keep the existing DEFAULT_SENTINEL checks but gate
the whole seeding logic with the seeded flag to prevent overwriting a deliberate
DEFAULT_SENTINEL selection by the user.
In `@packages/local-db/src/schema/todo-sessions.ts`:
- Around line 89-99: The supervisor's runClaudeTurn is currently pushing
params.claudeModel and params.claudeEffort into the spawn args without whitelist
checks; add validation there using the same logic as
claudeRuntimeOptions.fromPersistedModel and .fromPersistedEffort (or directly
check against CLAUDE_MODEL_OPTIONS and CLAUDE_EFFORT_OPTIONS) and only push
"--model" / "--effort" when the value is present and matches the allowed option
set; do not pass through arbitrary DB values—reject or skip unknown values so
spawn() only receives validated model/effort arguments.
---
Outside diff comments:
In
`@apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsx`:
- Around line 119-136: The new-schedule branch in ScheduleEditorDialog is
seeding Claude model/effort with DEFAULT_SENTINEL instead of the user's global
defaults; update the "else" new-item initialization to read the todo settings
(via electronTrpc.todoAgent.settings.get or the same prop/state TodoModal uses)
and call setClaudeModel(todoSettings.defaultClaudeModel) and
setClaudeEffort(todoSettings.defaultClaudeEffort) (falling back to
DEFAULT_SENTINEL only if those settings are undefined), ensuring the new form
fields are seeded consistently with the global defaults.
---
Nitpick comments:
In `@apps/desktop/src/main/todo-agent/types.ts`:
- Around line 28-39: The hardcoded Claude model names (CLAUDE_MODEL_OPTIONS /
TodoClaudeModel / todoClaudeModelSchema) can become invalid across CLI releases;
update the UI description and repository README to warn users that concrete
model strings (e.g., "claude-opus-4-7") may break and recommend using the stable
aliases ("opus", "sonnet", "haiku") instead, and also add a hint in the
supervisor/error path (where spawn/session failures are logged) to mention that
an invalid model name could be the cause so users know to try the alias or
update the model string.
In
`@apps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/claudeRuntimeOptions.ts`:
- Around line 19-22: DEFAULT_SENTINEL が将来の options
値と衝突してユニオンが縮退しないよう、型レベルのガードを追加してください: 具体的には
DEFAULT_SENTINEL、ClaudeModelPick、ClaudeEffortPick を用いるファイルで CLAUDE_MODEL_OPTIONS
と CLAUDE_EFFORT_OPTIONS に対してコンパイル時の否定的アサーション(conditional type / never
を用いた静的チェック)を追加し、DEFAULT_SENTINEL がいずれの options
値にも割り当てられないことを保証してください(エラーが出るようにして将来の衝突を防ぐ)。
In
`@apps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/ClaudeRuntimePicker.tsx`:
- Line 62: Replace the redundant single-argument cn call on the div in
ClaudeRuntimePicker (the JSX element with className={cn("flex flex-col
gap-1.5")}) with a plain string literal className; i.e., change
className={cn("flex flex-col gap-1.5")} to className="flex flex-col gap-1.5" so
the intent is clearer and unnecessary helper usage is removed.
In
`@apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsx`:
- Around line 25-34: The import uses a fragile deep relative path; update the
import of ClaudeRuntimePicker and its symbols (ClaudeRuntimePicker,
DEFAULT_SENTINEL, ClaudeModelPick, ClaudeEffortPick, fromPersistedEffort,
fromPersistedModel, toPersistedEffort, toPersistedModel) to use the tsconfig
path alias instead of "../../../../ClaudeRuntimePicker" (e.g., the alias that
maps to the renderer/features/todo-agent/ClaudeRuntimePicker), and ensure your
tsconfig/paths is configured and tests/build still resolve the new alias.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ec3c8319-e99d-4d55-ac0f-09101ccfa7f0
📒 Files selected for processing (18)
apps/desktop/src/main/todo-agent/schedule-store.tsapps/desktop/src/main/todo-agent/scheduler.tsapps/desktop/src/main/todo-agent/session-store.tsapps/desktop/src/main/todo-agent/settings.tsapps/desktop/src/main/todo-agent/supervisor.tsapps/desktop/src/main/todo-agent/trpc-router.tsapps/desktop/src/main/todo-agent/types.tsapps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/ClaudeRuntimePicker.tsxapps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/claudeRuntimeOptions.tsapps/desktop/src/renderer/features/todo-agent/ClaudeRuntimePicker/index.tsapps/desktop/src/renderer/features/todo-agent/TodoManager/PresetsDialog/PresetsDialog.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsxapps/desktop/src/renderer/features/todo-agent/TodoModal/TodoModal.tsxpackages/local-db/drizzle/0058_todo_claude_model_effort.sqlpackages/local-db/drizzle/meta/0058_snapshot.jsonpackages/local-db/drizzle/meta/_journal.jsonpackages/local-db/src/schema/todo-schedules.tspackages/local-db/src/schema/todo-sessions.ts
|
@codex review |
- supervisor が --model / --effort をスプロウンに渡す前に CLAUDE_*_OPTIONS 相当のホワイトリスト検証を行う。DB が破損して 不正値が入っても spawn 引数に漏れないよう二重の防御層にする - fromPersistedModel / fromPersistedEffort が未知値を黙って DEFAULT_SENTINEL に落とす挙動は維持しつつ、DevTools に console.warn を残してサイレント退行を観測できるようにする - TodoModal と PresetsDialog の useEffect を useRef ガードで 初回のみ実行にする。React Query のバックグラウンド refetch や ユーザが明示的に選んだ「デフォルト」の上書きを防ぐ
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13f6428b67
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex P2 指摘。これまで ScheduleEditorDialog の新規作成モードでは model/effort が常に DEFAULT_SENTINEL に初期化されており、TodoModal と 違って設定タブの既定値が反映されなかった。結果として新規スケジュール 保存時にも null が書かれ、発火時の session にも null がコピーされる ため --model/--effort が渡らず、既定値が事実上効かない状態だった。 - todoAgent.settings.get を ScheduleEditorDialog にも購読 - initial === null のときは claudeSeededRef 越しに一度だけ既定値で モデル/effort をシード。React Query refetch での再シードを防ぎ かつユーザの「デフォルト」選択を保護する
…chment を daemon へ移植 main 取り込み側で supervisor.ts に加わった以下の機能を、daemon 方式の 新しいアーキテクチャ (supervisor-engine.ts) に再実装する。 #244 ScheduleWakeup 継続 - engine に `wakeupResumeMarkers` を追加し、scheduler からの `fromScheduledWakeup: true` を経由してマーカーを立てる - `start()` option をIPC プロトコル (StartRequest) に追加し、 supervisor.ts (proxy) → client.ts → daemon/index.ts → engine.start の順にフラグを伝搬 - `runSession` がマーカーを消費し「再開」バナー/previous text 再送を スキップして短い継続キューだけを送る - `buildIterationPrompt` に `isScheduledWakeupContinuation` を追加、 claudeSessionId が null のときは iteration-1 フルプロンプトへ フォールバック #245 Claude model/effort - `runClaudeTurn` に `claudeModel`/`claudeEffort` を渡し、 CLAUDE_*_OPTIONS ホワイトリストで検証してから `--model`/`--effort` を spawn に追加(不明値は warn して無視する二重防御) - setup event に「Claude 設定」として選択内容を表示 #250 画像添付 tool_result - `extractToolResultDetails` が image ブロックのみの tool_result も `[画像 N 件]` プレースホルダで emit するよう修正 - `extractAttachmentPaths` を daemon 側にも複製し、iteration 1 の プロンプトに添付ファイルパスを列挙して Read を促す #243 done→resume は trpc-router.ts 側で完結するので追加変更なし
Summary
claude -pにそのまま--model/--effortを渡す形式なので、公式 CLI がサポートする alias (opus/sonnet/haiku) と固定名 (claude-opus-4-7/claude-sonnet-4-6/claude-haiku-4-5-20251001)、effort はlow/medium/high/xhigh/maxを選べるCloses
Changes
Model / Effort に関する注意
Test plan
Summary by CodeRabbit
リリースノート