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(playground): add tool role messages to ui #5103

Merged
merged 12 commits into from
Oct 22, 2024
4 changes: 3 additions & 1 deletion app/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@ input ChatCompletionInput {
input ChatCompletionMessageInput {
role: ChatCompletionMessageRole!

"""The content of the message as JSON to support text and tools"""
"""The content of the message as JSON to support various kinds of text"""
content: JSON!
toolCalls: [JSON!]
toolCallId: String
}

enum ChatCompletionMessageRole {
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/trace/SpanKindIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const ToolSVG = () => (
</svg>
);

const ToolFilledSVG = () => (
export const ToolFilledSVG = () => (
<svg
width="20"
height="20"
Expand Down
75 changes: 75 additions & 0 deletions app/src/pages/playground/ChatMessageToolCallsEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useCallback, useState } from "react";
import { JSONSchema7 } from "json-schema";

import { JSONEditor } from "@phoenix/components/code";
import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext";
import {
openAIToolCallsJSONSchema,
openAIToolCallsSchema,
} from "@phoenix/schemas";
import { ChatMessage } from "@phoenix/store";
import { safelyParseJSON } from "@phoenix/utils/jsonUtils";

import { PlaygroundInstanceProps } from "./types";

/**
* Editor for message tool calls
*/
export function ChatMessageToolCallsEditor({
playgroundInstanceId,
toolCalls,
templateMessages,
messageId,
}: PlaygroundInstanceProps & {
toolCalls: ChatMessage["toolCalls"];
templateMessages: ChatMessage[];
messageId: number;
}) {
const updateInstance = usePlaygroundContext((state) => state.updateInstance);
const [toolCallsValue, setToolCallsValue] = useState(() =>
JSON.stringify(toolCalls, null, 2)
Parker-Stafford marked this conversation as resolved.
Show resolved Hide resolved
);

const onChange = useCallback(
(value: string) => {
setToolCallsValue(value);
const { json: definition } = safelyParseJSON(value);
if (definition == null) {
return;
}
// Don't use data here returned by safeParse, as we want to allow for extra keys,
// there is no "deepPassthrough" to allow for extra keys
// at all levels of the schema, so we just use the json parsed value here,
// knowing that it is valid with potentially extra keys
const { success } = openAIToolCallsSchema.safeParse(definition);
if (!success) {
return;
}
updateInstance({
instanceId: playgroundInstanceId,
patch: {
template: {
__type: "chat",
messages: templateMessages.map((m) =>
messageId === m.id
? {
...m,
toolCalls: definition,
}
: m
),
},
},
});
},
[messageId, playgroundInstanceId, templateMessages, updateInstance]
);

return (
<JSONEditor
value={toolCallsValue}
jsonSchema={openAIToolCallsJSONSchema as JSONSchema7}
onChange={onChange}
/>
);
}
39 changes: 39 additions & 0 deletions app/src/pages/playground/MessageContentRadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";

import { Icon, Icons, Radio, RadioGroup } from "@arizeai/components";

export type MessageMode = "text" | "toolCalls";

function isMessageMode(value: string): value is MessageMode {
return value === "text" || value === "toolCalls";
}

export function MessageContentRadioGroup({
messageMode,
onChange,
}: {
messageMode: MessageMode;
onChange: (messageMode: MessageMode) => void;
}) {
return (
<RadioGroup
defaultValue={messageMode}
variant="inline-button"
size="compact"
onChange={(v) => {
if (isMessageMode(v)) {
onChange(v);
} else {
throw new Error(`Unknown message mode: ${v}`);
}
}}
>
<Radio label="text input" value={"text"}>
<Icon svg={<Icons.MessageSquareOutline />} />
</Radio>
<Radio label="tool calling" value={"toolCalls"}>
<Icon svg={<Icons.Code />} />
</Radio>
</RadioGroup>
);
}
1 change: 1 addition & 0 deletions app/src/pages/playground/MessageRolePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export function MessageRolePicker({
<Item key="system">System</Item>
<Item key="user">User</Item>
<Item key="ai">AI</Item>
<Item key="tool">Tool</Item>
</Picker>
);
}
Loading
Loading