Skip to main content
Glama

@arizeai/phoenix-mcp

Official
by Arize-ai
TracePaginationContext.tsx5.09 kB
import { createContext, PropsWithChildren, useCallback, useContext, useState, } from "react"; import { useLocation, useNavigate } from "react-router"; import { SELECTED_SPAN_NODE_ID_PARAM } from "@phoenix/constants/searchParams"; /** * A sequence of traceId/spanId pairs that represent the trace sequence. * The sequence is used to navigate between traces, or spans within a trace. */ type TraceSequence = { traceId: string; spanId: string }[]; type TracePaginationContextType = { traceSequence: TraceSequence; next: (currentId?: string) => void; previous: (currentId?: string) => void; setTraceSequence: (traceSequence: TraceSequence) => void; }; export const TracePaginationContext = createContext<TracePaginationContextType | null>(null); export const useTracePagination = () => { const context = useContext(TracePaginationContext); return context; }; /** * Get the next and previous traceId/spanId pairs based on the current traceId/spanId * @param traceSequence - The sequence of traceId/spanId pairs to paginate against, this could be from the spans table for example * @param currentId - The current traceId or spanId, the first sequence with a matching traceId or spanId will be matched against * @returns The next and previous traceId and spanId, if they exist in the sequence */ export const getNeighbors = ( traceSequence: { traceId: string; spanId: string }[], /** May be a traceId or a spanId */ currentId?: string ) => { const currentIndex = traceSequence.findIndex( ({ traceId, spanId }) => currentId && (traceId === currentId || spanId === currentId) ); const previousIndex = currentIndex - 1; const nextIndex = currentIndex + 1; const previousSequenceMember = traceSequence[previousIndex]; const nextSequenceMember = traceSequence[nextIndex]; return { nextTraceId: nextSequenceMember?.traceId, nextSpanId: nextSequenceMember?.spanId, previousTraceId: previousSequenceMember?.traceId, previousSpanId: previousSequenceMember?.spanId, }; }; /** * Make the next and previous trace urls based on the current traceId, spanId, and url pathname * @param location - The location object from useLocation * @param traceSequence - The sequence of traceId/spanId pairs to paginate against, this could be from the spans table for example * @param currentId - The current traceId or spanId, the first sequence with a matching traceId or spanId will be matched against * @returns The next and previous trace urls, if they exist in the sequence */ export const makeTraceUrls = ( location: ReturnType<typeof useLocation>, traceSequence: { traceId: string; spanId: string }[], currentId?: string ) => { const { nextTraceId, previousTraceId, nextSpanId, previousSpanId } = getNeighbors(traceSequence, currentId); // split up the url pathname into its components // e.g. /projects/my-project/traces/123/spans/456 -> ["projects", "my-project", "traces", "123", "spans", "456"] // we only really care about the last two components, which are the projectId and the resource // resource is either "traces" or "spans", which we need to keep track of so we can build the correct url const [projects, projectId, resource] = location.pathname .split("/") .filter((part) => part !== ""); const makeUrl = (traceId: string, currentSpanId?: string) => { // we always navigate directly to a traceId let path = `/${projects}/${projectId}/${resource}/${traceId}`; // we add a selected span node id if provided to makeUrl if (currentSpanId) { path += `?${SELECTED_SPAN_NODE_ID_PARAM}=${currentSpanId}`; } return path; }; const hasNext = !!nextTraceId; const hasPrevious = !!previousTraceId; // we build the next and previous trace urls if the traceId is present for those directions return { nextTracePath: hasNext ? makeUrl(nextTraceId, nextSpanId) : null, previousTracePath: hasPrevious ? makeUrl(previousTraceId, previousSpanId) : null, }; }; export const TracePaginationProvider = ({ children }: PropsWithChildren) => { const navigate = useNavigate(); const location = useLocation(); const [traceSequence, setTraceSequence] = useState< { traceId: string; spanId: string }[] >([]); const next = useCallback( (currentId?: string) => { const { nextTracePath } = makeTraceUrls( location, traceSequence, currentId ); if (nextTracePath) { navigate(nextTracePath); } }, [navigate, location, traceSequence] ); const previous = useCallback( (currentId?: string) => { const { previousTracePath } = makeTraceUrls( location, traceSequence, currentId ); if (previousTracePath) { navigate(previousTracePath); } }, [navigate, location, traceSequence] ); return ( <TracePaginationContext.Provider value={{ traceSequence, next, previous, setTraceSequence, }} > {children} </TracePaginationContext.Provider> ); };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Arize-ai/phoenix'

If you have feedback or need assistance with the MCP directory API, please join our Discord server