Skip to content

Commit 6dec70a

Browse files
Fix tree expansion in evaluation report (#6107)
The fix ensures that the root level of the scenario tree is expanded by default when the report is opened. Also includes a change to ensure that we collapse single child nodes only once right after the tree is constructed, plus a couple of other minor tweaks. --------- Co-authored-by: Peter Waldschmidt <[email protected]>
1 parent 0e16702 commit 6dec70a

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript/components/ScenarioTree.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import React, { useState, useCallback } from "react";
55
import { makeStyles, tokens, Tree, TreeItem, TreeItemLayout, TreeItemValue, TreeOpenChangeData, TreeOpenChangeEvent, mergeClasses } from "@fluentui/react-components";
6-
import { DefaultRootNodeName, ScoreNode, ScoreNodeType, getPromptDetails, ChatMessageDisplay } from "./Summary";
6+
import { ScoreNode, ScoreNodeType, getPromptDetails, ChatMessageDisplay } from "./Summary";
77
import { PassFailBar } from "./PassFailBar";
88
import { MetricCardList, type MetricType } from "./MetricCard";
99
import ReactMarkdown from "react-markdown";
@@ -16,7 +16,6 @@ const ScenarioLevel = ({ node, parentPath, isOpen, renderMarkdown }: {
1616
isOpen: (path: string) => boolean,
1717
renderMarkdown: boolean,
1818
}) => {
19-
node.collapseSingleChildNodes();
2019
const path = `${parentPath}.${node.name}`;
2120
if (node.isLeafNode) {
2221
return <TreeItem itemType="branch" value={path}>
@@ -53,7 +52,7 @@ export const ScenarioGroup = ({ node, renderMarkdown }: { node: ScoreNode, rende
5352
const isOpen = (name: string) => openItems.has(name);
5453

5554
return (
56-
<Tree aria-label="Default" appearance="transparent" onOpenChange={handleOpenChange} defaultOpenItems={["." + DefaultRootNodeName]}>
55+
<Tree aria-label="Default" appearance="transparent" onOpenChange={handleOpenChange} defaultOpenItems={["." + node.name]}>
5756
<ScenarioLevel node={node} parentPath={""} isOpen={isOpen} renderMarkdown={renderMarkdown} />
5857
</Tree>);
5958
};

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript/components/Summary.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,13 @@ export class ScoreNode {
129129
}
130130
};
131131

132-
export const DefaultRootNodeName = "All Evaluations";
133-
134132
export const createScoreTree = (dataset: Dataset): ScoreNode => {
135-
const root = new ScoreNode(DefaultRootNodeName, ScoreNodeType.Group);
133+
const root = new ScoreNode("All Evaluations", ScoreNodeType.Group);
136134
for (const scenario of dataset.scenarioRunResults) {
137135
const path = [...scenario.scenarioName.split('.'), scenario.iterationName];
138136
root.insertNode(path, scenario);
139137
}
138+
root.collapseSingleChildNodes();
140139
root.aggregate();
141140
return root;
142141
};
@@ -151,8 +150,8 @@ const shortenPrompt = (prompt: string | undefined) => {
151150
return prompt;
152151
};
153152

154-
function* flattener(node: ScoreNode, parentKey: string): Iterable<{key: string, node: ScoreNode}> {
155-
const key= `${parentKey}.${node.name}`;
153+
const flattener = function* (node: ScoreNode, parentKey: string): Iterable<{key: string, node: ScoreNode}> {
154+
const key = `${parentKey}.${node.name}`;
156155
if (node.isLeafNode) {
157156
yield {key, node};
158157
} else {
@@ -161,7 +160,7 @@ function* flattener(node: ScoreNode, parentKey: string): Iterable<{key: string,
161160
yield* flattener(child, key);
162161
}
163162
}
164-
}
163+
};
165164

166165
const isTextContent = (content: AIContent): content is TextContent => {
167166
return (content as TextContent).text !== undefined;

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript/html-report/init-devdata.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@ import fs from 'fs/promises';
55
import path from 'path';
66
import {fileURLToPath} from 'url';
77

8+
const storagePath = process.argv[2];
9+
if (!storagePath) {
10+
console.error('Usage: node init-devdata.js <storagePath>');
11+
process.exit(1);
12+
}
13+
814
const __filename = fileURLToPath(import.meta.url);
915
const __dirname = path.dirname(__filename);
1016

11-
const resultsDir = path.join(__dirname, '../../../.storage/results');
17+
const resultsDir = path.join(storagePath, 'results');
1218
const scenarioDirents = await fs.readdir(resultsDir, { withFileTypes: true });
1319

1420
let maxBirthtime = 0;

0 commit comments

Comments
 (0)