Skip to content

Commit

Permalink
Add prompt formatting test
Browse files Browse the repository at this point in the history
  • Loading branch information
cephalization committed Jan 23, 2025
1 parent 25dd410 commit 105ff11
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 2 deletions.
5 changes: 3 additions & 2 deletions js/packages/phoenix-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"build": "tsc --build tsconfig.json tsconfig.esm.json && tsc-alias -p tsconfig.esm.json",
"postbuild": "echo '{\"type\": \"module\"}' > ./dist/esm/package.json && rimraf dist/test dist/examples",
"type:check": "tsc --noEmit",
"test": "vitest run"
"test": "vitest"
},
"keywords": [],
"author": "",
Expand All @@ -48,7 +48,8 @@
"@anthropic-ai/sdk": "^0.35.0",
"@types/node": "^20.14.11",
"openapi-typescript": "^7.4.1",
"tsx": "^4.19.1"
"tsx": "^4.19.1",
"vitest": "^2.1.8"
},
"dependencies": {
"openapi-fetch": "^0.12.2",
Expand Down
214 changes: 214 additions & 0 deletions js/packages/phoenix-client/test/promptMessageFormatter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { describe, it, expect } from "vitest";
import { promptMessageFormatter } from "../src/utils/promptMessageFormatter";
import { PromptChatMessage } from "../src/types/prompts";
import { TextPart } from "../src/schemas/llm/promptSchemas";

describe("promptMessageFormatter", () => {
it("should only format TextPart content", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [
{ type: "text", text: { text: "Hello {{name}}" } } as TextPart,
{ type: "image", image: { url: "test.jpg" } },
],
},
];

const formatted = promptMessageFormatter("MUSTACHE", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello World" },
});
expect(formatted?.[0]?.content?.[1]).toEqual({
type: "image",
image: { url: "test.jpg" },
});
});

describe("MUSTACHE format", () => {
it("should replace single variable", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [{ type: "text", text: { text: "Hello {{name}}" } }],
},
];

const formatted = promptMessageFormatter("MUSTACHE", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello World" },
});
});

it("should replace multiple variables", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [
{
type: "text",
text: { text: "{{greeting}} there, {{name}}!" },
},
],
},
];

const formatted = promptMessageFormatter("MUSTACHE", messages, {
greeting: "Hello",
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello there, World!" },
});
});

it("should replace multiple instances of same variable", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [{ type: "text", text: { text: "{{name}}, {{name}}!" } }],
},
];

const formatted = promptMessageFormatter("MUSTACHE", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "World, World!" },
});
});

it("should handle escaped mustache syntax", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [
{
type: "text",
text: { text: "Hello {{name}}, use {{{escaped}}} {{name}}" },
},
],
},
];

const formatted = promptMessageFormatter("MUSTACHE", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello World, use {{{escaped}}} World" },
});
});
});

describe("FSTRING format", () => {
it("should replace single variable", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [{ type: "text", text: { text: "Hello {name}" } }],
},
];

const formatted = promptMessageFormatter("FSTRING", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello World" },
});
});

it("should replace multiple variables", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [
{ type: "text", text: { text: "{greeting} there, {name}!" } },
],
},
];

const formatted = promptMessageFormatter("FSTRING", messages, {
greeting: "Hello",
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello there, World!" },
});
});

it("should replace multiple instances of same variable", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [{ type: "text", text: { text: "{name}, {name}!" } }],
},
];

const formatted = promptMessageFormatter("FSTRING", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "World, World!" },
});
});

it("should handle escaped fstring syntax", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [
{
type: "text",
text: { text: "Hello {name}, use {{escaped}} {name}" },
},
],
},
];

const formatted = promptMessageFormatter("FSTRING", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello World, use {{escaped}} World" },
});
});
});

it("should not modify text when format is NONE", () => {
const messages: PromptChatMessage[] = [
{
role: "USER",
content: [{ type: "text", text: { text: "Hello {name} {{name}}" } }],
},
{
role: "AI",
content: [{ type: "text", text: { text: "Hello {name} {{name}}" } }],
},
];

const formatted = promptMessageFormatter("NONE", messages, {
name: "World",
});
expect(formatted?.[0]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello {name} {{name}}" },
});
expect(formatted?.[1]?.content?.[0]).toEqual({
type: "text",
text: { text: "Hello {name} {{name}}" },
});
});
});
3 changes: 3 additions & 0 deletions js/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 105ff11

Please sign in to comment.