diff --git a/agenta-web/public/assets/fallback.png b/agenta-web/public/assets/fallback.png new file mode 100644 index 0000000000..d3cbad0379 Binary files /dev/null and b/agenta-web/public/assets/fallback.png differ diff --git a/agenta-web/src/components/EvaluationTable/ABTestingEvaluationTable.tsx b/agenta-web/src/components/EvaluationTable/ABTestingEvaluationTable.tsx index 9c05bcca73..873b67e5c3 100644 --- a/agenta-web/src/components/EvaluationTable/ABTestingEvaluationTable.tsx +++ b/agenta-web/src/components/EvaluationTable/ABTestingEvaluationTable.tsx @@ -1,20 +1,6 @@ import {useState, useEffect} from "react" import type {ColumnType} from "antd/es/table" -import {CaretRightOutlined} from "@ant-design/icons" -import { - Button, - Card, - Col, - Input, - Radio, - Row, - Space, - Spin, - Statistic, - Table, - Typography, - message, -} from "antd" +import {Button, Card, Col, Radio, Row, Space, Statistic, Table, Typography, message} from "antd" import { updateEvaluationScenario, callVariant, @@ -34,6 +20,7 @@ import {EvaluationTypeLabels, camelToSnake} from "@/lib/helpers/utils" import {testsetRowToChatMessages} from "@/lib/helpers/testset" import EvaluationVotePanel from "../Evaluations/EvaluationCardView/EvaluationVotePanel" import VariantAlphabet from "../Evaluations/EvaluationCardView/VariantAlphabet" +import {ParamsFormWithRun} from "./SingleModelEvaluationTable" const {Title} = Typography @@ -76,7 +63,7 @@ const useStyles = createUseStyles({ "& button": { marginLeft: 10, }, - marginTop: 10, + marginTop: "0.75rem", }, recordInput: { marginBottom: 10, @@ -334,36 +321,24 @@ const ABTestingEvaluationTable: React.FC = ({ ), dataIndex: "inputs", - render: (text: any, record: ABTestingEvaluationTableRow, rowIndex: number) => ( -
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} - -
- -
-
- ), + render: (_: any, record: ABTestingEvaluationTableRow, rowIndex: number) => { + return ( + runEvaluation(record.id!)} + onParamChange={(name, value) => + handleInputChange( + {target: {value}} as any, + record.id, + record?.inputs.findIndex((ip) => ip.input_name === name), + ) + } + variantData={variantData} + /> + ) + }, }, ...dynamicColumns, { @@ -461,7 +436,6 @@ const ABTestingEvaluationTable: React.FC = ({ dataSource={rows} columns={columns} pagination={false} - rowClassName={() => "editable-row"} rowKey={(record) => record.id!} /> ) : ( @@ -473,6 +447,7 @@ const ABTestingEvaluationTable: React.FC = ({ onInputChange={handleInputChange} updateEvaluationScenarioData={updateEvaluationScenarioData} evaluation={evaluation} + variantData={variantData} /> )} diff --git a/agenta-web/src/components/EvaluationTable/AICritiqueEvaluationTable.tsx b/agenta-web/src/components/EvaluationTable/AICritiqueEvaluationTable.tsx index b6ab986f42..0c46619d43 100644 --- a/agenta-web/src/components/EvaluationTable/AICritiqueEvaluationTable.tsx +++ b/agenta-web/src/components/EvaluationTable/AICritiqueEvaluationTable.tsx @@ -32,6 +32,7 @@ import {exportAICritiqueEvaluationData} from "@/lib/helpers/evaluate" import SecondaryButton from "../SecondaryButton/SecondaryButton" import {useAppTheme} from "../Layout/ThemeContextProvider" import {contentToChatMessageString, testsetRowToChatMessages} from "@/lib/helpers/testset" +import ParamsForm from "../Playground/ParamsForm/ParamsForm" const {Title} = Typography @@ -214,13 +215,10 @@ Answer ONLY with one of the given grading or evaluation options. } }, [evaluationStatus, evaluation.id]) - const handleInputChange = ( - e: React.ChangeEvent, - rowIndex: any, - inputFieldKey: number, - ) => { + const handleInputChange = (value: any, name: string, rowIndex: any) => { const newRows = [...rows] - newRows[rowIndex].inputs[inputFieldKey].input_value = e.target.value + const ip = newRows[rowIndex].inputs.find((ip) => ip.input_name === name) + if (ip) ip.input_value = value setRows(newRows) } @@ -374,22 +372,25 @@ Answer ONLY with one of the given grading or evaluation options. dataIndex: "inputs", render: (text: any, record: AICritiqueEvaluationTableRow, rowIndex: number) => (
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} + {evaluation.testset.testsetChatColumn ? ( + evaluation.testset.csvdata[rowIndex][ + evaluation.testset.testsetChatColumn + ] || " - " + ) : ( + + handleInputChange(value, name, rowIndex) + } + inputParams={ + variantData[0].inputParams?.map((item) => ({ + ...item, + value: record.inputs.find((ip) => ip.input_name === item.name) + ?.input_value, + })) || [] + } + /> + )}
), }, @@ -522,12 +523,7 @@ Answer ONLY with one of the given grading or evaluation options.
- "editable-row"} - /> +
) diff --git a/agenta-web/src/components/EvaluationTable/CustomCodeRunEvaluationTable.tsx b/agenta-web/src/components/EvaluationTable/CustomCodeRunEvaluationTable.tsx index e378bd2f01..eeb8fd2c5e 100644 --- a/agenta-web/src/components/EvaluationTable/CustomCodeRunEvaluationTable.tsx +++ b/agenta-web/src/components/EvaluationTable/CustomCodeRunEvaluationTable.tsx @@ -36,6 +36,7 @@ import SecondaryButton from "../SecondaryButton/SecondaryButton" import {exportCustomCodeEvaluationData} from "@/lib/helpers/evaluate" import CodeBlock from "../DynamicCodeBlock/CodeBlock" import {contentToChatMessageString, testsetRowToChatMessages} from "@/lib/helpers/testset" +import ParamsForm from "../Playground/ParamsForm/ParamsForm" const {Title} = Typography @@ -209,13 +210,10 @@ const CustomCodeRunEvaluationTable: React.FC = ( getTests() }, [evaluation]) - const handleInputChange = ( - e: React.ChangeEvent, - rowIndex: any, - inputFieldKey: number, - ) => { + const handleInputChange = (value: any, name: string, rowIndex: any) => { const newRows = [...rows] - newRows[rowIndex].inputs[inputFieldKey].input_value = e.target.value + const ip = newRows[rowIndex].inputs.find((ip) => ip.input_name === name) + if (ip) ip.input_value = value setRows(newRows) } @@ -412,22 +410,25 @@ const CustomCodeRunEvaluationTable: React.FC = ( dataIndex: "inputs", render: (text: any, record: CustomCodeEvaluationTableRow, rowIndex: number) => (
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} + {evaluation.testset.testsetChatColumn ? ( + evaluation.testset.csvdata[rowIndex][ + evaluation.testset.testsetChatColumn + ] || " - " + ) : ( + + handleInputChange(value, name, rowIndex) + } + inputParams={ + variantData[0].inputParams?.map((item) => ({ + ...item, + value: record.inputs.find((ip) => ip.input_name === item.name) + ?.input_value, + })) || [] + } + /> + )}
), }, @@ -522,12 +523,7 @@ const CustomCodeRunEvaluationTable: React.FC = ( )}
-
"editable-row"} - /> +
= ({ setAccuracy(accuracy) }, [rows]) - const handleInputChange = ( - e: React.ChangeEvent, - rowIndex: any, - inputFieldKey: number, - ) => { + const handleInputChange = (value: any, name: string, rowIndex: any) => { const newRows = [...rows] - newRows[rowIndex].inputs[inputFieldKey].input_value = e.target.value + const ip = newRows[rowIndex].inputs.find((ip) => ip.input_name === name) + if (ip) ip.input_value = value setRows(newRows) } @@ -314,22 +312,25 @@ const ExactMatchEvaluationTable: React.FC = ({ dataIndex: "inputs", render: (text: any, record: ExactMatchEvaluationTableRow, rowIndex: number) => (
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} + {evaluation.testset.testsetChatColumn ? ( + evaluation.testset.csvdata[rowIndex][ + evaluation.testset.testsetChatColumn + ] || " - " + ) : ( + + handleInputChange(value, name, rowIndex) + } + inputParams={ + variantData[0].inputParams?.map((item) => ({ + ...item, + value: record.inputs.find((ip) => ip.input_name === item.name) + ?.input_value, + })) || [] + } + /> + )}
), }, @@ -432,13 +433,7 @@ const ExactMatchEvaluationTable: React.FC = ({
-
"editable-row"} - rowKey="id" - /> +
) diff --git a/agenta-web/src/components/EvaluationTable/RegexEvaluationTable.tsx b/agenta-web/src/components/EvaluationTable/RegexEvaluationTable.tsx index 348acba9c0..996e4b68fa 100644 --- a/agenta-web/src/components/EvaluationTable/RegexEvaluationTable.tsx +++ b/agenta-web/src/components/EvaluationTable/RegexEvaluationTable.tsx @@ -30,6 +30,7 @@ import SecondaryButton from "../SecondaryButton/SecondaryButton" import {exportRegexEvaluationData} from "@/lib/helpers/evaluate" import {isValidRegex} from "@/lib/helpers/validators" import {contentToChatMessageString, testsetRowToChatMessages} from "@/lib/helpers/testset" +import ParamsForm from "../Playground/ParamsForm/ParamsForm" const {Title} = Typography @@ -164,13 +165,10 @@ const RegexEvaluationTable: React.FC = ({ setAccuracy(accuracy) }, [rows]) - const handleInputChange = ( - e: React.ChangeEvent, - rowIndex: any, - inputFieldKey: number, - ) => { + const handleInputChange = (value: any, name: string, rowIndex: any) => { const newRows = [...rows] - newRows[rowIndex].inputs[inputFieldKey].input_value = e.target.value + const ip = newRows[rowIndex].inputs.find((ip) => ip.input_name === name) + if (ip) ip.input_value = value setRows(newRows) } @@ -330,22 +328,25 @@ const RegexEvaluationTable: React.FC = ({ dataIndex: "inputs", render: (_: any, record: RegexEvaluationTableRow, rowIndex: number) => (
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} + {evaluation.testset.testsetChatColumn ? ( + evaluation.testset.csvdata[rowIndex][ + evaluation.testset.testsetChatColumn + ] || " - " + ) : ( + + handleInputChange(value, name, rowIndex) + } + inputParams={ + variantData[0].inputParams?.map((item) => ({ + ...item, + value: record.inputs.find((ip) => ip.input_name === item.name) + ?.input_value, + })) || [] + } + /> + )}
), }, @@ -500,12 +501,7 @@ const RegexEvaluationTable: React.FC = ({ )}
-
"editable-row"} - /> +
) diff --git a/agenta-web/src/components/EvaluationTable/SimilarityMatchEvaluationTable.tsx b/agenta-web/src/components/EvaluationTable/SimilarityMatchEvaluationTable.tsx index 70d138f4a6..c1cce3b59f 100644 --- a/agenta-web/src/components/EvaluationTable/SimilarityMatchEvaluationTable.tsx +++ b/agenta-web/src/components/EvaluationTable/SimilarityMatchEvaluationTable.tsx @@ -6,7 +6,6 @@ import { Card, Col, Form, - Input, Row, Slider, Space, @@ -26,6 +25,7 @@ import {createUseStyles} from "react-jss" import {exportSimilarityEvaluationData} from "@/lib/helpers/evaluate" import SecondaryButton from "../SecondaryButton/SecondaryButton" import {contentToChatMessageString, testsetRowToChatMessages} from "@/lib/helpers/testset" +import ParamsForm from "../Playground/ParamsForm/ParamsForm" const {Title} = Typography @@ -166,13 +166,10 @@ const SimilarityMatchEvaluationTable: React.FC, - rowIndex: any, - inputFieldKey: number, - ) => { + const handleInputChange = (value: any, name: string, rowIndex: any) => { const newRows = [...rows] - newRows[rowIndex].inputs[inputFieldKey].input_value = e.target.value + const ip = newRows[rowIndex].inputs.find((ip) => ip.input_name === name) + if (ip) ip.input_value = value setRows(newRows) } @@ -316,22 +313,25 @@ const SimilarityMatchEvaluationTable: React.FC (
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} + {evaluation.testset.testsetChatColumn ? ( + evaluation.testset.csvdata[rowIndex][ + evaluation.testset.testsetChatColumn + ] || " - " + ) : ( + + handleInputChange(value, name, rowIndex) + } + inputParams={ + variantData[0].inputParams?.map((item) => ({ + ...item, + value: record.inputs.find((ip) => ip.input_name === item.name) + ?.input_value, + })) || [] + } + /> + )}
), }, @@ -467,12 +467,7 @@ const SimilarityMatchEvaluationTable: React.FC -
"editable-row"} - /> +
) diff --git a/agenta-web/src/components/EvaluationTable/SingleModelEvaluationTable.tsx b/agenta-web/src/components/EvaluationTable/SingleModelEvaluationTable.tsx index a07a948022..549a4ba381 100644 --- a/agenta-web/src/components/EvaluationTable/SingleModelEvaluationTable.tsx +++ b/agenta-web/src/components/EvaluationTable/SingleModelEvaluationTable.tsx @@ -5,23 +5,16 @@ import { Button, Card, Col, - Input, - InputNumber, + Form, Radio, Row, Space, - Spin, Statistic, Table, Typography, message, } from "antd" -import { - updateEvaluationScenario, - callVariant, - fetchEvaluationResults, - updateEvaluation, -} from "@/lib/services/api" +import {updateEvaluationScenario, callVariant, updateEvaluation} from "@/lib/services/api" import {useVariants} from "@/lib/hooks/useVariant" import {useRouter} from "next/router" import {EvaluationFlow} from "@/lib/enums" @@ -35,6 +28,7 @@ import {EvaluationTypeLabels, camelToSnake} from "@/lib/helpers/utils" import {testsetRowToChatMessages} from "@/lib/helpers/testset" import {debounce} from "lodash" import EvaluationVotePanel from "../Evaluations/EvaluationCardView/EvaluationVotePanel" +import ParamsForm from "../Playground/ParamsForm/ParamsForm" const {Title} = Typography @@ -78,6 +72,7 @@ const useStyles = createUseStyles({ "& button": { marginLeft: 10, }, + marginTop: "0.75rem", }, recordInput: { marginBottom: 10, @@ -105,6 +100,56 @@ const useStyles = createUseStyles({ }, }) +export const ParamsFormWithRun = ({ + evaluation, + record, + rowIndex, + onRun, + onParamChange, + variantData, +}: { + record: SingleModelEvaluationRow + rowIndex: number + evaluation: Evaluation + onRun: () => void + onParamChange: (name: string, value: any) => void + variantData: ReturnType +}) => { + const classes = useStyles() + const [form] = Form.useForm() + + return ( +
+ {evaluation.testset.testsetChatColumn ? ( + evaluation.testset.csvdata[rowIndex][evaluation.testset.testsetChatColumn] || " - " + ) : ( + ({ + ...item, + value: record.inputs.find((ip) => ip.input_name === item.name) + ?.input_value, + })) || [] + } + onFinish={onRun} + form={form} + /> + )} + +
+ +
+
+ ) +} + const SingleModelEvaluationTable: React.FC = ({ evaluation, evaluationScenarios, @@ -335,36 +380,24 @@ const SingleModelEvaluationTable: React.FC = ({ ), dataIndex: "inputs", - render: (text: any, record: SingleModelEvaluationRow, rowIndex: number) => ( -
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} - -
- -
-
- ), + render: (_: any, record: SingleModelEvaluationRow, rowIndex: number) => { + return ( + runEvaluation(record.id!)} + onParamChange={(name, value) => + handleInputChange( + {target: {value}} as any, + record.id, + record?.inputs.findIndex((ip) => ip.input_name === name), + ) + } + variantData={variantData} + /> + ) + }, }, ...dynamicColumns, { @@ -452,7 +485,6 @@ const SingleModelEvaluationTable: React.FC = ({ dataSource={rows} columns={columns} pagination={false} - rowClassName={() => "editable-row"} rowKey={(record) => record.id!} /> ) : ( @@ -464,6 +496,7 @@ const SingleModelEvaluationTable: React.FC = ({ onInputChange={handleInputChange} updateEvaluationScenarioData={updateEvaluationScenarioData} evaluation={evaluation} + variantData={variantData} /> )} diff --git a/agenta-web/src/components/EvaluationTable/WebhookEvaluationTable.tsx b/agenta-web/src/components/EvaluationTable/WebhookEvaluationTable.tsx index 9f8001f65a..cf7776838f 100644 --- a/agenta-web/src/components/EvaluationTable/WebhookEvaluationTable.tsx +++ b/agenta-web/src/components/EvaluationTable/WebhookEvaluationTable.tsx @@ -25,10 +25,11 @@ import {EvaluationFlow} from "@/lib/enums" import {evaluateWithWebhook} from "@/lib/services/evaluations" import {createUseStyles} from "react-jss" import {globalErrorHandler} from "@/lib/helpers/errorHandler" -import {isValidUrl} from "@/lib/helpers/validators" +import {isValidHttpUrl} from "@/lib/helpers/validators" import SecondaryButton from "../SecondaryButton/SecondaryButton" import {exportWebhookEvaluationData} from "@/lib/helpers/evaluate" import {contentToChatMessageString, testsetRowToChatMessages} from "@/lib/helpers/testset" +import ParamsForm from "../Playground/ParamsForm/ParamsForm" const {Title} = Typography @@ -144,13 +145,10 @@ const WebhookEvaluationTable: React.FC = ({ setAccuracy(avg * 100) }, [rows]) - const handleInputChange = ( - e: React.ChangeEvent, - rowIndex: any, - inputFieldKey: number, - ) => { + const handleInputChange = (value: any, name: string, rowIndex: any) => { const newRows = [...rows] - newRows[rowIndex].inputs[inputFieldKey].input_value = e.target.value + const ip = newRows[rowIndex].inputs.find((ip) => ip.input_name === name) + if (ip) ip.input_value = value setRows(newRows) } @@ -302,22 +300,25 @@ const WebhookEvaluationTable: React.FC = ({ dataIndex: "inputs", render: (_: any, record: WebhookEvaluationTableRow, rowIndex: number) => (
- {evaluation.testset.testsetChatColumn - ? evaluation.testset.csvdata[rowIndex][ - evaluation.testset.testsetChatColumn - ] || " - " - : record && - record.inputs && - record.inputs.length && // initial value of inputs is array with 1 element and variantInputs could contain more than 1 element - record.inputs.map((input: any, index: number) => ( -
- handleInputChange(e, record.id, index)} - /> -
- ))} + {evaluation.testset.testsetChatColumn ? ( + evaluation.testset.csvdata[rowIndex][ + evaluation.testset.testsetChatColumn + ] || " - " + ) : ( + + handleInputChange(value, name, rowIndex) + } + inputParams={ + variantData[0].inputParams?.map((item) => ({ + ...item, + value: record.inputs.find((ip) => ip.input_name === item.name) + ?.input_value, + })) || [] + } + /> + )}
), }, @@ -442,7 +443,7 @@ const WebhookEvaluationTable: React.FC = ({ { validator: (_, value) => new Promise((res, rej) => - isValidUrl(value) + isValidHttpUrl(value) ? res("") : rej("Please enter a valid url"), ), @@ -455,12 +456,7 @@ const WebhookEvaluationTable: React.FC = ({ )}
-
"editable-row"} - /> +
) diff --git a/agenta-web/src/components/Evaluations/EvaluationCardView/index.tsx b/agenta-web/src/components/Evaluations/EvaluationCardView/index.tsx index ed1e9476a1..acbb06228a 100644 --- a/agenta-web/src/components/Evaluations/EvaluationCardView/index.tsx +++ b/agenta-web/src/components/Evaluations/EvaluationCardView/index.tsx @@ -8,20 +8,20 @@ import { QuestionCircleOutlined, RightOutlined, } from "@ant-design/icons" -import {Button, Empty, Input, Space, Tooltip, Typography, theme} from "antd" +import {Button, Empty, Form, Input, Space, Tooltip, Typography, theme} from "antd" import React, {useCallback, useEffect, useMemo, useRef} from "react" import {createUseStyles} from "react-jss" import EvaluationVotePanel from "./EvaluationVotePanel" import EvaluationCard from "./EvaluationCard" -import EvaluationInputs from "./EvaluationInputs" import {ABTestingEvaluationTableRow} from "@/components/EvaluationTable/ABTestingEvaluationTable" import AlertPopup from "@/components/AlertPopup/AlertPopup" import {useLocalStorage} from "usehooks-ts" -import ChatInputs from "@/components/ChatInputs/ChatInputs" import {testsetRowToChatMessages} from "@/lib/helpers/testset" import {safeParse} from "@/lib/helpers/utils" import {debounce} from "lodash" import {EvaluationType} from "@/lib/enums" +import ParamsForm from "@/components/Playground/ParamsForm/ParamsForm" +import {useVariants} from "@/lib/hooks/useVariant" export const VARIANT_COLORS = [ "#297F87", // "#722ed1", @@ -132,6 +132,7 @@ interface Props { onInputChange: Function updateEvaluationScenarioData: (id: string, data: Partial) => void evaluation: Evaluation + variantData: ReturnType } const EvaluationCardView: React.FC = ({ @@ -142,6 +143,7 @@ const EvaluationCardView: React.FC = ({ onInputChange, updateEvaluationScenarioData, evaluation, + variantData, }) => { const classes = useStyles() const {token} = theme.useToken() @@ -170,6 +172,7 @@ const EvaluationCardView: React.FC = ({ const isChat = !!evaluation.testset.testsetChatColumn const testsetRow = evaluation.testset.csvdata[scenarioIndex] const isAbTesting = evaluation.evaluationType === EvaluationType.human_a_b_testing + const [form] = Form.useForm() const loadPrevious = () => { if (scenarioIndex === 0) return @@ -338,20 +341,33 @@ const EvaluationCardView: React.FC = ({ - {isChat ? ( -
- -
- ) : ( - - )} + + isChat + ? onChatChange(value) + : onInputChange( + {target: {value}} as any, + scenarioId, + scenario.inputs.findIndex((ip) => ip.input_name === name), + ) + } + inputParams={ + isChat + ? [{name: "chat", value: chat} as any] + : variantData[0].inputParams?.map((item) => ({ + ...item, + value: scenario.inputs.find( + (ip) => ip.input_name === item.name, + )?.input_value, + })) || [] + } + key={scenarioId} + useChatDefaultValue + form={form} + onFinish={() => onRun(scenarioId)} + imageSize="large" + />
@@ -386,7 +402,7 @@ const EvaluationCardView: React.FC = ({ onRun(scenarioId)} + onClick={form.submit} />
diff --git a/agenta-web/src/components/Playground/ParamsForm/ParamsForm.tsx b/agenta-web/src/components/Playground/ParamsForm/ParamsForm.tsx new file mode 100644 index 0000000000..8068f9d3a2 --- /dev/null +++ b/agenta-web/src/components/Playground/ParamsForm/ParamsForm.tsx @@ -0,0 +1,114 @@ +import React from "react" +import ChatInputs from "@/components/ChatInputs/ChatInputs" +import {GenericObject, Parameter} from "@/lib/Types" +import {renameVariables} from "@/lib/helpers/utils" +import {Form, FormInstance, Image, Input} from "antd" +import {createUseStyles} from "react-jss" + +const useStyles = createUseStyles({ + form: { + width: "100%", + "& .ant-form-item": { + marginBottom: "0px", + }, + }, + formItemRow: { + display: "flex", + gap: "0.5rem", + alignItems: "flex-start", + marginTop: "1rem", + + "& .ant-input": { + marginTop: 1, + }, + }, + cover: { + objectFit: "cover", + borderRadius: 6, + }, +}) + +const ASPECT_RATIO = 1.55 + +interface Props { + inputParams: (Parameter & {value: any})[] + onFinish?: (values: GenericObject) => void + onParamChange?: (name: string, value: any) => void + isChatVariant?: boolean + useChatDefaultValue?: boolean + form?: FormInstance + imageSize?: "small" | "large" +} + +const ParamsForm: React.FC = ({ + inputParams, + onFinish, + onParamChange, + isChatVariant, + useChatDefaultValue, + form, + imageSize = "small", +}) => { + const classes = useStyles() + const imgHeight = imageSize === "small" ? 90 : 120 + + const chat = inputParams.find((param) => param.name === "chat")?.value + + return isChatVariant ? ( + onParamChange?.("chat", val)} + /> + ) : ( +
+ {/*@ts-ignore*/} + {(_, formInstance) => { + return inputParams.map((param, index) => { + const type = param.type === "file_url" ? "url" : param.type + return ( + +
+ {type === "url" && + param.value && + formInstance.getFieldError(param.name).length === 0 && ( + + )} + onParamChange?.(param.name, e.target.value)} + autoSize={{minRows: 2, maxRows: 8}} + /> +
+
+ ) + }) + }} + + ) +} + +export default ParamsForm diff --git a/agenta-web/src/components/Playground/Views/TestView.tsx b/agenta-web/src/components/Playground/Views/TestView.tsx index 3244a70240..b6d9bb5dfd 100644 --- a/agenta-web/src/components/Playground/Views/TestView.tsx +++ b/agenta-web/src/components/Playground/Views/TestView.tsx @@ -1,9 +1,9 @@ import React, {useEffect, useState} from "react" -import {Button, Input, Card, Row, Col, Space} from "antd" +import {Button, Input, Card, Row, Col, Space, Form} from "antd" import {CaretRightOutlined, PlusOutlined} from "@ant-design/icons" import {callVariant} from "@/lib/services/api" import {ChatMessage, ChatRole, GenericObject, Parameter, Variant} from "@/lib/Types" -import {randString, removeKeys, renameVariables} from "@/lib/helpers/utils" +import {randString, removeKeys} from "@/lib/helpers/utils" import LoadTestsModal from "../LoadTestsModal" import AddToTestSetDrawer from "../AddToTestSetDrawer/AddToTestSetDrawer" import {DeleteOutlined} from "@ant-design/icons" @@ -11,10 +11,12 @@ import {getErrorMessage} from "@/lib/helpers/errorHandler" import {createUseStyles} from "react-jss" import CopyButton from "@/components/CopyButton/CopyButton" import {useRouter} from "next/router" -import ChatInputs, {getDefaultNewMessage} from "@/components/ChatInputs/ChatInputs" +import {getDefaultNewMessage} from "@/components/ChatInputs/ChatInputs" import {v4 as uuidv4} from "uuid" import {testsetRowToChatMessages} from "@/lib/helpers/testset" +import ParamsForm from "../ParamsForm/ParamsForm" +const {TextArea} = Input const LOADING_TEXT = "Loading..." const useStylesBox = createUseStyles({ @@ -110,18 +112,16 @@ const BoxComponent: React.FC = ({ isChatVariant = false, }) => { const classes = useStylesBox() - const {TextArea} = Input const loading = result === LOADING_TEXT + const [form] = Form.useForm() if (!inputParams) { return
Loading...
} - const inputParamsNames = inputParams.map((param) => param.name) - const handleAddToTestset = () => { const params: Record = {} - inputParamsNames.forEach((name) => { + inputParams.forEach(({name}) => { params[name] = testData[name] || "" }) params.correct_answer = result @@ -142,22 +142,18 @@ const BoxComponent: React.FC = ({ - {isChatVariant ? ( - onInputParamChange("chat", val)} - /> - ) : ( - inputParamsNames.map((key, index) => ( -