mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-07-29 07:14:20 +00:00
updated font to make dark mode more readable
Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>
This commit is contained in:
parent
f8311c827d
commit
a520430ebb
6 changed files with 185 additions and 78 deletions
82
llama_stack/ui/app/logs/vector-stores/[id]/page.tsx
Normal file
82
llama_stack/ui/app/logs/vector-stores/[id]/page.tsx
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useParams, useRouter } from "next/navigation";
|
||||||
|
import { useAuthClient } from "@/hooks/use-auth-client";
|
||||||
|
import type { VectorStore } from "llama-stack-client/resources/vector-stores/vector-stores";
|
||||||
|
import type { VectorStoreFile } from "llama-stack-client/resources/vector-stores/files";
|
||||||
|
import { VectorStoreDetailView } from "@/components/vector-stores/vector-store-detail";
|
||||||
|
|
||||||
|
export default function VectorStoreDetailPage() {
|
||||||
|
const params = useParams();
|
||||||
|
const id = params.id as string;
|
||||||
|
const client = useAuthClient();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const [store, setStore] = useState<VectorStore | null>(null);
|
||||||
|
const [files, setFiles] = useState<VectorStoreFile[]>([]);
|
||||||
|
const [isLoadingStore, setIsLoadingStore] = useState(true);
|
||||||
|
const [isLoadingFiles, setIsLoadingFiles] = useState(true);
|
||||||
|
const [errorStore, setErrorStore] = useState<Error | null>(null);
|
||||||
|
const [errorFiles, setErrorFiles] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!id) {
|
||||||
|
setErrorStore(new Error("Vector Store ID is missing."));
|
||||||
|
setIsLoadingStore(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fetchStore = async () => {
|
||||||
|
setIsLoadingStore(true);
|
||||||
|
setErrorStore(null);
|
||||||
|
try {
|
||||||
|
const response = await client.vectorStores.retrieve(id);
|
||||||
|
setStore(response as VectorStore);
|
||||||
|
} catch (err) {
|
||||||
|
setErrorStore(
|
||||||
|
err instanceof Error
|
||||||
|
? err
|
||||||
|
: new Error("Failed to load vector store."),
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setIsLoadingStore(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchStore();
|
||||||
|
}, [id, client]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!id) {
|
||||||
|
setErrorFiles(new Error("Vector Store ID is missing."));
|
||||||
|
setIsLoadingFiles(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fetchFiles = async () => {
|
||||||
|
setIsLoadingFiles(true);
|
||||||
|
setErrorFiles(null);
|
||||||
|
try {
|
||||||
|
const result = await client.vectorStores.files.list(id as any);
|
||||||
|
setFiles((result as any).data);
|
||||||
|
} catch (err) {
|
||||||
|
setErrorFiles(
|
||||||
|
err instanceof Error ? err : new Error("Failed to load files."),
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setIsLoadingFiles(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchFiles();
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VectorStoreDetailView
|
||||||
|
store={store}
|
||||||
|
files={files}
|
||||||
|
isLoadingStore={isLoadingStore}
|
||||||
|
isLoadingFiles={isLoadingFiles}
|
||||||
|
errorStore={errorStore}
|
||||||
|
errorFiles={errorFiles}
|
||||||
|
id={id}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useEffect } from "react";
|
import React from "react";
|
||||||
import { useAuthClient } from "@/hooks/use-auth-client";
|
import { useAuthClient } from "@/hooks/use-auth-client";
|
||||||
import type {
|
import type {
|
||||||
ListVectorStoresResponse,
|
ListVectorStoresResponse,
|
||||||
VectorStore,
|
VectorStore,
|
||||||
} from "llama-stack-client/resources/vector-stores/vector-stores";
|
} from "llama-stack-client/resources/vector-stores/vector-stores";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { usePagination } from "@/hooks/use-pagination";
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
|
@ -21,30 +22,34 @@ import { Skeleton } from "@/components/ui/skeleton";
|
||||||
export default function VectorStoresPage() {
|
export default function VectorStoresPage() {
|
||||||
const client = useAuthClient();
|
const client = useAuthClient();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [stores, setStores] = useState<VectorStore[]>([]);
|
const {
|
||||||
const [loading, setLoading] = useState(true);
|
data: stores,
|
||||||
const [error, setError] = useState<string | null>(null);
|
status,
|
||||||
|
hasMore,
|
||||||
|
error,
|
||||||
|
loadMore,
|
||||||
|
} = usePagination<VectorStore>({
|
||||||
|
limit: 20,
|
||||||
|
order: "desc",
|
||||||
|
fetchFunction: async (client, params) => {
|
||||||
|
const response = await client.vectorStores.list({
|
||||||
|
after: params.after,
|
||||||
|
limit: params.limit,
|
||||||
|
order: params.order,
|
||||||
|
} as any);
|
||||||
|
return response as ListVectorStoresResponse;
|
||||||
|
},
|
||||||
|
errorMessagePrefix: "vector stores",
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
// Auto-load all pages for infinite scroll behavior (like Responses)
|
||||||
async function fetchStores() {
|
React.useEffect(() => {
|
||||||
try {
|
if (status === "idle" && hasMore) {
|
||||||
const response = await client.vectorStores.list();
|
loadMore();
|
||||||
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();
|
}, [status, hasMore, loadMore]);
|
||||||
}, [client]);
|
|
||||||
|
|
||||||
if (loading) {
|
if (status === "loading") {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Skeleton className="h-8 w-full" />
|
<Skeleton className="h-8 w-full" />
|
||||||
|
@ -54,52 +59,63 @@ export default function VectorStoresPage() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (status === "error") {
|
||||||
return <div className="text-destructive">Error: {error}</div>;
|
return <div className="text-destructive">Error: {error?.message}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stores || stores.length === 0) {
|
||||||
|
return <p>No vector stores found.</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table>
|
<div className="overflow-auto flex-1 min-h-0">
|
||||||
<TableCaption>A list of your vector stores.</TableCaption>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>ID</TableHead>
|
<TableHead>ID</TableHead>
|
||||||
<TableHead>Name</TableHead>
|
<TableHead>Name</TableHead>
|
||||||
<TableHead>Created</TableHead>
|
<TableHead>Created</TableHead>
|
||||||
<TableHead>Completed</TableHead>
|
<TableHead>Completed</TableHead>
|
||||||
<TableHead>Cancelled</TableHead>
|
<TableHead>Cancelled</TableHead>
|
||||||
<TableHead>Failed</TableHead>
|
<TableHead>Failed</TableHead>
|
||||||
<TableHead>In Progress</TableHead>
|
<TableHead>In Progress</TableHead>
|
||||||
<TableHead>Total</TableHead>
|
<TableHead>Total</TableHead>
|
||||||
<TableHead>Usage Bytes</TableHead>
|
<TableHead>Usage Bytes</TableHead>
|
||||||
<TableHead>Provider ID</TableHead>
|
<TableHead>Provider ID</TableHead>
|
||||||
<TableHead>Provider Vector DB ID</TableHead>
|
<TableHead>Provider Vector DB ID</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{stores.map((store) => {
|
{stores.map((store) => {
|
||||||
const fileCounts = store.file_counts;
|
const fileCounts = store.file_counts;
|
||||||
const metadata = store.metadata || {};
|
const metadata = store.metadata || {};
|
||||||
const providerId = metadata.provider_id ?? "";
|
const providerId = metadata.provider_id ?? "";
|
||||||
const providerDbId = metadata.provider_vector_db_id ?? "";
|
const providerDbId = metadata.provider_vector_db_id ?? "";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow key={store.id} className="hover:bg-muted/50">
|
<TableRow
|
||||||
<TableCell>{store.id}</TableCell>
|
key={store.id}
|
||||||
<TableCell>{store.name}</TableCell>
|
onClick={() => router.push(`/logs/vector-stores/${store.id}`)}
|
||||||
<TableCell>{new Date(store.created_at * 1000).toLocaleString()}</TableCell>
|
className="cursor-pointer hover:bg-muted/50"
|
||||||
<TableCell>{fileCounts.completed}</TableCell>
|
>
|
||||||
<TableCell>{fileCounts.cancelled}</TableCell>
|
<TableCell>{store.id}</TableCell>
|
||||||
<TableCell>{fileCounts.failed}</TableCell>
|
<TableCell>{store.name}</TableCell>
|
||||||
<TableCell>{fileCounts.in_progress}</TableCell>
|
<TableCell>
|
||||||
<TableCell>{fileCounts.total}</TableCell>
|
{new Date(store.created_at * 1000).toLocaleString()}
|
||||||
<TableCell>{store.usage_bytes}</TableCell>
|
</TableCell>
|
||||||
<TableCell>{providerId}</TableCell>
|
<TableCell>{fileCounts.completed}</TableCell>
|
||||||
<TableCell>{providerDbId}</TableCell>
|
<TableCell>{fileCounts.cancelled}</TableCell>
|
||||||
</TableRow>
|
<TableCell>{fileCounts.failed}</TableCell>
|
||||||
);
|
<TableCell>{fileCounts.in_progress}</TableCell>
|
||||||
})}
|
<TableCell>{fileCounts.total}</TableCell>
|
||||||
</TableBody>
|
<TableCell>{store.usage_bytes}</TableCell>
|
||||||
</Table>
|
<TableCell>{providerId}</TableCell>
|
||||||
|
<TableCell>{providerDbId}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { MessageSquareText, MessagesSquare, MoveUpRight, Database } from "lucide-react";
|
import {
|
||||||
|
MessageSquareText,
|
||||||
|
MessagesSquare,
|
||||||
|
MoveUpRight,
|
||||||
|
Database,
|
||||||
|
} from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
@ -62,13 +67,13 @@ export function AppSidebar() {
|
||||||
className={cn(
|
className={cn(
|
||||||
"justify-start",
|
"justify-start",
|
||||||
isActive &&
|
isActive &&
|
||||||
"bg-gray-200 hover:bg-gray-200 text-primary hover:text-primary",
|
"bg-gray-200 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-900 dark:text-gray-100",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Link href={item.url}>
|
<Link href={item.url}>
|
||||||
<item.icon
|
<item.icon
|
||||||
className={cn(
|
className={cn(
|
||||||
isActive && "text-primary",
|
isActive && "text-gray-900 dark:text-gray-100",
|
||||||
"mr-2 h-4 w-4",
|
"mr-2 h-4 w-4",
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -93,7 +93,9 @@ export function PropertyItem({
|
||||||
>
|
>
|
||||||
<strong>{label}:</strong>{" "}
|
<strong>{label}:</strong>{" "}
|
||||||
{typeof value === "string" || typeof value === "number" ? (
|
{typeof value === "string" || typeof value === "number" ? (
|
||||||
<span className="text-gray-900 font-medium">{value}</span>
|
<span className="text-gray-900 dark:text-gray-100 font-medium">
|
||||||
|
{value}
|
||||||
|
</span>
|
||||||
) : (
|
) : (
|
||||||
value
|
value
|
||||||
)}
|
)}
|
||||||
|
@ -112,7 +114,9 @@ export function PropertiesCard({ children }: PropertiesCardProps) {
|
||||||
<CardTitle>Properties</CardTitle>
|
<CardTitle>Properties</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<ul className="space-y-2 text-sm text-gray-600">{children}</ul>
|
<ul className="space-y-2 text-sm text-gray-600 dark:text-gray-400">
|
||||||
|
{children}
|
||||||
|
</ul>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,10 +17,10 @@ export const MessageBlock: React.FC<MessageBlockProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className={`mb-4 ${className}`}>
|
<div className={`mb-4 ${className}`}>
|
||||||
<p className="py-1 font-semibold text-gray-800 mb-1">
|
<p className="py-1 font-semibold text-muted-foreground mb-1">
|
||||||
{label}
|
{label}
|
||||||
{labelDetail && (
|
{labelDetail && (
|
||||||
<span className="text-xs text-gray-500 font-normal ml-1">
|
<span className="text-xs text-muted-foreground font-normal ml-1">
|
||||||
{labelDetail}
|
{labelDetail}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
12
llama_stack/ui/package-lock.json
generated
12
llama_stack/ui/package-lock.json
generated
|
@ -3962,9 +3962,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -4887,9 +4887,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue