diff --git a/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts index 1e44d9a25a0..d0f81eac7b3 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts @@ -41,8 +41,8 @@ test.describe("Proxy Admin - Keys", () => { // Submit await page.getByRole("button", { name: "Create Key", exact: true }).click(); - // Success shows "Save your Key" in a second dialog - await expect(page.getByText("Save your Key")).toBeVisible({ timeout: 10_000 }); + // Success shows "API Key Created" in a second dialog + await expect(page.getByText("API Key Created")).toBeVisible({ timeout: 10_000 }); await page.keyboard.press("Escape"); // Verify the new key appears in the table @@ -150,7 +150,7 @@ test.describe("Proxy Admin - Keys", () => { await page.getByRole("button", { name: "Create Key", exact: true }).click(); - await expect(page.getByText("Save your Key")).toBeVisible({ timeout: 10_000 }); + await expect(page.getByText("API Key Created")).toBeVisible({ timeout: 10_000 }); await page.keyboard.press("Escape"); await expect(page.getByText(keyName)).toBeVisible({ timeout: 10_000 }); @@ -182,7 +182,7 @@ test.describe("Proxy Admin - Keys", () => { await page.getByRole("button", { name: "Create Key", exact: true }).click(); - await expect(page.getByText("Save your Key")).toBeVisible({ timeout: 10_000 }); + await expect(page.getByText("API Key Created")).toBeVisible({ timeout: 10_000 }); // Grab the new key from the success modal (rendered inside a
) and
     // verify it can call /chat/completions for the model it was scoped to.
diff --git a/ui/litellm-dashboard/e2e_tests/tests/team-admin/teamAdmin.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/team-admin/teamAdmin.spec.ts
index 1612e6929bd..aa33ce75654 100644
--- a/ui/litellm-dashboard/e2e_tests/tests/team-admin/teamAdmin.spec.ts
+++ b/ui/litellm-dashboard/e2e_tests/tests/team-admin/teamAdmin.spec.ts
@@ -109,7 +109,7 @@ test.describe("Team Admin", () => {
 
     await page.getByRole("button", { name: "Create Key", exact: true }).click();
 
-    await expect(page.getByText("Save your Key")).toBeVisible({ timeout: 10_000 });
+    await expect(page.getByText("API Key Created")).toBeVisible({ timeout: 10_000 });
     await page.keyboard.press("Escape");
 
     await expect(page.getByText(keyName)).toBeVisible({ timeout: 10_000 });
diff --git a/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx b/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
index bd139df4833..27436a27b67 100644
--- a/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
+++ b/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
@@ -52,6 +52,8 @@ vi.mock("@/app/(dashboard)/hooks/keys/useKeys", () => ({
 
 vi.mock("@ant-design/icons", () => ({
   InfoCircleOutlined: () => null,
+  CopyOutlined: () => null,
+  WarningOutlined: () => null,
 }));
 
 vi.mock("react-copy-to-clipboard", () => ({
diff --git a/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx b/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
index b590a7dc043..97b2f7e8ed9 100644
--- a/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
+++ b/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
@@ -1657,17 +1657,12 @@ const CreateKey: React.FC = ({ team, teams, data, addKey, autoOp
       )}
 
       {apiKey && (
-        
-          
-            Save your Key
-            
-              {apiKey != null ? (
-                
-              ) : (
-                Key being created, this might take 30s
-              )}
-            
-          
+        
+          {apiKey != null ? (
+            
+          ) : (
+            Key being created, this might take 30s
+          )}
         
       )}
     
diff --git a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx
index eb6fe5f50cd..ed418221bfd 100644
--- a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx
+++ b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.test.tsx
@@ -7,51 +7,74 @@ vi.mock("@/components/molecules/message_manager", () => ({
   default: { success: vi.fn(), error: vi.fn(), warning: vi.fn(), info: vi.fn(), loading: vi.fn(), destroy: vi.fn() },
 }));
 
+vi.mock("@/components/networking", () => ({
+  proxyBaseUrl: "https://litellm.example.com",
+}));
+
 import MessageManager from "@/components/molecules/message_manager";
 
 describe("CreatedKeyDisplay", () => {
   beforeEach(() => {
     vi.useFakeTimers({ shouldAdvanceTime: true });
+    vi.mocked(MessageManager.success).mockClear();
   });
 
   afterEach(() => {
     vi.useRealTimers();
   });
 
-  it("should render", () => {
+  it("renders the API key value", () => {
     render();
-    expect(screen.getByText("sk-test-123")).toBeInTheDocument();
+    expect(screen.getByTestId("created-key-value")).toHaveTextContent("sk-test-123");
   });
 
-  it("should display the security warning", () => {
+  it("displays the security warning and modal heading", () => {
     render();
-    expect(screen.getByText(/you will not be able to view it again/i)).toBeInTheDocument();
+    expect(screen.getByRole("heading", { name: /api key created/i })).toBeInTheDocument();
+    expect(
+      screen.getByText(/make sure to copy your api key now/i),
+    ).toBeInTheDocument();
+    expect(screen.getByText(/you won't be able to see it again/i)).toBeInTheDocument();
   });
 
-  it("should show the copy button with initial label", () => {
+  it("builds a coding agent prompt that embeds the key, base URL, and docs links", () => {
     render();
-    expect(screen.getByRole("button", { name: /copy virtual key/i })).toBeInTheDocument();
+    const prompt = screen.getByTestId("coding-agent-prompt").textContent ?? "";
+
+    expect(prompt).toMatch(/Base URL: https:\/\/litellm\.example\.com/);
+    expect(prompt).toMatch(/API key: sk-test-123/);
+    expect(prompt).toContain("Authorization: Bearer sk-test-123");
+    expect(prompt).toContain("https://litellm.example.com/v1/models");
+    expect(prompt).toContain("https://docs.litellm.ai/llms.txt");
+    expect(prompt).toContain("https://docs.litellm.ai/llms-full.txt");
   });
 
-  it("should change button text to Copied after clicking copy", async () => {
-    const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
+  it("does not produce a trailing slash in the base URL when proxyBaseUrl is provided", () => {
     render();
-
-    await user.click(screen.getByRole("button", { name: /copy virtual key/i }));
-
-    expect(screen.getByRole("button", { name: /copied/i })).toBeInTheDocument();
+    const prompt = screen.getByTestId("coding-agent-prompt").textContent ?? "";
+    expect(prompt).not.toMatch(/Base URL: https:\/\/litellm\.example\.com\//);
   });
 
-  it("should show a success message when the key is copied", async () => {
+  it("copies the API key to clipboard when the primary button is clicked", async () => {
     const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
     render();
 
     await user.click(screen.getByRole("button", { name: /copy virtual key/i }));
 
     expect(MessageManager.success).toHaveBeenCalledWith("Key copied to clipboard");
+    expect(screen.getByRole("button", { name: /copied/i })).toBeInTheDocument();
   });
 
-  it("should revert button text back after 2 seconds", async () => {
+  it("copies the coding agent prompt to clipboard when its copy button is clicked", async () => {
+    const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
+    render();
+
+    await user.click(screen.getByRole("button", { name: /copy prompt for coding agents/i }));
+
+    expect(MessageManager.success).toHaveBeenCalledWith("Prompt copied to clipboard");
+  });
+
+  it("reverts the primary button label after 2 seconds", async () => {
     const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
     render();
 
diff --git a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx
index 00ffb8c6e20..6defe40d959 100644
--- a/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx
+++ b/ui/litellm-dashboard/src/components/shared/CreatedKeyDisplay.tsx
@@ -1,50 +1,150 @@
-import React, { useState } from "react";
+import React, { useMemo, useState } from "react";
 import { CopyToClipboard } from "react-copy-to-clipboard";
-import { Button } from "antd";
+import { Button, Tooltip } from "antd";
+import { CopyOutlined, WarningOutlined } from "@ant-design/icons";
 import MessageManager from "@/components/molecules/message_manager";
+import { proxyBaseUrl } from "@/components/networking";
 
 interface CreatedKeyDisplayProps {
   apiKey: string;
 }
 
-/**
- * Shared component for displaying a newly-created virtual key.
- * Used on the Virtual Keys page and in the Add Agent wizard.
- */
-const CreatedKeyDisplay: React.FC = ({ apiKey }) => {
-  const [copied, setCopied] = useState(false);
+const buildCodingAgentPrompt = (apiKey: string, baseUrl: string): string => {
+  return `You have access to LiteLLM, an OpenAI-compatible AI gateway that lets you call 100+ LLMs (OpenAI, Anthropic, Gemini, Bedrock, etc.) through a single API.
 
-  const handleCopy = () => {
-    setCopied(true);
+Use these credentials:
+- Base URL: ${baseUrl}
+- API key: ${apiKey}
+
+LiteLLM is a drop-in replacement for the OpenAI SDK. Point the SDK's \`base_url\` at the URL above and use the key as your \`OPENAI_API_KEY\`. To list the models available to this key, GET ${baseUrl}/v1/models with header \`Authorization: Bearer ${apiKey}\`.
+
+LiteLLM docs:
+- llms.txt (overview + all doc links): https://docs.litellm.ai/llms.txt
+- llms-full.txt (complete reference with inline code examples): https://docs.litellm.ai/llms-full.txt`;
+};
+
+const resolveProxyBaseUrl = (): string => {
+  if (proxyBaseUrl) return proxyBaseUrl.replace(/\/$/, "");
+  if (typeof window !== "undefined" && window.location?.origin) {
+    return window.location.origin;
+  }
+  return "https://your-litellm-proxy";
+};
+
+const CreatedKeyDisplay: React.FC = ({ apiKey }) => {
+  const [copiedKey, setCopiedKey] = useState(false);
+  const [copiedPrompt, setCopiedPrompt] = useState(false);
+
+  const codingAgentPrompt = useMemo(
+    () => buildCodingAgentPrompt(apiKey, resolveProxyBaseUrl()),
+    [apiKey],
+  );
+
+  const handleCopyKey = () => {
+    setCopiedKey(true);
     MessageManager.success("Key copied to clipboard");
-    setTimeout(() => setCopied(false), 2000);
+    setTimeout(() => setCopiedKey(false), 2000);
+  };
+
+  const handleCopyPrompt = () => {
+    setCopiedPrompt(true);
+    MessageManager.success("Prompt copied to clipboard");
+    setTimeout(() => setCopiedPrompt(false), 2000);
   };
 
   return (
-    
-

- Please save this secret key somewhere safe and accessible. For security reasons,{" "} - you will not be able to view it again through your LiteLLM account. If you - lose this secret key, you will need to generate a new one. -

- -

Virtual Key:

-
-
-          {apiKey}
-        
+
+
+

API Key Created

+

+ Paste this prompt into any coding agent to start using LiteLLM. +

- -
+
+
+            {apiKey}
+          
+
+
+ +
+
+ + Prompt for coding agents + + + +
+
+
+            {codingAgentPrompt}
+          
+
+
+ + +