first commit
This commit is contained in:
195
ui/lib/config/celFieldsRouting.ts
Normal file
195
ui/lib/config/celFieldsRouting.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* CEL Fields Configuration for Routing Rules
|
||||
* Defines available fields for building routing rule expressions
|
||||
*/
|
||||
|
||||
import { getProviderLabel } from "@/lib/constants/logs";
|
||||
|
||||
export interface CELFieldDefinition {
|
||||
name: string;
|
||||
label: string;
|
||||
placeholder?: string;
|
||||
inputType?: "text" | "select" | "keyValue" | "number";
|
||||
valueEditorType?:
|
||||
| "text"
|
||||
| "select"
|
||||
| "keyValue"
|
||||
| "number"
|
||||
| "textarea"
|
||||
| "budgetNumber"
|
||||
| ((operator: string) => "text" | "select" | "keyValue" | "number" | "textarea" | "budgetNumber");
|
||||
operators?: string[];
|
||||
defaultOperator?: string;
|
||||
defaultValue?: any;
|
||||
values?: Array<{ name: string; label: string; disabled?: boolean }>;
|
||||
metricOptions?: Array<{ name: string; label: string }>; // For budgetNumber type
|
||||
description?: string; // Helpful note for the user
|
||||
}
|
||||
|
||||
export const baseRoutingFields: CELFieldDefinition[] = [
|
||||
{
|
||||
name: "model",
|
||||
label: "Model",
|
||||
placeholder: "e.g., gpt-4, claude-3-sonnet",
|
||||
inputType: "text",
|
||||
valueEditorType: (operator: string) =>
|
||||
operator === "=" || operator === "!=" ? "select" : operator === "in" || operator === "notIn" ? "select" : "text",
|
||||
operators: ["=", "!=", "in", "notIn", "contains", "beginsWith", "endsWith", "matches"],
|
||||
defaultOperator: "=",
|
||||
},
|
||||
{
|
||||
name: "provider",
|
||||
label: "Provider",
|
||||
placeholder: "Select provider",
|
||||
inputType: "select",
|
||||
valueEditorType: (operator: string) =>
|
||||
operator === "matches" ? "text" : operator === "in" || operator === "notIn" ? "select" : "select",
|
||||
operators: ["=", "!=", "in", "notIn", "matches", "null", "notNull"],
|
||||
defaultOperator: "=",
|
||||
},
|
||||
{
|
||||
name: "request_type",
|
||||
label: "Request Type",
|
||||
placeholder: "Select request type",
|
||||
inputType: "select",
|
||||
valueEditorType: (operator: string) =>
|
||||
operator === "matches" ? "text" : operator === "in" || operator === "notIn" ? "select" : "select",
|
||||
operators: ["=", "!=", "in", "notIn", "matches"],
|
||||
defaultOperator: "=",
|
||||
values: [
|
||||
{ name: "text_completion", label: "Text Completion" },
|
||||
{ name: "chat_completion", label: "Chat Completion" },
|
||||
{ name: "responses", label: "Responses" },
|
||||
{ name: "embedding", label: "Embeddings" },
|
||||
{ name: "image_generation", label: "Image Generation" },
|
||||
{ name: "image_edit", label: "Image Edit" },
|
||||
{ name: "image_variation", label: "Image Variation" },
|
||||
{ name: "speech", label: "Speech" },
|
||||
{ name: "transcription", label: "Transcription" },
|
||||
{ name: "count_tokens", label: "Count Tokens" },
|
||||
{ name: "rerank", label: "Rerank" },
|
||||
{ name: "video_generation", label: "Video Generation" },
|
||||
],
|
||||
description: "Filter rules by the type of API request (chat, text, embeddings, images, audio, etc.)",
|
||||
},
|
||||
{
|
||||
name: "headers",
|
||||
label: "Header",
|
||||
placeholder: "e.g., authorization, x-custom-header (use lowercase)",
|
||||
inputType: "keyValue",
|
||||
valueEditorType: "keyValue",
|
||||
operators: ["=", "!=", "contains", "beginsWith", "endsWith", "matches", "null", "notNull"],
|
||||
defaultOperator: "=",
|
||||
},
|
||||
{
|
||||
name: "tokens_used",
|
||||
label: "Tokens Used (%)",
|
||||
placeholder: "e.g., 80",
|
||||
inputType: "text",
|
||||
valueEditorType: "number",
|
||||
operators: ["=", "!=", ">", "<", ">=", "<="],
|
||||
defaultOperator: ">=",
|
||||
description: "Check token usage as percentage. Checked against max of model and provider configs.",
|
||||
},
|
||||
{
|
||||
name: "request",
|
||||
label: "Request (%)",
|
||||
placeholder: "e.g., 80",
|
||||
inputType: "text",
|
||||
valueEditorType: "number",
|
||||
operators: ["=", "!=", ">", "<", ">=", "<="],
|
||||
defaultOperator: ">=",
|
||||
description: "Check request usage as percentage. Checked against max of model and provider configs.",
|
||||
},
|
||||
{
|
||||
name: "budget_used",
|
||||
label: "Budget Used (%)",
|
||||
placeholder: "e.g., 50",
|
||||
inputType: "text",
|
||||
valueEditorType: "number",
|
||||
operators: ["=", "!=", ">", "<", ">=", "<="],
|
||||
defaultOperator: ">=",
|
||||
description: "Check budget usage as percentage. Checked against max of model and provider configs.",
|
||||
},
|
||||
{
|
||||
name: "params",
|
||||
label: "Query Parameter",
|
||||
placeholder: "e.g., api_key, user_id",
|
||||
inputType: "keyValue",
|
||||
valueEditorType: "keyValue",
|
||||
operators: ["=", "!=", "contains", "beginsWith", "endsWith", "matches", "null", "notNull"],
|
||||
defaultOperator: "=",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Get routing fields with dynamic providers and models
|
||||
* Provider field values are populated dynamically from available providers
|
||||
* Metric options for rate limits and budget are populated from available providers and models
|
||||
*/
|
||||
export function getRoutingFields(providers: string[] = [], models: string[] = []): CELFieldDefinition[] {
|
||||
// Create provider field values
|
||||
const providerValues =
|
||||
providers.length > 0
|
||||
? providers.map((provider) => ({
|
||||
name: provider,
|
||||
label: getProviderLabel(provider),
|
||||
}))
|
||||
: [{ name: "_no_providers", label: "No providers configured", disabled: true }];
|
||||
|
||||
// Create model field values
|
||||
const modelValues =
|
||||
models.length > 0
|
||||
? models.map((model) => ({
|
||||
name: model,
|
||||
label: model,
|
||||
}))
|
||||
: [];
|
||||
|
||||
// Create metric options for scope input: providers + models
|
||||
const scopeOptions = [
|
||||
{ name: "", label: "(provider-level)" }, // Empty scope for provider-level
|
||||
...providers.map((provider) => ({
|
||||
name: provider,
|
||||
label: `${provider} (provider)`,
|
||||
})),
|
||||
...models.map((model) => ({
|
||||
name: model,
|
||||
label: `${model} (model)`,
|
||||
})),
|
||||
];
|
||||
|
||||
// Update provider field with dynamic values and rate limit/budget fields with scope options
|
||||
const fieldsWithDynamicValues = baseRoutingFields.map((field) => {
|
||||
if (field.name === "provider") {
|
||||
return {
|
||||
...field,
|
||||
values: providerValues,
|
||||
};
|
||||
}
|
||||
if (field.name === "model") {
|
||||
return {
|
||||
...field,
|
||||
values: modelValues,
|
||||
};
|
||||
}
|
||||
if (field.name === "tokens_used" || field.name === "request" || field.name === "budget_used") {
|
||||
return {
|
||||
...field,
|
||||
metricOptions: scopeOptions,
|
||||
};
|
||||
}
|
||||
return field;
|
||||
});
|
||||
|
||||
return fieldsWithDynamicValues;
|
||||
}
|
||||
|
||||
export const PROVIDER_DISPLAY_NAMES: Record<string, string> = {
|
||||
openai: "OpenAI",
|
||||
anthropic: "Anthropic",
|
||||
azure: "Azure OpenAI",
|
||||
gemini: "Google Gemini",
|
||||
vertex: "Vertex AI",
|
||||
cohere: "Cohere",
|
||||
};
|
||||
Reference in New Issue
Block a user