diff --git a/llama_stack/ui/app/logs/vector-stores/layout.tsx b/llama_stack/ui/app/logs/vector-stores/layout.tsx
new file mode 100644
index 000000000..9245f5486
--- /dev/null
+++ b/llama_stack/ui/app/logs/vector-stores/layout.tsx
@@ -0,0 +1,16 @@
+"use client";
+
+import React from "react";
+import LogsLayout from "@/components/layout/logs-layout";
+
+export default function VectorStoresLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/llama_stack/ui/app/logs/vector-stores/page.tsx b/llama_stack/ui/app/logs/vector-stores/page.tsx
new file mode 100644
index 000000000..8b8ea3d3a
--- /dev/null
+++ b/llama_stack/ui/app/logs/vector-stores/page.tsx
@@ -0,0 +1,105 @@
+"use client";
+
+import React, { useState, useEffect } from "react";
+import { useAuthClient } from "@/hooks/use-auth-client";
+import type {
+ ListVectorStoresResponse,
+ VectorStore,
+} from "llama-stack-client/resources/vector-stores/vector-stores";
+import { useRouter } from "next/navigation";
+import {
+ Table,
+ TableBody,
+ TableCaption,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
+import { Skeleton } from "@/components/ui/skeleton";
+
+export default function VectorStoresPage() {
+ const client = useAuthClient();
+ const router = useRouter();
+ const [stores, setStores] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ async function fetchStores() {
+ try {
+ const response = await client.vectorStores.list();
+ const res = response as ListVectorStoresResponse;
+ setStores(res.data);
+ } catch (err) {
+ setError(
+ err instanceof Error
+ ? err.message
+ : "Failed to load vector stores.",
+ );
+ } finally {
+ setLoading(false);
+ }
+ }
+ fetchStores();
+ }, [client]);
+
+ if (loading) {
+ return (
+
+
+
+
+
+ );
+ }
+
+ if (error) {
+ return Error: {error}
;
+ }
+
+ return (
+
+ A list of your vector stores.
+
+
+ ID
+ Name
+ Created
+ Completed
+ Cancelled
+ Failed
+ In Progress
+ Total
+ Usage Bytes
+ Provider ID
+ Provider Vector DB ID
+
+
+
+ {stores.map((store) => {
+ const fileCounts = store.file_counts;
+ const metadata = store.metadata || {};
+ const providerId = metadata.provider_id ?? "";
+ const providerDbId = metadata.provider_vector_db_id ?? "";
+
+ return (
+
+ {store.id}
+ {store.name}
+ {new Date(store.created_at * 1000).toLocaleString()}
+ {fileCounts.completed}
+ {fileCounts.cancelled}
+ {fileCounts.failed}
+ {fileCounts.in_progress}
+ {fileCounts.total}
+ {store.usage_bytes}
+ {providerId}
+ {providerDbId}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/llama_stack/ui/components/layout/app-sidebar.tsx b/llama_stack/ui/components/layout/app-sidebar.tsx
index 1c53d6cc5..a0468a607 100644
--- a/llama_stack/ui/components/layout/app-sidebar.tsx
+++ b/llama_stack/ui/components/layout/app-sidebar.tsx
@@ -1,6 +1,6 @@
"use client";
-import { MessageSquareText, MessagesSquare, MoveUpRight } from "lucide-react";
+import { MessageSquareText, MessagesSquare, MoveUpRight, Database } from "lucide-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { cn } from "@/lib/utils";
@@ -28,6 +28,11 @@ const logItems = [
url: "/logs/responses",
icon: MessagesSquare,
},
+ {
+ title: "Vector Stores",
+ url: "/logs/vector-stores",
+ icon: Database,
+ },
{
title: "Documentation",
url: "https://llama-stack.readthedocs.io/en/latest/references/api_reference/index.html",
diff --git a/llama_stack/ui/package-lock.json b/llama_stack/ui/package-lock.json
index 8fd5fb56c..7bbfaa966 100644
--- a/llama_stack/ui/package-lock.json
+++ b/llama_stack/ui/package-lock.json
@@ -3962,9 +3962,9 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4887,9 +4887,9 @@
}
},
"node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {