diff --git a/.changeset/workflow-model-lanes-settings.md b/.changeset/workflow-model-lanes-settings.md
new file mode 100644
index 0000000000..9479088e9c
--- /dev/null
+++ b/.changeset/workflow-model-lanes-settings.md
@@ -0,0 +1,5 @@
+---
+"@runfusion/fusion": patch
+---
+
+Expose default-workflow Plan/Triage, Executor, and Reviewer model lanes from Project Models settings while keeping workflow setting values as the source of truth.
diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md
index 2901300749..c8b2fdb0a5 100644
--- a/docs/dashboard-guide.md
+++ b/docs/dashboard-guide.md
@@ -107,6 +107,8 @@ Navigation:
Behavior:
- Opens a workflow node editor with a workflow list/sidebar, canvas, inspector, and settings/authoring panels
+- The Settings panel is value-first for built-in workflows and groups workflow settings by Models, Review & Approval, Step Execution, and Advanced. Definitions remain available for custom workflow schema authoring.
+- The main Settings modal also exposes the default workflow's Plan/Triage, Executor, and Reviewer model lanes from **Project Models**; those controls write workflow setting values for the active default workflow.
- On desktop, the editor uses a multi-panel layout for editing the graph and adjacent workflow metadata
- On viewports `<=768px`, the editor switches to a full-screen mobile sheet and stacks the sidebar, canvas, inspector, and settings/authoring panels vertically so each section remains scrollable and usable on phones
- The create-workflow dialog and workflow AI authoring popover follow the same mobile full-screen/sheet pattern so they are not clipped by the editor canvas on narrow screens
diff --git a/docs/plans/2026-06-08-001-feat-workflow-settings-simplification-plan.md b/docs/plans/2026-06-08-001-feat-workflow-settings-simplification-plan.md
new file mode 100644
index 0000000000..0725179bfc
--- /dev/null
+++ b/docs/plans/2026-06-08-001-feat-workflow-settings-simplification-plan.md
@@ -0,0 +1,197 @@
+---
+title: "feat: Simplify workflow settings and restore main settings model lanes"
+type: feat
+status: active
+date: 2026-06-08
+depth: standard
+origin: none (follow-up to docs/plans/2026-06-04-002-feat-workflow-settings-mechanism-plan.md)
+---
+
+# feat: Simplify workflow settings and restore main settings model lanes
+
+## Summary
+
+Keep workflow setting values as the only persisted authority for moved workflow policy, but make the common path usable again from Settings. Main project settings should expose Plan/Triage, Executor, and Reviewer model selectors by proxy-editing the active default workflow's model-lane values. The workflow editor should stop leading with schema mechanics for normal users and instead present grouped value sections with an advanced definitions area.
+
+---
+
+## Problem Frame
+
+The workflow settings hard move solved the source-of-truth problem: per-phase model lanes and workflow execution policy no longer live as ambient project settings. The resulting UX is too expensive for the most common task. A user who only wants to set the model used for planning/triage, execution, or review now has to leave Settings, open the workflow editor, understand definitions vs values, and find raw setting ids among unrelated workflow policy knobs.
+
+The fix is not to reintroduce the old project settings keys. Those keys are intentionally tombstoned in `packages/core/src/moved-settings.ts`, and stale writes are stripped before persistence. The fix is to add a first-class proxy surface in Settings for the active project's default workflow values, while making the workflow settings panel itself grouped, value-first, and less schema-editor-shaped.
+
+---
+
+## Requirements
+
+**Main Settings Model Lanes**
+
+- R1. The Project Models section exposes three project-level workflow model lanes: Plan/Triage, Executor, and Reviewer.
+- R2. Saving those controls writes workflow setting values for the active project's default workflow, never the tombstoned project settings keys.
+- R3. The selectors preserve the current model picker affordances: provider/model choices, favorites, loading/empty states, reset-to-inherit, and visible inherited/customized state.
+- R4. When no active project or default workflow is available, the controls render a clear disabled state and do not write.
+
+**Workflow Settings Usability**
+
+- R5. Workflow settings values are grouped by user intent: Models, Review & Approval, Step Execution, and Advanced.
+- R6. For built-in workflows, the panel opens to grouped Values by default and hides Definitions behind a read-only Advanced area.
+- R7. For custom workflows, declaration editing remains available, but normal value editing stays the primary surface.
+- R8. Moved-setting redirect stubs in Settings are replaced or narrowed so users are not sent away for the model-lane case.
+
+**Authority and Compatibility**
+
+- R9. `MOVED_SETTINGS_KEYS` remains the persistence boundary; no moved key is restored to `DEFAULT_PROJECT_SETTINGS`, settings export project payloads, sync diffs, or CLI `settings set`.
+- R10. Engine model resolution remains unchanged: workflow lane value -> global lane -> project default -> global default.
+
+---
+
+## Scope Boundaries
+
+### In scope
+
+- Project Models UI for Plan/Triage, Executor, and Reviewer model lanes, backed by workflow setting-value endpoints.
+- A reusable grouped workflow-setting value editor shared between `ProjectModelsSection` and `WorkflowSettingsPanel`.
+- Narrow copy and navigation changes for moved-setting stubs.
+- Focused tests for proxy writes, grouped rendering, and persistence-boundary regressions.
+
+### Deferred
+
+- Full workflow setting sync across nodes. The existing "workflow settings are not synced yet" stance remains.
+- Per-task workflow setting overrides.
+- New model-lane types or engine resolution changes.
+- Reworking workflow declaration schema.
+
+### Out of scope
+
+- Re-adding `executionProvider`, `planningProvider`, `validatorProvider`, or related moved keys to project settings.
+- Changing task-level model override behavior in `TaskForm`.
+- Moving merge trait or capacity settings into this follow-up.
+
+---
+
+## Key Technical Decisions
+
+- KTD-1 — **Proxy-edit default workflow values from Settings.** The Project Models section reads the active default workflow id, calls `fetchWorkflowSettingValues(workflowId, projectId)`, and saves patches through `updateWorkflowSettingValues`. This keeps the source of truth in `workflow_settings` while restoring the main Settings workflow users expect.
+
+- KTD-2 — **Use user-facing lane names, not storage names.** Settings labels should be Plan/Triage, Executor, and Reviewer. They map to `planningProvider`/`planningModelId`, `executionProvider`/`executionModelId`, and `validatorProvider`/`validatorModelId`. The existing engine still calls the reviewer lane `validator`; the UI should not expose that implementation vocabulary as the primary label.
+
+- KTD-3 — **Grouped values are display metadata, not IR schema.** Add dashboard-side grouping metadata for known workflow settings rather than expanding `WorkflowSettingDefinition` immediately. Custom or unknown settings fall into Advanced. This avoids a schema change for a UX-only regrouping.
+
+- KTD-4 — **One reusable value editor.** Extract the Values-tab row rendering from `WorkflowSettingsPanel.tsx` into a reusable component that can render a filtered set of workflow settings. `ProjectModelsSection` uses it in model-lane mode; `WorkflowSettingsPanel` uses it for all grouped sections.
+
+- KTD-5 — **Keep save authorities separate.** Settings modal project/global saves continue through `updateSettings` / `updateGlobalSettings`. Workflow model-lane saves happen through a dedicated workflow-values save path. The UI may place them on the same screen, but the payloads must not be fused.
+
+---
+
+## High-Level Technical Design
+
+```mermaid
+flowchart TB
+ PM["Project Models section"] --> DW["Resolve active default workflow id"]
+ DW --> GET["GET /workflows/:id/setting-values?projectId"]
+ GET --> LANE["Grouped model lane editor
Plan/Triage, Executor, Reviewer"]
+ LANE --> PATCH["PATCH /workflows/:id/setting-values
planning*, execution*, validator*"]
+ PATCH --> TABLE["workflow_settings table"]
+ TABLE --> RES["resolveEffectiveSettingsDetailed"]
+ RES --> ENG["Engine model resolution
workflow -> global lane -> project default -> global default"]
+
+ PM -. "must not send" .-> DEAD["updateSettings moved-key payload"]
+```
+
+The Settings modal remains a shell over multiple authorities. Its regular Save button can either save normal project settings and workflow lane values in one user action with two API calls, or the lane group can have its own inline "Save workflow models" action. Implementation should choose the smaller UI change after checking the current dirty-state model in `SettingsModal.tsx`; the invariant is that moved model keys never enter the project settings payload.
+
+---
+
+## Implementation Units
+
+### U1. Workflow setting display metadata and grouped value editor
+
+- **Goal:** Create the reusable display and editing primitives needed by both Settings and the workflow editor.
+- **Requirements:** R3, R5, R6, R7
+- **Files:** `packages/dashboard/app/components/workflow-setting-display.ts` (new), `packages/dashboard/app/components/WorkflowSettingValueEditor.tsx` (new), `packages/dashboard/app/components/WorkflowSettingValueEditor.css` (new), `packages/dashboard/app/components/WorkflowSettingsPanel.tsx`, `packages/dashboard/app/components/__tests__/WorkflowSettingsPanel.test.tsx`
+- **Approach:** Add a dashboard-side catalog mapping known ids to group, label, description, and lane pair metadata. Extract the current Values-tab row logic into `WorkflowSettingValueEditor`, accepting declarations, stored/effective values, orphaned values, allowed ids/group filter, project stale state, and save callback. Unknown declarations render under Advanced.
+- **Test scenarios:**
+ - Built-in workflow values render grouped as Models, Review & Approval, Step Execution, Advanced.
+ - Plan/Triage, Executor, and Reviewer labels appear instead of raw planning/execution/validator storage names.
+ - Unknown custom setting renders in Advanced.
+ - Orphaned values still render in the disclosure and delete through a null patch.
+ - Built-in workflow opens to Values by default; Definitions remains read-only and secondary.
+
+### U2. Main Settings proxy model lanes for the default workflow
+
+- **Goal:** Let users set Plan/Triage, Executor, and Reviewer models from Project Models without restoring project setting keys.
+- **Requirements:** R1, R2, R3, R4, R8, R9
+- **Files:** `packages/dashboard/app/components/settings/sections/ProjectModelsSection.tsx`, `packages/dashboard/app/components/SettingsModal.tsx`, `packages/dashboard/app/components/__tests__/SettingsModal.test.tsx`, `packages/dashboard/app/components/__tests__/SettingsModalNodeRouting.test.tsx`
+- **Approach:** Resolve the active project's default workflow id from the project settings already loaded in the modal, defaulting to `builtin:coding` when unset, matching `workflow-settings-resolver.ts`. Load workflow setting values for that id and render only model lane pairs. Reset clears the stored workflow value via null patch. Keep the project default model lane in the existing project-settings save path.
+- **Test scenarios:**
+ - Project Models renders Plan/Triage, Executor, and Reviewer lane controls when a project is active.
+ - Editing Plan/Triage writes `planningProvider` and `planningModelId` through `updateWorkflowSettingValues`, not `updateSettings`.
+ - Editing Executor writes `executionProvider` and `executionModelId`.
+ - Editing Reviewer writes `validatorProvider` and `validatorModelId`.
+ - Reset sends nulls for the relevant workflow setting ids.
+ - No active project disables workflow model controls and makes no API call.
+ - Normal Project Default Model still saves through `updateSettings`.
+
+### U3. Save-flow and error handling integration
+
+- **Goal:** Make mixed project-settings and workflow-values edits feel coherent without blurring persistence boundaries.
+- **Requirements:** R2, R3, R9
+- **Files:** `packages/dashboard/app/components/SettingsModal.tsx`, `packages/dashboard/app/components/settings/save-split.ts`, `packages/dashboard/app/__tests__/settings-save-split.test.ts`, `packages/dashboard/app/components/__tests__/SettingsModal.test.tsx`
+- **Approach:** Keep `splitSettingsSave` focused on actual settings keys. Add a separate workflow-values dirty state in `SettingsModal`. If the global Save button covers both authorities, run the normal settings save and workflow-values save as separate calls and report partial failures with section-local errors. If the workflow lane group uses its own save button, keep the global dirty state untouched by workflow lane edits.
+- **Test scenarios:**
+ - A workflow lane edit never appears in `splitSettingsSave` output.
+ - A combined save issues separate `updateSettings` and `updateWorkflowSettingValues` calls when both authorities are dirty.
+ - A workflow value rejection renders on the lane row and does not discard pending edits.
+ - A project settings save failure does not falsely report workflow lane values as saved.
+
+### U4. Narrow moved-setting stubs and workflow editor entry points
+
+- **Goal:** Stop sending users away from Settings for the model-lane case while keeping workflow-owned policy discoverable.
+- **Requirements:** R5, R8
+- **Files:** `packages/dashboard/app/components/settings/sections/ProjectModelsSection.tsx`, `packages/dashboard/app/components/settings/sections/MergeSection.tsx`, `packages/dashboard/app/components/settings/sections/SchedulingSection.tsx`, `packages/dashboard/app/components/settings/sections/MovedSettingsStub.tsx`, `packages/dashboard/app/components/__tests__/SettingsModal.test.tsx`
+- **Approach:** Replace the Project Models moved stub with the proxy model controls. Keep or narrow stubs for step execution and review/approval settings that remain workflow-editor-only. Update stub copy to say "Advanced workflow policy" instead of implying all per-phase model lanes require leaving Settings.
+- **Test scenarios:**
+ - Project Models no longer renders the generic "Open workflow settings" stub for per-phase model lanes.
+ - Merge/Scheduling still do not render moved setting inputs such as `verificationFixRetries`.
+ - Stub button still opens the workflow editor for advanced workflow policy.
+
+### U5. Documentation and permanent boundary tests
+
+- **Goal:** Document the simplified mental model and guard against accidental project-key resurrection.
+- **Requirements:** R9, R10
+- **Files:** `docs/settings-reference.md`, `docs/dashboard-guide.md`, `packages/core/src/__tests__/settings-parity.test.ts`, `packages/core/src/__tests__/settings-consistency.test.ts`, `packages/dashboard/app/__tests__/settings-sections.test.tsx`
+- **Approach:** Update docs to state that Settings can edit default-workflow model lanes, while workflow settings remain the source of truth. Extend parity tests to assert moved model-lane keys are absent from project/global schema lists and present in built-in workflow declarations. Add a UI section test that Project Models contains the proxy lane surface.
+- **Test scenarios:**
+ - `executionProvider`, `planningProvider`, and `validatorProvider` remain absent from `PROJECT_SETTINGS_KEYS`.
+ - Built-in workflow declarations still include all proxy-edited model lane ids.
+ - Settings section inventory includes Project Models proxy controls and no stale moved-key stub for model lanes.
+
+---
+
+## Acceptance Examples
+
+- AE1. Given an active project using the default built-in workflow, when a user sets Plan/Triage to `openai/gpt-5` from Project Models and saves, then `workflow_settings` stores `planningProvider: "openai"` and `planningModelId: "gpt-5"` for `(builtin:coding, projectId)`, and the project settings payload contains neither key.
+- AE2. Given a project with a custom default workflow, when a user sets Executor from Project Models, then the value is written for that custom workflow id, not globally for every workflow.
+- AE3. Given no project is selected, when Settings opens Project Models, then workflow model lane controls are disabled and no workflow setting-value request is sent.
+- AE4. Given a built-in workflow is opened in the workflow editor, when the Settings panel opens, then grouped Values are primary and Definitions are read-only secondary details.
+
+---
+
+## Risks & Dependencies
+
+- **Default workflow ambiguity:** Settings must resolve the same default workflow id as the engine, including unset defaults falling back to `builtin:coding`. Reuse the resolver's normalization behavior in tests.
+- **Two-authority save UX:** A shared Save button can create partial-success states. Keep errors section-local and avoid mutating the project settings payload with workflow keys.
+- **Terminology drift:** Reviewer maps to `validator*` internally. Tests should assert the user-facing label so the UI does not regress back to storage vocabulary.
+
+---
+
+## Sources
+
+- Prior workflow settings hard move: `docs/plans/2026-06-04-002-feat-workflow-settings-mechanism-plan.md`
+- Workflow setting value authority: `packages/core/src/workflow-settings.ts`, `packages/core/src/store.ts`
+- Effective settings resolver and engine merge semantics: `packages/core/src/workflow-settings-resolver.ts`
+- Built-in moved setting declarations: `packages/core/src/builtin-workflow-settings.ts`
+- Tombstone boundary: `packages/core/src/moved-settings.ts`
+- Current workflow settings UI: `packages/dashboard/app/components/WorkflowSettingsPanel.tsx`
+- Current Project Models section and moved stub: `packages/dashboard/app/components/settings/sections/ProjectModelsSection.tsx`, `packages/dashboard/app/components/settings/sections/MovedSettingsStub.tsx`
diff --git a/docs/settings-reference.md b/docs/settings-reference.md
index 183b6217bc..a59581f677 100644
--- a/docs/settings-reference.md
+++ b/docs/settings-reference.md
@@ -181,8 +181,15 @@ Some knobs that used to live in this Settings reference as project settings are
*how* tasks execute, so the timeouts, review gates, and per-phase model lanes that
govern that execution belong to the workflow.
-**Where to set them.** Open the **workflow editor** (the workflow node editor in the
-dashboard) and select the **Settings** panel. It has two tabs:
+**Where to set them.** The common model lanes for a project's default workflow are
+available directly in **Settings → Project Models → Default workflow model lanes**:
+Plan/Triage, Executor, and Reviewer. Those controls still write workflow setting
+values for the active project's default workflow; they do not restore the old
+project settings keys.
+
+For step execution, review/approval policy, fallbacks, title summarization, and
+custom workflow settings, open the **workflow editor** (the workflow node editor in
+the dashboard) and select the **Settings** panel. It has two tabs:
- **Definitions** — the typed declarations and defaults (read-only for the built-in
`builtin:coding` workflow; editable for custom workflows).
@@ -223,9 +230,10 @@ These groups moved out of project settings and into workflow settings (built-in
| **Review / approval** | `requirePrApproval`, `requirePlanApproval`, `reviewHandoffPolicy`, `maxReviewerContextRetries`, `maxReviewerFallbackRetries` |
| **Per-phase model lanes** | `executionProvider`/`executionModelId`, `planningProvider`/`planningModelId` (+ fallbacks), `validatorProvider`/`validatorModelId` (+ fallbacks), `titleSummarizerProvider`/`titleSummarizerModelId` (+ fallback) |
-In the dashboard Settings modal, the former locations now show a short redirect stub
-linking to the workflow editor (for one release). Set these in the workflow editor's
-**Settings → Values** tab for the workflow you want to tune.
+In the dashboard Settings modal, Project Models now exposes Plan/Triage, Executor,
+and Reviewer controls for the default workflow. Former locations for advanced
+workflow policy still show a short redirect stub linking to the workflow editor
+(for one release).
> Note: the global baseline model lanes (`executionGlobalProvider` etc.) and
> integrity guarantees stay where they are — only the per-workflow process policy
@@ -239,8 +247,9 @@ Defaults from `DEFAULT_PROJECT_SETTINGS`; key scope from `PROJECT_SETTINGS_KEYS`
> review/approval, and per-phase model-lane keys listed under
> [Where did my setting go?](#where-did-my-setting-go) — are no longer project
> settings. They are documented here for type/default reference only; configure them
-> in the **workflow editor → Settings → Values** tab. They are not writable through
-> `PUT /api/settings`.
+> in **Settings → Project Models** for default-workflow Plan/Triage, Executor, and
+> Reviewer lanes, or in **workflow editor → Settings → Values** for advanced
+> workflow policy. They are not writable through `PUT /api/settings`.
| Setting | Type | Default | Description |
|---|---|---:|---|
@@ -757,12 +766,12 @@ Short-lived token bounds are enforced server-side:
## Model Selection Hierarchy
-Fusion uses a dual-scope model settings system with five lanes. Global settings provide baseline defaults, and project settings provide per-project overrides.
+Fusion resolves task models through workflow-backed lane values first, then global lane defaults, then the project/global default model fallback. The common workflow lanes are stored as setting values on the project's default workflow and can be edited from Settings -> Project Models -> Default workflow model lanes.
### Planning model
1. Per-task `planningModelProvider` + `planningModelId`
-2. Project `planningProvider` + `planningModelId`
+2. Default workflow lane value `planningProvider` + `planningModelId`
3. Global `planningGlobalProvider` + `planningGlobalModelId`
4. Project `defaultProviderOverride` + `defaultModelIdOverride`
5. Global `defaultProvider` + `defaultModelId`
@@ -772,7 +781,7 @@ Fusion uses a dual-scope model settings system with five lanes. Global settings
1. Assigned durable agent runtime model (`runtimeConfig.model` or `runtimeConfig.modelProvider` + `runtimeConfig.modelId`) when both provider and model ID are set
2. Per-task `modelProvider` + `modelId`
-3. Project `executionProvider` + `executionModelId`
+3. Default workflow lane value `executionProvider` + `executionModelId`
4. Global `executionGlobalProvider` + `executionGlobalModelId`
5. Project `defaultProviderOverride` + `defaultModelIdOverride`
6. Global `defaultProvider` + `defaultModelId`
@@ -783,7 +792,7 @@ Fusion uses a dual-scope model settings system with five lanes. Global settings
Heartbeat sessions for durable agents use this order:
1. Assigned durable agent runtime model (`runtimeConfig.model` or `runtimeConfig.modelProvider` + `runtimeConfig.modelId`) when present
-2. Project `executionProvider` + `executionModelId`
+2. Default workflow lane value `executionProvider` + `executionModelId`
3. Global `executionGlobalProvider` + `executionGlobalModelId`
4. Project `defaultProviderOverride` + `defaultModelIdOverride`
5. Global `defaultProvider` + `defaultModelId`
@@ -794,7 +803,7 @@ When heartbeat has both (1) and (2-5), the runtime model is used as primary and
### Reviewer model
1. Per-task `validatorModelProvider` + `validatorModelId`
-2. Project `validatorProvider` + `validatorModelId`
+2. Default workflow lane value `validatorProvider` + `validatorModelId`
3. Global `validatorGlobalProvider` + `validatorGlobalModelId`
4. Project `defaultProviderOverride` + `defaultModelIdOverride`
5. Global `defaultProvider` + `defaultModelId`
@@ -1370,7 +1379,7 @@ Project-scoped default permission policy for permanent-agent action gates.
All three lanes (planning / executor / reviewer) follow the same 5-tier precedence:
1. Per-task override (`planningModelProvider`/`Id`, `modelProvider`/`Id`, `validatorModelProvider`/`Id`)
-2. Project lane (`planningProvider`/`Id`, `executionProvider`/`Id`, `validatorProvider`/`Id`)
+2. Default workflow lane value (`planningProvider`/`Id`, `executionProvider`/`Id`, `validatorProvider`/`Id`)
3. Global lane (`planningGlobalProvider`/`Id`, `executionGlobalProvider`/`Id`, `validatorGlobalProvider`/`Id`)
4. Project `defaultProviderOverride` / `defaultModelIdOverride`
5. Global `defaultProvider` / `defaultModelId` → automatic resolution
diff --git a/packages/dashboard/app/components/CustomModelDropdown.tsx b/packages/dashboard/app/components/CustomModelDropdown.tsx
index 90e1d79636..6210529e34 100644
--- a/packages/dashboard/app/components/CustomModelDropdown.tsx
+++ b/packages/dashboard/app/components/CustomModelDropdown.tsx
@@ -18,6 +18,8 @@ export interface CustomModelDropdownProps {
noChangeValue?: string;
/** Display label for noChangeValue (defaults to "No change"). */
noChangeLabel?: string;
+ /** Display label for the inherited/default option (defaults to "Use default"). */
+ defaultOptionLabel?: string;
/** List of favorite provider names in preferred order */
favoriteProviders?: string[];
/** Called when user toggles a provider's favorite status */
@@ -62,10 +64,12 @@ export function CustomModelDropdown({
onToggleModelFavorite,
noChangeValue,
noChangeLabel: noChangeLabelProp,
+ defaultOptionLabel: defaultOptionLabelProp,
}: CustomModelDropdownProps) {
const { t } = useTranslation("app");
const placeholder = placeholderProp ?? t("model.selectPlaceholder", "Select a model…");
const noChangeLabel = noChangeLabelProp ?? t("model.noChange", "No change");
+ const defaultOptionLabel = defaultOptionLabelProp ?? t("models.useDefault", "Use default");
const [isOpen, setIsOpen] = useState(false);
const [localFilter, setLocalFilter] = useState("");
const [highlightedIndex, setHighlightedIndex] = useState(0);
@@ -143,9 +147,9 @@ export function CustomModelDropdown({
if (hasNoChangeOption) {
options.push({ type: "no-change", value: noChangeValue, label: noChangeLabel });
}
- options.push({ type: "default", value: "", label: t("models.useDefault", "Use default") });
+ options.push({ type: "default", value: "", label: defaultOptionLabel });
return options;
- }, [hasNoChangeOption, noChangeLabel, noChangeValue]);
+ }, [defaultOptionLabel, hasNoChangeOption, noChangeLabel, noChangeValue]);
// Build list of all selectable options (for keyboard navigation)
// Includes special rows first (optional "No change" + "Use default"),
@@ -183,14 +187,14 @@ export function CustomModelDropdown({
if (hasNoChangeOption && value === noChangeValue) {
return noChangeLabel;
}
- if (!value) return t("models.useDefault", "Use default");
+ if (!value) return defaultOptionLabel;
const slashIdx = value.indexOf("/");
if (slashIdx === -1) return value;
const provider = value.slice(0, slashIdx);
const modelId = value.slice(slashIdx + 1);
const model = models.find((m) => m.provider === provider && m.id === modelId);
return model?.name || value;
- }, [hasNoChangeOption, noChangeLabel, noChangeValue, value, models]);
+ }, [defaultOptionLabel, hasNoChangeOption, noChangeLabel, noChangeValue, value, models]);
// Find index of current value in options list
const currentValueIndex = useMemo(() => {
diff --git a/packages/dashboard/app/components/SettingsModal.tsx b/packages/dashboard/app/components/SettingsModal.tsx
index 48c9af8f43..cf15fc9855 100644
--- a/packages/dashboard/app/components/SettingsModal.tsx
+++ b/packages/dashboard/app/components/SettingsModal.tsx
@@ -2481,6 +2481,8 @@ export function SettingsModal({
scopeBanner={renderScopeBanner()}
form={form}
setForm={setForm}
+ projectId={projectId}
+ addToast={addToast}
onOpenWorkflowSettings={onOpenWorkflowSettings}
models={{
modelLanes: MODEL_LANES,
diff --git a/packages/dashboard/app/components/WorkflowSettingsPanel.css b/packages/dashboard/app/components/WorkflowSettingsPanel.css
index 76dbea5fa9..27038a214b 100644
--- a/packages/dashboard/app/components/WorkflowSettingsPanel.css
+++ b/packages/dashboard/app/components/WorkflowSettingsPanel.css
@@ -246,11 +246,25 @@
}
.wf-settings-values-list {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-md);
+}
+
+.wf-settings-value-group {
display: flex;
flex-direction: column;
gap: var(--space-xs);
}
+.wf-settings-value-group-title {
+ margin: 0;
+ font-size: 0.72rem;
+ color: var(--text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0;
+}
+
.wf-settings-value-item {
position: relative;
display: flex;
diff --git a/packages/dashboard/app/components/WorkflowSettingsPanel.tsx b/packages/dashboard/app/components/WorkflowSettingsPanel.tsx
index b0a3877b67..7c095257f2 100644
--- a/packages/dashboard/app/components/WorkflowSettingsPanel.tsx
+++ b/packages/dashboard/app/components/WorkflowSettingsPanel.tsx
@@ -41,6 +41,11 @@ import {
ApiRequestError,
type WorkflowSettingValuesPayload,
} from "../api";
+import {
+ getWorkflowSettingDisplay,
+ groupWorkflowSettings,
+ WORKFLOW_SETTING_GROUP_LABELS,
+} from "./workflow-setting-display";
import {
SettingsToggleRow,
SettingsNumberRow,
@@ -609,10 +614,11 @@ function ValuesTab({
const value = effectiveOf(setting);
const error = rejections[setting.id]?.message;
const customized = isCustomized(setting);
+ const display = getWorkflowSettingDisplay(setting);
const descriptor = {
key: setting.id,
- label: setting.name,
- help: setting.description,
+ label: display.label,
+ help: display.description ?? setting.description,
scope: "project" as const,
};
const clearable = customized;
@@ -732,15 +738,22 @@ function ValuesTab({
+ These controls edit model values on this project's default workflow ({resolvedWorkflowId}). + They use workflow settings as the source of truth. +
+ {!projectId ? ( +