From ee741485d3fff5515e39c5d9d81e8c4594e65788 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Thu, 25 Jul 2024 22:52:34 -0600 Subject: [PATCH] feat: lazy load spans --- app/src/components/trace/TraceTree.tsx | 22 +- app/src/components/trace/types.ts | 1 + .../pages/example/ExampleDetailsDialog.tsx | 6 +- .../ExampleDetailsDialogQuery.graphql.ts | 18 +- app/src/pages/project/SpansTable.tsx | 7 +- app/src/pages/project/TracesTable.tsx | 4 +- app/src/pages/trace/SpanDetails.tsx | 118 +++- app/src/pages/trace/TraceDetails.tsx | 58 +- .../__generated__/SpanDetailsQuery.graphql.ts | 505 ++++++++++++++ .../TraceDetailsQuery.graphql.ts | 630 +++++------------- 10 files changed, 816 insertions(+), 553 deletions(-) create mode 100644 app/src/pages/trace/__generated__/SpanDetailsQuery.graphql.ts diff --git a/app/src/components/trace/TraceTree.tsx b/app/src/components/trace/TraceTree.tsx index d5efc35c5f..d1d7684617 100644 --- a/app/src/components/trace/TraceTree.tsx +++ b/app/src/components/trace/TraceTree.tsx @@ -13,12 +13,12 @@ import { createSpanTree, SpanTreeNode } from "./utils"; type TraceTreeProps = { spans: ISpanItem[]; - onSpanClick?: (spanId: string) => void; - selectedSpanId: string; + onSpanClick?: (span: ISpanItem) => void; + selectedSpanNodeId: string; }; export function TraceTree(props: TraceTreeProps) { - const { spans, onSpanClick, selectedSpanId } = props; + const { spans, onSpanClick, selectedSpanNodeId } = props; const spanTree = createSpanTree(spans); return ( @@ -43,10 +43,10 @@ export function TraceTree(props: TraceTreeProps) { function SpanTreeItem(props: { node: SpanTreeNode; - selectedSpanId: string; - onSpanClick?: (spanId: string) => void; + selectedSpanNodeId: string; + onSpanClick?: (span: ISpanItem) => void; }) { - const { node, selectedSpanId, onSpanClick } = props; + const { node, selectedSpanNodeId, onSpanClick } = props; const childNodes = node.children; return (
@@ -58,11 +58,11 @@ function SpanTreeItem(props: { `} onClick={() => { startTransition(() => { - onSpanClick && onSpanClick(node.span.context.spanId); + onSpanClick && onSpanClick(node.span); }); }} > - + (props: {
); diff --git a/app/src/components/trace/types.ts b/app/src/components/trace/types.ts index 4aa23fdfbb..30f8f8acab 100644 --- a/app/src/components/trace/types.ts +++ b/app/src/components/trace/types.ts @@ -2,6 +2,7 @@ * A generic interface for a span to be re-used as a constraint */ export interface ISpanItem { + id: string; name: string; spanKind: string; statusCode: SpanStatusCodeType; diff --git a/app/src/pages/example/ExampleDetailsDialog.tsx b/app/src/pages/example/ExampleDetailsDialog.tsx index 598c6e81ad..0e14919875 100644 --- a/app/src/pages/example/ExampleDetailsDialog.tsx +++ b/app/src/pages/example/ExampleDetailsDialog.tsx @@ -47,8 +47,8 @@ export function ExampleDetailsDialog({ metadata } span { + id context { - spanId traceId } project { @@ -77,7 +77,7 @@ export function ExampleDetailsDialog({ return null; } return { - spanId: sourceSpan.context.spanId, + id: sourceSpan.id, traceId: sourceSpan.context.traceId, projectId: sourceSpan.project.id, }; @@ -98,7 +98,7 @@ export function ExampleDetailsDialog({ size="compact" onClick={() => { navigate( - `/projects/${sourceSpanInfo.projectId}/traces/${sourceSpanInfo.traceId}?selectedSpanId=${sourceSpanInfo.spanId}` + `/projects/${sourceSpanInfo.projectId}/traces/${sourceSpanInfo.traceId}?selectedSpanNodeId=${sourceSpanInfo.id}` ); }} > diff --git a/app/src/pages/example/__generated__/ExampleDetailsDialogQuery.graphql.ts b/app/src/pages/example/__generated__/ExampleDetailsDialogQuery.graphql.ts index eba159785c..6d1e6111bd 100644 --- a/app/src/pages/example/__generated__/ExampleDetailsDialogQuery.graphql.ts +++ b/app/src/pages/example/__generated__/ExampleDetailsDialogQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<1e4437ea31a23ab9d891186bded929e8>> + * @generated SignedSource<<5930c1dbf55baf0619403784534be419>> * @lightSyntaxTransform * @nogrep */ @@ -23,9 +23,9 @@ export type ExampleDetailsDialogQuery$data = { }; readonly span?: { readonly context: { - readonly spanId: string; readonly traceId: string; }; + readonly id: string; readonly project: { readonly id: string; }; @@ -108,6 +108,7 @@ v6 = { "name": "span", "plural": false, "selections": [ + (v2/*: any*/), { "alias": null, "args": null, @@ -116,13 +117,6 @@ v6 = { "name": "context", "plural": false, "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "spanId", - "storageKey": null - }, (v5/*: any*/) ], "storageKey": null @@ -427,16 +421,16 @@ return { ] }, "params": { - "cacheID": "3a826f05abb4b9ae214c0d16ba70d8a1", + "cacheID": "6fa23dc80c23ecdf48e57d139d76a721", "id": null, "metadata": {}, "name": "ExampleDetailsDialogQuery", "operationKind": "query", - "text": "query ExampleDetailsDialogQuery(\n $exampleId: GlobalID!\n) {\n example: node(id: $exampleId) {\n __typename\n ... on DatasetExample {\n id\n latestRevision: revision {\n input\n output\n metadata\n }\n span {\n context {\n spanId\n traceId\n }\n project {\n id\n }\n }\n }\n ...ExampleExperimentRunsTableFragment\n __isNode: __typename\n id\n }\n}\n\nfragment ExampleExperimentRunsTableFragment on DatasetExample {\n experimentRuns(first: 100) {\n edges {\n run: node {\n id\n startTime\n endTime\n error\n output\n trace {\n traceId\n projectId\n }\n annotations {\n edges {\n annotation: node {\n id\n name\n label\n score\n explanation\n annotatorKind\n trace {\n traceId\n projectId\n }\n }\n }\n }\n }\n cursor\n node {\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n" + "text": "query ExampleDetailsDialogQuery(\n $exampleId: GlobalID!\n) {\n example: node(id: $exampleId) {\n __typename\n ... on DatasetExample {\n id\n latestRevision: revision {\n input\n output\n metadata\n }\n span {\n id\n context {\n traceId\n }\n project {\n id\n }\n }\n }\n ...ExampleExperimentRunsTableFragment\n __isNode: __typename\n id\n }\n}\n\nfragment ExampleExperimentRunsTableFragment on DatasetExample {\n experimentRuns(first: 100) {\n edges {\n run: node {\n id\n startTime\n endTime\n error\n output\n trace {\n traceId\n projectId\n }\n annotations {\n edges {\n annotation: node {\n id\n name\n label\n score\n explanation\n annotatorKind\n trace {\n traceId\n projectId\n }\n }\n }\n }\n }\n cursor\n node {\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n" } }; })(); -(node as any).hash = "e0deec4a6716862bd003e56ea5c7c3ad"; +(node as any).hash = "65b1c049bacc1ef8739c61af32a9414c"; export default node; diff --git a/app/src/pages/project/SpansTable.tsx b/app/src/pages/project/SpansTable.tsx index 112601f010..4e70807d1c 100644 --- a/app/src/pages/project/SpansTable.tsx +++ b/app/src/pages/project/SpansTable.tsx @@ -264,9 +264,10 @@ export function SpansTable(props: SpansTableProps) { accessorKey: "name", enableSorting: false, cell: ({ getValue, row }) => { - const { spanId, traceId } = row.original.context; + const span = row.original; + const { traceId } = span.context; return ( - + {getValue() as string} ); @@ -470,7 +471,7 @@ export function SpansTable(props: SpansTableProps) { key={row.id} onClick={() => navigate( - `traces/${row.original.context.traceId}?selectedSpanId=${row.original.context.spanId}` + `traces/${row.original.context.traceId}?selectedSpanNodeId=${row.original.id}` ) } > diff --git a/app/src/pages/project/TracesTable.tsx b/app/src/pages/project/TracesTable.tsx index 68a026625e..33fc06e995 100644 --- a/app/src/pages/project/TracesTable.tsx +++ b/app/src/pages/project/TracesTable.tsx @@ -372,9 +372,9 @@ export function TracesTable(props: TracesTableProps) { accessorKey: "name", enableSorting: false, cell: ({ getValue, row }) => { - const { spanId, traceId } = row.original.context; + const { traceId } = row.original.context; return ( - + {getValue() as string} ); diff --git a/app/src/pages/trace/SpanDetails.tsx b/app/src/pages/trace/SpanDetails.tsx index 00e0644705..8d27f54e06 100644 --- a/app/src/pages/trace/SpanDetails.tsx +++ b/app/src/pages/trace/SpanDetails.tsx @@ -6,6 +6,7 @@ import React, { useMemo, useState, } from "react"; +import { graphql, useLazyLoadQuery } from "react-relay"; import { useNavigate } from "react-router"; import { json } from "@codemirror/lang-json"; import { nord } from "@uiw/codemirror-theme-nord"; @@ -80,8 +81,9 @@ import { RetrievalEvaluationLabel } from "../project/RetrievalEvaluationLabel"; import { MimeType, - TraceDetailsQuery$data, -} from "./__generated__/TraceDetailsQuery.graphql"; + SpanDetailsQuery, + SpanDetailsQuery$data, +} from "./__generated__/SpanDetailsQuery.graphql"; import { EditSpanAnnotationsButton } from "./EditSpanAnnotationsButton"; import { SpanCodeDropdown } from "./SpanCodeDropdown"; import { SpanEvaluationsTable } from "./SpanEvaluationsTable"; @@ -98,11 +100,9 @@ type AttributeObject = { [SemanticAttributePrefixes.llm]?: AttributeLlm; }; -type Span = NonNullable< - TraceDetailsQuery$data["project"]["trace"] ->["spans"]["edges"][number]["span"]; +type Span = Extract; -type DocumentEvaluation = Span["documentEvaluations"][number]; +type DocumentEvaluation = NonNullable[number]; /** * Hook that safely parses a JSON string. @@ -134,15 +134,87 @@ const defaultCardProps: Partial = { }; export function SpanDetails({ - selectedSpan, + spanNodeId, projectId, }: { - selectedSpan: Span; + /** + * The Global ID of the span + */ + spanNodeId: string; projectId: string; }) { + const { span } = useLazyLoadQuery( + graphql` + query SpanDetailsQuery($spanId: GlobalID!) { + span: node(id: $spanId) { + __typename + ... on Span { + id + context { + spanId + traceId + } + name + spanKind + statusCode: propagatedStatusCode + statusMessage + startTime + parentId + latencyMs + tokenCountTotal + tokenCountPrompt + tokenCountCompletion + input { + value + mimeType + } + output { + value + mimeType + } + attributes + events @required(action: THROW) { + name + message + timestamp + } + spanEvaluations { + name + label + score + } + documentRetrievalMetrics { + evaluationName + ndcg + precision + hit + } + documentEvaluations { + documentPosition + name + label + score + explanation + } + ...SpanEvaluationsTable_evals + } + } + } + `, + { + spanId: spanNodeId, + } + ); + + if (span.__typename !== "Span") { + throw new Error( + "Expected a span, but got a different type" + span.__typename + ); + } + const hasExceptions = useMemo(() => { - return spanHasException(selectedSpan); - }, [selectedSpan]); + return spanHasException(span); + }, [span]); const showAnnotations = useFeatureFlag("annotations"); return ( @@ -159,16 +231,16 @@ export function SpanDetails({ justifyContent="space-between" alignItems="center" > - + - + {showAnnotations ? ( ) : null} @@ -177,18 +249,16 @@ export function SpanDetails({ - + - {selectedSpan.spanEvaluations.length} - + {span.spanEvaluations.length} } > {(selected) => { - return selected ? : null; + return selected ? : null; }} @@ -197,10 +267,10 @@ export function SpanDetails({ title="All Attributes" {...defaultCardProps} titleExtra={attributesContextualHelp} - extra={} + extra={} bodyStyle={{ padding: 0 }} > - {selectedSpan.attributes} + {span.attributes} @@ -208,11 +278,11 @@ export function SpanDetails({ name={"Events"} extra={ - {selectedSpan.events.length} + {span.events.length} } > - + diff --git a/app/src/pages/trace/TraceDetails.tsx b/app/src/pages/trace/TraceDetails.tsx index ed3a5fc03c..50acd9f9e8 100644 --- a/app/src/pages/trace/TraceDetails.tsx +++ b/app/src/pages/trace/TraceDetails.tsx @@ -1,4 +1,4 @@ -import React, { PropsWithChildren, useEffect, useMemo } from "react"; +import React, { PropsWithChildren, Suspense, useEffect, useMemo } from "react"; import { graphql, useLazyLoadQuery } from "react-relay"; import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; import { useSearchParams } from "react-router-dom"; @@ -6,6 +6,7 @@ import { css } from "@emotion/react"; import { Flex, Text, View } from "@arizeai/components"; +import { Loading } from "@phoenix/components"; import { resizeHandleCSS } from "@phoenix/components/resize"; import { LatencyText } from "@phoenix/components/trace/LatencyText"; import { SpanStatusCodeIcon } from "@phoenix/components/trace/SpanStatusCodeIcon"; @@ -20,6 +21,8 @@ import { } from "./__generated__/TraceDetailsQuery.graphql"; import { SpanDetails } from "./SpanDetails"; +export const SELECTED_SPAN_NODE_ID_URL_PARAM = "selectedSpanNodeId"; + type Span = NonNullable< TraceDetailsQuery$data["project"]["trace"] >["spans"]["edges"][number]["span"]; @@ -70,46 +73,17 @@ export function TraceDetails(props: TraceDetailsProps) { name spanKind statusCode: propagatedStatusCode - statusMessage startTime parentId latencyMs tokenCountTotal tokenCountPrompt tokenCountCompletion - input { - value - mimeType - } - output { - value - mimeType - } - attributes - events { - name - message - timestamp - } spanEvaluations { name label score } - documentRetrievalMetrics { - evaluationName - ndcg - precision - hit - } - documentEvaluations { - documentPosition - name - label - score - explanation - } - ...SpanEvaluationsTable_evals } } } @@ -127,11 +101,9 @@ export function TraceDetails(props: TraceDetailsProps) { const gqlSpans = data.project.trace?.spans.edges || []; return gqlSpans.map((node) => node.span); }, [data]); - const urlSelectedSpanId = searchParams.get("selectedSpanId"); - const selectedSpanId = urlSelectedSpanId ?? spansList[0].context.spanId; - const selectedSpan = spansList.find( - (span) => span.context.spanId === selectedSpanId - ); + const urlSpanNodeId = searchParams.get(SELECTED_SPAN_NODE_ID_URL_PARAM); + const selectedSpanNodeId = urlSpanNodeId ?? spansList[0].id; + const selectedSpan = spansList.find((span) => span.id === selectedSpanNodeId); const rootSpan = useMemo(() => findRootSpan(spansList), [spansList]); // Clear the selected span param when the component unmounts @@ -139,7 +111,7 @@ export function TraceDetails(props: TraceDetailsProps) { return () => { setSearchParams( (searchParams) => { - searchParams.delete("selectedSpanId"); + searchParams.delete("spanNodeId"); return searchParams; }, { replace: true } @@ -169,11 +141,11 @@ export function TraceDetails(props: TraceDetailsProps) { { + selectedSpanNodeId={selectedSpanNodeId} + onSpanClick={(span) => { setSearchParams( (searchParams) => { - searchParams.set("selectedSpanId", spanId); + searchParams.set(SELECTED_SPAN_NODE_ID_URL_PARAM, span.id); return searchParams; }, { replace: true } @@ -185,8 +157,10 @@ export function TraceDetails(props: TraceDetailsProps) { - {selectedSpan ? ( - + {selectedSpan && urlSpanNodeId ? ( + }> + + ) : null} @@ -201,8 +175,8 @@ function TraceHeader({ rootSpan }: { rootSpan: Span | null }) { statusCode: "UNSET", spanEvaluations: [], }; + const hasEvaluations = spanEvaluations.length > 0; const statusColor = useSpanStatusCodeColor(statusCode); - const hasEvaluations = spanEvaluations.length; return ( diff --git a/app/src/pages/trace/__generated__/SpanDetailsQuery.graphql.ts b/app/src/pages/trace/__generated__/SpanDetailsQuery.graphql.ts new file mode 100644 index 0000000000..8cdaf57d28 --- /dev/null +++ b/app/src/pages/trace/__generated__/SpanDetailsQuery.graphql.ts @@ -0,0 +1,505 @@ +/** + * @generated SignedSource<<353a86207783c9525898f58f87984ece>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest, Query } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type MimeType = "json" | "text"; +export type SpanKind = "agent" | "chain" | "embedding" | "evaluator" | "guardrail" | "llm" | "reranker" | "retriever" | "tool" | "unknown"; +export type SpanStatusCode = "ERROR" | "OK" | "UNSET"; +export type SpanDetailsQuery$variables = { + spanId: string; +}; +export type SpanDetailsQuery$data = { + readonly span: { + readonly __typename: "Span"; + readonly attributes: string; + readonly context: { + readonly spanId: string; + readonly traceId: string; + }; + readonly documentEvaluations: ReadonlyArray<{ + readonly documentPosition: number; + readonly explanation: string | null; + readonly label: string | null; + readonly name: string; + readonly score: number | null; + }>; + readonly documentRetrievalMetrics: ReadonlyArray<{ + readonly evaluationName: string; + readonly hit: number | null; + readonly ndcg: number | null; + readonly precision: number | null; + }>; + readonly events: ReadonlyArray<{ + readonly message: string; + readonly name: string; + readonly timestamp: string; + }>; + readonly id: string; + readonly input: { + readonly mimeType: MimeType; + readonly value: string; + } | null; + readonly latencyMs: number | null; + readonly name: string; + readonly output: { + readonly mimeType: MimeType; + readonly value: string; + } | null; + readonly parentId: string | null; + readonly spanEvaluations: ReadonlyArray<{ + readonly label: string | null; + readonly name: string; + readonly score: number | null; + }>; + readonly spanKind: SpanKind; + readonly startTime: string; + readonly statusCode: SpanStatusCode; + readonly statusMessage: string; + readonly tokenCountCompletion: number | null; + readonly tokenCountPrompt: number | null; + readonly tokenCountTotal: number | null; + readonly " $fragmentSpreads": FragmentRefs<"SpanEvaluationsTable_evals">; + } | { + // This will never be '%other', but we need some + // value in case none of the concrete values match. + readonly __typename: "%other"; + }; +}; +export type SpanDetailsQuery = { + response: SpanDetailsQuery$data; + variables: SpanDetailsQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "spanId" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "spanId" + } +], +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v4 = { + "alias": null, + "args": null, + "concreteType": "SpanContext", + "kind": "LinkedField", + "name": "context", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "spanId", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "traceId", + "storageKey": null + } + ], + "storageKey": null +}, +v5 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null +}, +v6 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "spanKind", + "storageKey": null +}, +v7 = { + "alias": "statusCode", + "args": null, + "kind": "ScalarField", + "name": "propagatedStatusCode", + "storageKey": null +}, +v8 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "statusMessage", + "storageKey": null +}, +v9 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startTime", + "storageKey": null +}, +v10 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "parentId", + "storageKey": null +}, +v11 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "latencyMs", + "storageKey": null +}, +v12 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "tokenCountTotal", + "storageKey": null +}, +v13 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "tokenCountPrompt", + "storageKey": null +}, +v14 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "tokenCountCompletion", + "storageKey": null +}, +v15 = [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "value", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "mimeType", + "storageKey": null + } +], +v16 = { + "alias": null, + "args": null, + "concreteType": "SpanIOValue", + "kind": "LinkedField", + "name": "input", + "plural": false, + "selections": (v15/*: any*/), + "storageKey": null +}, +v17 = { + "alias": null, + "args": null, + "concreteType": "SpanIOValue", + "kind": "LinkedField", + "name": "output", + "plural": false, + "selections": (v15/*: any*/), + "storageKey": null +}, +v18 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "attributes", + "storageKey": null +}, +v19 = { + "alias": null, + "args": null, + "concreteType": "SpanEvent", + "kind": "LinkedField", + "name": "events", + "plural": true, + "selections": [ + (v5/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "message", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "timestamp", + "storageKey": null + } + ], + "storageKey": null +}, +v20 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "label", + "storageKey": null +}, +v21 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "score", + "storageKey": null +}, +v22 = { + "alias": null, + "args": null, + "concreteType": "DocumentRetrievalMetrics", + "kind": "LinkedField", + "name": "documentRetrievalMetrics", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "evaluationName", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "ndcg", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "precision", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hit", + "storageKey": null + } + ], + "storageKey": null +}, +v23 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "explanation", + "storageKey": null +}, +v24 = { + "alias": null, + "args": null, + "concreteType": "DocumentEvaluation", + "kind": "LinkedField", + "name": "documentEvaluations", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "documentPosition", + "storageKey": null + }, + (v5/*: any*/), + (v20/*: any*/), + (v21/*: any*/), + (v23/*: any*/) + ], + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "SpanDetailsQuery", + "selections": [ + { + "alias": "span", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v8/*: any*/), + (v9/*: any*/), + (v10/*: any*/), + (v11/*: any*/), + (v12/*: any*/), + (v13/*: any*/), + (v14/*: any*/), + (v16/*: any*/), + (v17/*: any*/), + (v18/*: any*/), + { + "kind": "RequiredField", + "field": (v19/*: any*/), + "action": "THROW", + "path": "span.events" + }, + { + "alias": null, + "args": null, + "concreteType": "SpanEvaluation", + "kind": "LinkedField", + "name": "spanEvaluations", + "plural": true, + "selections": [ + (v5/*: any*/), + (v20/*: any*/), + (v21/*: any*/) + ], + "storageKey": null + }, + (v22/*: any*/), + (v24/*: any*/), + { + "args": null, + "kind": "FragmentSpread", + "name": "SpanEvaluationsTable_evals" + } + ], + "type": "Span", + "abstractKey": null + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "SpanDetailsQuery", + "selections": [ + { + "alias": "span", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + { + "kind": "TypeDiscriminator", + "abstractKey": "__isNode" + }, + (v3/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + (v4/*: any*/), + (v5/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v8/*: any*/), + (v9/*: any*/), + (v10/*: any*/), + (v11/*: any*/), + (v12/*: any*/), + (v13/*: any*/), + (v14/*: any*/), + (v16/*: any*/), + (v17/*: any*/), + (v18/*: any*/), + (v19/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "SpanEvaluation", + "kind": "LinkedField", + "name": "spanEvaluations", + "plural": true, + "selections": [ + (v5/*: any*/), + (v20/*: any*/), + (v21/*: any*/), + (v23/*: any*/) + ], + "storageKey": null + }, + (v22/*: any*/), + (v24/*: any*/) + ], + "type": "Span", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "994295103990e4b8fbff3b1422e1647f", + "id": null, + "metadata": {}, + "name": "SpanDetailsQuery", + "operationKind": "query", + "text": "query SpanDetailsQuery(\n $spanId: GlobalID!\n) {\n span: node(id: $spanId) {\n __typename\n ... on Span {\n id\n context {\n spanId\n traceId\n }\n name\n spanKind\n statusCode: propagatedStatusCode\n statusMessage\n startTime\n parentId\n latencyMs\n tokenCountTotal\n tokenCountPrompt\n tokenCountCompletion\n input {\n value\n mimeType\n }\n output {\n value\n mimeType\n }\n attributes\n events {\n name\n message\n timestamp\n }\n spanEvaluations {\n name\n label\n score\n }\n documentRetrievalMetrics {\n evaluationName\n ndcg\n precision\n hit\n }\n documentEvaluations {\n documentPosition\n name\n label\n score\n explanation\n }\n ...SpanEvaluationsTable_evals\n }\n __isNode: __typename\n id\n }\n}\n\nfragment SpanEvaluationsTable_evals on Span {\n spanEvaluations {\n name\n label\n score\n explanation\n }\n}\n" + } +}; +})(); + +(node as any).hash = "39420c6270d451eca0528e7bb90fd065"; + +export default node; diff --git a/app/src/pages/trace/__generated__/TraceDetailsQuery.graphql.ts b/app/src/pages/trace/__generated__/TraceDetailsQuery.graphql.ts index 2aa9e2fe85..048cacfa47 100644 --- a/app/src/pages/trace/__generated__/TraceDetailsQuery.graphql.ts +++ b/app/src/pages/trace/__generated__/TraceDetailsQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<96098d0f874bb55df24c3a83a4d0a53b>> * @lightSyntaxTransform * @nogrep */ @@ -9,8 +9,6 @@ // @ts-nocheck import { ConcreteRequest, Query } from 'relay-runtime'; -import { FragmentRefs } from "relay-runtime"; -export type MimeType = "json" | "text"; export type SpanKind = "agent" | "chain" | "embedding" | "evaluator" | "guardrail" | "llm" | "reranker" | "retriever" | "tool" | "unknown"; export type SpanStatusCode = "ERROR" | "OK" | "UNSET"; export type TraceDetailsQuery$variables = { @@ -23,40 +21,13 @@ export type TraceDetailsQuery$data = { readonly spans: { readonly edges: ReadonlyArray<{ readonly span: { - readonly attributes: string; readonly context: { readonly spanId: string; readonly traceId: string; }; - readonly documentEvaluations: ReadonlyArray<{ - readonly documentPosition: number; - readonly explanation: string | null; - readonly label: string | null; - readonly name: string; - readonly score: number | null; - }>; - readonly documentRetrievalMetrics: ReadonlyArray<{ - readonly evaluationName: string; - readonly hit: number | null; - readonly ndcg: number | null; - readonly precision: number | null; - }>; - readonly events: ReadonlyArray<{ - readonly message: string; - readonly name: string; - readonly timestamp: string; - }>; readonly id: string; - readonly input: { - readonly mimeType: MimeType; - readonly value: string; - } | null; readonly latencyMs: number | null; readonly name: string; - readonly output: { - readonly mimeType: MimeType; - readonly value: string; - } | null; readonly parentId: string | null; readonly spanEvaluations: ReadonlyArray<{ readonly label: string | null; @@ -66,11 +37,9 @@ export type TraceDetailsQuery$data = { readonly spanKind: SpanKind; readonly startTime: string; readonly statusCode: SpanStatusCode; - readonly statusMessage: string; readonly tokenCountCompletion: number | null; readonly tokenCountPrompt: number | null; readonly tokenCountTotal: number | null; - readonly " $fragmentSpreads": FragmentRefs<"SpanEvaluationsTable_evals">; }; }>; }; @@ -100,272 +69,191 @@ v2 = [ "variableName": "id" } ], -v3 = [ - { - "kind": "Variable", - "name": "traceId", - "variableName": "traceId" - } -], -v4 = [ - { - "kind": "Literal", - "name": "first", - "value": 1000 - } -], -v5 = { +v3 = { "alias": null, "args": null, "kind": "ScalarField", "name": "id", "storageKey": null }, -v6 = { - "alias": null, - "args": null, - "concreteType": "SpanContext", - "kind": "LinkedField", - "name": "context", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "spanId", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "traceId", - "storageKey": null - } - ], - "storageKey": null -}, -v7 = { +v4 = { "alias": null, "args": null, "kind": "ScalarField", "name": "name", "storageKey": null }, -v8 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "spanKind", - "storageKey": null -}, -v9 = { - "alias": "statusCode", - "args": null, - "kind": "ScalarField", - "name": "propagatedStatusCode", - "storageKey": null -}, -v10 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "statusMessage", - "storageKey": null -}, -v11 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "startTime", - "storageKey": null -}, -v12 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "parentId", - "storageKey": null -}, -v13 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "latencyMs", - "storageKey": null -}, -v14 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "tokenCountTotal", - "storageKey": null -}, -v15 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "tokenCountPrompt", - "storageKey": null -}, -v16 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "tokenCountCompletion", - "storageKey": null -}, -v17 = [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "value", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "mimeType", - "storageKey": null - } -], -v18 = { - "alias": null, - "args": null, - "concreteType": "SpanIOValue", - "kind": "LinkedField", - "name": "input", - "plural": false, - "selections": (v17/*: any*/), - "storageKey": null -}, -v19 = { - "alias": null, - "args": null, - "concreteType": "SpanIOValue", - "kind": "LinkedField", - "name": "output", - "plural": false, - "selections": (v17/*: any*/), - "storageKey": null -}, -v20 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "attributes", - "storageKey": null -}, -v21 = { - "alias": null, - "args": null, - "concreteType": "SpanEvent", - "kind": "LinkedField", - "name": "events", - "plural": true, - "selections": [ - (v7/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "message", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "timestamp", - "storageKey": null - } - ], - "storageKey": null -}, -v22 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "label", - "storageKey": null -}, -v23 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "score", - "storageKey": null -}, -v24 = { - "alias": null, - "args": null, - "concreteType": "DocumentRetrievalMetrics", - "kind": "LinkedField", - "name": "documentRetrievalMetrics", - "plural": true, +v5 = { + "kind": "InlineFragment", "selections": [ { "alias": null, - "args": null, - "kind": "ScalarField", - "name": "evaluationName", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "ndcg", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "precision", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "hit", + "args": [ + { + "kind": "Variable", + "name": "traceId", + "variableName": "traceId" + } + ], + "concreteType": "Trace", + "kind": "LinkedField", + "name": "trace", + "plural": false, + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Literal", + "name": "first", + "value": 1000 + } + ], + "concreteType": "SpanConnection", + "kind": "LinkedField", + "name": "spans", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "SpanEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": "span", + "args": null, + "concreteType": "Span", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "SpanContext", + "kind": "LinkedField", + "name": "context", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "spanId", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "traceId", + "storageKey": null + } + ], + "storageKey": null + }, + (v4/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "spanKind", + "storageKey": null + }, + { + "alias": "statusCode", + "args": null, + "kind": "ScalarField", + "name": "propagatedStatusCode", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startTime", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "parentId", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "latencyMs", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "tokenCountTotal", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "tokenCountPrompt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "tokenCountCompletion", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "SpanEvaluation", + "kind": "LinkedField", + "name": "spanEvaluations", + "plural": true, + "selections": [ + (v4/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "label", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "score", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "spans(first:1000)" + } + ], "storageKey": null } ], - "storageKey": null -}, -v25 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "explanation", - "storageKey": null -}, -v26 = { - "alias": null, - "args": null, - "concreteType": "DocumentEvaluation", - "kind": "LinkedField", - "name": "documentEvaluations", - "plural": true, - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "documentPosition", - "storageKey": null - }, - (v7/*: any*/), - (v22/*: any*/), - (v23/*: any*/), - (v25/*: any*/) - ], - "storageKey": null + "type": "Project", + "abstractKey": null }; return { "fragment": { @@ -385,94 +273,7 @@ return { "name": "node", "plural": false, "selections": [ - { - "kind": "InlineFragment", - "selections": [ - { - "alias": null, - "args": (v3/*: any*/), - "concreteType": "Trace", - "kind": "LinkedField", - "name": "trace", - "plural": false, - "selections": [ - { - "alias": null, - "args": (v4/*: any*/), - "concreteType": "SpanConnection", - "kind": "LinkedField", - "name": "spans", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "SpanEdge", - "kind": "LinkedField", - "name": "edges", - "plural": true, - "selections": [ - { - "alias": "span", - "args": null, - "concreteType": "Span", - "kind": "LinkedField", - "name": "node", - "plural": false, - "selections": [ - (v5/*: any*/), - (v6/*: any*/), - (v7/*: any*/), - (v8/*: any*/), - (v9/*: any*/), - (v10/*: any*/), - (v11/*: any*/), - (v12/*: any*/), - (v13/*: any*/), - (v14/*: any*/), - (v15/*: any*/), - (v16/*: any*/), - (v18/*: any*/), - (v19/*: any*/), - (v20/*: any*/), - (v21/*: any*/), - { - "alias": null, - "args": null, - "concreteType": "SpanEvaluation", - "kind": "LinkedField", - "name": "spanEvaluations", - "plural": true, - "selections": [ - (v7/*: any*/), - (v22/*: any*/), - (v23/*: any*/) - ], - "storageKey": null - }, - (v24/*: any*/), - (v26/*: any*/), - { - "args": null, - "kind": "FragmentSpread", - "name": "SpanEvaluationsTable_evals" - } - ], - "storageKey": null - } - ], - "storageKey": null - } - ], - "storageKey": "spans(first:1000)" - } - ], - "storageKey": null - } - ], - "type": "Project", - "abstractKey": null - } + (v5/*: any*/) ], "storageKey": null } @@ -504,111 +305,28 @@ return { "name": "__typename", "storageKey": null }, - { - "kind": "InlineFragment", - "selections": [ - { - "alias": null, - "args": (v3/*: any*/), - "concreteType": "Trace", - "kind": "LinkedField", - "name": "trace", - "plural": false, - "selections": [ - { - "alias": null, - "args": (v4/*: any*/), - "concreteType": "SpanConnection", - "kind": "LinkedField", - "name": "spans", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "SpanEdge", - "kind": "LinkedField", - "name": "edges", - "plural": true, - "selections": [ - { - "alias": "span", - "args": null, - "concreteType": "Span", - "kind": "LinkedField", - "name": "node", - "plural": false, - "selections": [ - (v5/*: any*/), - (v6/*: any*/), - (v7/*: any*/), - (v8/*: any*/), - (v9/*: any*/), - (v10/*: any*/), - (v11/*: any*/), - (v12/*: any*/), - (v13/*: any*/), - (v14/*: any*/), - (v15/*: any*/), - (v16/*: any*/), - (v18/*: any*/), - (v19/*: any*/), - (v20/*: any*/), - (v21/*: any*/), - { - "alias": null, - "args": null, - "concreteType": "SpanEvaluation", - "kind": "LinkedField", - "name": "spanEvaluations", - "plural": true, - "selections": [ - (v7/*: any*/), - (v22/*: any*/), - (v23/*: any*/), - (v25/*: any*/) - ], - "storageKey": null - }, - (v24/*: any*/), - (v26/*: any*/) - ], - "storageKey": null - } - ], - "storageKey": null - } - ], - "storageKey": "spans(first:1000)" - } - ], - "storageKey": null - } - ], - "type": "Project", - "abstractKey": null - }, + (v5/*: any*/), { "kind": "TypeDiscriminator", "abstractKey": "__isNode" }, - (v5/*: any*/) + (v3/*: any*/) ], "storageKey": null } ] }, "params": { - "cacheID": "a7eb8bfce36ca7633be29b3bde1952b8", + "cacheID": "872e8d6e17fb1b6cf51bae98d6767208", "id": null, "metadata": {}, "name": "TraceDetailsQuery", "operationKind": "query", - "text": "query TraceDetailsQuery(\n $traceId: ID!\n $id: GlobalID!\n) {\n project: node(id: $id) {\n __typename\n ... on Project {\n trace(traceId: $traceId) {\n spans(first: 1000) {\n edges {\n span: node {\n id\n context {\n spanId\n traceId\n }\n name\n spanKind\n statusCode: propagatedStatusCode\n statusMessage\n startTime\n parentId\n latencyMs\n tokenCountTotal\n tokenCountPrompt\n tokenCountCompletion\n input {\n value\n mimeType\n }\n output {\n value\n mimeType\n }\n attributes\n events {\n name\n message\n timestamp\n }\n spanEvaluations {\n name\n label\n score\n }\n documentRetrievalMetrics {\n evaluationName\n ndcg\n precision\n hit\n }\n documentEvaluations {\n documentPosition\n name\n label\n score\n explanation\n }\n ...SpanEvaluationsTable_evals\n }\n }\n }\n }\n }\n __isNode: __typename\n id\n }\n}\n\nfragment SpanEvaluationsTable_evals on Span {\n spanEvaluations {\n name\n label\n score\n explanation\n }\n}\n" + "text": "query TraceDetailsQuery(\n $traceId: ID!\n $id: GlobalID!\n) {\n project: node(id: $id) {\n __typename\n ... on Project {\n trace(traceId: $traceId) {\n spans(first: 1000) {\n edges {\n span: node {\n id\n context {\n spanId\n traceId\n }\n name\n spanKind\n statusCode: propagatedStatusCode\n startTime\n parentId\n latencyMs\n tokenCountTotal\n tokenCountPrompt\n tokenCountCompletion\n spanEvaluations {\n name\n label\n score\n }\n }\n }\n }\n }\n }\n __isNode: __typename\n id\n }\n}\n" } }; })(); -(node as any).hash = "77c479ec3740896d2dadf3010f72760a"; +(node as any).hash = "73a6eacf0bb44e37ed4963cb27883c51"; export default node;