Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 167 additions & 51 deletions ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
useGetProvidersQuery,
useGetVirtualKeysQuery,
} from "@/lib/store";
import { useGetAllKeysQuery } from "@/lib/store/apis/providersApi";
import { ProviderIconType, RenderProviderIcon } from "@/lib/constants/icons";
import { getProviderLabel } from "@/lib/constants/logs";
import { PricingOverride, PricingOverrideScopeKind } from "@/lib/types/governance";
Expand Down Expand Up @@ -150,6 +151,7 @@ export default function ScopedPricingOverridesView() {
}, [totalCount, offset]);
const { data: providersData } = useGetProvidersQuery();
const { data: virtualKeysData } = useGetVirtualKeysQuery();
const { data: allKeysData = [] } = useGetAllKeysQuery();
const [deleteOverride, { isLoading: isDeleting }] = useDeletePricingOverrideMutation();

useEffect(() => {
Expand All @@ -169,14 +171,12 @@ export default function ScopedPricingOverridesView() {
const providerMap = useMemo(() => new Map<string, string>(providers.map((provider) => [provider.name, provider.name])), [providers]);
const providerKeyOptions = useMemo(
() =>
providers.flatMap((provider) =>
(provider.keys || []).map((key) => ({
id: key.id,
label: key.name || key.id,
providerName: provider.name,
})),
),
[providers],
allKeysData.map((key) => ({
id: key.key_id,
label: key.name || key.key_id,
providerName: key.provider,
})),
[allKeysData],
);
const providerKeyProviderMap = useMemo(
() => new Map<string, string>(providerKeyOptions.map((key) => [key.id, key.providerName])),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export function AddCustomProviderSheetContent({ show = true, onClose, onSave }:
retry_backoff_initial: 500,
retry_backoff_max: 5000,
},
keys: [],
};

addProvider(payload)
Expand Down
8 changes: 4 additions & 4 deletions ui/app/workspace/providers/dialogs/addNewKeySheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ interface Props {
show: boolean;
onCancel: () => void;
provider: ModelProvider;
keyIndex: number;
keyId: string | null;
providerName?: string;
}

export default function AddNewKeySheet({ show, onCancel, provider, keyIndex, providerName }: Props) {
const isEditing = keyIndex < provider.keys.length;
export default function AddNewKeySheet({ show, onCancel, provider, keyId, providerName }: Props) {
const isEditing = keyId !== null;
const resolvedProviderName = (providerName ?? provider.name).toLowerCase();
const isVLLM = resolvedProviderName === "vllm";
const entityLabel = isVLLM ? "model" : "key";
Expand Down Expand Up @@ -47,7 +47,7 @@ export default function AddNewKeySheet({ show, onCancel, provider, keyIndex, pro
<div>
<ProviderKeyForm
provider={provider}
keyIndex={keyIndex}
keyId={keyId}
onCancel={onCancel}
onSave={() => {
toast.success(successMessage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useEffect, useMemo } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { buildProviderUpdatePayload } from "../views/utils";
import { AllowedRequestsFields } from "./allowedRequestsFields";

// Type for form data
Expand Down Expand Up @@ -66,15 +67,14 @@ export function ApiStructureFormFragment({ provider }: Props) {

const onSubmit = (data: FormCustomProviderConfig) => {
// Create updated provider configuration
updateProvider({
...provider,
updateProvider(buildProviderUpdatePayload(provider, {
custom_provider_config: {
base_provider_type: data.base_provider_type as unknown as BaseProvider,
is_key_less: data.is_key_less ?? false,
allowed_requests: data.allowed_requests,
request_path_overrides: cleanPathOverrides(data.request_path_overrides),
},
})
}))
.unwrap()
.then(() => {
toast.success("Provider configuration updated successfully");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm, type Resolver } from "react-hook-form";
import { toast } from "sonner";
import { buildProviderUpdatePayload } from "../views/utils";

interface DebuggingFormFragmentProps {
provider: ModelProvider;
Expand Down Expand Up @@ -45,12 +46,11 @@ export function DebuggingFormFragment({ provider }: DebuggingFormFragmentProps)
}, [form, provider.name, provider.send_back_raw_request, provider.send_back_raw_response, provider.store_raw_request_response]);

const onSubmit = (data: DebuggingFormSchema) => {
const updatedProvider: ModelProvider = {
...provider,
const updatedProvider = buildProviderUpdatePayload(provider, {
send_back_raw_request: data.send_back_raw_request,
send_back_raw_response: data.send_back_raw_response,
store_raw_request_response: data.store_raw_request_response,
};
});
updateProvider(updatedProvider)
.unwrap()
.then(() => {
Expand Down
6 changes: 3 additions & 3 deletions ui/app/workspace/providers/fragments/networkFormFragment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm, type Resolver } from "react-hook-form";
import { toast } from "sonner";
import { buildProviderUpdatePayload } from "../views/utils";

interface NetworkFormFragmentProps {
provider: ModelProvider;
Expand Down Expand Up @@ -98,8 +99,7 @@ export function NetworkFormFragment({ provider }: NetworkFormFragmentProps) {
return;
}
// Create updated provider configuration
const updatedProvider: ModelProvider = {
...provider,
const updatedProvider = buildProviderUpdatePayload(provider, {
network_config: {
...provider.network_config,
base_url: data.network_config?.base_url || undefined,
Expand All @@ -116,7 +116,7 @@ export function NetworkFormFragment({ provider }: NetworkFormFragmentProps) {
data.network_config?.max_conns_per_host ?? DefaultNetworkConfig.max_conns_per_host,
enforce_http2: data.network_config?.enforce_http2 ?? DefaultNetworkConfig.enforce_http2,
},
};
});
updateProvider(updatedProvider)
.unwrap()
.then(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm, type Resolver } from "react-hook-form";
import { toast } from "sonner";
import { buildProviderUpdatePayload } from "../views/utils";

interface PerformanceFormFragmentProps {
provider: ModelProvider;
Expand Down Expand Up @@ -51,13 +52,12 @@ export function PerformanceFormFragment({ provider }: PerformanceFormFragmentPro

const onSubmit = (data: PerformanceFormSchema) => {
// Create updated provider configuration (raw request/response are in Debugging tab)
const updatedProvider: ModelProvider = {
...provider,
const updatedProvider = buildProviderUpdatePayload(provider, {
concurrency_and_buffer_size: {
concurrency: data.concurrency_and_buffer_size.concurrency,
buffer_size: data.concurrency_and_buffer_size.buffer_size,
},
};
});
updateProvider(updatedProvider)
.unwrap()
.then(() => {
Expand Down
6 changes: 3 additions & 3 deletions ui/app/workspace/providers/fragments/proxyFormFragment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { buildProviderUpdatePayload } from "../views/utils";

interface ProxyFormFragmentProps {
provider: ModelProvider;
Expand Down Expand Up @@ -58,16 +59,15 @@ export function ProxyFormFragment({ provider }: ProxyFormFragmentProps) {
const watchedProxyType = form.watch("proxy_config.type");

const onSubmit = (data: ProxyOnlyFormSchema) => {
updateProvider({
...provider,
updateProvider(buildProviderUpdatePayload(provider, {
proxy_config: {
type: data.proxy_config?.type ?? "none",
url: data.proxy_config?.url || undefined,
username: data.proxy_config?.username || undefined,
password: data.proxy_config?.password || undefined,
ca_cert_pem: data.proxy_config?.ca_cert_pem || undefined,
},
})
}))
.unwrap()
.then(() => {
toast.success("Provider configuration updated successfully");
Expand Down
21 changes: 4 additions & 17 deletions ui/app/workspace/providers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export default function Providers() {
dispatch(
setSelectedProvider({
name: provider as ModelProviderName,
keys: [],

concurrency_and_buffer_size: DefaultPerformanceConfig,
network_config: DefaultNetworkConfig,
custom_provider_config: undefined,
Expand Down Expand Up @@ -123,7 +123,7 @@ export default function Providers() {

const handleSelectKnownProvider = async (name: string) => {
try {
await createProvider({ provider: name as ModelProviderName, keys: [] }).unwrap();
await createProvider({ provider: name as ModelProviderName }).unwrap();
setProvider(name);
} catch (err: any) {
if (err?.status === 409) {
Expand Down Expand Up @@ -320,33 +320,20 @@ function KeyDiscoveryFailedBadge({
provider,
}: {
provider: {
keys: Array<{ status?: string }>;
status?: string;
description?: string;
};
}) {
const hasFailedKeys = provider.keys?.some((key) => key.status === "list_models_failed");
const providerFailed = provider.status === "list_models_failed";
const hasFailed = hasFailedKeys || providerFailed;

if (!hasFailed) return null;

// Determine the tooltip message
let tooltipMessage = "";
if (providerFailed && hasFailedKeys) {
tooltipMessage = "Provider and one or more keys have failed model discovery.";
} else if (providerFailed) {
tooltipMessage = provider.description || "Provider model discovery failed.";
} else if (hasFailedKeys) {
tooltipMessage = "One or more keys have failed list models. Check keys for details.";
}
if (!providerFailed) return null;

return (
<Tooltip>
<TooltipTrigger>
<AlertCircle className="h-3 w-3" />
</TooltipTrigger>
<TooltipContent>{tooltipMessage}</TooltipContent>
<TooltipContent>{provider.description || "Provider model discovery failed."}</TooltipContent>
</Tooltip>
);
}
Loading