Skip to content

Commit dc47b6e

Browse files
committed
refactor(prompts): unify template format and language (#6403)
* refactor(prompts): unify template format * migrate the frontend * build openapi * refactor python client * refactor JS * fix db * run ruff * fix tests * cleanup * more cleanup * run ci on prompts * ruff again * more fixes to python tests * restore PromptTemplateFormat * ruff * build openapi * build client * cleanup * fix tests * cleanup
1 parent cfbc6a7 commit dc47b6e

File tree

55 files changed

+350
-593
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+350
-593
lines changed

.github/workflows/typescript-packages-CI.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Typescript Packages CI
22

33
on:
44
push:
5-
branches: [main, js]
5+
branches: [main, prompts]
66
pull_request:
77
paths:
88
- "js/**"

app/schema.graphql

+8-14
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ input ChatCompletionInput {
109109
invocationParameters: [InvocationParameterInput!]! = []
110110
tools: [JSON!]
111111
apiKey: String = null
112-
template: TemplateOptions
112+
template: PromptTemplateOptions
113113
promptName: Identifier = null
114114
}
115115

@@ -154,7 +154,7 @@ input ChatCompletionOverDatasetInput {
154154
invocationParameters: [InvocationParameterInput!]! = []
155155
tools: [JSON!]
156156
apiKey: String = null
157-
templateLanguage: TemplateLanguage!
157+
templateFormat: PromptTemplateFormat! = MUSTACHE
158158
datasetId: GlobalID!
159159
datasetVersionId: GlobalID = null
160160
experimentName: String = null
@@ -1573,10 +1573,15 @@ union PromptTemplate = PromptStringTemplate | PromptChatTemplate
15731573

15741574
enum PromptTemplateFormat {
15751575
MUSTACHE
1576-
FSTRING
1576+
F_STRING
15771577
NONE
15781578
}
15791579

1580+
input PromptTemplateOptions {
1581+
variables: JSON!
1582+
format: PromptTemplateFormat!
1583+
}
1584+
15801585
enum PromptTemplateType {
15811586
STRING
15821587
CHAT
@@ -1979,17 +1984,6 @@ type SystemApiKey implements ApiKey & Node {
19791984
id: GlobalID!
19801985
}
19811986

1982-
enum TemplateLanguage {
1983-
NONE
1984-
MUSTACHE
1985-
F_STRING
1986-
}
1987-
1988-
input TemplateOptions {
1989-
variables: JSON!
1990-
language: TemplateLanguage!
1991-
}
1992-
19931987
type TextChunk implements ChatCompletionSubscriptionPayload {
19941988
datasetExampleId: GlobalID
19951989
content: String!

app/src/components/templateEditor/TemplateEditor.tsx

+10-10
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import { assertUnreachable } from "@phoenix/typeUtils";
1515

1616
import { FStringTemplating } from "./language/fString";
1717
import { MustacheLikeTemplating } from "./language/mustacheLike";
18-
import { TemplateLanguages } from "./constants";
19-
import { TemplateLanguage } from "./types";
18+
import { TemplateFormats } from "./constants";
19+
import { TemplateFormat } from "./types";
2020

2121
type TemplateEditorProps = Omit<ReactCodeMirrorProps, "value"> & {
22-
templateLanguage: TemplateLanguage;
22+
templateFormat: TemplateFormat;
2323
defaultValue: string;
2424
};
2525

@@ -49,7 +49,7 @@ const baseExtensions = [
4949
* cursor position when value is updated.
5050
*/
5151
export const TemplateEditor = ({
52-
templateLanguage,
52+
templateFormat,
5353
defaultValue,
5454
readOnly,
5555
...props
@@ -59,20 +59,20 @@ export const TemplateEditor = ({
5959
const codeMirrorTheme = theme === "light" ? githubLight : nord;
6060
const extensions = useMemo(() => {
6161
const ext: TemplateEditorProps["extensions"] = [...baseExtensions];
62-
switch (templateLanguage) {
63-
case TemplateLanguages.FString:
62+
switch (templateFormat) {
63+
case TemplateFormats.FString:
6464
ext.push(FStringTemplating());
6565
break;
66-
case TemplateLanguages.Mustache:
66+
case TemplateFormats.Mustache:
6767
ext.push(MustacheLikeTemplating());
6868
break;
69-
case TemplateLanguages.NONE:
69+
case TemplateFormats.NONE:
7070
break;
7171
default:
72-
assertUnreachable(templateLanguage);
72+
assertUnreachable(templateFormat);
7373
}
7474
return ext;
75-
}, [templateLanguage]);
75+
}, [templateFormat]);
7676

7777
useEffect(() => {
7878
if (readOnly) {

app/src/components/templateEditor/constants.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
/**
2-
* Enum for the different template languages supported by the template editor
2+
* Enum for the different template formats supported by the template editor
33
*
44
* - FString: `variables look like {variable}`
55
* - Mustache: `variables look like {{variable}}`
66
*
77
* @example
88
* ```tsx
9-
* <TemplateEditor language={TemplateLanguages.Mustache} />
9+
* <TemplateEditor format={TemplateFormats.Mustache} />
1010
* ```
1111
*/
12-
export const TemplateLanguages = {
12+
export const TemplateFormats = {
1313
NONE: "NONE", // No templating
1414
FString: "F_STRING", // {variable}
1515
Mustache: "MUSTACHE", // {{variable}}

app/src/components/templateEditor/templateEditorUtils.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {
55
extractVariablesFromMustacheLike,
66
formatMustacheLike,
77
} from "./language/mustacheLike";
8-
import { TemplateLanguages } from "./constants";
9-
import { TemplateLanguage } from "./types";
8+
import { TemplateFormats } from "./constants";
9+
import { TemplateFormat } from "./types";
1010

1111
/**
1212
* A function that formats a template with the given variables
@@ -24,35 +24,35 @@ export type ExtractVariablesFn = (template: string) => string[];
2424
/**
2525
* Get an object of isomorphic functions for processing templates of the given language
2626
*
27-
* @param templateLanguage - The language of the template to process
27+
* @param templateFormat - The format of the template to process
2828
*
2929
* @returns An object containing the `format` and `extractVariables` functions.
3030
* These functions share the same signature despite the different underlying
3131
* templating languages.
3232
*/
33-
export const getTemplateLanguageUtils = (
34-
templateLanguage: TemplateLanguage
33+
export const getTemplateFormatUtils = (
34+
templateFormat: TemplateFormat
3535
): {
3636
format: FormatFn;
3737
extractVariables: ExtractVariablesFn;
3838
} => {
39-
switch (templateLanguage) {
40-
case TemplateLanguages.FString:
39+
switch (templateFormat) {
40+
case TemplateFormats.FString:
4141
return {
4242
format: formatFString,
4343
extractVariables: extractVariablesFromFString,
4444
};
45-
case TemplateLanguages.Mustache:
45+
case TemplateFormats.Mustache:
4646
return {
4747
format: formatMustacheLike,
4848
extractVariables: extractVariablesFromMustacheLike,
4949
};
50-
case TemplateLanguages.NONE:
50+
case TemplateFormats.NONE:
5151
return {
5252
format: ({ text }) => text,
5353
extractVariables: () => [],
5454
};
5555
default:
56-
assertUnreachable(templateLanguage);
56+
assertUnreachable(templateFormat);
5757
}
5858
};
+6-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { TemplateLanguages } from "./constants";
1+
import { TemplateFormats } from "./constants";
22

3-
export type TemplateLanguage =
4-
(typeof TemplateLanguages)[keyof typeof TemplateLanguages];
3+
export type TemplateFormat =
4+
(typeof TemplateFormats)[keyof typeof TemplateFormats];
55

66
/**
7-
* Type guard for the TemplateLanguage type
7+
* Type guard for the TemplateFormat type
88
*/
9-
export function isTemplateLanguage(v: string): v is TemplateLanguage {
10-
return Object.values(TemplateLanguages).includes(v as TemplateLanguage);
9+
export function isTemplateFormat(v: string): v is TemplateFormat {
10+
return Object.values(TemplateFormats).includes(v as TemplateFormat);
1111
}

app/src/pages/playground/Playground.tsx

+5-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
import { ConfirmNavigationDialog } from "@phoenix/components/ConfirmNavigation";
2121
import { resizeHandleCSS } from "@phoenix/components/resize";
2222
import { StopPropagation } from "@phoenix/components/StopPropagation";
23-
import { TemplateLanguages } from "@phoenix/components/templateEditor/constants";
23+
import { TemplateFormats } from "@phoenix/components/templateEditor/constants";
2424
import {
2525
PlaygroundProvider,
2626
usePlaygroundContext,
@@ -40,7 +40,7 @@ import { PlaygroundOutput } from "./PlaygroundOutput";
4040
import { PlaygroundRunButton } from "./PlaygroundRunButton";
4141
import { PlaygroundStreamToggle } from "./PlaygroundStreamToggle";
4242
import { PlaygroundTemplate } from "./PlaygroundTemplate";
43-
import { TemplateLanguageRadioGroup } from "./TemplateLanguageRadioGroup";
43+
import { TemplateFormatRadioGroup } from "./TemplateFormatRadioGroup";
4444

4545
const playgroundWrapCSS = css`
4646
display: flex;
@@ -209,9 +209,7 @@ const DEFAULT_EXPANDED_PARAMS = ["input", "output"];
209209

210210
function PlaygroundContent() {
211211
const instances = usePlaygroundContext((state) => state.instances);
212-
const templateLanguage = usePlaygroundContext(
213-
(state) => state.templateLanguage
214-
);
212+
const templateFormat = usePlaygroundContext((state) => state.templateFormat);
215213
const [searchParams] = useSearchParams();
216214
const datasetId = searchParams.get("datasetId");
217215
const isDatasetMode = datasetId != null;
@@ -272,7 +270,7 @@ function PlaygroundContent() {
272270
Prompts
273271
<StopPropagation>
274272
<Flex direction="row" gap="size-100" alignItems="center">
275-
<TemplateLanguageRadioGroup size="M" />
273+
<TemplateFormatRadioGroup size="M" />
276274
<AddPromptButton />
277275
</Flex>
278276
</StopPropagation>
@@ -307,7 +305,7 @@ function PlaygroundContent() {
307305
) : (
308306
<div css={playgroundInputOutputPanelContentCSS}>
309307
<DisclosureGroup defaultExpandedKeys={DEFAULT_EXPANDED_PARAMS}>
310-
{templateLanguage !== TemplateLanguages.NONE ? (
308+
{templateFormat !== TemplateFormats.NONE ? (
311309
<Disclosure id="input" size="L">
312310
<DisclosureTrigger arrowPosition="start">
313311
Inputs

app/src/pages/playground/PlaygroundChatTemplate.tsx

+9-11
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import {
3939
TemplateEditor,
4040
TemplateEditorWrap,
4141
} from "@phoenix/components/templateEditor";
42-
import { TemplateLanguage } from "@phoenix/components/templateEditor/types";
42+
import { TemplateFormat } from "@phoenix/components/templateEditor/types";
4343
import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext";
4444
import { useChatMessageStyles } from "@phoenix/hooks/useChatMessageStyles";
4545
import { ChatMessage, PlaygroundState } from "@phoenix/store";
@@ -85,9 +85,7 @@ interface PlaygroundChatTemplateProps extends PlaygroundInstanceProps {}
8585
export function PlaygroundChatTemplate(props: PlaygroundChatTemplateProps) {
8686
const id = props.playgroundInstanceId;
8787

88-
const templateLanguage = usePlaygroundContext(
89-
(state) => state.templateLanguage
90-
);
88+
const templateFormat = usePlaygroundContext((state) => state.templateFormat);
9189
const updateInstance = usePlaygroundContext((state) => state.updateInstance);
9290
const instanceSelector = useMemo(() => selectPlaygroundInstance(id), [id]);
9391
const playgroundInstance = usePlaygroundContext(instanceSelector);
@@ -156,7 +154,7 @@ export function PlaygroundChatTemplate(props: PlaygroundChatTemplateProps) {
156154
return (
157155
<SortableMessageItem
158156
playgroundInstanceId={id}
159-
templateLanguage={templateLanguage}
157+
templateFormat={templateFormat}
160158
key={messageId}
161159
messageId={messageId}
162160
/>
@@ -191,13 +189,13 @@ export function PlaygroundChatTemplate(props: PlaygroundChatTemplateProps) {
191189
function MessageEditor({
192190
message,
193191
updateMessage,
194-
templateLanguage,
192+
templateFormat,
195193
playgroundInstanceId,
196194
messageMode,
197195
}: {
198196
playgroundInstanceId: number;
199197
message: ChatMessage;
200-
templateLanguage: TemplateLanguage;
198+
templateFormat: TemplateFormat;
201199
updateMessage: (patch: Partial<ChatMessage>) => void;
202200
messageMode: MessageMode;
203201
}) {
@@ -277,7 +275,7 @@ function MessageEditor({
277275
height="100%"
278276
defaultValue={message.content || ""}
279277
aria-label="Message content"
280-
templateLanguage={templateLanguage}
278+
templateFormat={templateFormat}
281279
onChange={onChange}
282280
placeholder={
283281
message.role === "system"
@@ -293,12 +291,12 @@ function MessageEditor({
293291

294292
function SortableMessageItem({
295293
playgroundInstanceId,
296-
templateLanguage,
294+
templateFormat,
297295
messageId,
298296
}: PropsWithChildren<{
299297
playgroundInstanceId: number;
300298
messageId: number;
301-
templateLanguage: TemplateLanguage;
299+
templateFormat: TemplateFormat;
302300
}>) {
303301
const updateMessage = usePlaygroundContext((state) => state.updateMessage);
304302
const deleteMessage = usePlaygroundContext((state) => state.deleteMessage);
@@ -482,7 +480,7 @@ function SortableMessageItem({
482480
message={message}
483481
messageMode={aiMessageMode}
484482
playgroundInstanceId={playgroundInstanceId}
485-
templateLanguage={templateLanguage}
483+
templateFormat={templateFormat}
486484
updateMessage={onMessageUpdate}
487485
/>
488486
</div>

app/src/pages/playground/PlaygroundDatasetExamplesTable.tsx

+3-5
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,7 @@ export function PlaygroundDatasetExamplesTable({
421421
const allInstanceMessages = usePlaygroundContext(
422422
(state) => state.allInstanceMessages
423423
);
424-
const templateLanguage = usePlaygroundContext(
425-
(state) => state.templateLanguage
426-
);
424+
const templateFormat = usePlaygroundContext((state) => state.templateFormat);
427425

428426
const updateInstance = usePlaygroundContext((state) => state.updateInstance);
429427
const updateExampleData = usePlaygroundDatasetExamplesTableContext(
@@ -766,7 +764,7 @@ export function PlaygroundDatasetExamplesTable({
766764
);
767765
const instanceVariables = extractVariablesFromInstance({
768766
instance: enrichedInstance,
769-
templateLanguage,
767+
templateFormat,
770768
});
771769
return {
772770
id: `instance-${instance.id}`,
@@ -792,7 +790,7 @@ export function PlaygroundDatasetExamplesTable({
792790
size: 500,
793791
};
794792
});
795-
}, [hasSomeRunIds, instances, templateLanguage, allInstanceMessages]);
793+
}, [hasSomeRunIds, instances, templateFormat, allInstanceMessages]);
796794

797795
const columns: ColumnDef<TableRow>[] = [
798796
{

app/src/pages/playground/PlaygroundInput.tsx

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22

33
import { Flex, Text, View } from "@phoenix/components";
4+
import { TemplateFormats } from "@phoenix/components/templateEditor/constants";
45
import { usePlaygroundContext } from "@phoenix/contexts/PlaygroundContext";
56
import { assertUnreachable } from "@phoenix/typeUtils";
67

@@ -12,25 +13,23 @@ export function PlaygroundInput() {
1213
const setVariableValue = usePlaygroundContext(
1314
(state) => state.setVariableValue
1415
);
15-
const templateLanguage = usePlaygroundContext(
16-
(state) => state.templateLanguage
17-
);
16+
const templateFormat = usePlaygroundContext((state) => state.templateFormat);
1817
if (variableKeys.length === 0) {
1918
let templateSyntax = "";
20-
switch (templateLanguage) {
21-
case "F_STRING": {
19+
switch (templateFormat) {
20+
case TemplateFormats.FString: {
2221
templateSyntax = "{input name}";
2322
break;
2423
}
25-
case "MUSTACHE": {
24+
case TemplateFormats.Mustache: {
2625
templateSyntax = "{{input name}}";
2726
break;
2827
}
29-
case "NONE": {
28+
case TemplateFormats.NONE: {
3029
return null;
3130
}
3231
default:
33-
assertUnreachable(templateLanguage);
32+
assertUnreachable(templateFormat);
3433
}
3534
return (
3635
<View padding="size-100">

0 commit comments

Comments
 (0)