diff --git a/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx b/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx index cc34868938..822ef04a94 100644 --- a/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx +++ b/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx @@ -511,6 +511,7 @@ export default function RoutingTab() { const [jsonErrors, setJsonErrors] = useState>({}); const [showJsonEditor, setShowJsonEditor] = useState>({}); const [addOpKind, setAddOpKind] = useState>({}); + const [newProviderId, setNewProviderId] = useState(""); const [loading, setLoading] = useState(true); const [lkgpCacheLoading, setLkgpCacheLoading] = useState(false); const [lkgpCacheStatus, setLkgpCacheStatus] = useState({ type: "", message: "" }); @@ -664,6 +665,22 @@ export default function RoutingTab() { updateProviderTransforms(providerId, { enabled: current.enabled, pipeline }); }; + const BUILTIN_PROVIDERS = new Set([PROVIDER_CLAUDE, PROVIDER_CC_BRIDGE]); + + const addProvider = () => { + const id = newProviderId.trim(); + if (!id || systemTransforms.providers[id]) return; + updateProviderTransforms(id, { enabled: false, pipeline: [] }); + setNewProviderId(""); + }; + + const removeProvider = (providerId: string) => { + if (BUILTIN_PROVIDERS.has(providerId)) return; + const providers = systemTransforms.providers as Record; + const { [providerId]: _removed, ...rest } = providers; + updateSetting({ systemTransforms: { providers: rest } }); + }; + const toggleCliCompatProvider = (providerId: string, enabled: boolean) => { const normalizedProviderId = normalizeCliCompatProviderId(providerId); const nextProviders = new Set(cliCompatProviders); @@ -921,208 +938,257 @@ export default function RoutingTab() { })} + -
-

System-block transform pipeline

-

- Per-provider ordered pipeline. Add/edit ops via the form below, or import JSON for bulk - changes. All ops are idempotent on re-run. -

+ +
+
+ +
+
+

{t("systemTransforms")}

+

{t("systemTransformsDesc")}

+
+
-
- {Object.entries(systemTransforms.providers).map(([providerId, providerCfg]) => { - const display = PROVIDER_TILE_DISPLAY[providerId] ?? { - name: providerId, - description: "Custom provider.", - icon: "extension", - tone: "purple", - }; - const draft = jsonDrafts[providerId] ?? JSON.stringify(providerCfg, null, 2); - const errorMsg = jsonErrors[providerId] ?? null; - const opCount = Array.isArray(providerCfg.pipeline) ? providerCfg.pipeline.length : 0; - const hasDefault = Boolean( - (DEFAULT_SYSTEM_TRANSFORMS_CLIENT.providers as Record)[providerId] - ); - const isJsonOpen = showJsonEditor[providerId] ?? false; - const selectedKind = - (addOpKind[providerId] as TransformOpKind | undefined) ?? - "drop_paragraph_if_contains"; +
+ {Object.entries(systemTransforms.providers).map(([providerId, providerCfg]) => { + const isBuiltin = BUILTIN_PROVIDERS.has(providerId); + const display = PROVIDER_TILE_DISPLAY[providerId] ?? { + name: providerId, + description: "Custom provider.", + icon: "extension", + tone: "purple", + }; + const draft = jsonDrafts[providerId] ?? JSON.stringify(providerCfg, null, 2); + const errorMsg = jsonErrors[providerId] ?? null; + const opCount = Array.isArray(providerCfg.pipeline) ? providerCfg.pipeline.length : 0; + const hasDefault = Boolean( + (DEFAULT_SYSTEM_TRANSFORMS_CLIENT.providers as Record)[providerId] + ); + const isJsonOpen = showJsonEditor[providerId] ?? false; + const selectedKind = + (addOpKind[providerId] as TransformOpKind | undefined) ?? + "drop_paragraph_if_contains"; - return ( -
- {/* Provider header row */} -
-
-
- - {providerId} - - {display.name} -
-

{display.description}

-

- {opCount} op{opCount === 1 ? "" : "s"} -

+ return ( +
+ {/* Provider header row */} +
+
+
+ + {providerId} + + {display.name}
+

{display.description}

+

+ {opCount} op{opCount === 1 ? "" : "s"} +

+
+
toggleProviderEnabled(providerId, checked)} disabled={loading} ariaLabel={`Enable ${display.name} transforms`} /> -
- - {/* Pipeline op list with per-op editor */} - {opCount > 0 && ( -
    - {(providerCfg.pipeline as any[]).map((op, index) => ( -
  1. -
    - - {index + 1} - - {op?.kind} -
    - - - -
    -
    -
    - updateOp(providerId, index, next)} - /> -
    -
  2. - ))} -
- )} - - {/* Add op row */} -
-