Skip to content

Commit 9f0f5e4

Browse files
authored
feat: align ep logs chat view with tokenized rollout prompts (#431)
1 parent e80c7ae commit 9f0f5e4

File tree

9 files changed

+158
-146
lines changed

9 files changed

+158
-146
lines changed

vite-app/dist/assets/index-10cZ11iB.js

Lines changed: 0 additions & 137 deletions
This file was deleted.

vite-app/dist/assets/index-10cZ11iB.js.map

Lines changed: 0 additions & 1 deletion
This file was deleted.

vite-app/dist/assets/index-DFeF7AG_.js

Lines changed: 75 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vite-app/dist/assets/index-DFeF7AG_.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vite-app/dist/assets/index-DOD73Wyg.css

Lines changed: 0 additions & 1 deletion
This file was deleted.

vite-app/dist/assets/index-DvKW7FQL.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vite-app/dist/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>EP | Log Viewer</title>
77
<link rel="icon" href="/assets/favicon-BkAAWQga.png" />
8-
<script type="module" crossorigin src="/assets/index-10cZ11iB.js"></script>
9-
<link rel="stylesheet" crossorigin href="/assets/index-DOD73Wyg.css">
8+
<script type="module" crossorigin src="/assets/index-DFeF7AG_.js"></script>
9+
<link rel="stylesheet" crossorigin href="/assets/index-DvKW7FQL.css">
1010
</head>
1111
<body>
1212
<div id="root"></div>

vite-app/src/components/EvaluationRow.tsx

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,77 @@ const ToolsSection = observer(
337337
)
338338
);
339339

340+
function buildToolDeclareContent(tools: EvaluationRowType["tools"]): string {
341+
if (!tools?.length) return "";
342+
const blocks = tools
343+
.map((tool) => {
344+
const fn = (tool as any)?.function || {};
345+
const properties = fn.parameters?.properties || {};
346+
const actionEnum = Array.isArray(properties.action?.enum)
347+
? properties.action.enum.map((value: string) => `"${value}"`).join(" | ")
348+
: "string";
349+
return [
350+
`// ${fn.description || "Tool declaration."}`,
351+
`type ${fn.name || "tool"} = (_: {`,
352+
` // ${properties.action?.description || "Tool argument."}`,
353+
` action: ${actionEnum},`,
354+
" [k: string]: never",
355+
"}) => any;",
356+
].join("\n");
357+
})
358+
.join("\n");
359+
360+
return `# Tools\n\n## functions\nnamespace functions {\n${blocks}\n}`;
361+
}
362+
363+
function buildPromptFaithfulMessages(
364+
messages: EvaluationRowType["messages"],
365+
tools: EvaluationRowType["tools"]
366+
): EvaluationRowType["messages"] {
367+
const toolDeclareContent = buildToolDeclareContent(tools);
368+
if (!toolDeclareContent) return messages;
369+
const nextMessages = [...(messages || [])];
370+
const firstSystemIdx = nextMessages.findIndex(
371+
(message) => message?.role === "system"
372+
);
373+
if (firstSystemIdx === -1) {
374+
return [{ role: "system", content: toolDeclareContent } as any, ...nextMessages];
375+
}
376+
377+
const firstSystem = nextMessages[firstSystemIdx] as any;
378+
const existingContent =
379+
typeof firstSystem?.content === "string"
380+
? firstSystem.content
381+
: Array.isArray(firstSystem?.content)
382+
? firstSystem.content
383+
.map((part: any) => {
384+
if (part?.type === "text") return part.text || "";
385+
if (part?.type === "image_url") return "[Image]";
386+
return JSON.stringify(part);
387+
})
388+
.join("")
389+
: firstSystem?.content != null
390+
? JSON.stringify(firstSystem.content)
391+
: "";
392+
393+
nextMessages[firstSystemIdx] = {
394+
...firstSystem,
395+
content: existingContent
396+
? `${toolDeclareContent}\n\n${existingContent}`
397+
: toolDeclareContent,
398+
} as any;
399+
return nextMessages;
400+
}
401+
340402
const ChatInterfaceSection = observer(
341-
({ messages }: { messages: EvaluationRowType["messages"] }) => (
342-
<ChatInterface messages={messages} />
403+
({
404+
messages,
405+
tools,
406+
}: {
407+
messages: EvaluationRowType["messages"];
408+
tools: EvaluationRowType["tools"];
409+
}) => (
410+
<ChatInterface messages={buildPromptFaithfulMessages(messages, tools)} />
343411
)
344412
);
345413

@@ -376,7 +444,7 @@ const ExpandedContent = observer(
376444
<div className="flex gap-3 w-fit">
377445
{/* Left Column - Chat Interface */}
378446
<div className="min-w-0">
379-
<ChatInterfaceSection messages={messages} />
447+
<ChatInterfaceSection messages={messages} tools={tools} />
380448
</div>
381449

382450
{/* Token Debug Column */}

vite-app/src/components/MessageBubble.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ export const MessageBubble = ({ message }: { message: Message }) => {
1414
const isTool = message.role === "tool";
1515
const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
1616
const hasFunctionCall = message.function_call;
17+
const hideMessageContent = message.role === "assistant" && hasToolCalls;
1718

1819
// Get the message content as a string
1920
const reasoning = (message as any).reasoning_content as string | undefined;
21+
const titleLabel =
22+
message.role === "system" && message.name ? message.name : message.role;
2023
const getMessageContent = () => {
2124
if (typeof message.content === "string") {
2225
return message.content;
@@ -33,11 +36,14 @@ export const MessageBubble = ({ message }: { message: Message }) => {
3336
}
3437
};
3538

36-
const messageContent = getMessageContent();
39+
const messageContent = hideMessageContent ? "" : getMessageContent();
3740
const hasMessageContent = messageContent.trim().length > 0;
3841
const isLongMessage = messageContent.length > 200; // Threshold for considering a message "long"
3942

4043
const renderContent = () => {
44+
if (hideMessageContent) {
45+
return null;
46+
}
4147
if (typeof message.content === "string") {
4248
return isLongMessage && !isExpanded
4349
? message.content.substring(0, 200) + "..."
@@ -161,7 +167,7 @@ export const MessageBubble = ({ message }: { message: Message }) => {
161167
hasMessageContent ? "pr-8" : ""
162168
}`}
163169
>
164-
{message.role}
170+
{titleLabel}
165171
</div>
166172
<div className="whitespace-pre-wrap break-words overflow-hidden text-xs">
167173
{renderContent()}

0 commit comments

Comments
 (0)