diff --git a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx
index e35fd788759..4646f075b1d 100644
--- a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx
@@ -2,7 +2,7 @@ import { cloneElement, type MouseEventHandler, type ReactElement, type ReactNode
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { render, screen, act } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
-import { toSiTerminology } from "@/lib/terminology";
+import { TerminologyProvider, useTerminology } from "@/contexts/TerminologyContext";
import CreatedKeyDisplay, { buildAgentInstructions } from "./CreatedKeyDisplay";
import { toast } from "@/lib/toast";
@@ -13,6 +13,10 @@ vi.mock("@/components/networking", () => ({
getProxyBaseUrl: vi.fn(() => "http://gw.test:4000/"),
}));
+vi.mock("@/app/(dashboard)/hooks/uiConfig/useUIConfig", () => ({
+ useUIConfig: () => ({ data: { use_si_terminology: true } }),
+}));
+
vi.mock("react-copy-to-clipboard", () => ({
CopyToClipboard: ({
text,
@@ -159,6 +163,23 @@ describe("CreatedKeyDisplay", () => {
expect(screen.getByRole("button", { name: "Copied!" })).toBeInTheDocument();
expect(toast.success).toHaveBeenCalledWith("Instructions copied");
});
+
+ it("copies agent instructions in AI wording even when the UI uses SI terminology", async () => {
+ const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
+ const GatewayLabel = () => {useTerminology()("AI Gateway")};
+ render(
+
+
+
+ ,
+ );
+
+ expect(screen.getByText("SI Gateway")).toBeInTheDocument();
+ await user.click(screen.getByRole("button", { name: "Copy instructions" }));
+
+ expect(mockCopy).toHaveBeenLastCalledWith(buildAgentInstructions("http://gw.test:4000", "sk-test-123"));
+ expect(mockCopy.mock.calls.at(-1)?.[0]).toContain("Use this LiteLLM AI gateway for model inference.");
+ });
});
describe("buildAgentInstructions", () => {
@@ -183,11 +204,4 @@ describe("buildAgentInstructions", () => {
].join("\n"),
);
});
-
- it("rewrites only its own copy under SI terminology, never the gateway URL or the key", () => {
- const lines = buildAgentInstructions("http://AI.example.com/", "sk-AI-1", toSiTerminology).split("\n");
- expect(lines[0]).toBe("Use this LiteLLM SI gateway for model inference.");
- expect(lines).toContain("Gateway URL: http://AI.example.com");
- expect(lines).toContain("Virtual key: sk-AI-1");
- });
});
diff --git a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx
index e483d2546bb..d58a1864575 100644
--- a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx
+++ b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx
@@ -1,5 +1,3 @@
-import { useTerminology } from "@/contexts/TerminologyContext";
-import { keepTerminology, type Term } from "@/lib/terminology";
import React, { useState } from "react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { ChevronDown, ChevronUp } from "lucide-react";
@@ -13,14 +11,14 @@ interface CreatedKeyDisplayProps {
apiKey: string;
}
-export const buildAgentInstructions = (baseUrl: string, apiKey: string, term: Term = keepTerminology): string => {
+export const buildAgentInstructions = (baseUrl: string, apiKey: string): string => {
const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
const endpointIntroduction =
"LiteLLM is a gateway that exposes OpenAI and Anthropic compatible APIs. " +
`Send the virtual key as a Bearer token (Authorization: Bearer ${apiKey}) to:`;
return [
- term("Use this LiteLLM AI gateway for model inference."),
+ "Use this LiteLLM AI gateway for model inference.",
"",
`Gateway URL: ${normalizedBaseUrl}`,
`Virtual key: ${apiKey}`,
@@ -43,12 +41,11 @@ export const buildAgentInstructions = (baseUrl: string, apiKey: string, term: Te
* Used on the Virtual Keys page and in the Add Agent wizard.
*/
const CreatedKeyDisplay: React.FC = ({ apiKey }) => {
- const term = useTerminology();
const [copied, setCopied] = useState(false);
const [instructionsCopied, setInstructionsCopied] = useState(false);
const [showInstructions, setShowInstructions] = useState(false);
const baseUrl = getProxyBaseUrl().replace(/\/+$/, "");
- const instructions = buildAgentInstructions(baseUrl, apiKey, term);
+ const instructions = buildAgentInstructions(baseUrl, apiKey);
const handleCopy = () => {
setCopied(true);
diff --git a/ui/litellm-dashboard/src/lib/terminology.test.ts b/ui/litellm-dashboard/src/lib/terminology.test.ts
index 9e5d6af036e..7fa24cb4f83 100644
--- a/ui/litellm-dashboard/src/lib/terminology.test.ts
+++ b/ui/litellm-dashboard/src/lib/terminology.test.ts
@@ -39,6 +39,8 @@ describe("toSiTerminology", () => {
["Cisco AI Defense Inspection API for AI apps", "Cisco AI Defense Inspection API for SI apps"],
["DeepKeep AI Firewall for AI security", "DeepKeep AI Firewall for SI security"],
["Defend AI Agentic Guardrails", "Defend AI Agentic Guardrails"],
+ ["CyCraft XecGuard AI security gateway for AI apps", "CyCraft XecGuard AI security gateway for SI apps"],
+ ["Airia AI security platform for responsible AI", "Airia AI security platform for responsible SI"],
])("keeps third-party names inside %j", (input, expected) => {
expect(toSiTerminology(input)).toBe(expected);
});
diff --git a/ui/litellm-dashboard/src/lib/terminology.ts b/ui/litellm-dashboard/src/lib/terminology.ts
index 0f18ae95fa9..e056ae59f55 100644
--- a/ui/litellm-dashboard/src/lib/terminology.ts
+++ b/ui/litellm-dashboard/src/lib/terminology.ts
@@ -9,6 +9,8 @@ const THIRD_PARTY_NAMES: readonly string[] = [
"DeepKeep AI Firewall",
"Defend AI",
"Prisma AI Runtime Security",
+ "XecGuard AI",
+ "Airia AI",
];
const THIRD_PARTY_NAME_PATTERN = new RegExp(`(${THIRD_PARTY_NAMES.join("|")})`);