-
Notifications
You must be signed in to change notification settings - Fork 285
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Playground UI prototype (#4778)
* docs: initial playground PRD * feat: playground prototype * add rudamentary messages UI * WIP * routing * add a playground button * cleanup * cleanup routes * Update app/src/pages/playground/PlaygroundTemplate.tsx * Update app/src/pages/playground/spanPlaygroundPageLoader.ts * cleanup store
- Loading branch information
1 parent
2a0ddd9
commit a0a83a2
Showing
17 changed files
with
739 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React from "react"; | ||
|
||
import { Card, TextArea } from "@arizeai/components"; | ||
|
||
import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext"; | ||
|
||
import { PlaygroundInstanceProps } from "./types"; | ||
|
||
interface PlaygroundChatTemplateProps extends PlaygroundInstanceProps {} | ||
export function PlaygroundChatTemplate(props: PlaygroundChatTemplateProps) { | ||
const id = props.playgroundInstanceId; | ||
// TODO: remove the hard coding of the first instance | ||
const instances = usePlaygroundContext((state) => state.instances); | ||
const updateInstance = usePlaygroundContext((state) => state.updateInstance); | ||
const playground = instances.find((instance) => instance.id === id); | ||
if (!playground) { | ||
throw new Error(`Playground instance ${id} not found`); | ||
} | ||
const { template } = playground; | ||
if (template.__type !== "chat") { | ||
throw new Error(`Invalid template type ${template.__type}`); | ||
} | ||
|
||
return ( | ||
<ul> | ||
{template.messages.map((message, index) => { | ||
return ( | ||
<li key={index}> | ||
<Card title={message.role} variant="compact"> | ||
<TextArea | ||
height={100} | ||
value={message.content} | ||
onChange={(val) => { | ||
updateInstance({ | ||
instanceId: id, | ||
patch: { | ||
template: { | ||
__type: "chat", | ||
messages: template.messages.map((message, i) => | ||
i === index ? { ...message, content: val } : message | ||
), | ||
}, | ||
}, | ||
}); | ||
}} | ||
/> | ||
</Card> | ||
</li> | ||
); | ||
})} | ||
</ul> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
app/src/pages/playground/PlaygroundInputModeRadioGroup.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React from "react"; | ||
|
||
import { Radio, RadioGroup } from "@arizeai/components"; | ||
|
||
import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext"; | ||
|
||
/** | ||
* A store connected radio group that toggles between manual and dataset input types. | ||
*/ | ||
export function PlaygroundInputTypeTypeRadioGroup() { | ||
const inputMode = usePlaygroundContext((state) => state.inputMode); | ||
const setInputMode = usePlaygroundContext((state) => state.setInputMode); | ||
return ( | ||
<RadioGroup | ||
value={inputMode} | ||
variant="inline-button" | ||
size="compact" | ||
onChange={(value) => { | ||
if (value === "manual" || value === "dataset") { | ||
setInputMode(value); | ||
} | ||
}} | ||
> | ||
<Radio label="manual" value={"manual"}> | ||
Manual | ||
</Radio> | ||
<Radio label="Dataset" value={"dataset"}> | ||
dataset | ||
</Radio> | ||
</RadioGroup> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React from "react"; | ||
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; | ||
import { css } from "@emotion/react"; | ||
|
||
import { | ||
compactResizeHandleCSS, | ||
resizeHandleCSS, | ||
} from "@phoenix/components/resize"; | ||
import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext"; | ||
|
||
import { PlaygroundInput } from "./PlaygroundInput"; | ||
import { PlaygroundOutput } from "./PlaygroundOutput"; | ||
import { PlaygroundTemplate } from "./PlaygroundTemplate"; | ||
import { PlaygroundTools } from "./PlaygroundTools"; | ||
import { PlaygroundInstanceProps } from "./types"; | ||
|
||
const panelContentCSS = css` | ||
padding: var(--ac-global-dimension-size-200); | ||
overflow: auto; | ||
display: flex; | ||
flex-direction: column; | ||
gap: var(--ac-global-dimension-size-200); | ||
`; | ||
|
||
export function PlaygroundInstance(props: PlaygroundInstanceProps) { | ||
const numInstances = usePlaygroundContext((state) => state.instances.length); | ||
const isSingleInstance = numInstances == 1; | ||
return ( | ||
<PanelGroup direction={isSingleInstance ? "horizontal" : "vertical"}> | ||
<Panel defaultSize={50} order={1} css={panelContentCSS}> | ||
<PlaygroundTemplate {...props} /> | ||
<PlaygroundTools /> | ||
</Panel> | ||
<PanelResizeHandle | ||
css={isSingleInstance ? resizeHandleCSS : compactResizeHandleCSS} | ||
/> | ||
<Panel defaultSize={50} order={2} css={panelContentCSS}> | ||
<PlaygroundInput /> | ||
<PlaygroundOutput /> | ||
</Panel> | ||
</PanelGroup> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,70 @@ | ||
import React from "react"; | ||
|
||
import { Card } from "@arizeai/components"; | ||
import { Button, Card, Icon, Icons } from "@arizeai/components"; | ||
|
||
import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext"; | ||
|
||
export function PlaygroundTemplate() { | ||
const operationType = usePlaygroundContext((state) => state.operationType); | ||
import { NUM_MAX_PLAYGROUND_INSTANCES } from "./constants"; | ||
import { PlaygroundChatTemplate } from "./PlaygroundChatTemplate"; | ||
import { PlaygroundInstanceProps } from "./types"; | ||
|
||
interface PlaygroundTemplateProps extends PlaygroundInstanceProps {} | ||
|
||
export function PlaygroundTemplate(props: PlaygroundTemplateProps) { | ||
const id = props.playgroundInstanceId; | ||
const instances = usePlaygroundContext((state) => state.instances); | ||
const playground = instances.find((instance) => instance.id === id); | ||
if (!playground) { | ||
throw new Error(`Playground instance ${id} not found`); | ||
} | ||
const { template } = playground; | ||
|
||
return ( | ||
<Card title="Template" collapsible variant="compact"> | ||
{operationType === "chat" ? ( | ||
<div>Chat Template goes here</div> | ||
<Card | ||
title="Template" | ||
collapsible | ||
variant="compact" | ||
extra={ | ||
instances.length >= NUM_MAX_PLAYGROUND_INSTANCES ? ( | ||
<DeleteButton {...props} /> | ||
) : ( | ||
<CompareButton /> | ||
) | ||
} | ||
> | ||
{template.__type === "chat" ? ( | ||
<PlaygroundChatTemplate {...props} /> | ||
) : ( | ||
<div>Completion Template goes here</div> | ||
"Completion Template" | ||
)} | ||
</Card> | ||
); | ||
} | ||
|
||
function CompareButton() { | ||
const addInstance = usePlaygroundContext((state) => state.addInstance); | ||
return ( | ||
<Button | ||
variant="default" | ||
size="compact" | ||
icon={<Icon svg={<Icons.ArrowCompareOutline />} />} | ||
onClick={() => { | ||
addInstance(); | ||
}} | ||
/> | ||
); | ||
} | ||
|
||
function DeleteButton(props: PlaygroundInstanceProps) { | ||
const deleteInstance = usePlaygroundContext((state) => state.deleteInstance); | ||
return ( | ||
<Button | ||
variant="default" | ||
size="compact" | ||
icon={<Icon svg={<Icons.TrashOutline />} />} | ||
onClick={() => { | ||
deleteInstance(props.playgroundInstanceId); | ||
}} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from "react"; | ||
|
||
// import { useLoaderData } from "react-router"; | ||
import { Playground } from "./Playground"; | ||
|
||
export function SpanPlaygroundPage() { | ||
// const data = useLoaderData(); | ||
|
||
return <Playground />; | ||
} |
Oops, something went wrong.