mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-12 03:48:56 +00:00
refactor(ui): share the Decisions error count helper and cover the cURL preview
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
1e8a6ade2a
commit
5de7e70a6d
5 changed files with 34 additions and 6 deletions
|
|
@ -0,0 +1,26 @@
|
|||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import CurlPreview from "./CurlPreview";
|
||||
|
||||
const input = {
|
||||
baseUrl: "http://localhost:4000",
|
||||
endpoint: "/v1/systemone" as const,
|
||||
payload: JSON.stringify({ model: "jev-latest", state: "ok" }),
|
||||
authHeaderName: "Authorization",
|
||||
};
|
||||
|
||||
describe("CurlPreview", () => {
|
||||
it("shows the command and a copy button for a valid payload", () => {
|
||||
render(<CurlPreview {...input} />);
|
||||
expect(screen.getByLabelText("cURL request")).toHaveTextContent("http://localhost:4000/v1/systemone");
|
||||
expect(screen.getByRole("button", { name: /copy curl/i })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("hides the copy button and points back to the form while the payload has errors", () => {
|
||||
render(<CurlPreview {...input} errorCount={2} />);
|
||||
expect(screen.getByRole("alert")).toHaveTextContent("Fix 2 issues on the Form tab");
|
||||
expect(screen.getByLabelText("cURL request")).toHaveTextContent("jev-latest");
|
||||
expect(screen.queryByRole("button", { name: /copy curl/i })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
@ -7,13 +7,12 @@ interface CurlPreviewProps extends CurlCommandInput {
|
|||
|
||||
export default function CurlPreview({ errorCount = 0, ...input }: CurlPreviewProps) {
|
||||
const command = buildCurlCommand(input);
|
||||
const invalid = errorCount > 0;
|
||||
return (
|
||||
<div className="flex min-h-0 flex-1 flex-col rounded-md border">
|
||||
<div className="flex items-center justify-between gap-2 border-b px-3 py-2 text-sm">
|
||||
<span className="font-medium">cURL request</span>
|
||||
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
||||
{invalid ? (
|
||||
{errorCount > 0 ? (
|
||||
<span role="alert" className="text-destructive">
|
||||
Fix {errorCount} {errorCount === 1 ? "issue" : "issues"} on the Form tab before copying
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import CurlPreview from "./CurlPreview";
|
|||
import ResponseView from "./ResponseView";
|
||||
import SystemOneForm from "./SystemOneForm";
|
||||
import OpenAIDecisionsForm from "./OpenAIDecisionsForm";
|
||||
import { validateSystemOnePayload, validateOpenAIDecisionsPayload } from "./lib/validatePayload";
|
||||
import { validateSystemOnePayload, validateOpenAIDecisionsPayload, errorCount } from "./lib/validatePayload";
|
||||
import { useDecisionModels, type ApiKeySource } from "./useDecisionModels";
|
||||
|
||||
interface SystemOneUIProps {
|
||||
|
|
@ -281,7 +281,7 @@ export default function SystemOneUI({ accessToken, disabledPersonalKeyCreation =
|
|||
endpoint={endpoint}
|
||||
payload={validation.payload === undefined ? rawPayload : JSON.stringify(validation.payload)}
|
||||
authHeaderName={getGlobalLitellmHeaderName()}
|
||||
errorCount={validation.issues.filter((issue) => issue.severity === "error").length}
|
||||
errorCount={errorCount(validation)}
|
||||
/>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { Badge } from "@/components/ui/badge";
|
||||
import { CircleAlert, CircleCheck, TriangleAlert } from "lucide-react";
|
||||
import type { PayloadValidation } from "./lib/validatePayload";
|
||||
import { errorCount as countErrors, type PayloadValidation } from "./lib/validatePayload";
|
||||
|
||||
export function ValidationStatus({ validation }: { validation: PayloadValidation<unknown> }) {
|
||||
const errorCount = validation.issues.filter((issue) => issue.severity === "error").length;
|
||||
const errorCount = countErrors(validation);
|
||||
if (errorCount > 0) {
|
||||
return (
|
||||
<Badge variant="destructive">
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ export interface PayloadValidation<T> {
|
|||
|
||||
export type SystemOnePayloadValidation = PayloadValidation<PlaygroundRequest>;
|
||||
|
||||
export const errorCount = (validation: PayloadValidation<unknown>): number =>
|
||||
validation.issues.filter((issue) => issue.severity === "error").length;
|
||||
|
||||
const invalid = (path: string, message: string) => ({
|
||||
isValid: false,
|
||||
issues: [{ path, message, severity: "error" as const }],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue