diff --git a/apps/web/src/domains/settings/ai/ai-types.ts b/apps/web/src/domains/settings/ai/ai-types.ts
index 4b614586dc3..0b34484e38c 100644
--- a/apps/web/src/domains/settings/ai/ai-types.ts
+++ b/apps/web/src/domains/settings/ai/ai-types.ts
@@ -304,4 +304,4 @@ export const LS_TTS_VOICE_ID_PREFIX = "vellum:voice:ttsVoiceId:";
export const LS_STT_PROVIDER = "vellum:voice:sttProvider";
export const LS_STT_API_KEY_PREFIX = "vellum:voice:sttApiKey:";
-export const LS_IMAGE_GEN_CREDENTIAL = "vellum:ai:geminiKey";
+
diff --git a/apps/web/src/domains/settings/ai/call-site-helpers.test.ts b/apps/web/src/domains/settings/ai/call-site-helpers.test.ts
index c54981262b9..41d849976d9 100644
--- a/apps/web/src/domains/settings/ai/call-site-helpers.test.ts
+++ b/apps/web/src/domains/settings/ai/call-site-helpers.test.ts
@@ -5,7 +5,7 @@ import { buildOrderedProfiles } from "@/domains/settings/ai/ai-utils";
import {
isDraftActive,
draftsEqual,
-} from "@/domains/settings/ai/call-site-overrides-modal";
+} from "@/domains/settings/ai/call-site-helpers";
// ---------------------------------------------------------------------------
// isDraftActive
diff --git a/apps/web/src/domains/settings/ai/call-site-helpers.ts b/apps/web/src/domains/settings/ai/call-site-helpers.ts
new file mode 100644
index 00000000000..530ea5df990
--- /dev/null
+++ b/apps/web/src/domains/settings/ai/call-site-helpers.ts
@@ -0,0 +1,31 @@
+import type { CallSiteOverrideDraft } from "@/domains/settings/ai/ai-types";
+
+// ---------------------------------------------------------------------------
+// Sentinel value for the "Custom" profile picker option
+// ---------------------------------------------------------------------------
+
+export const CUSTOM_SENTINEL = "__custom__";
+
+// ---------------------------------------------------------------------------
+// Pure helpers
+// ---------------------------------------------------------------------------
+
+export function isDraftActive(d: CallSiteOverrideDraft | null | undefined): boolean {
+ if (!d) return false;
+ return !!(d.profile || d.provider || d.model);
+}
+
+export function draftsEqual(
+ a: CallSiteOverrideDraft | null | undefined,
+ b: CallSiteOverrideDraft | null | undefined,
+): boolean {
+ const aActive = isDraftActive(a);
+ const bActive = isDraftActive(b);
+ if (aActive !== bActive) return false;
+ if (!aActive) return true;
+ return (
+ (a?.profile ?? null) === (b?.profile ?? null) &&
+ (a?.provider ?? null) === (b?.provider ?? null) &&
+ (a?.model ?? null) === (b?.model ?? null)
+ );
+}
diff --git a/apps/web/src/domains/settings/ai/call-site-overrides-modal.tsx b/apps/web/src/domains/settings/ai/call-site-overrides-modal.tsx
index 5ef179d1e23..7b449bda452 100644
--- a/apps/web/src/domains/settings/ai/call-site-overrides-modal.tsx
+++ b/apps/web/src/domains/settings/ai/call-site-overrides-modal.tsx
@@ -5,9 +5,7 @@ import { useQuery } from "@tanstack/react-query";
import { Button } from "@vellum/design-library/components/button";
import { ConfirmDialog } from "@vellum/design-library/components/confirm-dialog";
-import { Dropdown } from "@vellum/design-library/components/dropdown";
import { Input } from "@vellum/design-library/components/input";
-import { Toggle } from "@vellum/design-library/components/toggle";
import { Modal } from "@vellum/design-library/components/modal";
import { toast } from "@vellum/design-library/components/toast";
import type { ConfigLlmCallsitesGetResponse } from "@/generated/daemon/types.gen";
@@ -16,12 +14,10 @@ import { captureError } from "@/lib/sentry/capture-error";
import { useAssistantFeatureFlagStore } from "@/stores/assistant-feature-flag-store";
import {
getDefaultModelForProvider,
- getModelsForProvider,
} from "@/assistant/llm-model-catalog";
import {
type CallSiteOverrideDraft,
- INFERENCE_PROVIDER_DISPLAY_NAMES,
INFERENCE_PROVIDERS,
} from "@/domains/settings/ai/ai-types";
import {
@@ -34,12 +30,8 @@ import {
useDaemonConfigQuery,
useDaemonConfigMutation,
} from "@/domains/settings/ai/use-daemon-config";
-
-// ---------------------------------------------------------------------------
-// Sentinel value for the "Custom" profile picker option
-// ---------------------------------------------------------------------------
-
-const CUSTOM_SENTINEL = "__custom__";
+import { CUSTOM_SENTINEL, isDraftActive, draftsEqual } from "@/domains/settings/ai/call-site-helpers";
+import { CallSiteOverrideRow } from "@/domains/settings/ai/call-site-overrides-row";
// ---------------------------------------------------------------------------
// Types
@@ -55,30 +47,6 @@ export interface CallSiteOverridesModalProps {
assistantId: string;
}
-// ---------------------------------------------------------------------------
-// Helpers
-// ---------------------------------------------------------------------------
-
-export function isDraftActive(d: CallSiteOverrideDraft | null | undefined): boolean {
- if (!d) return false;
- return !!(d.profile || d.provider || d.model);
-}
-
-export function draftsEqual(
- a: CallSiteOverrideDraft | null | undefined,
- b: CallSiteOverrideDraft | null | undefined,
-): boolean {
- const aActive = isDraftActive(a);
- const bActive = isDraftActive(b);
- if (aActive !== bActive) return false;
- if (!aActive) return true;
- return (
- (a?.profile ?? null) === (b?.profile ?? null) &&
- (a?.provider ?? null) === (b?.provider ?? null) &&
- (a?.model ?? null) === (b?.model ?? null)
- );
-}
-
// ---------------------------------------------------------------------------
// CallSiteOverridesModal
// ---------------------------------------------------------------------------
@@ -192,8 +160,6 @@ function CallSiteOverridesModalInner({
// Derived state
// ---------------------------------------------------------------------------
- const availableProviders = INFERENCE_PROVIDERS;
-
const gatedCallSiteIdSet = useMemo(
() => new Set(catalogCallSiteIds),
[catalogCallSiteIds],
@@ -281,75 +247,41 @@ function CallSiteOverridesModalInner({
}, [catalog, filteredCallSites]);
// ---------------------------------------------------------------------------
- // Row helpers
+ // Row callbacks
// ---------------------------------------------------------------------------
- function getDraft(id: string): CallSiteOverrideDraft | null {
- return drafts[id] ?? null;
- }
-
- function isOverrideOn(id: string): boolean {
- return isDraftActive(getDraft(id));
- }
-
- function getProfilePickerValue(id: string): string {
- const d = getDraft(id);
- if (!d || !isDraftActive(d)) return "";
- if (d.provider || d.model) return CUSTOM_SENTINEL;
- return d.profile ?? "";
- }
-
- function handleToggle(id: string, on: boolean, defaultProfile?: string) {
- if (!on) {
- setDraftEdits((prev) => ({ ...prev, [id]: null }));
- return;
- }
- const seedProfile = selectSeedProfileForOverride(
- orderedProfiles,
- defaultProfile,
- queryComplexityRoutingEnabled,
- );
- if (seedProfile) {
- setDraftEdits((prev) => ({ ...prev, [id]: { profile: seedProfile } }));
- } else {
- const defaultProvider = availableProviders[0];
- const defaultModel = getDefaultModelForProvider(defaultProvider) ?? "";
- setDraftEdits((prev) => ({
- ...prev,
- [id]: { provider: defaultProvider, model: defaultModel },
- }));
- }
- }
-
- function handleProfilePickerChange(id: string, val: string) {
- if (val === CUSTOM_SENTINEL) {
- const defaultProvider = availableProviders[0];
- const defaultModel = getDefaultModelForProvider(defaultProvider) ?? "";
- setDraftEdits((prev) => ({
- ...prev,
- [id]: { profile: null, provider: defaultProvider, model: defaultModel },
- }));
- } else if (val === "") {
- setDraftEdits((prev) => ({ ...prev, [id]: null }));
- } else {
- setDraftEdits((prev) => ({
- ...prev,
- [id]: { profile: val, provider: null, model: null },
- }));
- }
- }
-
- function handleProviderChange(id: string, provider: string) {
- const defaultModel = getDefaultModelForProvider(provider) ?? "";
- setDraftEdits((prev) => ({
- ...prev,
- [id]: { ...(prev[id] ?? drafts[id]), profile: null, provider, model: defaultModel },
- }));
- }
+ const handleDraftChange = useCallback(
+ (id: string, draft: CallSiteOverrideDraft | null) => {
+ setDraftEdits((prev) => ({ ...prev, [id]: draft }));
+ },
+ [],
+ );
- function handleModelChange(id: string, model: string) {
- setDraftEdits((prev) => ({ ...prev, [id]: { ...(prev[id] ?? drafts[id]), model } }));
- }
+ const handleToggle = useCallback(
+ (id: string, on: boolean) => {
+ if (!on) {
+ setDraftEdits((prev) => ({ ...prev, [id]: null }));
+ return;
+ }
+ const cs = gatedCallSites.find((c) => c.id === id);
+ const seedProfile = selectSeedProfileForOverride(
+ orderedProfiles,
+ cs?.defaultProfile,
+ queryComplexityRoutingEnabled,
+ );
+ if (seedProfile) {
+ setDraftEdits((prev) => ({ ...prev, [id]: { profile: seedProfile } }));
+ } else {
+ const defaultProvider = INFERENCE_PROVIDERS[0];
+ const defaultModel = getDefaultModelForProvider(defaultProvider) ?? "";
+ setDraftEdits((prev) => ({
+ ...prev,
+ [id]: { provider: defaultProvider, model: defaultModel },
+ }));
+ }
+ },
+ [gatedCallSites, orderedProfiles, queryComplexityRoutingEnabled],
+ );
// ---------------------------------------------------------------------------
// Save / Reset
@@ -471,25 +403,12 @@ function CallSiteOverridesModalInner({
{sites.map((cs) => {
- const overrideOn = isOverrideOn(cs.id);
- const profileVal = getProfilePickerValue(cs.id);
- const isCustom = profileVal === CUSTOM_SENTINEL;
- const draft = getDraft(cs.id);
- const currentProvider =
- draft?.provider ?? availableProviders[0];
- const availableModels = getModelsForProvider(
- currentProvider ?? "anthropic",
- );
- const modelOptions = availableModels.map((m) => ({
- value: m.id,
- label: m.displayName,
- }));
- const hasModelError = !!draft?.provider && !draft?.model;
- const profileOptions = buildProfileOptionsForRow(
- profileVal === "" || profileVal === CUSTOM_SENTINEL
- ? null
- : profileVal,
- );
+ const profileVal = (() => {
+ const d = drafts[cs.id] ?? null;
+ if (!d || !isDraftActive(d)) return "";
+ if (d.provider || d.model) return CUSTOM_SENTINEL;
+ return d.profile ?? "";
+ })();
const defaultProfileLabel = cs.defaultProfile
? (orderedProfiles.find(
(op) => op.name === cs.defaultProfile,
@@ -497,90 +416,21 @@ function CallSiteOverridesModalInner({
: null;
return (
-
-
-
- {/* typography: off-scale — call-site name uses medium weight for visual hierarchy within card */}
-
- {cs.displayName}
-
- {cs.description && (
-
- {cs.description}
- {defaultProfileLabel && (
-
- · Default: {defaultProfileLabel}
-
- )}
-
- )}
-
-
- {overrideOn && (
-
- handleProfilePickerChange(cs.id, val)
- }
- options={profileOptions}
- className="w-36"
- />
- )}
-
- handleToggle(cs.id, on, cs.defaultProfile)
- }
- aria-label={`Override ${cs.displayName}`}
- />
-
-
-
- {/* Custom provider + model pickers */}
- {overrideOn && isCustom && (
-
-
-
-
-
- handleProviderChange(cs.id, val)
- }
- options={availableProviders.map((p) => ({
- value: p,
- label:
- INFERENCE_PROVIDER_DISPLAY_NAMES[p] ??
- p,
- }))}
- />
-
-
-
-
- handleModelChange(cs.id, val)
- }
- options={modelOptions}
- />
-
-
- {hasModelError && (
-
- Pick a model
-
- )}
-
+ id={cs.id}
+ displayName={cs.displayName}
+ description={cs.description}
+ defaultProfileLabel={defaultProfileLabel}
+ draft={drafts[cs.id] ?? null}
+ profileOptions={buildProfileOptionsForRow(
+ profileVal === "" || profileVal === CUSTOM_SENTINEL
+ ? null
+ : profileVal,
)}
-
+ onDraftChange={handleDraftChange}
+ onToggle={handleToggle}
+ />
);
})}
diff --git a/apps/web/src/domains/settings/ai/call-site-overrides-row.tsx b/apps/web/src/domains/settings/ai/call-site-overrides-row.tsx
new file mode 100644
index 00000000000..37317b32a54
--- /dev/null
+++ b/apps/web/src/domains/settings/ai/call-site-overrides-row.tsx
@@ -0,0 +1,160 @@
+import { Dropdown } from "@vellum/design-library/components/dropdown";
+import { Toggle } from "@vellum/design-library/components/toggle";
+
+import type { CallSiteOverrideDraft } from "@/domains/settings/ai/ai-types";
+import {
+ INFERENCE_PROVIDERS,
+ INFERENCE_PROVIDER_DISPLAY_NAMES,
+} from "@/domains/settings/ai/ai-types";
+import {
+ getDefaultModelForProvider,
+ getModelsForProvider,
+} from "@/assistant/llm-model-catalog";
+import { CUSTOM_SENTINEL, isDraftActive } from "@/domains/settings/ai/call-site-helpers";
+
+// ---------------------------------------------------------------------------
+// Types
+// ---------------------------------------------------------------------------
+
+interface ProfileOption {
+ value: string;
+ label: string;
+}
+
+export interface CallSiteOverrideRowProps {
+ id: string;
+ displayName: string;
+ description?: string;
+ defaultProfileLabel: string | null;
+ draft: CallSiteOverrideDraft | null;
+ profileOptions: ProfileOption[];
+ onDraftChange: (id: string, draft: CallSiteOverrideDraft | null) => void;
+ onToggle: (id: string, on: boolean) => void;
+}
+
+// ---------------------------------------------------------------------------
+// CallSiteOverrideRow
+// ---------------------------------------------------------------------------
+
+export function CallSiteOverrideRow({
+ id,
+ displayName,
+ description,
+ defaultProfileLabel,
+ draft,
+ profileOptions,
+ onDraftChange,
+ onToggle,
+}: CallSiteOverrideRowProps) {
+ const overrideOn = isDraftActive(draft);
+
+ const profileVal = (() => {
+ if (!draft || !overrideOn) return "";
+ if (draft.provider || draft.model) return CUSTOM_SENTINEL;
+ return draft.profile ?? "";
+ })();
+
+ const isCustom = profileVal === CUSTOM_SENTINEL;
+ const currentProvider = draft?.provider ?? INFERENCE_PROVIDERS[0];
+ const availableModels = getModelsForProvider(currentProvider ?? "anthropic");
+ const modelOptions = availableModels.map((m) => ({
+ value: m.id,
+ label: m.displayName,
+ }));
+ const hasModelError = !!draft?.provider && !draft?.model;
+
+ function handleProfilePickerChange(val: string) {
+ if (val === CUSTOM_SENTINEL) {
+ const defaultProvider = INFERENCE_PROVIDERS[0];
+ const defaultModel = getDefaultModelForProvider(defaultProvider) ?? "";
+ onDraftChange(id, { profile: null, provider: defaultProvider, model: defaultModel });
+ } else if (val === "") {
+ onDraftChange(id, null);
+ } else {
+ onDraftChange(id, { profile: val, provider: null, model: null });
+ }
+ }
+
+ function handleProviderChange(provider: string) {
+ const defaultModel = getDefaultModelForProvider(provider) ?? "";
+ onDraftChange(id, { ...(draft ?? {}), profile: null, provider, model: defaultModel });
+ }
+
+ function handleModelChange(model: string) {
+ onDraftChange(id, { ...(draft ?? {}), model });
+ }
+
+ return (
+
+
+
+ {/* typography: off-scale — call-site name uses medium weight for visual hierarchy within card */}
+
+ {displayName}
+
+ {description && (
+
+ {description}
+ {defaultProfileLabel && (
+
+ · Default: {defaultProfileLabel}
+
+ )}
+
+ )}
+
+
+ {overrideOn && (
+
+ )}
+ onToggle(id, on)}
+ aria-label={`Override ${displayName}`}
+ />
+
+
+
+ {/* Custom provider + model pickers */}
+ {overrideOn && isCustom && (
+
+
+
+
+ ({
+ value: p,
+ label: INFERENCE_PROVIDER_DISPLAY_NAMES[p] ?? p,
+ }))}
+ />
+
+
+
+
+
+
+ {hasModelError && (
+
+ Pick a model
+
+ )}
+
+ )}
+
+ );
+}
diff --git a/apps/web/src/domains/settings/ai/email-managed-content.tsx b/apps/web/src/domains/settings/ai/email-managed-content.tsx
index 8ded7461d2a..695544ceb69 100644
--- a/apps/web/src/domains/settings/ai/email-managed-content.tsx
+++ b/apps/web/src/domains/settings/ai/email-managed-content.tsx
@@ -325,7 +325,7 @@ export function EmailManagedContent({
return (
{subscriptionWarning}
-