Skip to main content
Glama

@arizeai/phoenix-mcp

Official
by Arize-ai
EditExampleDialog.tsx8.87 kB
import { useCallback, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { graphql, useMutation } from "react-relay"; import { css } from "@emotion/react"; import { Alert, Button, Card, CardProps, Dialog, DialogCloseButton, DialogContent, DialogHeader, DialogTitle, DialogTitleExtra, FieldError, Flex, Icon, Icons, Label, Text, TextArea, TextField, View, } from "@phoenix/components"; import { JSONEditor } from "@phoenix/components/code"; import { isJSONObjectString } from "@phoenix/utils/jsonUtils"; import { EditExampleDialogMutation } from "./__generated__/EditExampleDialogMutation.graphql"; type ExamplePatch = { input: string; output: string; metadata: string; description?: string; }; export type EditExampleDialogProps = { exampleId: string; currentRevision: ExamplePatch; onCompleted: () => void; }; const defaultCardProps: Partial<CardProps> = { backgroundColor: "light", borderColor: "light", collapsible: true, }; export function EditExampleDialog(props: EditExampleDialogProps) { const { exampleId, onCompleted } = props; const [submitError, setSubmitError] = useState<string | null>(null); const [commit, isCommitting] = useMutation<EditExampleDialogMutation>(graphql` mutation EditExampleDialogMutation($input: PatchDatasetExamplesInput!) { patchDatasetExamples(input: $input) { __typename } } `); const { control, setError, handleSubmit, formState: { isValid }, } = useForm<ExamplePatch>({ defaultValues: props.currentRevision, }); const onSubmit = useCallback( (updatedExample: ExamplePatch, close: () => void) => { setSubmitError(null); if (!isJSONObjectString(updatedExample?.input)) { return setError("input", { message: "Input must be a valid JSON object", }); } if (!isJSONObjectString(updatedExample?.output)) { return setError("output", { message: "Output must be a valid JSON object", }); } if (!isJSONObjectString(updatedExample?.metadata)) { return setError("metadata", { message: "Metadata must be a valid JSON object", }); } commit({ variables: { input: { patches: [ { exampleId, input: JSON.parse(updatedExample.input), output: JSON.parse(updatedExample.output), metadata: JSON.parse(updatedExample.metadata), }, ], versionDescription: updatedExample.description, }, }, onCompleted: () => { onCompleted(); close(); }, onError: (error) => { setSubmitError(error.message); }, }); }, [commit, exampleId, setError, onCompleted] ); return ( <Dialog> {({ close }) => ( <DialogContent> <DialogHeader> <DialogTitle>Edit Example: {exampleId}</DialogTitle> <DialogTitleExtra> <Button variant="primary" size="S" isDisabled={!isValid || isCommitting} leadingVisual={ <Icon svg={ isCommitting ? ( <Icons.LoadingOutline /> ) : ( <Icons.SaveOutline /> ) } /> } onPress={() => handleSubmit((updatedExample) => onSubmit(updatedExample, close) )() } > Save Changes </Button> <DialogCloseButton /> </DialogTitleExtra> </DialogHeader> <div css={css` overflow-y: auto; padding: var(--ac-global-dimension-size-400); /* Make widths configurable */ .dataset-picker { width: 100%; .ac-dropdown--picker, .ac-dropdown-button { width: 100%; } } `} > <Flex direction="row" justifyContent="center"> <View width="900px" paddingStart="auto" paddingEnd="auto"> <Flex direction="column" gap="size-200"> {submitError ? ( <Alert variant="danger">{submitError}</Alert> ) : null} <Controller control={control} name={"input"} render={({ field: { onChange, onBlur, value }, fieldState: { invalid, error }, }) => ( <Card title="Input" subTitle="The input to the LLM, retriever, program, etc." {...defaultCardProps} > {invalid ? ( <Alert variant="danger" banner> {error?.message} </Alert> ) : null} <JSONEditor value={value} onChange={onChange} onBlur={onBlur} /> </Card> )} /> <Controller control={control} name={"output"} render={({ field: { onChange, onBlur, value }, fieldState: { invalid, error }, }) => ( <Card title="Output" subTitle="The output of the LLM or program to be used as an expected output" {...defaultCardProps} backgroundColor="green-100" borderColor="green-700" > {invalid ? ( <Alert variant="danger" banner> {error?.message} </Alert> ) : null} <JSONEditor value={value} onChange={onChange} onBlur={onBlur} /> </Card> )} /> <Controller control={control} name={"metadata"} render={({ field: { onChange, onBlur, value }, fieldState: { invalid, error }, }) => ( <Card title="Metadata" subTitle="All data from the span to use during experimentation or evaluation" {...defaultCardProps} > {invalid ? ( <Alert variant="danger" banner> {error?.message} </Alert> ) : null} <JSONEditor value={value} onChange={onChange} onBlur={onBlur} /> </Card> )} /> <Controller control={control} name={"description"} render={({ field: { onChange, onBlur, value }, fieldState: { invalid, error }, }) => ( <TextField value={value} onChange={onChange} onBlur={onBlur} isInvalid={invalid} > <Label>Revision Description</Label> <TextArea /> {error ? ( <FieldError>{error?.message}</FieldError> ) : ( <Text slot="description"> A description of the changes made in this revision. Will be displayed in the version history. </Text> )} </TextField> )} /> </Flex> </View> </Flex> </div> </DialogContent> )} </Dialog> ); }

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