From 7ef8aeee8342c9fe464e2b773b2da1dc5e248329 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 23 Jul 2024 16:43:01 -0600 Subject: [PATCH] feat(annotations): refetch annootations on annotation changes --- app/schema.graphql | 2 + .../project/DatasetSelectorPopoverContent.tsx | 6 +- .../pages/trace/EditSpanAnnotationsDialog.tsx | 83 ++++--- app/src/pages/trace/NewSpanAnnotationForm.tsx | 11 +- .../pages/trace/SpanAnnotationActionMenu.tsx | 13 +- .../EditSpanAnnotationsDialogQuery.graphql.ts | 141 +++++------ ...tionsDialogSpanAnnotationsQuery.graphql.ts | 173 ++++++++++++++ ...notationsDialog_spanAnnotations.graphql.ts | 115 +++++++++ .../NewSpanAnnotationFormMutation.graphql.ts | 225 ++++++++++++++---- ...otationActionMenuDeleteMutation.graphql.ts | 224 ++++++++++++++--- .../mutations/span_annotations_mutations.py | 11 +- .../mutations/trace_annotations_mutations.py | 11 +- 12 files changed, 821 insertions(+), 194 deletions(-) create mode 100644 app/src/pages/trace/__generated__/EditSpanAnnotationsDialogSpanAnnotationsQuery.graphql.ts create mode 100644 app/src/pages/trace/__generated__/EditSpanAnnotationsDialog_spanAnnotations.graphql.ts diff --git a/app/schema.graphql b/app/schema.graphql index 44f247128f..5d6b4e80fb 100644 --- a/app/schema.graphql +++ b/app/schema.graphql @@ -1194,6 +1194,7 @@ type SpanAnnotation implements Node & Annotation { type SpanAnnotationMutationPayload { spanAnnotations: [SpanAnnotation!]! + query: Query! } type SpanAsExampleRevision implements ExampleRevision { @@ -1339,6 +1340,7 @@ type TraceAnnotation implements Node { type TraceAnnotationMutationPayload { traceAnnotations: [TraceAnnotation!]! + query: Query! } type TraceEvaluation implements Annotation { diff --git a/app/src/pages/project/DatasetSelectorPopoverContent.tsx b/app/src/pages/project/DatasetSelectorPopoverContent.tsx index 7ac4e96545..4505167547 100644 --- a/app/src/pages/project/DatasetSelectorPopoverContent.tsx +++ b/app/src/pages/project/DatasetSelectorPopoverContent.tsx @@ -16,6 +16,7 @@ import { } from "@arizeai/components"; import { DatasetSelectorPopoverContent_datasets$key } from "./__generated__/DatasetSelectorPopoverContent_datasets.graphql"; +import { DatasetSelectorPopoverContentDatasetsQuery } from "./__generated__/DatasetSelectorPopoverContentDatasetsQuery.graphql"; import { DatasetSelectorPopoverContentQuery } from "./__generated__/DatasetSelectorPopoverContentQuery.graphql"; export type DatasetSelectorPopoverContentProps = { @@ -83,7 +84,10 @@ function DatasetsListBox(props: { onDatasetSelected: (datasetId: string) => void; }) { const { search, onDatasetSelected } = props; - const [data] = useRefetchableFragment( + const [data] = useRefetchableFragment< + DatasetSelectorPopoverContentDatasetsQuery, + DatasetSelectorPopoverContent_datasets$key + >( graphql` fragment DatasetSelectorPopoverContent_datasets on Query @refetchable(queryName: "DatasetSelectorPopoverContentDatasetsQuery") { diff --git a/app/src/pages/trace/EditSpanAnnotationsDialog.tsx b/app/src/pages/trace/EditSpanAnnotationsDialog.tsx index c0ee4f4ab6..90688f5c32 100644 --- a/app/src/pages/trace/EditSpanAnnotationsDialog.tsx +++ b/app/src/pages/trace/EditSpanAnnotationsDialog.tsx @@ -1,5 +1,5 @@ import React, { Suspense, useMemo, useState } from "react"; -import { graphql, useLazyLoadQuery } from "react-relay"; +import { graphql, useLazyLoadQuery, useRefetchableFragment } from "react-relay"; import { css } from "@emotion/react"; import { @@ -22,12 +22,14 @@ import { Empty } from "@phoenix/components/Empty"; import { useNotifySuccess } from "@phoenix/contexts"; import { formatFloat } from "@phoenix/utils/numberFormatUtils"; -import { EditSpanAnnotationsDialogNewAnnotationQuery } from "./__generated__/EditSpanAnnotationsDialogNewAnnotationQuery.graphql"; import { AnnotatorKind, - EditSpanAnnotationsDialogQuery, - EditSpanAnnotationsDialogQuery$data, -} from "./__generated__/EditSpanAnnotationsDialogQuery.graphql"; + EditSpanAnnotationsDialog_spanAnnotations$data, + EditSpanAnnotationsDialog_spanAnnotations$key, +} from "./__generated__/EditSpanAnnotationsDialog_spanAnnotations.graphql"; +import { EditSpanAnnotationsDialogNewAnnotationQuery } from "./__generated__/EditSpanAnnotationsDialogNewAnnotationQuery.graphql"; +import { EditSpanAnnotationsDialogQuery } from "./__generated__/EditSpanAnnotationsDialogQuery.graphql"; +import { EditSpanAnnotationsDialogSpanAnnotationsQuery } from "./__generated__/EditSpanAnnotationsDialogSpanAnnotationsQuery.graphql"; import { NewSpanAnnotationForm } from "./NewSpanAnnotationForm"; import { SpanAnnotationActionMenu } from "./SpanAnnotationActionMenu"; import { SpanAnnotationForm } from "./SpanAnnotationForm"; @@ -43,7 +45,6 @@ export function EditSpanAnnotationsDialog( const [newAnnotationName, setNewAnnotationName] = useState( null ); - const [fetchKey, setFetchKey] = useState(0); const notifySuccess = useNotifySuccess(); return ( { setNewAnnotationName(null); - setFetchKey((key) => key + 1); notifySuccess({ title: `New Span Annotation`, message: `Annotation ${newAnnotationName} has been created.`, @@ -86,7 +86,7 @@ export function EditSpanAnnotationsDialog( )} - + @@ -166,36 +166,52 @@ function NewAnnotationPopover(props: NewAnnotationPopoverProps) { ); } -type EditSpanAnnotationsProps = EditSpanAnnotationsDialogProps & { - /** - * Key used to force a refetch of the annotations - */ - fetchKey: number; -}; +type EditSpanAnnotationsProps = EditSpanAnnotationsDialogProps; + function EditSpanAnnotations(props: EditSpanAnnotationsProps) { - const { fetchKey } = props; const data = useLazyLoadQuery( graphql` query EditSpanAnnotationsDialogQuery($spanId: GlobalID!) { span: node(id: $spanId) { id ... on Span { - spanAnnotations { - id - name - annotatorKind - score - label - explanation - } + ...EditSpanAnnotationsDialog_spanAnnotations } } } `, { spanId: props.spanNodeId }, - { fetchKey, fetchPolicy: "store-and-network" } + { fetchPolicy: "store-and-network" } + ); + return ; +} + +function SpanAnnotationsList(props: { + span: EditSpanAnnotationsDialog_spanAnnotations$key; +}) { + const { span } = props; + const [data] = useRefetchableFragment< + EditSpanAnnotationsDialogSpanAnnotationsQuery, + EditSpanAnnotationsDialog_spanAnnotations$key + >( + graphql` + fragment EditSpanAnnotationsDialog_spanAnnotations on Span + @refetchable(queryName: "EditSpanAnnotationsDialogSpanAnnotationsQuery") { + id + spanAnnotations { + id + name + annotatorKind + score + label + explanation + } + } + `, + span ); - const annotations = data.span.spanAnnotations || []; + + const annotations = data.spanAnnotations || []; const hasAnnotations = annotations.length > 0; return (
@@ -211,7 +227,7 @@ function EditSpanAnnotations(props: EditSpanAnnotationsProps) { > {annotations.map((annotation, idx) => (
  • - +
  • ))} @@ -263,11 +279,14 @@ function NewSpanAnnotationCard(props: { } type Annotation = NonNullable< - EditSpanAnnotationsDialogQuery$data["span"]["spanAnnotations"] + EditSpanAnnotationsDialog_spanAnnotations$data["spanAnnotations"] >[number]; -function SpanAnnotationCard(props: { annotation: Annotation }) { - const { annotation } = props; +function SpanAnnotationCard(props: { + annotation: Annotation; + spanNodeId: string; +}) { + const { annotation, spanNodeId } = props; const [error, setError] = useState(null); const notifySuccess = useNotifySuccess(); return ( @@ -287,6 +306,7 @@ function SpanAnnotationCard(props: { annotation: Annotation }) { { notifySuccess({ @@ -412,8 +432,9 @@ function NewAnnotationPopoverContent(props: { if (keys === "all" || keys.size === 0) { return; } - const name = keys.entries().next().value[0]; - setNewName(name); + const nameKey = keys.values().next().value; + const name = nameKey as string; + setNewName(name || ""); }} disabledKeys={existingAnnotationNames} > diff --git a/app/src/pages/trace/NewSpanAnnotationForm.tsx b/app/src/pages/trace/NewSpanAnnotationForm.tsx index d2097f017d..3e49073bc5 100644 --- a/app/src/pages/trace/NewSpanAnnotationForm.tsx +++ b/app/src/pages/trace/NewSpanAnnotationForm.tsx @@ -19,11 +19,15 @@ export function NewSpanAnnotationForm(props: NewSpanAnnotationFormProps) { graphql` mutation NewSpanAnnotationFormMutation( $input: CreateSpanAnnotationInput! + $spanId: GlobalID! ) { createSpanAnnotations(input: [$input]) { - spanAnnotations { - id - name + query { + node(id: $spanId) { + ... on Span { + ...EditSpanAnnotationsDialog_spanAnnotations + } + } } } } @@ -37,6 +41,7 @@ export function NewSpanAnnotationForm(props: NewSpanAnnotationFormProps) { annotatorKind: "HUMAN", ...data, }, + spanId: spanNodeId, }, onCompleted: () => { onCreated(); diff --git a/app/src/pages/trace/SpanAnnotationActionMenu.tsx b/app/src/pages/trace/SpanAnnotationActionMenu.tsx index 35e669cd26..1083e0f319 100644 --- a/app/src/pages/trace/SpanAnnotationActionMenu.tsx +++ b/app/src/pages/trace/SpanAnnotationActionMenu.tsx @@ -20,6 +20,7 @@ import { AnnotationActionMenu } from "./AnnotationActionMenu"; type SpanAnnotationActionMenuProps = { annotationId: string; + spanNodeId: string; annotationName: string; onSpanAnnotationDelete: () => void; onSpanAnnotationDeleteError: (error: Error) => void; @@ -28,6 +29,7 @@ type SpanAnnotationActionMenuProps = { export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) { const { annotationId, + spanNodeId, annotationName, onSpanAnnotationDelete, onSpanAnnotationDeleteError, @@ -37,9 +39,16 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) { useMutation(graphql` mutation SpanAnnotationActionMenuDeleteMutation( $annotationId: GlobalID! + $spanId: GlobalID! ) { deleteSpanAnnotations(input: { annotationIds: [$annotationId] }) { - __typename + query { + node(id: $spanId) { + ... on Span { + ...EditSpanAnnotationsDialog_spanAnnotations + } + } + } } } `); @@ -49,6 +58,7 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) { commitDelete({ variables: { annotationId, + spanId: spanNodeId, }, onCompleted: () => { onSpanAnnotationDelete(); @@ -61,6 +71,7 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) { }, [ commitDelete, annotationId, + spanNodeId, onSpanAnnotationDelete, onSpanAnnotationDeleteError, ]); diff --git a/app/src/pages/trace/__generated__/EditSpanAnnotationsDialogQuery.graphql.ts b/app/src/pages/trace/__generated__/EditSpanAnnotationsDialogQuery.graphql.ts index 4d2cfe92f2..899dbdb7be 100644 --- a/app/src/pages/trace/__generated__/EditSpanAnnotationsDialogQuery.graphql.ts +++ b/app/src/pages/trace/__generated__/EditSpanAnnotationsDialogQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<7184374db9223191cda8fda4684866cd>> + * @generated SignedSource<<7c443ddd13fc27d1f78994baa4d450ab>> * @lightSyntaxTransform * @nogrep */ @@ -9,21 +9,14 @@ // @ts-nocheck import { ConcreteRequest, Query } from 'relay-runtime'; -export type AnnotatorKind = "HUMAN" | "LLM"; +import { FragmentRefs } from "relay-runtime"; export type EditSpanAnnotationsDialogQuery$variables = { spanId: string; }; export type EditSpanAnnotationsDialogQuery$data = { readonly span: { readonly id: string; - readonly spanAnnotations?: ReadonlyArray<{ - readonly annotatorKind: AnnotatorKind; - readonly explanation: string | null; - readonly id: string; - readonly label: string | null; - readonly name: string; - readonly score: number | null; - }>; + readonly " $fragmentSpreads": FragmentRefs<"EditSpanAnnotationsDialog_spanAnnotations">; }; }; export type EditSpanAnnotationsDialogQuery = { @@ -52,60 +45,6 @@ v2 = { "kind": "ScalarField", "name": "id", "storageKey": null -}, -v3 = { - "kind": "InlineFragment", - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "SpanAnnotation", - "kind": "LinkedField", - "name": "spanAnnotations", - "plural": true, - "selections": [ - (v2/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "name", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "annotatorKind", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "score", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "label", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "explanation", - "storageKey": null - } - ], - "storageKey": null - } - ], - "type": "Span", - "abstractKey": null }; return { "fragment": { @@ -123,7 +62,18 @@ return { "plural": false, "selections": [ (v2/*: any*/), - (v3/*: any*/) + { + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "EditSpanAnnotationsDialog_spanAnnotations" + } + ], + "type": "Span", + "abstractKey": null + } ], "storageKey": null } @@ -153,23 +103,76 @@ return { "storageKey": null }, (v2/*: any*/), - (v3/*: any*/) + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "SpanAnnotation", + "kind": "LinkedField", + "name": "spanAnnotations", + "plural": true, + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "annotatorKind", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "score", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "label", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "explanation", + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Span", + "abstractKey": null + } ], "storageKey": null } ] }, "params": { - "cacheID": "4703de6d0a741188580b0c6bc115471e", + "cacheID": "532b3c148c3bf1411b8820714c68f4e3", "id": null, "metadata": {}, "name": "EditSpanAnnotationsDialogQuery", "operationKind": "query", - "text": "query EditSpanAnnotationsDialogQuery(\n $spanId: GlobalID!\n) {\n span: node(id: $spanId) {\n __typename\n id\n ... on Span {\n spanAnnotations {\n id\n name\n annotatorKind\n score\n label\n explanation\n }\n }\n }\n}\n" + "text": "query EditSpanAnnotationsDialogQuery(\n $spanId: GlobalID!\n) {\n span: node(id: $spanId) {\n __typename\n id\n ... on Span {\n ...EditSpanAnnotationsDialog_spanAnnotations\n }\n }\n}\n\nfragment EditSpanAnnotationsDialog_spanAnnotations on Span {\n id\n spanAnnotations {\n id\n name\n annotatorKind\n score\n label\n explanation\n }\n}\n" } }; })(); -(node as any).hash = "0e5850a0584aaf8e194cad2066d9b2fe"; +(node as any).hash = "36093f4285a168993ec87fd6aac82365"; export default node; diff --git a/app/src/pages/trace/__generated__/EditSpanAnnotationsDialogSpanAnnotationsQuery.graphql.ts b/app/src/pages/trace/__generated__/EditSpanAnnotationsDialogSpanAnnotationsQuery.graphql.ts new file mode 100644 index 0000000000..9ea8bfd35d --- /dev/null +++ b/app/src/pages/trace/__generated__/EditSpanAnnotationsDialogSpanAnnotationsQuery.graphql.ts @@ -0,0 +1,173 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest, Query } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type EditSpanAnnotationsDialogSpanAnnotationsQuery$variables = { + id: string; +}; +export type EditSpanAnnotationsDialogSpanAnnotationsQuery$data = { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"EditSpanAnnotationsDialog_spanAnnotations">; + }; +}; +export type EditSpanAnnotationsDialogSpanAnnotationsQuery = { + response: EditSpanAnnotationsDialogSpanAnnotationsQuery$data; + variables: EditSpanAnnotationsDialogSpanAnnotationsQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "id" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "id" + } +], +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "EditSpanAnnotationsDialogSpanAnnotationsQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "EditSpanAnnotationsDialog_spanAnnotations" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "EditSpanAnnotationsDialogSpanAnnotationsQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + { + "kind": "TypeDiscriminator", + "abstractKey": "__isNode" + }, + (v2/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "SpanAnnotation", + "kind": "LinkedField", + "name": "spanAnnotations", + "plural": true, + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "annotatorKind", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "score", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "label", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "explanation", + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Span", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "8649eb1dd42a29a0d38b9a1538490de4", + "id": null, + "metadata": {}, + "name": "EditSpanAnnotationsDialogSpanAnnotationsQuery", + "operationKind": "query", + "text": "query EditSpanAnnotationsDialogSpanAnnotationsQuery(\n $id: GlobalID!\n) {\n node(id: $id) {\n __typename\n ...EditSpanAnnotationsDialog_spanAnnotations\n __isNode: __typename\n id\n }\n}\n\nfragment EditSpanAnnotationsDialog_spanAnnotations on Span {\n id\n spanAnnotations {\n id\n name\n annotatorKind\n score\n label\n explanation\n }\n}\n" + } +}; +})(); + +(node as any).hash = "07aedb847a2af03a77823f0afc0c98d4"; + +export default node; diff --git a/app/src/pages/trace/__generated__/EditSpanAnnotationsDialog_spanAnnotations.graphql.ts b/app/src/pages/trace/__generated__/EditSpanAnnotationsDialog_spanAnnotations.graphql.ts new file mode 100644 index 0000000000..f5a30d8413 --- /dev/null +++ b/app/src/pages/trace/__generated__/EditSpanAnnotationsDialog_spanAnnotations.graphql.ts @@ -0,0 +1,115 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment, RefetchableFragment } from 'relay-runtime'; +export type AnnotatorKind = "HUMAN" | "LLM"; +import { FragmentRefs } from "relay-runtime"; +export type EditSpanAnnotationsDialog_spanAnnotations$data = { + readonly id: string; + readonly spanAnnotations: ReadonlyArray<{ + readonly annotatorKind: AnnotatorKind; + readonly explanation: string | null; + readonly id: string; + readonly label: string | null; + readonly name: string; + readonly score: number | null; + }>; + readonly " $fragmentType": "EditSpanAnnotationsDialog_spanAnnotations"; +}; +export type EditSpanAnnotationsDialog_spanAnnotations$key = { + readonly " $data"?: EditSpanAnnotationsDialog_spanAnnotations$data; + readonly " $fragmentSpreads": FragmentRefs<"EditSpanAnnotationsDialog_spanAnnotations">; +}; + +import EditSpanAnnotationsDialogSpanAnnotationsQuery_graphql from './EditSpanAnnotationsDialogSpanAnnotationsQuery.graphql'; + +const node: ReaderFragment = (function(){ +var v0 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": { + "refetch": { + "connection": null, + "fragmentPathInResult": [ + "node" + ], + "operation": EditSpanAnnotationsDialogSpanAnnotationsQuery_graphql, + "identifierInfo": { + "identifierField": "id", + "identifierQueryVariableName": "id" + } + } + }, + "name": "EditSpanAnnotationsDialog_spanAnnotations", + "selections": [ + (v0/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "SpanAnnotation", + "kind": "LinkedField", + "name": "spanAnnotations", + "plural": true, + "selections": [ + (v0/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "annotatorKind", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "score", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "label", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "explanation", + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Span", + "abstractKey": null +}; +})(); + +(node as any).hash = "07aedb847a2af03a77823f0afc0c98d4"; + +export default node; diff --git a/app/src/pages/trace/__generated__/NewSpanAnnotationFormMutation.graphql.ts b/app/src/pages/trace/__generated__/NewSpanAnnotationFormMutation.graphql.ts index f19b443042..8059637506 100644 --- a/app/src/pages/trace/__generated__/NewSpanAnnotationFormMutation.graphql.ts +++ b/app/src/pages/trace/__generated__/NewSpanAnnotationFormMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<79ed54366bce1fa7c735125598139cc8>> + * @generated SignedSource<<01d86be78c16abd5b9e41431b756515e>> * @lightSyntaxTransform * @nogrep */ @@ -9,6 +9,7 @@ // @ts-nocheck import { ConcreteRequest, Mutation } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; export type AnnotatorKind = "HUMAN" | "LLM"; export type CreateSpanAnnotationInput = { annotatorKind: AnnotatorKind; @@ -21,13 +22,15 @@ export type CreateSpanAnnotationInput = { }; export type NewSpanAnnotationFormMutation$variables = { input: CreateSpanAnnotationInput; + spanId: string; }; export type NewSpanAnnotationFormMutation$data = { readonly createSpanAnnotations: { - readonly spanAnnotations: ReadonlyArray<{ - readonly id: string; - readonly name: string; - }>; + readonly query: { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"EditSpanAnnotationsDialog_spanAnnotations">; + }; + }; }; }; export type NewSpanAnnotationFormMutation = { @@ -41,65 +44,93 @@ var v0 = [ "defaultValue": null, "kind": "LocalArgument", "name": "input" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "spanId" } ], v1 = [ { - "alias": null, - "args": [ + "items": [ { - "items": [ - { - "kind": "Variable", - "name": "input.0", - "variableName": "input" - } - ], - "kind": "ListValue", - "name": "input" + "kind": "Variable", + "name": "input.0", + "variableName": "input" } ], - "concreteType": "SpanAnnotationMutationPayload", - "kind": "LinkedField", - "name": "createSpanAnnotations", - "plural": false, + "kind": "ListValue", + "name": "input" + } +], +v2 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "spanId" + } +], +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "NewSpanAnnotationFormMutation", "selections": [ { "alias": null, - "args": null, - "concreteType": "SpanAnnotation", + "args": (v1/*: any*/), + "concreteType": "SpanAnnotationMutationPayload", "kind": "LinkedField", - "name": "spanAnnotations", - "plural": true, + "name": "createSpanAnnotations", + "plural": false, "selections": [ { "alias": null, "args": null, - "kind": "ScalarField", - "name": "id", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "name", + "concreteType": "Query", + "kind": "LinkedField", + "name": "query", + "plural": false, + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "EditSpanAnnotationsDialog_spanAnnotations" + } + ], + "type": "Span", + "abstractKey": null + } + ], + "storageKey": null + } + ], "storageKey": null } ], "storageKey": null } ], - "storageKey": null - } -]; -return { - "fragment": { - "argumentDefinitions": (v0/*: any*/), - "kind": "Fragment", - "metadata": null, - "name": "NewSpanAnnotationFormMutation", - "selections": (v1/*: any*/), "type": "Mutation", "abstractKey": null }, @@ -108,19 +139,119 @@ return { "argumentDefinitions": (v0/*: any*/), "kind": "Operation", "name": "NewSpanAnnotationFormMutation", - "selections": (v1/*: any*/) + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": "SpanAnnotationMutationPayload", + "kind": "LinkedField", + "name": "createSpanAnnotations", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Query", + "kind": "LinkedField", + "name": "query", + "plural": false, + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + { + "kind": "TypeDiscriminator", + "abstractKey": "__isNode" + }, + (v3/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "SpanAnnotation", + "kind": "LinkedField", + "name": "spanAnnotations", + "plural": true, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "annotatorKind", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "score", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "label", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "explanation", + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Span", + "abstractKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ] }, "params": { - "cacheID": "0a925286639f9e4c3e0d8dd9a7fbb359", + "cacheID": "d6f016f4dfb0c142854c3ecd840b09f5", "id": null, "metadata": {}, "name": "NewSpanAnnotationFormMutation", "operationKind": "mutation", - "text": "mutation NewSpanAnnotationFormMutation(\n $input: CreateSpanAnnotationInput!\n) {\n createSpanAnnotations(input: [$input]) {\n spanAnnotations {\n id\n name\n }\n }\n}\n" + "text": "mutation NewSpanAnnotationFormMutation(\n $input: CreateSpanAnnotationInput!\n $spanId: GlobalID!\n) {\n createSpanAnnotations(input: [$input]) {\n query {\n node(id: $spanId) {\n __typename\n ... on Span {\n ...EditSpanAnnotationsDialog_spanAnnotations\n }\n __isNode: __typename\n id\n }\n }\n }\n}\n\nfragment EditSpanAnnotationsDialog_spanAnnotations on Span {\n id\n spanAnnotations {\n id\n name\n annotatorKind\n score\n label\n explanation\n }\n}\n" } }; })(); -(node as any).hash = "f15659fb1f6af1293742a5fa1edf52e5"; +(node as any).hash = "ded0a7a64a2706f6ec472a63c1c57eca"; export default node; diff --git a/app/src/pages/trace/__generated__/SpanAnnotationActionMenuDeleteMutation.graphql.ts b/app/src/pages/trace/__generated__/SpanAnnotationActionMenuDeleteMutation.graphql.ts index 08122bfc67..9199a7e7f0 100644 --- a/app/src/pages/trace/__generated__/SpanAnnotationActionMenuDeleteMutation.graphql.ts +++ b/app/src/pages/trace/__generated__/SpanAnnotationActionMenuDeleteMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<603156bd64d9bf9bdc5d25052634c9ae>> + * @generated SignedSource<<07f2e34c77d2b1b7483985187913fc92>> * @lightSyntaxTransform * @nogrep */ @@ -9,12 +9,18 @@ // @ts-nocheck import { ConcreteRequest, Mutation } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; export type SpanAnnotationActionMenuDeleteMutation$variables = { annotationId: string; + spanId: string; }; export type SpanAnnotationActionMenuDeleteMutation$data = { readonly deleteSpanAnnotations: { - readonly __typename: "SpanAnnotationMutationPayload"; + readonly query: { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"EditSpanAnnotationsDialog_spanAnnotations">; + }; + }; }; }; export type SpanAnnotationActionMenuDeleteMutation = { @@ -28,53 +34,99 @@ var v0 = [ "defaultValue": null, "kind": "LocalArgument", "name": "annotationId" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "spanId" } ], v1 = [ { - "alias": null, - "args": [ + "fields": [ { - "fields": [ + "items": [ { - "items": [ - { - "kind": "Variable", - "name": "annotationIds.0", - "variableName": "annotationId" - } - ], - "kind": "ListValue", - "name": "annotationIds" + "kind": "Variable", + "name": "annotationIds.0", + "variableName": "annotationId" } ], - "kind": "ObjectValue", - "name": "input" + "kind": "ListValue", + "name": "annotationIds" } ], - "concreteType": "SpanAnnotationMutationPayload", - "kind": "LinkedField", - "name": "deleteSpanAnnotations", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "__typename", - "storageKey": null - } - ], - "storageKey": null + "kind": "ObjectValue", + "name": "input" + } +], +v2 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "spanId" } -]; +], +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; return { "fragment": { "argumentDefinitions": (v0/*: any*/), "kind": "Fragment", "metadata": null, "name": "SpanAnnotationActionMenuDeleteMutation", - "selections": (v1/*: any*/), + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": "SpanAnnotationMutationPayload", + "kind": "LinkedField", + "name": "deleteSpanAnnotations", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Query", + "kind": "LinkedField", + "name": "query", + "plural": false, + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "EditSpanAnnotationsDialog_spanAnnotations" + } + ], + "type": "Span", + "abstractKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], "type": "Mutation", "abstractKey": null }, @@ -83,19 +135,119 @@ return { "argumentDefinitions": (v0/*: any*/), "kind": "Operation", "name": "SpanAnnotationActionMenuDeleteMutation", - "selections": (v1/*: any*/) + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": "SpanAnnotationMutationPayload", + "kind": "LinkedField", + "name": "deleteSpanAnnotations", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Query", + "kind": "LinkedField", + "name": "query", + "plural": false, + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + { + "kind": "TypeDiscriminator", + "abstractKey": "__isNode" + }, + (v3/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "SpanAnnotation", + "kind": "LinkedField", + "name": "spanAnnotations", + "plural": true, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "annotatorKind", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "score", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "label", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "explanation", + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Span", + "abstractKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ] }, "params": { - "cacheID": "6745f5629565f1a550bcc4cf6514b795", + "cacheID": "422687a283120080277d2649c1b9f6ee", "id": null, "metadata": {}, "name": "SpanAnnotationActionMenuDeleteMutation", "operationKind": "mutation", - "text": "mutation SpanAnnotationActionMenuDeleteMutation(\n $annotationId: GlobalID!\n) {\n deleteSpanAnnotations(input: {annotationIds: [$annotationId]}) {\n __typename\n }\n}\n" + "text": "mutation SpanAnnotationActionMenuDeleteMutation(\n $annotationId: GlobalID!\n $spanId: GlobalID!\n) {\n deleteSpanAnnotations(input: {annotationIds: [$annotationId]}) {\n query {\n node(id: $spanId) {\n __typename\n ... on Span {\n ...EditSpanAnnotationsDialog_spanAnnotations\n }\n __isNode: __typename\n id\n }\n }\n }\n}\n\nfragment EditSpanAnnotationsDialog_spanAnnotations on Span {\n id\n spanAnnotations {\n id\n name\n annotatorKind\n score\n label\n explanation\n }\n}\n" } }; })(); -(node as any).hash = "911d3053fb16cfc65512f83b0d428772"; +(node as any).hash = "a898fcb037b08cb626daaf3d385588ce"; export default node; diff --git a/src/phoenix/server/api/mutations/span_annotations_mutations.py b/src/phoenix/server/api/mutations/span_annotations_mutations.py index 6a574c4886..1b4f3d62b2 100644 --- a/src/phoenix/server/api/mutations/span_annotations_mutations.py +++ b/src/phoenix/server/api/mutations/span_annotations_mutations.py @@ -11,6 +11,7 @@ from phoenix.server.api.input_types.DeleteAnnotationsInput import DeleteAnnotationsInput from phoenix.server.api.input_types.PatchAnnotationInput import PatchAnnotationInput from phoenix.server.api.mutations.auth import IsAuthenticated +from phoenix.server.api.queries import Query from phoenix.server.api.types.node import from_global_id_with_expected_type from phoenix.server.api.types.SpanAnnotation import SpanAnnotation, to_gql_span_annotation @@ -18,6 +19,7 @@ @strawberry.type class SpanAnnotationMutationPayload: span_annotations: List[SpanAnnotation] + query: Query @strawberry.type @@ -49,7 +51,8 @@ async def create_span_annotations( return SpanAnnotationMutationPayload( span_annotations=[ to_gql_span_annotation(annotation) for annotation in inserted_annotations - ] + ], + query=Query(), ) @strawberry.mutation(permission_classes=[IsAuthenticated]) # type: ignore @@ -89,7 +92,7 @@ async def patch_span_annotations( if span_annotation is not None: patched_annotations.append(to_gql_span_annotation(span_annotation)) - return SpanAnnotationMutationPayload(span_annotations=patched_annotations) + return SpanAnnotationMutationPayload(span_annotations=patched_annotations, query=Query()) @strawberry.mutation(permission_classes=[IsAuthenticated]) # type: ignore async def delete_span_annotations( @@ -111,4 +114,6 @@ async def delete_span_annotations( deleted_annotations_gql = [ to_gql_span_annotation(annotation) for annotation in deleted_annotations ] - return SpanAnnotationMutationPayload(span_annotations=deleted_annotations_gql) + return SpanAnnotationMutationPayload( + span_annotations=deleted_annotations_gql, query=Query() + ) diff --git a/src/phoenix/server/api/mutations/trace_annotations_mutations.py b/src/phoenix/server/api/mutations/trace_annotations_mutations.py index 704fdbed83..db6b313d81 100644 --- a/src/phoenix/server/api/mutations/trace_annotations_mutations.py +++ b/src/phoenix/server/api/mutations/trace_annotations_mutations.py @@ -11,6 +11,7 @@ from phoenix.server.api.input_types.DeleteAnnotationsInput import DeleteAnnotationsInput from phoenix.server.api.input_types.PatchAnnotationInput import PatchAnnotationInput from phoenix.server.api.mutations.auth import IsAuthenticated +from phoenix.server.api.queries import Query from phoenix.server.api.types.node import from_global_id_with_expected_type from phoenix.server.api.types.TraceAnnotation import TraceAnnotation, to_gql_trace_annotation @@ -18,6 +19,7 @@ @strawberry.type class TraceAnnotationMutationPayload: trace_annotations: List[TraceAnnotation] + query: Query @strawberry.type @@ -49,7 +51,8 @@ async def create_trace_annotations( return TraceAnnotationMutationPayload( trace_annotations=[ to_gql_trace_annotation(annotation) for annotation in inserted_annotations - ] + ], + query=Query(), ) @strawberry.mutation(permission_classes=[IsAuthenticated]) # type: ignore @@ -89,7 +92,7 @@ async def patch_trace_annotations( if trace_annotation: patched_annotations.append(to_gql_trace_annotation(trace_annotation)) - return TraceAnnotationMutationPayload(trace_annotations=patched_annotations) + return TraceAnnotationMutationPayload(trace_annotations=patched_annotations, query=Query()) @strawberry.mutation(permission_classes=[IsAuthenticated]) # type: ignore async def delete_trace_annotations( @@ -111,4 +114,6 @@ async def delete_trace_annotations( deleted_annotations_gql = [ to_gql_trace_annotation(annotation) for annotation in deleted_annotations ] - return TraceAnnotationMutationPayload(trace_annotations=deleted_annotations_gql) + return TraceAnnotationMutationPayload( + trace_annotations=deleted_annotations_gql, query=Query() + )