= ({
? "w-full"
: chartsData.length === 2
? "basis-1/2"
- : "basis-2/5";
+ : "basis-[520px]";
return (
0 && "mb-6",
+ "flex items-center gap-4 overflow-y-auto",
+ chartsData.length > 0 && "mb-4",
)}
>
{chartsData.map((data) => (
diff --git a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutput.tsx b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutput.tsx
index 36a67e8301..e1ed354522 100644
--- a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutput.tsx
+++ b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutput.tsx
@@ -1,7 +1,7 @@
import React from "react";
import ReactMarkdown from "react-markdown";
-import { getAlphabetLetter } from "@/lib/utils";
+import { cn, getAlphabetLetter } from "@/lib/utils";
import PlaygroundOutputLoader from "@/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputLoader/PlaygroundOutputLoader";
import {
useOutputLoadingByPromptDatasetItemId,
@@ -25,7 +25,11 @@ const PlaygroundOutput = ({ promptId, index }: PlaygroundOutputProps) => {
}
return (
-
+
{value}
);
diff --git a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputActions/usePromptDatasetItemCombination.ts b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputActions/usePromptDatasetItemCombination.ts
index 75197e8bca..00681d2ca7 100644
--- a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputActions/usePromptDatasetItemCombination.ts
+++ b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputActions/usePromptDatasetItemCombination.ts
@@ -16,6 +16,7 @@ import mustache from "mustache";
import cloneDeep from "lodash/cloneDeep";
import set from "lodash/set";
import isObject from "lodash/isObject";
+import useLocalAIProviderData from "@/hooks/useLocalAIProviderData";
export interface DatasetItemPromptCombination {
datasetItem?: DatasetItem;
@@ -85,6 +86,8 @@ const usePromptDatasetItemCombination = ({
// the prop is just taken as the value on the moment of creation
const isToStopRef = useRef(isToStop);
+ const { getLocalIAProviderURL } = useLocalAIProviderData();
+
const runStreaming = useCompletionProxyStreaming({
workspaceName,
});
@@ -138,6 +141,7 @@ const usePromptDatasetItemCombination = ({
);
const run = await runStreaming({
+ url: getLocalIAProviderURL(prompt.provider),
model: prompt.model,
messages: providerMessages,
configs: prompt.configs,
@@ -149,7 +153,8 @@ const usePromptDatasetItemCombination = ({
},
});
- const error = run.opikError || run.providerError;
+ const error =
+ run.opikError || run.providerError || run.pythonProxyError;
updateOutput(prompt.id, datasetItemId, {
isLoading: false,
@@ -160,7 +165,7 @@ const usePromptDatasetItemCombination = ({
providerMessages,
configs: prompt.configs,
model: prompt.model,
-
+ provider: prompt.provider,
promptId: prompt.id,
datasetName,
datasetItemId: datasetItemId,
@@ -182,10 +187,11 @@ const usePromptDatasetItemCombination = ({
},
[
- datasetName,
- runStreaming,
- updateOutput,
addAbortController,
+ updateOutput,
+ runStreaming,
+ getLocalIAProviderURL,
+ datasetName,
deleteAbortController,
],
);
diff --git a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputTable/PlaygroundOutputCell.tsx b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputTable/PlaygroundOutputCell.tsx
index 626b16a7d3..17a48cbe09 100644
--- a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputTable/PlaygroundOutputCell.tsx
+++ b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputTable/PlaygroundOutputCell.tsx
@@ -9,6 +9,7 @@ import {
} from "@/store/PlaygroundStore";
import ReactMarkdown from "react-markdown";
import PlaygroundOutputLoader from "@/components/pages/PlaygroundPage/PlaygroundOutputs/PlaygroundOutputLoader/PlaygroundOutputLoader";
+import { cn } from "@/lib/utils";
interface PlaygroundOutputCellData {
dataItemId: string;
@@ -46,7 +47,11 @@ const PlaygroundOutputCell: React.FunctionComponent<
}
return (
-
+
{value}
);
diff --git a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompt.tsx b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompt.tsx
index 8b6bbfc8d6..523add9792 100644
--- a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompt.tsx
+++ b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompt.tsx
@@ -15,11 +15,7 @@ import {
generateDefaultPrompt,
getDefaultConfigByProvider,
} from "@/lib/playground";
-import {
- generateDefaultLLMPromptMessage,
- getModelProvider,
- getNextMessageType,
-} from "@/lib/llm";
+import { generateDefaultLLMPromptMessage, getNextMessageType } from "@/lib/llm";
import LLMPromptMessages from "@/components/pages-shared/llm/LLMPromptMessages/LLMPromptMessages";
import PromptModelSelect from "@/components/pages-shared/llm/PromptModelSelect/PromptModelSelect";
import { getAlphabetLetter } from "@/lib/utils";
@@ -33,9 +29,11 @@ import {
useUpdateOutput,
useUpdatePrompt,
} from "@/store/PlaygroundStore";
-import { getDefaultProviderKey } from "@/lib/provider";
-import { PROVIDERS } from "@/constants/providers";
import useLastPickedModel from "@/components/pages/PlaygroundPage/PlaygroundPrompts/useLastPickedModel";
+import {
+ ModelResolver,
+ ProviderResolver,
+} from "@/hooks/useLLMProviderModelsData";
interface PlaygroundPromptProps {
workspaceName: string;
@@ -43,6 +41,8 @@ interface PlaygroundPromptProps {
promptId: string;
providerKeys: PROVIDER_TYPE[];
isPendingProviderKeys: boolean;
+ providerResolver: ProviderResolver;
+ modelResolver: ModelResolver;
}
const PlaygroundPrompt = ({
@@ -51,6 +51,8 @@ const PlaygroundPrompt = ({
index,
providerKeys,
isPendingProviderKeys,
+ providerResolver,
+ modelResolver,
}: PlaygroundPromptProps) => {
const checkedIfModelIsValidRef = useRef(false);
@@ -66,7 +68,7 @@ const PlaygroundPrompt = ({
const deletePrompt = useDeletePrompt();
const updateOutput = useUpdateOutput();
- const provider = model ? getModelProvider(model) : "";
+ const provider = providerResolver(model);
const hintMessage = datasetVariables?.length
? `Reference dataset variables using mustache syntax: ${datasetVariables
@@ -91,6 +93,8 @@ const PlaygroundPrompt = ({
const newPrompt = generateDefaultPrompt({
initPrompt: prompt,
setupProviders: providerKeys,
+ providerResolver: providerResolver,
+ modelResolver: modelResolver,
});
addPrompt(newPrompt, index + 1);
@@ -116,32 +120,40 @@ const PlaygroundPrompt = ({
);
const handleUpdateModel = useCallback(
- (model: PROVIDER_MODEL_TYPE) => {
- updatePrompt(promptId, { model });
- setLastPickedModel(model);
+ (newModel: PROVIDER_MODEL_TYPE, newProvider: PROVIDER_TYPE) => {
+ updatePrompt(promptId, {
+ model: newModel,
+ provider: newProvider,
+ ...(newProvider !== provider && {
+ configs: getDefaultConfigByProvider(newProvider),
+ }),
+ });
+ setLastPickedModel(newModel);
},
- [updatePrompt, promptId, setLastPickedModel],
+ [updatePrompt, promptId, provider, setLastPickedModel],
);
const handleAddProvider = useCallback(
(provider: PROVIDER_TYPE) => {
- const modelProvider = model ? getModelProvider(model) : "";
- const noCurrentModel = !modelProvider;
-
- if (noCurrentModel) {
- const newModel = PROVIDERS[provider]?.defaultModel || "";
-
- const newDefaultConfigs = provider
- ? getDefaultConfigByProvider(provider)
- : {};
+ const newModel = modelResolver(model, providerKeys, provider);
+ if (newModel !== model) {
+ const newProvider = providerResolver(newModel);
updatePrompt(promptId, {
model: newModel,
- configs: newDefaultConfigs,
+ provider: newProvider,
+ configs: getDefaultConfigByProvider(newProvider),
});
}
},
- [model, promptId, updatePrompt],
+ [
+ modelResolver,
+ model,
+ providerKeys,
+ providerResolver,
+ updatePrompt,
+ promptId,
+ ],
);
useEffect(() => {
@@ -149,40 +161,24 @@ const PlaygroundPrompt = ({
if (!checkedIfModelIsValidRef.current && !isPendingProviderKeys) {
checkedIfModelIsValidRef.current = true;
- const modelProvider = model ? getModelProvider(model) : "";
+ const newModel = modelResolver(model, providerKeys);
- const noModelProviderWhenProviderKeysSet =
- !modelProvider && providerKeys.length > 0;
- const modelProviderIsNotFromProviderKeys =
- modelProvider && !providerKeys.includes(modelProvider);
-
- const needToChangeProvider =
- noModelProviderWhenProviderKeysSet ||
- modelProviderIsNotFromProviderKeys;
+ if (newModel !== model) {
+ const newProvider = providerResolver(newModel);
+ updatePrompt(promptId, {
+ model: newModel,
+ provider: newProvider,
+ configs: getDefaultConfigByProvider(newProvider),
+ });
- if (!needToChangeProvider) {
- return;
+ updateOutput(promptId, "", { value: "" });
}
-
- const newProvider = getDefaultProviderKey(providerKeys);
- const newModel = newProvider
- ? PROVIDERS[newProvider]?.defaultModel || ""
- : "";
-
- const newDefaultConfigs = newProvider
- ? getDefaultConfigByProvider(newProvider)
- : {};
-
- updatePrompt(promptId, {
- model: newModel,
- configs: newDefaultConfigs,
- });
-
- updateOutput(promptId, "", { value: "" });
}
}, [
providerKeys,
isPendingProviderKeys,
+ providerResolver,
+ modelResolver,
updateOutput,
updatePrompt,
promptId,
diff --git a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompts.tsx b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompts.tsx
index c14df24854..8d7eae76d2 100644
--- a/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompts.tsx
+++ b/apps/opik-frontend/src/components/pages/PlaygroundPage/PlaygroundPrompts/PlaygroundPrompts.tsx
@@ -11,6 +11,7 @@ import {
useSetPromptMap,
} from "@/store/PlaygroundStore";
import useLastPickedModel from "@/components/pages/PlaygroundPage/PlaygroundPrompts/useLastPickedModel";
+import useLLMProviderModelsData from "@/hooks/useLLMProviderModelsData";
interface PlaygroundPromptsState {
workspaceName: string;
@@ -32,11 +33,15 @@ const PlaygroundPrompts = ({
const promptIds = usePromptIds();
const [lastPickedModel] = useLastPickedModel();
+ const { calculateModelProvider, calculateDefaultModel } =
+ useLLMProviderModelsData();
const handleAddPrompt = () => {
const newPrompt = generateDefaultPrompt({
setupProviders: providerKeys,
lastPickedModel,
+ providerResolver: calculateModelProvider,
+ modelResolver: calculateDefaultModel,
});
addPrompt(newPrompt);
};
@@ -45,10 +50,19 @@ const PlaygroundPrompts = ({
const newPrompt = generateDefaultPrompt({
setupProviders: providerKeys,
lastPickedModel,
+ providerResolver: calculateModelProvider,
+ modelResolver: calculateDefaultModel,
});
setPromptMap([newPrompt.id], { [newPrompt.id]: newPrompt });
onResetHeight();
- }, [setPromptMap, providerKeys, lastPickedModel, onResetHeight]);
+ }, [
+ providerKeys,
+ lastPickedModel,
+ calculateModelProvider,
+ calculateDefaultModel,
+ setPromptMap,
+ onResetHeight,
+ ]);
useEffect(() => {
// hasn't been initialized yet or the last prompt is removed
@@ -84,6 +98,8 @@ const PlaygroundPrompts = ({
key={promptId}
providerKeys={providerKeys}
isPendingProviderKeys={isPendingProviderKeys}
+ providerResolver={calculateModelProvider}
+ modelResolver={calculateDefaultModel}
/>
))}
diff --git a/apps/opik-frontend/src/components/pages/ProjectsPage/ProjectsPage.tsx b/apps/opik-frontend/src/components/pages/ProjectsPage/ProjectsPage.tsx
index 137f698962..80ae01ffe5 100644
--- a/apps/opik-frontend/src/components/pages/ProjectsPage/ProjectsPage.tsx
+++ b/apps/opik-frontend/src/components/pages/ProjectsPage/ProjectsPage.tsx
@@ -1,6 +1,13 @@
import React, { useCallback, useMemo, useRef, useState } from "react";
import { keepPreviousData } from "@tanstack/react-query";
+import {
+ JsonParam,
+ NumberParam,
+ StringParam,
+ useQueryParam,
+} from "use-query-params";
import isNumber from "lodash/isNumber";
+import get from "lodash/get";
import { formatNumericData } from "@/lib/utils";
import DataTable from "@/components/shared/DataTable/DataTable";
@@ -30,18 +37,13 @@ import {
} from "@/types/shared";
import { convertColumnDataToColumn, mapColumnDataFields } from "@/lib/table";
import useLocalStorageState from "use-local-storage-state";
-import {
- ColumnPinningState,
- ColumnSort,
- RowSelectionState,
-} from "@tanstack/react-table";
+import { ColumnPinningState, ColumnSort } from "@tanstack/react-table";
import {
generateActionsColumDef,
generateSelectColumDef,
} from "@/components/shared/DataTable/utils";
import { RESOURCE_TYPE } from "@/components/shared/ResourceLink/ResourceLink";
import FeedbackScoreListCell from "@/components/shared/DataTableCells/FeedbackScoreListCell";
-import { get } from "lodash";
export const getRowId = (p: ProjectWithStatistic) => p.id;
@@ -175,12 +177,22 @@ const ProjectsPage: React.FunctionComponent = () => {
const resetDialogKeyRef = useRef(0);
const [openDialog, setOpenDialog] = useState
(false);
-
- const [search, setSearch] = useState("");
- const [page, setPage] = useState(1);
- const [size, setSize] = useState(10);
-
- const [rowSelection, setRowSelection] = useState({});
+ const [search = "", setSearch] = useQueryParam("search", StringParam, {
+ updateType: "replaceIn",
+ });
+ const [page = 1, setPage] = useQueryParam("page", NumberParam, {
+ updateType: "replaceIn",
+ });
+ const [size = 10, setSize] = useQueryParam("size", NumberParam, {
+ updateType: "replaceIn",
+ });
+ const [rowSelection = {}, setRowSelection] = useQueryParam(
+ "selection",
+ JsonParam,
+ {
+ updateType: "replaceIn",
+ },
+ );
const [sortedColumns, setSortedColumns] = useLocalStorageState(
COLUMNS_SORT_KEY,
@@ -192,7 +204,7 @@ const ProjectsPage: React.FunctionComponent = () => {
const { data, isPending } = useProjectWithStatisticsList(
{
workspaceName,
- search,
+ search: search!,
sorting: sortedColumns.map((column) => {
if (column.id === "last_updated_at") {
return {
@@ -202,8 +214,8 @@ const ProjectsPage: React.FunctionComponent = () => {
}
return column;
}),
- page,
- size,
+ page: page!,
+ size: size!,
},
{
placeholderData: keepPreviousData,
@@ -292,7 +304,7 @@ const ProjectsPage: React.FunctionComponent = () => {