+
+
+
-
- {activeCategoryLabel}
-
{
if (selection === "all") return;
@@ -297,32 +357,71 @@ function EvaluatorGallery() {
setSelectedTemplate(templateName);
}
}}
+ onAction={(key) => {
+ if (typeof key === "string") {
+ navigate(paths.galleryNewLlmFromTemplate(key));
+ }
+ }}
>
- {(template) => (
-
-
-
- {template.name}
-
- LLM
-
-
-
- {template.description}
-
-
-
- )}
+ {categories.map((category) => {
+ const headingId = getCategoryHeadingId(category);
+ return (
+
+
+ {
+ if (element) {
+ headingRefs.current.set(category, element);
+ } else {
+ headingRefs.current.delete(category);
+ }
+ }}
+ id={headingId}
+ className="project-evaluator-gallery__template-category-heading"
+ elementType="h2"
+ size="M"
+ weight="heavy"
+ >
+ {getProjectEvaluatorTemplateCategoryLabel(
+ category === OTHER_CATEGORY ? null : category
+ )}
+
+
+ {(templatesByCategory.get(category) ?? []).map((template) => (
+ {
+ if (element) {
+ templateCardRefs.current.set(template.name, element);
+ } else {
+ templateCardRefs.current.delete(template.name);
+ }
+ }}
+ id={template.name}
+ textValue={template.name}
+ >
+
+ {template.name}
+
+
+
+ {template.description}
+
+
+
+
+ ))}
+
+ );
+ })}
- navigate(paths.galleryNewLlm)}
- onCreateCodeEvaluator={() => navigate(paths.galleryNewCode)}
- />
@@ -343,23 +442,59 @@ function EvaluatorGallery() {
);
}
-function EvaluatorScratchActions({
- className,
- onCreateLlmEvaluator,
- onCreateCodeEvaluator,
+function EvaluatorGalleryAddMenu({
+ creationPaths,
+}: {
+ creationPaths: ProjectEvaluatorCreationPaths;
+}) {
+ return (
+
+ );
+}
+
+function EvaluatorTemplateCardFooter({
+ evaluatorKind,
+ evaluationTargets,
}: {
- className: string;
- onCreateLlmEvaluator: () => void;
- onCreateCodeEvaluator: () => void;
+ evaluatorKind: "CODE" | "LLM";
+ evaluationTargets: readonly [
+ ProjectEvaluatorTarget,
+ ...ProjectEvaluatorTarget[],
+ ];
}) {
return (
-
-
-
+
+
+
+
+
+ {evaluationTargets.map((target) => (
+
+ {capitalize(formatEvaluationTargetPlural(target))}
+
+ ))}
+
);
}
@@ -377,19 +512,17 @@ function EvaluatorTemplateDetails({
optimizationDirection: template.optimizationDirection,
values: choices,
});
+ const messages = getProjectEvaluatorTemplateMessages(template);
return (
{template.name}
- LLM
+
{getProjectEvaluatorTemplateCategoryLabel(template.category)}
-
- {template.description}
-
{template.details ? (
{template.details}
@@ -400,7 +533,7 @@ function EvaluatorTemplateDetails({
- Scope
+ Target
@@ -424,7 +557,7 @@ function EvaluatorTemplateDetails({
- Output choices
+ Annotation values
{choices.map(({ label, score }) => (
@@ -454,13 +587,72 @@ function EvaluatorTemplateDetails({
))}
-
+ {messages.length > 0 ? (
+
+
+ Prompt
+
+
+
+
+ {messages.map((message) => (
+
+
+ {capitalize(message.role)}
+
+
+ {message.content}
+
+
+ ))}
+
+
+
+
+ ) : null}
+
+
+
);
}
+// Bleeds out to the edges of the details column's own padding/gap (both
+// `var(--global-dimension-size-200)`) and re-adds that same space as padding
+// inside this element's own background, so nothing scrolls behind it.
+const stickyUseTemplateFooterCSS = css`
+ position: sticky;
+ bottom: calc(-1 * var(--project-evaluator-gallery-column-padding));
+ z-index: 1;
+ margin: calc(-1 * var(--global-dimension-size-200))
+ calc(-1 * var(--project-evaluator-gallery-column-padding))
+ calc(-1 * var(--project-evaluator-gallery-column-padding));
+ padding: var(--global-dimension-size-200)
+ var(--project-evaluator-gallery-column-padding)
+ var(--project-evaluator-gallery-column-padding);
+ background-color: var(--global-background-color-default);
+`;
+
+const PROMPT_PREVIEW_COLLAPSED_HEIGHT = 160;
+
+const promptPreviewWellCSS = css`
+ background-color: var(--global-background-color-100);
+ border: var(--global-border-size-thin) solid
+ var(--global-border-color-default);
+ border-radius: var(--global-rounding-medium);
+ padding: var(--global-dimension-size-150);
+`;
+
+const promptPreviewMessageCSS = css`
+ white-space: pre-wrap;
+`;
+
function capitalize(value: string): string {
return `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
}
@@ -517,7 +709,7 @@ const galleryCSS = css`
);
--project-evaluator-gallery-column-padding: var(--global-dimension-size-200);
--project-evaluator-gallery-template-card-min-width: var(
- --global-dimension-size-3000
+ --global-dimension-size-4600
);
--project-evaluator-gallery-template-column-min-width: calc(
var(--project-evaluator-gallery-template-card-min-width) +
@@ -567,9 +759,9 @@ const galleryCSS = css`
}
.project-evaluator-gallery__category-list {
- flex: 1 1 auto;
- min-height: 0;
+ flex: none;
gap: var(--global-dimension-size-100);
+ overflow: visible;
.react-aria-ListBoxSection {
display: flex;
@@ -584,28 +776,52 @@ const galleryCSS = css`
}
}
+ .project-evaluator-gallery__category-scroll-region {
+ flex: 1 1 auto;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+ gap: var(--global-dimension-size-100);
+ overflow-y: auto;
+ }
+
.project-evaluator-gallery__category-section-heading {
padding: var(--global-dimension-size-50) var(--global-dimension-size-100);
letter-spacing: 0.06em;
text-transform: uppercase;
}
- .project-evaluator-gallery__scratch-actions,
- .project-evaluator-gallery__compact-scratch-actions {
+ .project-evaluator-gallery__add-evaluator-button {
flex: none;
- padding-top: var(--global-dimension-size-200);
- border-top: var(--global-border-size-thin) solid
- var(--global-border-color-default);
+ align-self: stretch;
+ width: 100%;
+ margin-bottom: var(--global-dimension-size-200);
}
- .project-evaluator-gallery__compact-category-select,
- .project-evaluator-gallery__compact-scratch-actions {
+ .project-evaluator-gallery__compact-category-select {
display: none;
}
- .project-evaluator-gallery__template-list {
+ .project-evaluator-gallery__compact-add-evaluator-menu {
+ display: none;
+ }
+
+ .project-evaluator-gallery__template-card-scroll-region {
flex: 1 1 auto;
min-height: 0;
+ display: flex;
+ flex-direction: column;
+ gap: var(--global-dimension-size-400);
+ margin-top: var(--global-dimension-size-100);
+ overflow-y: auto;
+ scroll-behavior: smooth;
+
+ @media (prefers-reduced-motion: reduce) {
+ scroll-behavior: auto;
+ }
+ }
+
+ .project-evaluator-gallery__template-category-section {
display: grid;
grid-template-columns: repeat(
auto-fit,
@@ -613,16 +829,29 @@ const galleryCSS = css`
);
align-content: start;
gap: var(--global-dimension-size-100);
- margin-top: var(--global-dimension-size-100);
+ }
- .react-aria-ListBoxItem {
- min-height: var(--global-dimension-size-1400);
- gap: var(--global-dimension-size-100);
- margin: 0;
- padding: var(--global-dimension-size-150);
- border: var(--global-border-size-thin) solid
- var(--global-border-color-default);
- }
+ .project-evaluator-gallery__template-category-header {
+ grid-column: 1 / -1;
+ }
+
+ .project-evaluator-gallery__template-category-heading {
+ /* Anchor target for the category nav; offset so scrollIntoView doesn't
+ tuck it flush against the scroll region's top edge. */
+ scroll-margin-top: var(--global-dimension-size-100);
+ }
+
+ .project-evaluator-gallery__template-card-footer {
+ width: 100%;
+ margin-top: auto;
+ }
+
+ .project-evaluator-gallery__template-kind {
+ flex: none;
+ }
+
+ .project-evaluator-gallery__template-targets {
+ min-width: 0;
}
.project-evaluator-gallery__definition-list {
@@ -662,27 +891,17 @@ const galleryCSS = css`
width: 100%;
}
+ .project-evaluator-gallery__compact-add-evaluator-menu {
+ display: flex;
+ flex: none;
+ justify-content: flex-start;
+ }
+
.project-evaluator-gallery__templates {
grid-column: 1;
grid-row: 1;
}
- .project-evaluator-gallery__template-list-title {
- display: none;
- }
-
- .project-evaluator-gallery__template-list {
- grid-template-columns: minmax(
- var(--project-evaluator-gallery-template-card-min-width),
- 1fr
- );
- }
-
- .project-evaluator-gallery__compact-scratch-actions {
- display: flex;
- margin-top: var(--global-dimension-size-200);
- }
-
.project-evaluator-gallery__details {
grid-column: 2;
grid-row: 1;
diff --git a/js/app/src/pages/project/evaluators/ProjectEvaluatorSlideoverRoutes.tsx b/js/app/src/pages/project/evaluators/ProjectEvaluatorSlideoverRoutes.tsx
index a40b30b7f9f..bfc68f70f51 100644
--- a/js/app/src/pages/project/evaluators/ProjectEvaluatorSlideoverRoutes.tsx
+++ b/js/app/src/pages/project/evaluators/ProjectEvaluatorSlideoverRoutes.tsx
@@ -1,6 +1,6 @@
import { useMemo } from "react";
import { useLazyLoadQuery } from "react-relay";
-import { useNavigate, useParams } from "react-router";
+import { useLocation, useNavigate, useParams } from "react-router";
import invariant from "tiny-invariant";
import type { projectEvaluatorDetailsQuery } from "@phoenix/pages/project/evaluators/__generated__/projectEvaluatorDetailsQuery.graphql";
@@ -18,7 +18,6 @@ import {
projectEvaluatorDetailsQueryNode,
UNSUPPORTED_PROMPT_TEMPLATE_ERROR,
} from "@phoenix/pages/project/evaluators/projectEvaluatorOptions";
-import { useProjectEvaluatorPaths } from "@phoenix/pages/project/evaluators/projectEvaluatorPaths";
import { ProjectEvaluatorSlideoverError } from "@phoenix/pages/project/evaluators/ProjectEvaluatorSlideoverError";
import {
buildTemplateCreationMode,
@@ -26,29 +25,24 @@ import {
} from "@phoenix/pages/project/evaluators/projectEvaluatorTemplates";
/**
- * Closes the slideover by leaving its route — to the evaluators list unless
- * the caller names another destination. Replaces rather than pushes, so a
- * slideover the user has dismissed does not sit one step back in history
- * waiting to be reopened.
+ * Closes the slideover by leaving its nested route for its parent page.
+ * Replaces rather than pushes, so a dismissed slideover does not sit one step
+ * back in history waiting to be reopened. The current search is retained so
+ * the parent page restores the view state the slideover was opened over.
*/
-function useCloseSlideover(to?: string) {
+function useCloseSlideover() {
const navigate = useNavigate();
- const { list } = useProjectEvaluatorPaths();
- const destination = to ?? list;
+ const { search } = useLocation();
return (isOpen: boolean) => {
if (!isOpen) {
- navigate(destination, { replace: true });
+ navigate(
+ { pathname: "..", search },
+ { relative: "route", replace: true }
+ );
}
};
}
-function useCloseGallerySlideover() {
- // Gallery slideovers close over the selected category and template rather
- // than resetting the gallery to its default view.
- const { galleryReturn } = useProjectEvaluatorPaths();
- return useCloseSlideover(galleryReturn);
-}
-
function useRouteProjectId() {
const { projectId } = useParams();
invariant(projectId, "projectId is required");
@@ -84,19 +78,6 @@ export function NewLlmProjectEvaluatorPage() {
);
}
-export function NewGalleryLlmProjectEvaluatorPage() {
- const projectId = useRouteProjectId();
- const onOpenChange = useCloseGallerySlideover();
- return (
-
- );
-}
-
export function NewCodeProjectEvaluatorPage() {
const projectId = useRouteProjectId();
const onOpenChange = useCloseSlideover();
@@ -110,24 +91,11 @@ export function NewCodeProjectEvaluatorPage() {
);
}
-export function NewGalleryCodeProjectEvaluatorPage() {
- const projectId = useRouteProjectId();
- const onOpenChange = useCloseGallerySlideover();
- return (
-
- );
-}
-
export function NewGalleryLlmFromTemplateProjectEvaluatorPage() {
const projectId = useRouteProjectId();
const { templateName } = useParams();
invariant(templateName, "templateName is required");
- const onOpenChange = useCloseGallerySlideover();
+ const onOpenChange = useCloseSlideover();
const data = useLazyLoadQuery(
projectEvaluatorTemplatesQuery,
{},
@@ -233,10 +201,7 @@ export function AttachCodeProjectEvaluatorPage() {
export function EditProjectEvaluatorPage() {
const { projectEvaluatorId } = useParams();
invariant(projectEvaluatorId, "projectEvaluatorId is required");
- // The edit route nests under the evaluator's details page, so closing lands
- // on the details view it was opened over rather than the list.
- const { details } = useProjectEvaluatorPaths();
- const onOpenChange = useCloseSlideover(details(projectEvaluatorId));
+ const onOpenChange = useCloseSlideover();
const { evaluator, sandboxConfigs } = useProjectEvaluator(projectEvaluatorId);
if (
evaluator.evaluator.kind !== "LLM" &&
diff --git a/js/app/src/pages/project/evaluators/ProjectEvaluatorsEmptyState.tsx b/js/app/src/pages/project/evaluators/ProjectEvaluatorsEmptyState.tsx
index 71cce7c00e4..c46292a553a 100644
--- a/js/app/src/pages/project/evaluators/ProjectEvaluatorsEmptyState.tsx
+++ b/js/app/src/pages/project/evaluators/ProjectEvaluatorsEmptyState.tsx
@@ -1,6 +1,6 @@
import { css } from "@emotion/react";
import { type ReactNode, Suspense, useRef, useState } from "react";
-import { useLazyLoadQuery } from "react-relay";
+import { graphql, useLazyLoadQuery } from "react-relay";
import {
Flex,
@@ -13,20 +13,31 @@ import {
Text,
} from "@phoenix/components";
import { ErrorBoundary } from "@phoenix/components/exception";
-import type { projectEvaluatorTemplatesQuery as ProjectEvaluatorTemplatesQueryType } from "@phoenix/pages/project/evaluators/__generated__/projectEvaluatorTemplatesQuery.graphql";
+import type {
+ projectEvaluatorCategoryCardsQuery as ProjectEvaluatorCategoryCardsQueryType,
+ projectEvaluatorCategoryCardsQuery$data,
+} from "@phoenix/pages/project/evaluators/__generated__/projectEvaluatorCategoryCardsQuery.graphql";
import { BuildProjectEvaluatorMenu } from "@phoenix/pages/project/evaluators/AddProjectEvaluatorMenu";
import { useProjectEvaluatorPaths } from "@phoenix/pages/project/evaluators/projectEvaluatorPaths";
-import {
- PROJECT_EVALUATOR_CATEGORIES,
- type ProjectEvaluatorTemplate,
- projectEvaluatorTemplatesQuery,
-} from "@phoenix/pages/project/evaluators/projectEvaluatorTemplates";
+import { PROJECT_EVALUATOR_CATEGORIES } from "@phoenix/pages/project/evaluators/projectEvaluatorTemplates";
const MAX_CATEGORY_TEMPLATES = 3;
const CATEGORY_CARDS_PER_VIEW = 3;
const CATEGORY_CARD_MIN_HEIGHT = 250;
const CATEGORY_CAROUSEL_ID = "project-evaluator-category-carousel";
+const projectEvaluatorCategoryCardsQuery = graphql`
+ query projectEvaluatorCategoryCardsQuery {
+ evaluatorGalleryConfigs {
+ name
+ category
+ }
+ }
+`;
+
+type ProjectEvaluatorCategoryCardTemplate =
+ projectEvaluatorCategoryCardsQuery$data["evaluatorGalleryConfigs"][number];
+
export function ProjectEvaluatorsEmptyState() {
const paths = useProjectEvaluatorPaths();
return (
@@ -43,9 +54,12 @@ export function ProjectEvaluatorsEmptyState() {
-
+
- Browse the library
+ Browse eval gallery
@@ -53,8 +67,8 @@ export function ProjectEvaluatorsEmptyState() {
}
function EvaluatorCategoryCards() {
- const data = useLazyLoadQuery(
- projectEvaluatorTemplatesQuery,
+ const data = useLazyLoadQuery(
+ projectEvaluatorCategoryCardsQuery,
{},
{ fetchPolicy: "store-and-network" }
);
@@ -64,7 +78,7 @@ function EvaluatorCategoryCards() {
function CategoryCards({
templates,
}: {
- templates: readonly ProjectEvaluatorTemplate[];
+ templates: readonly ProjectEvaluatorCategoryCardTemplate[];
}) {
const paths = useProjectEvaluatorPaths();
// Keep the full track mounted so native scrolling can animate continuously
@@ -82,22 +96,37 @@ function CategoryCards({
const showCategoryAtIndex = (categoryIndex: number) => {
const categoryCardList = categoryCardListRef.current;
const targetCategoryCard = categoryCardList?.children.item(categoryIndex);
- if (targetCategoryCard instanceof HTMLElement) {
- // The scroll port's padding keeps adjacent cards peeking at the edges.
- targetCategoryCard.scrollIntoView({
- block: "nearest",
- inline: "start",
+ if (categoryCardList && targetCategoryCard instanceof HTMLElement) {
+ const categoryCardListRect = categoryCardList.getBoundingClientRect();
+ const targetCategoryCardRect = targetCategoryCard.getBoundingClientRect();
+ const scrollPaddingInlineStart =
+ Number.parseFloat(
+ getComputedStyle(categoryCardList).scrollPaddingInlineStart
+ ) || 0;
+ // Move only the carousel. scrollIntoView would also move the table's
+ // shared horizontal scroll container when the table overflows.
+ categoryCardList.scrollTo({
+ left:
+ categoryCardList.scrollLeft +
+ targetCategoryCardRect.left -
+ categoryCardListRect.left -
+ scrollPaddingInlineStart,
});
}
setFirstVisibleCategoryIndex(categoryIndex);
};
const showPreviousCategories = () => {
- showCategoryAtIndex(Math.max(firstVisibleCategoryIndex - 1, 0));
+ showCategoryAtIndex(
+ Math.max(firstVisibleCategoryIndex - CATEGORY_CARDS_PER_VIEW, 0)
+ );
};
const showNextCategories = () => {
showCategoryAtIndex(
- Math.min(firstVisibleCategoryIndex + 1, lastFirstVisibleCategoryIndex)
+ Math.min(
+ firstVisibleCategoryIndex + CATEGORY_CARDS_PER_VIEW,
+ lastFirstVisibleCategoryIndex
+ )
);
};
@@ -253,7 +282,7 @@ function CategoryCarouselControls({
const emptyStateContentCSS = css`
box-sizing: border-box;
margin-inline: auto;
- padding: var(--global-dimension-size-400) 0 var(--global-dimension-size-600);
+ padding: var(--global-dimension-size-700) 0 var(--global-dimension-size-600);
`;
const categoryCarouselControlCSS = css`
diff --git a/js/app/src/pages/project/evaluators/ProjectEvaluatorsPage.tsx b/js/app/src/pages/project/evaluators/ProjectEvaluatorsPage.tsx
index b7911b710dc..a460d96b467 100644
--- a/js/app/src/pages/project/evaluators/ProjectEvaluatorsPage.tsx
+++ b/js/app/src/pages/project/evaluators/ProjectEvaluatorsPage.tsx
@@ -4,10 +4,11 @@ import { graphql, useLazyLoadQuery } from "react-relay";
import { Outlet, useParams } from "react-router";
import invariant from "tiny-invariant";
-import { Flex, PageHeader, Skeleton, View } from "@phoenix/components";
+import { Flex, Skeleton, Text, View } from "@phoenix/components";
import { useTimeRange } from "@phoenix/components/datetime";
import type { ProjectEvaluatorsPageQuery } from "@phoenix/pages/project/evaluators/__generated__/ProjectEvaluatorsPageQuery.graphql";
import { AddProjectEvaluatorMenu } from "@phoenix/pages/project/evaluators/AddProjectEvaluatorMenu";
+import { useProjectEvaluatorPaths } from "@phoenix/pages/project/evaluators/projectEvaluatorPaths";
import { ProjectEvaluatorsTable } from "@phoenix/pages/project/evaluators/ProjectEvaluatorsTable";
import { ProjectEvaluatorsToolbar } from "@phoenix/pages/project/evaluators/ProjectEvaluatorsToolbar";
@@ -80,17 +81,34 @@ function ProjectEvaluatorsPageContent({
{ fetchPolicy: "store-and-network" }
);
invariant(data.project, "project is required");
+ const paths = useProjectEvaluatorPaths();
const isEmptyState =
(data.project.evaluatorCount ?? 0) === 0 && filter.trim().length === 0;
return (
<>
{isEmptyState ? (
-
- }
- />
+
+
+
+ Evaluators read span inputs, outputs, retrieved documents, and
+ tool calls, then return labels or scores you can filter, chart,
+ and alert on.
+
+
+
) : (
);
}
+ // hasNext means more evaluators exist beyond this page, so rows.length is
+ // only the true total once the full connection has loaded.
+ const showGalleryPromo =
+ !isFiltered && !hasNext && rows.length < GALLERY_PROMO_MAX_EVALUATOR_COUNT;
return (
) : null}
+ {showGalleryPromo ? (
+
+
+
+ ) : null}
);
}
diff --git a/js/app/src/pages/project/evaluators/ProjectEvaluatorsToolbar.tsx b/js/app/src/pages/project/evaluators/ProjectEvaluatorsToolbar.tsx
index f02f779a7c3..b134727ea26 100644
--- a/js/app/src/pages/project/evaluators/ProjectEvaluatorsToolbar.tsx
+++ b/js/app/src/pages/project/evaluators/ProjectEvaluatorsToolbar.tsx
@@ -1,5 +1,6 @@
import { DebouncedSearch, Flex, View } from "@phoenix/components";
import { AddProjectEvaluatorMenu } from "@phoenix/pages/project/evaluators/AddProjectEvaluatorMenu";
+import { useProjectEvaluatorPaths } from "@phoenix/pages/project/evaluators/projectEvaluatorPaths";
/**
* The evaluators tab's own header: search on the left, creation on the right.
@@ -13,6 +14,7 @@ export function ProjectEvaluatorsToolbar({
filter: string;
onFilterChange: (filter: string) => void;
}) {
+ const paths = useProjectEvaluatorPaths();
return (
-
+
diff --git a/js/app/src/pages/project/evaluators/__generated__/projectEvaluatorCategoryCardsQuery.graphql.ts b/js/app/src/pages/project/evaluators/__generated__/projectEvaluatorCategoryCardsQuery.graphql.ts
new file mode 100644
index 00000000000..f340ad66ac0
--- /dev/null
+++ b/js/app/src/pages/project/evaluators/__generated__/projectEvaluatorCategoryCardsQuery.graphql.ts
@@ -0,0 +1,82 @@
+/**
+ * @generated SignedSource<>
+ * @lightSyntaxTransform
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest } from 'relay-runtime';
+export type EvaluatorCategory = "AGENTS" | "GROUNDING_AND_RETRIEVAL" | "RESPONSE_QUALITY" | "SAFETY_AND_SECURITY" | "USER_EXPERIENCE";
+export type projectEvaluatorCategoryCardsQuery$variables = Record;
+export type projectEvaluatorCategoryCardsQuery$data = {
+ readonly evaluatorGalleryConfigs: ReadonlyArray<{
+ readonly category: EvaluatorCategory | null;
+ readonly name: string;
+ }>;
+};
+export type projectEvaluatorCategoryCardsQuery = {
+ response: projectEvaluatorCategoryCardsQuery$data;
+ variables: projectEvaluatorCategoryCardsQuery$variables;
+};
+
+const node: ConcreteRequest = (function(){
+var v0 = [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "ClassificationEvaluatorConfig",
+ "kind": "LinkedField",
+ "name": "evaluatorGalleryConfigs",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "name",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "category",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+];
+return {
+ "fragment": {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "projectEvaluatorCategoryCardsQuery",
+ "selections": (v0/*:: as any*/),
+ "type": "Query",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": [],
+ "kind": "Operation",
+ "name": "projectEvaluatorCategoryCardsQuery",
+ "selections": (v0/*:: as any*/)
+ },
+ "params": {
+ "cacheID": "37f203807a26e3217d23ff16be421fca",
+ "id": null,
+ "metadata": {},
+ "name": "projectEvaluatorCategoryCardsQuery",
+ "operationKind": "query",
+ "text": "query projectEvaluatorCategoryCardsQuery {\n evaluatorGalleryConfigs {\n name\n category\n }\n}\n"
+ }
+};
+})();
+
+(node as any).hash = "e41ebc1806e1a898862f3022618e20b9";
+
+export default node;
diff --git a/js/app/src/pages/project/evaluators/__generated__/projectEvaluatorTemplatesQuery.graphql.ts b/js/app/src/pages/project/evaluators/__generated__/projectEvaluatorTemplatesQuery.graphql.ts
index aefb875852f..2f674d903cb 100644
--- a/js/app/src/pages/project/evaluators/__generated__/projectEvaluatorTemplatesQuery.graphql.ts
+++ b/js/app/src/pages/project/evaluators/__generated__/projectEvaluatorTemplatesQuery.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<71a77d7dc4a2b943c67f5d9f41d16c54>>
+ * @generated SignedSource<<3ba5bece667c2aeb6e53064903e2ff41>>
* @lightSyntaxTransform
*/
@@ -24,7 +24,6 @@ export type projectEvaluatorTemplatesQuery$data = {
}>;
readonly name: string;
readonly optimizationDirection: OptimizationDirection;
- readonly recommended: boolean;
readonly scope: EvaluatorScope | null;
}>;
};
@@ -70,27 +69,20 @@ v4 = {
"storageKey": null
},
v5 = {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "recommended",
- "storageKey": null
-},
-v6 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
},
-v7 = {
+v6 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "details",
"storageKey": null
},
-v8 = {
+v7 = {
"kind": "InlineFragment",
"selections": [
{
@@ -115,7 +107,7 @@ v8 = {
"type": "TextContentPart",
"abstractKey": null
},
-v9 = {
+v8 = {
"alias": null,
"args": null,
"kind": "ScalarField",
@@ -144,7 +136,6 @@ return {
(v4/*:: as any*/),
(v5/*:: as any*/),
(v6/*:: as any*/),
- (v7/*:: as any*/),
{
"alias": null,
"args": null,
@@ -165,11 +156,11 @@ return {
"name": "content",
"plural": true,
"selections": [
- (v8/*:: as any*/)
+ (v7/*:: as any*/)
],
"storageKey": null
},
- (v9/*:: as any*/)
+ (v8/*:: as any*/)
],
"args": null,
"argumentDefinitions": []
@@ -205,7 +196,6 @@ return {
(v4/*:: as any*/),
(v5/*:: as any*/),
(v6/*:: as any*/),
- (v7/*:: as any*/),
{
"alias": null,
"args": null,
@@ -229,11 +219,11 @@ return {
"name": "__typename",
"storageKey": null
},
- (v8/*:: as any*/)
+ (v7/*:: as any*/)
],
"storageKey": null
},
- (v9/*:: as any*/)
+ (v8/*:: as any*/)
],
"storageKey": null
}
@@ -243,16 +233,16 @@ return {
]
},
"params": {
- "cacheID": "df501872be9d85392c84aca78c3a9bdb",
+ "cacheID": "f0e73fa7c6554ae4221a97efd090ac9c",
"id": null,
"metadata": {},
"name": "projectEvaluatorTemplatesQuery",
"operationKind": "query",
- "text": "query projectEvaluatorTemplatesQuery {\n evaluatorGalleryConfigs {\n name\n description\n choices\n optimizationDirection\n scope\n recommended\n category\n details\n messages {\n ...promptUtils_promptMessages\n }\n }\n}\n\nfragment promptUtils_promptMessages on PromptMessage {\n content {\n __typename\n ... on TextContentPart {\n text {\n text\n }\n }\n }\n role\n}\n"
+ "text": "query projectEvaluatorTemplatesQuery {\n evaluatorGalleryConfigs {\n name\n description\n choices\n optimizationDirection\n scope\n category\n details\n messages {\n ...promptUtils_promptMessages\n }\n }\n}\n\nfragment promptUtils_promptMessages on PromptMessage {\n content {\n __typename\n ... on TextContentPart {\n text {\n text\n }\n }\n }\n role\n}\n"
}
};
})();
-(node as any).hash = "0e340a9d94ce94b0cc95de808a9b6de5";
+(node as any).hash = "157fdc1db6e6d4a22592570e2efd0a2d";
export default node;
diff --git a/js/app/src/pages/project/evaluators/__tests__/projectEvaluatorPaths.test.tsx b/js/app/src/pages/project/evaluators/__tests__/projectEvaluatorPaths.test.tsx
index 2db3eaddff6..75cfcfac354 100644
--- a/js/app/src/pages/project/evaluators/__tests__/projectEvaluatorPaths.test.tsx
+++ b/js/app/src/pages/project/evaluators/__tests__/projectEvaluatorPaths.test.tsx
@@ -26,7 +26,20 @@ function TestProjectEvaluatorPaths() {
return (