Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(annotations): refetch annotations on annotation changes #3980

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,7 @@ type SpanAnnotation implements Node & Annotation {

type SpanAnnotationMutationPayload {
spanAnnotations: [SpanAnnotation!]!
query: Query!
}

type SpanAsExampleRevision implements ExampleRevision {
Expand Down Expand Up @@ -1339,6 +1340,7 @@ type TraceAnnotation implements Node {

type TraceAnnotationMutationPayload {
traceAnnotations: [TraceAnnotation!]!
query: Query!
}

type TraceEvaluation implements Annotation {
Expand Down
6 changes: 5 additions & 1 deletion app/src/pages/project/DatasetSelectorPopoverContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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") {
Expand Down
83 changes: 52 additions & 31 deletions app/src/pages/trace/EditSpanAnnotationsDialog.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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";
Expand All @@ -43,7 +45,6 @@ export function EditSpanAnnotationsDialog(
const [newAnnotationName, setNewAnnotationName] = useState<string | null>(
null
);
const [fetchKey, setFetchKey] = useState(0);
const notifySuccess = useNotifySuccess();
return (
<Dialog
Expand Down Expand Up @@ -76,7 +77,6 @@ export function EditSpanAnnotationsDialog(
}}
onCreated={() => {
setNewAnnotationName(null);
setFetchKey((key) => key + 1);
notifySuccess({
title: `New Span Annotation`,
message: `Annotation ${newAnnotationName} has been created.`,
Expand All @@ -86,7 +86,7 @@ export function EditSpanAnnotationsDialog(
</View>
)}
<Suspense>
<EditSpanAnnotations {...props} fetchKey={fetchKey} />
<EditSpanAnnotations {...props} />
</Suspense>
</div>
</Dialog>
Expand Down Expand Up @@ -166,36 +166,52 @@ function NewAnnotationPopover(props: NewAnnotationPopoverProps) {
</Card>
);
}
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<EditSpanAnnotationsDialogQuery>(
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 <SpanAnnotationsList span={data.span} />;
}

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 (
<div>
Expand All @@ -211,7 +227,7 @@ function EditSpanAnnotations(props: EditSpanAnnotationsProps) {
>
{annotations.map((annotation, idx) => (
<li key={idx}>
<SpanAnnotationCard annotation={annotation} />
<SpanAnnotationCard annotation={annotation} spanNodeId={data.id} />
</li>
))}
</ul>
Expand Down Expand Up @@ -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<Error | null>(null);
const notifySuccess = useNotifySuccess();
return (
Expand All @@ -287,6 +306,7 @@ function SpanAnnotationCard(props: { annotation: Annotation }) {
<AnnotatorKindLabel kind={annotation.annotatorKind} />
<SpanAnnotationActionMenu
annotationId={annotation.id}
spanNodeId={spanNodeId}
annotationName={annotation.name}
onSpanAnnotationDelete={() => {
notifySuccess({
Expand Down Expand Up @@ -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}
>
Expand Down
11 changes: 8 additions & 3 deletions app/src/pages/trace/NewSpanAnnotationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How things are supposed to work @axiomofjoy

}
}
}
}
}
Expand All @@ -37,6 +41,7 @@ export function NewSpanAnnotationForm(props: NewSpanAnnotationFormProps) {
annotatorKind: "HUMAN",
...data,
},
spanId: spanNodeId,
},
onCompleted: () => {
onCreated();
Expand Down
13 changes: 12 additions & 1 deletion app/src/pages/trace/SpanAnnotationActionMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { AnnotationActionMenu } from "./AnnotationActionMenu";

type SpanAnnotationActionMenuProps = {
annotationId: string;
spanNodeId: string;
annotationName: string;
onSpanAnnotationDelete: () => void;
onSpanAnnotationDeleteError: (error: Error) => void;
Expand All @@ -28,6 +29,7 @@ type SpanAnnotationActionMenuProps = {
export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
const {
annotationId,
spanNodeId,
annotationName,
onSpanAnnotationDelete,
onSpanAnnotationDeleteError,
Expand All @@ -37,9 +39,16 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
useMutation<SpanAnnotationActionMenuDeleteMutation>(graphql`
mutation SpanAnnotationActionMenuDeleteMutation(
$annotationId: GlobalID!
$spanId: GlobalID!
) {
deleteSpanAnnotations(input: { annotationIds: [$annotationId] }) {
__typename
query {
node(id: $spanId) {
... on Span {
...EditSpanAnnotationsDialog_spanAnnotations
}
}
}
}
}
`);
Expand All @@ -49,6 +58,7 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
commitDelete({
variables: {
annotationId,
spanId: spanNodeId,
},
onCompleted: () => {
onSpanAnnotationDelete();
Expand All @@ -61,6 +71,7 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
}, [
commitDelete,
annotationId,
spanNodeId,
onSpanAnnotationDelete,
onSpanAnnotationDeleteError,
]);
Expand Down
Loading
Loading