Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import MaterialIcon from "@/components/MaterialIcon";
import { MainConfig } from "@/config/config";
import { PLAYGROUND_CUSTOM_INPUT_NAME } from "@/config/constants";
import { usePlaygroundContext } from "@/hooks/usePlaygroundContext";
import { useParams } from "next/navigation";
import {
continueChatBSxSQuery,
inferenceChatCompletionQuery,
Expand Down Expand Up @@ -92,6 +93,12 @@ export default function InputCardActionsRow() {
setIsNewChat,
} = usePlaygroundContext();
const { projectState, isSideBySide } = useProjectContext();
const params = useParams<{ id: string }>();
const activeProjectId =
projectState?.projectId ||
projectState?.project?.project_id ||
(params?.id as string) ||
"";

const allCustomInputs = useMemo(() => {
return inputs
Expand Down Expand Up @@ -145,7 +152,7 @@ export default function InputCardActionsRow() {

return inferenceChatCompletionQuery(
payload,
projectState?.project?.project_id || "",
activeProjectId,
);
},
onSuccess: (response: ChatCompletionResponse) => {
Expand Down Expand Up @@ -208,7 +215,7 @@ export default function InputCardActionsRow() {
}

await inferenceChatCompletionStreamingConnection(
projectState?.project?.project_id || "",
activeProjectId,
{
payload,
onStart: () => {
Expand Down Expand Up @@ -326,7 +333,7 @@ export default function InputCardActionsRow() {
model_id_b: models?.[1]?.id || null,
prompts: [...allCustomInputs],
},
projectState?.project?.project_id || "",
activeProjectId,
pairId || "",
),
onSuccess: (response) => {
Expand Down Expand Up @@ -359,7 +366,7 @@ export default function InputCardActionsRow() {
})),
variables: variables || {},
},
projectState?.project?.project_id || "",
activeProjectId,
),
onSuccess: (response) => {
onSxSQuerySuccess(response);
Expand Down Expand Up @@ -427,18 +434,28 @@ export default function InputCardActionsRow() {
!firstItem.hidden;

return (
!activeProjectId || // Disable generate output when project is not resolved
generateOutputNoInputsPresent || // Disable generate output when there are no inputs
generateOutputNoModelsPresent || // Disable generate output when there are missing models
isChatStartingWithAssistant || // Disable generate output when the chat is starting with an assistant
isChatEndingWithAssistant || // Disable generate output when the chat is ending with an assistant
generateOutputEmptyUserInputs || // Disable generate output when there are empty user inputs
!isPlaygroundModified
);
}, [isSideBySide, models, inputs]);
}, [
activeProjectId,
generateOutputNoInputsPresent,
generateOutputNoModelsPresent,
generateOutputEmptyUserInputs,
isPlaygroundModified,
inputs,
]);

const generateOutputTooltip = useMemo(() => {
let tooltip = "";
if (generateOutputNoInputsPresent) {
if (!activeProjectId) {
tooltip = "Project is still loading or invalid.";
} else if (generateOutputNoInputsPresent) {
tooltip = "There are no inputs to generate an output.";
} else if (generateOutputNoModelsPresent) {
tooltip = "There are no selected models to generate an output.";
Expand All @@ -450,6 +467,7 @@ export default function InputCardActionsRow() {

return tooltip;
}, [
activeProjectId,
generateOutputNoInputsPresent,
generateOutputNoModelsPresent,
generateOutputEmptyUserInputs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,19 @@ import { GAevents } from "@/types";
import logGAevent from "@/utils/logGAevent";
import { Text, UnstyledButton } from "@mantine/core";
import { useMutation } from "@tanstack/react-query";
import { useParams } from "next/navigation";
import { useMemo } from "react";

import { CHAT_THUMBS, SIDE_BY_SIDE_EVAL_OPTIONS } from "../../consts";

export default function OutputCardEvaluator() {
const { projectState, isSideBySide } = useProjectContext();
const params = useParams<{ id: string }>();
const activeProjectId =
projectState?.projectId ||
projectState?.project?.project_id ||
(params?.id as string) ||
"";
const { feedbackEvalId } = useHumanEvalsContext();
const {
outputs,
Expand Down Expand Up @@ -107,7 +114,7 @@ export default function OutputCardEvaluator() {
if (isSideBySide) {
const rating = thumb.value as HUMAN_SXS_RATING;
humanEvalSxSMutation.mutate({
projectId: projectState?.project?.project_id || "",
projectId: activeProjectId,
pairId,
rating:
rating && rating === humanEvaluator?.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { usePlaygroundContext } from "@/hooks/usePlaygroundContext";
import LocalStorage from "@/utils/LocalStorage";
import { Button, Group, Modal, Text } from "@mantine/core";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import { useCallback } from "react";

import { useProjectContext } from "../../../hooks/useProjectContext";
Expand All @@ -36,11 +36,17 @@ export default function PromptCleaningModal({
}: PromptCleaningModalProps) {
const hasSeen = LocalStorage.get(SHOW_PLAYGROUND_INFO_BAR);
const { projectState } = useProjectContext();
const params = useParams<{ id: string }>();
const activeProjectId =
projectState?.projectId ||
projectState?.project?.project_id ||
(params?.id as string) ||
"";
const { resetPlayground } = usePlaygroundContext();
const router = useRouter();
const onNavigateToProject = useCallback(() => {
router.push(`${routes.projects}/${projectState?.project?.project_id}`);
}, [router, projectState?.project?.project_id]);
router.push(`${routes.projects}/${activeProjectId}`);
}, [router, activeProjectId]);

const handleClose = useCallback(() => {
onClose();
Expand Down
14 changes: 10 additions & 4 deletions frontend/app/(authRoutes)/projects/[id]/playground/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { usePlaygroundContext } from "@/hooks/usePlaygroundContext";
import { Model } from "@/queries/types";
import { InferenceChatCompletionPromptRole } from "@/types";
import { Group, ScrollArea, Text } from "@mantine/core";
import { useRouter } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import { useCallback, useEffect, useMemo, useState } from "react";

import { useProjectContext } from "../../hooks/useProjectContext";
Expand All @@ -43,6 +43,12 @@ import { InputCardItemProps, PROMPTS } from "./types";

export default function ProjectPlayground() {
const { projectState, isSideBySide } = useProjectContext();
const params = useParams<{ id: string }>();
const activeProjectId =
projectState?.projectId ||
projectState?.project?.project_id ||
(params?.id as string) ||
"";
const {
isPromptCleaningModalOpen,
closePromptCleaningModalOpen,
Expand Down Expand Up @@ -96,8 +102,8 @@ export default function ProjectPlayground() {

const router = useRouter();
const onNavigateTo = useCallback(() => {
router.push(`${routes.projects}/${projectState?.project?.project_id}`);
}, [router, projectState?.project?.project_id]);
router.push(`${routes.projects}/${activeProjectId}`);
}, [router, activeProjectId]);

const onDeleteInput = (id: string) => {
const customInputs = inputs.filter((input) =>
Expand Down Expand Up @@ -180,7 +186,7 @@ export default function ProjectPlayground() {
/>
<BreadcrumbSegment
label={projectState?.project?.name || "Untitled"}
routes={`${routes.projects}/${projectState?.project?.project_id}`}
routes={`${routes.projects}/${activeProjectId}`}
showArrow={false}
/>
<Group>
Expand Down
22 changes: 20 additions & 2 deletions frontend/app/(authRoutes)/projects/hooks/useProjectContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { useProjectsContext } from "@/hooks/useProjectsContext";
import {
SxsHumanEvalPassRateQuery,
getPointwiseEvalAnalyticsQuery,
getProjectByIdQuery,
getProjectQuery,
getProjectSxSQuery,
getSxSEvalAnalyticsQuery,
Expand Down Expand Up @@ -70,6 +71,7 @@ import { getProjectModals } from "../[id]/utils/projectModals";

type ProjectMetricsData = MetricsSummaryResponse | SxsInferenceMetricsResponse;
interface ProjectState {
projectId: string;
project: Project | null;
activeStep: number;
metricsData: ProjectMetricsData | undefined;
Expand Down Expand Up @@ -293,12 +295,27 @@ export const ProjectProvider = (props: PropsWithChildren) => {
}, [projectData?.total_size, totalSize]);

useEffect(() => {
if (projectId && allProjects && allProjects.length > 0) {
if (!projectId) return;

if (allProjects && allProjects.length > 0) {
const foundProject = allProjects.find(
(proj) => proj.project_id === projectId,
);
setProject(foundProject || null);
if (foundProject) {
setProject(foundProject);
return;
}
}

getProjectByIdQuery(projectId)
.then((proj) => {
if (proj) {
setProject(proj);
}
})
.catch((err) => {
console.error("Failed to load project by ID", err);
});
}, [projectId, allProjects]);

const resetMetrics = () => {
Expand Down Expand Up @@ -494,6 +511,7 @@ export const ProjectProvider = (props: PropsWithChildren) => {

const projectContext: ProjectContextType = {
projectState: {
projectId: projectId || project?.project_id || "",
project,
activeStep,
metricsData,
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/api/[...anyRoutes]/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ async function handle(request: Request) {
const config: AxiosRequestConfig = {
method: request.method.toUpperCase(),
url: relativeEndpoint,
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8080",
headers,
timeout: 180000, // 3 minutes timeout
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/config/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const getModelDetails = (
}
};

export const DEFAULT_EVALUATOR_MODEL = "gemini-2.5-flash";
export const DEFAULT_EVALUATOR_MODEL = "gemini-flash-latest";

export const getProviders = (): ModelProvider[] => [
{
Expand Down
7 changes: 3 additions & 4 deletions frontend/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,12 @@ const nextConfig = {
},
];
},
experimental: {
proxyTimeout: 300000,
},
async rewrites() {
const backendUrl = process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8080";
return [
{
source: "/api/:path*",
destination: `${backendUrl}/:path*`,
},
{
source: "/streaming/:path*",
destination: `${backendUrl}/streaming/:path*`,
Expand Down
38 changes: 30 additions & 8 deletions frontend/queries/clientQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ export const getProjectsQuery = async (params: GetProjectsParams = {}) => {
)) as ProjectsDto;
};

export const getProjectByIdQuery = async (projectId: string) => {
return (await getRequest(
`${backendEndpoints.PROJECTS.INDEX}/${projectId}`,
)) as Project;
};

export const createProjectQuery = async (data: Project) =>
(await postRequest(backendEndpoints.PROJECTS.INDEX, data)) as Project;

Expand Down Expand Up @@ -289,20 +295,28 @@ export const deleteModelQuery = async (id: string) => {
export const inferenceChatCompletionQuery = async (
payload: InferenceChatCompletionPayload,
projectId: string,
) =>
(await postRequest(
) => {
if (!projectId) {
throw new Error("Cannot execute chat completion: Project ID is required.");
}
return (await postRequest(
`inference/projects/${projectId}/${backendEndpoints.INFERENCE.QUICK_COMPARE_CHAT_COMPLETION}`,
payload,
)) as ChatCompletionResponse;
};

export const inferenceAllChatCompletionBulkQuery = async (
payload: any,
projectId: string,
) =>
(await postRequest(
) => {
if (!projectId) {
throw new Error("Cannot execute bulk inference: Project ID is required.");
}
return (await postRequest(
`/inference/projects/${projectId}/bulk/all`,
payload,
)) as ChatCompletionResponse;
};

export const deleteUserDataQuery = () =>
deleteRequest(backendEndpoints.AUTH.DELETE_USER_DATA);
Expand Down Expand Up @@ -656,21 +670,29 @@ export const getSxsProjectBulkExport = async (
export const inferenceChatCompletionSxSQuery = async (
payload: InferenceChatCompletionSxSPayload,
projectId: string,
) =>
(await postRequest(
) => {
if (!projectId) {
throw new Error("Cannot execute SxS inference: Project ID is required.");
}
return (await postRequest(
`sxs/${backendEndpoints.CONTAINERS}/${projectId}/inference`,
payload,
)) as ChatCompletionSxSResponse;
};

export const continueChatBSxSQuery = async (
payload: ContinueChatBSxSQueryPayload,
projectId: string,
pairId: string,
) =>
(await postRequest(
) => {
if (!projectId) {
throw new Error("Cannot continue SxS chat: Project ID is required.");
}
return (await postRequest(
`sxs/${backendEndpoints.CONTAINERS}/${projectId}/${pairId}/continue`,
payload,
)) as ChatCompletionSxSResponse;
};

export const uploadDatasetFileQuery = async (
datasetId: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,19 @@ protected void doFilterInternal(
String email = PlanckConstants.DEFAULT_USER;
String firstName = PlanckConstants.DEFAULT_USER_FIRSTNAME;
String lastName = PlanckConstants.DEFAULT_USER_LASTNAME;
User user =
userService
.findByEmail(email)
.orElseGet(
() -> {
User newUser = new User(firstName, lastName, email, Role.USER);
userService.save(newUser);
humanEvaluatorService.createUserThumbsEvaluator(newUser);
return newUser;
});
User user;
synchronized (IntegrationTestSecurityConfiguration.class) {
user =
userService
.findByEmail(email)
.orElseGet(
() -> {
User newUser = new User(firstName, lastName, email, Role.USER);
userService.save(newUser);
humanEvaluatorService.createUserThumbsEvaluator(newUser);
return newUser;
});
}
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
Expand Down
Loading