diff --git a/app/src/components/AlphabeticIndexIcon.tsx b/app/src/components/AlphabeticIndexIcon.tsx new file mode 100644 index 0000000000..a0d944cc41 --- /dev/null +++ b/app/src/components/AlphabeticIndexIcon.tsx @@ -0,0 +1,33 @@ +import React, { useMemo } from "react"; +import { schemeSet2 } from "d3-scale-chromatic"; +import { transparentize } from "polished"; +import { css } from "@emotion/react"; + +function indexToChar(index: number) { + // Wrap around using modulo if index exceeds 'C' + const charCode = 65 + index; // 'A' has ASCII code 65, 'B' is 66, 'C' is 67 + return String.fromCharCode(charCode); +} + +export function AlphabeticIndexIcon({ index }: { index: number }) { + const char = useMemo(() => indexToChar(index), [index]); + const color = useMemo(() => schemeSet2[index % 8], [index]); + const backgroundColor = useMemo(() => transparentize(0.8, color), [color]); + return ( +
+ {char} +
+ ); +} diff --git a/app/src/pages/playground/Playground.tsx b/app/src/pages/playground/Playground.tsx index bed0f4edd2..14adc0962e 100644 --- a/app/src/pages/playground/Playground.tsx +++ b/app/src/pages/playground/Playground.tsx @@ -1,7 +1,7 @@ import React, { Fragment } from "react"; import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; -import { Button, Flex, Heading, View } from "@arizeai/components"; +import { Button, Flex, Heading, Icon, Icons, View } from "@arizeai/components"; import { resizeHandleCSS } from "@phoenix/components/resize"; import { @@ -10,6 +10,7 @@ import { } from "@phoenix/contexts/PlaygroundContext"; import { InitialPlaygroundState } from "@phoenix/store"; +import { NUM_MAX_PLAYGROUND_INSTANCES } from "./constants"; import { PlaygroundInputTypeTypeRadioGroup } from "./PlaygroundInputModeRadioGroup"; import { PlaygroundInstance } from "./PlaygroundInstance"; import { PlaygroundRunButton } from "./PlaygroundRunButton"; @@ -35,6 +36,7 @@ export function Playground(props: InitialPlaygroundState) { + @@ -45,6 +47,25 @@ export function Playground(props: InitialPlaygroundState) { ); } +function AddPromptButton() { + const addInstance = usePlaygroundContext((state) => state.addInstance); + const numInstances = usePlaygroundContext((state) => state.instances.length); + return ( + + ); +} + function PlaygroundInstances() { const instances = usePlaygroundContext((state) => state.instances); return ( diff --git a/app/src/pages/playground/PlaygroundInstance.tsx b/app/src/pages/playground/PlaygroundInstance.tsx index 37be6bc84e..8e6bf27de8 100644 --- a/app/src/pages/playground/PlaygroundInstance.tsx +++ b/app/src/pages/playground/PlaygroundInstance.tsx @@ -22,7 +22,7 @@ export function PlaygroundInstance(props: PlaygroundInstanceProps) { - + state.instances[instanceId]); + const instance = usePlaygroundContext((state) => + state.instances.find((instance) => instance.id === instanceId) + ); + const index = usePlaygroundContext((state) => + state.instances.findIndex((instance) => instance.id === instanceId) + ); if (!instance) { return null; } + const runId = instance.activeRunId; const hasRunId = runId !== null; return ( - + } + collapsible + variant="compact" + > {hasRunId ? ( ) : ( diff --git a/app/src/pages/playground/PlaygroundTemplate.tsx b/app/src/pages/playground/PlaygroundTemplate.tsx index 643fca727b..f5448d2ea5 100644 --- a/app/src/pages/playground/PlaygroundTemplate.tsx +++ b/app/src/pages/playground/PlaygroundTemplate.tsx @@ -4,6 +4,7 @@ import { Button, Card, Content, + Flex, Icon, Icons, Tooltip, @@ -11,9 +12,9 @@ import { TriggerWrap, } from "@arizeai/components"; +import { AlphabeticIndexIcon } from "@phoenix/components/AlphabeticIndexIcon"; import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext"; -import { NUM_MAX_PLAYGROUND_INSTANCES } from "./constants"; import { PlaygroundChatTemplate } from "./PlaygroundChatTemplate"; import { PlaygroundInstanceProps } from "./types"; @@ -23,6 +24,7 @@ export function PlaygroundTemplate(props: PlaygroundTemplateProps) { const instanceId = props.playgroundInstanceId; const instances = usePlaygroundContext((state) => state.instances); const instance = instances.find((instance) => instance.id === instanceId); + const index = instances.findIndex((instance) => instance.id === instanceId); if (!instance) { throw new Error(`Playground instance ${instanceId} not found`); } @@ -30,17 +32,16 @@ export function PlaygroundTemplate(props: PlaygroundTemplateProps) { return ( + + Prompt + + } collapsible variant="compact" bodyStyle={{ padding: 0 }} - extra={ - instances.length >= NUM_MAX_PLAYGROUND_INSTANCES ? ( - - ) : ( - - ) - } + extra={instances.length > 1 ? : null} > {template.__type === "chat" ? ( @@ -51,20 +52,6 @@ export function PlaygroundTemplate(props: PlaygroundTemplateProps) { ); } -function CompareButton() { - const addInstance = usePlaygroundContext((state) => state.addInstance); - return ( -