feat(merger,dashboard): use title-summarization model for commit body AI + reword settings

Wires the AI commit-body generator (introduced in 52928ff5e) to the
existing dedicated title-summarization model lane, and updates the
settings UI so users understand the model is now used for two
short-summary jobs instead of just one. Also de-duplicates the
project-scope settings UI which was exposing the same model setting in
two places.

Engine (merger.ts):
- aiGenerateCommitBody now prefers settings.titleSummarizerProvider /
  titleSummarizerModelId over the merger's default model. The
  summarization lane is the right tier for this work — small, fast,
  cheap. Falls back to the default merger model when the summarization
  lane is unset.

Dashboard (SettingsModal.tsx):
- MODEL_LANES summarization lane label updated:
  "Title Summarization Model" → "Title and Git Commit Message
  Summarization Model". Helper text updated to mention the dual purpose
  (auto-generated task titles + fallback merge commit message bodies).
  This change flows through automatically to BOTH the global model
  lanes view and any project-scope rendering of MODEL_LANES.
- Removed the duplicate summarization picker from the project-scope
  Model Lanes section: previously it appeared once under Model Lanes
  AND once under "AI Summarization". Now lives only in the dedicated
  picker so users have a single source of truth in project scope.
- The dedicated picker section heading + description rewritten:
  "AI Summarization" → "AI Title and Git Commit Message Summarization",
  with a paragraph explaining both jobs the model performs.
- Inner dropdown label updated for consistency.

Tests + checks: engine 2887/2887 pass, dashboard typecheck clean,
workspace lint clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-29 08:22:04 -07:00
parent 52928ff5e7
commit 5c2240caab
2 changed files with 41 additions and 15 deletions

View File

@@ -1118,12 +1118,12 @@ export function SettingsModal({
},
{
laneId: "summarization",
label: "Title Summarization Model",
label: "Title and Git Commit Message Summarization Model",
globalProviderKey: "titleSummarizerGlobalProvider",
globalModelKey: "titleSummarizerGlobalModelId",
projectProviderKey: "titleSummarizerProvider",
projectModelKey: "titleSummarizerModelId",
helperText: "AI model used for auto-generating task titles from descriptions.",
helperText: "AI model used for auto-generating task titles from descriptions and for synthesizing fallback merge commit message bodies when the branch's commit log is empty.",
fallbackOrder: "Project override → Global summarization lane → Project planning lane → Project default lane → Global default lane → Automatic resolution",
},
];
@@ -1865,13 +1865,16 @@ export function SettingsModal({
const inUsePresetIds = new Set(Object.values(form.defaultPresetBySize || {}).filter(Boolean));
// Filter model lanes to show in project scope.
// The "summarization" lane is intentionally excluded here — it has a
// dedicated picker further down ("AI Title and Git Commit Message
// Summarization") so the project tab doesn't surface the same model
// setting twice.
const projectModelLanes = MODEL_LANES.filter(
(lane) =>
lane.laneId === "default"
|| lane.laneId === "execution"
|| lane.laneId === "planning"
|| lane.laneId === "validator"
|| lane.laneId === "summarization",
|| lane.laneId === "validator",
);
const resolvedPlanningModel = resolvePlanningSettingsModel(form);
const resolvedDefaultModel = resolveProjectDefaultModel(form);
@@ -2255,8 +2258,16 @@ export function SettingsModal({
</div>
) : null}
{/* --- AI Summarization --- */}
<h4 className="settings-section-heading settings-section-heading--spaced">AI Summarization</h4>
{/* --- AI Title and Git Commit Message Summarization --- */}
<h4 className="settings-section-heading settings-section-heading--spaced">
AI Title and Git Commit Message Summarization
</h4>
<p className="settings-description">
Configures the model used for two short-summary jobs:
auto-generating task titles from long descriptions, and
synthesizing fallback merge commit message bodies when the
branch's commit log is empty.
</p>
<div className="form-group">
<label htmlFor="autoSummarizeTitles" className="checkbox-label">
<input
@@ -2269,14 +2280,16 @@ export function SettingsModal({
</label>
<small>
When enabled, tasks created without a title but with descriptions over 200 characters
will automatically get an AI-generated title (max 60 characters).
will automatically get an AI-generated title (max 60 characters). The same model is
also used to generate fallback merge commit message bodies when the branch's commit
log is empty (e.g. squash merges with no unique commits).
</small>
</div>
{(form.autoSummarizeTitles || false) && (
<>
<div className="form-group">
<label>Title summarization model</label>
<label>Title and commit message summarization model</label>
{modelsLoading ? (
<small>Loading available models...</small>
) : availableModels.length === 0 ? (
@@ -2284,7 +2297,7 @@ export function SettingsModal({
) : (
<CustomModelDropdown
id="titleSummarizerModel"
label="Title summarization model"
label="Title and commit message summarization model"
models={availableModels}
value={
form.titleSummarizerProvider && form.titleSummarizerModelId