- {parameters.map((param) => (
+ {nonEnrichmentParams.map((param) => (
{param.label}
@@ -100,25 +238,168 @@ const TemplateParameterModal: React.FC = ({
))}
- {template?.llm_enrichment && (
-
-
- This template uses AI to automatically discover your competitors and configure
- guardrails. An onboarded LLM will be called to identify competitor names.
-
-
+ {hasEnrichment && (
+ <>
+
+
+ Competitor Discovery
+
+
setCompetitorMode(e.target.value)}
+ className="w-full"
+ >
+
+
+ ✨ Use AI
+
+
+ Enter Manually
+
+
+
+
+
+ {/* Brand Name */}
+
+
+ Your Brand Name
+ *
+
+
+ setParameterValues((prev) => ({
+ ...prev,
+ [enrichmentParam || "brand_name"]: e.target.value,
+ }))
+ }
+ />
+
+
+ {competitorMode === "ai" && (
+ <>
+
+
+ Select Model
+ *
+
+ setSelectedModel(value)}
+ loading={isLoadingModels}
+ showSearch
+ className="w-full"
+ options={availableModels.map((m) => ({ label: m, value: m }))}
+ filterOption={(input, option) =>
+ (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
+ }
+ />
+
+
+
+ {isGenerating ? "✨ Generating names..." : "✨ Generate Competitor Names"}
+
+ >
+ )}
+
+ {/* Competitor Tags */}
+
+
+ Competitor Names
+ {competitorTags.length > 0 && (
+
+ ({competitorTags.length})
+
+ )}
+
+
setCompetitorTags(values)}
+ tokenSeparators={[","]}
+ open={false}
+ suffixIcon={null}
+ />
+
+ Type a name and press Enter to add. Click ✕ to remove.
+
+ {statusMessage && (
+
+
+ {statusMessage}
+
+ )}
+ {Object.keys(variationsMap).length > 0 && !statusMessage && (
+
+ ✓ {Object.values(variationsMap).flat().length} alternate spellings & variations auto-generated for guardrail matching
+
+ )}
+
+
+ {/* Refinement input — shown after initial generation in AI mode */}
+ {competitorMode === "ai" && hasGenerated && competitorTags.length > 0 && (
+
+
+ Refine List
+
+
+ setRefinementInput(e.target.value)}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" && refinementInput.trim() && !isRefining) {
+ handleRefine();
+ }
+ }}
+ disabled={isRefining}
+ />
+
+ {isRefining ? "..." : "Send"}
+
+
+
+ Give instructions to add, remove, or change competitors. Press Enter to send.
+
+
+ )}
+ >
)}
- {isLoading && (
-
-
-
- {template?.llm_enrichment
- ? "Using AI to discover competitors..."
- : "Processing template..."}
-
-
- )}
+ {!hasEnrichment &&
+ parameters.map((param) => (
+
+
+ {param.label}
+ {param.required && * }
+
+
+ setParameterValues((prev) => ({
+ ...prev,
+ [param.name]: e.target.value,
+ }))
+ }
+ />
+
+ ))}
);
diff --git a/ui/litellm-dashboard/src/components/query_param_input.tsx b/ui/litellm-dashboard/src/components/query_param_input.tsx
new file mode 100644
index 00000000000..4a98ab48bca
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/query_param_input.tsx
@@ -0,0 +1,57 @@
+import React, { useState } from "react";
+import { Button, Space } from "antd";
+import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
+import { TextInput } from "@tremor/react";
+
+interface QueryParamInputProps {
+ value?: Record