From f6abb8a3eb30236ed2d04891251d683e5ff6e202 Mon Sep 17 00:00:00 2001 From: Justin Date: Wed, 22 Jan 2025 14:16:00 -0800 Subject: [PATCH] added input from prod in prompts --- .../controllers/public/promptController.ts | 2 +- .../shared/prompts/VariablesPanel.tsx | 94 +++++++++++++ web/components/shared/prompts/helpers.ts | 22 ++++ web/components/shared/prompts/hooks.ts | 55 ++++++++ .../experiments/experimentInputSelector.tsx | 123 +++++++++++------- .../templates/prompts/id/promptIdPage.tsx | 1 + web/components/ui/button.tsx | 21 ++- 7 files changed, 269 insertions(+), 49 deletions(-) create mode 100644 web/components/shared/prompts/helpers.ts create mode 100644 web/components/shared/prompts/hooks.ts diff --git a/valhalla/jawn/src/controllers/public/promptController.ts b/valhalla/jawn/src/controllers/public/promptController.ts index 048eba23e..57fb22b95 100644 --- a/valhalla/jawn/src/controllers/public/promptController.ts +++ b/valhalla/jawn/src/controllers/public/promptController.ts @@ -453,7 +453,7 @@ export class PromptController extends Controller { } else { this.setStatus(200); // set return status 201 } - return resultMap(result, data => data?.[0]); + return resultMap(result, (data) => data?.[0]); } @Delete("version/{promptVersionId}") diff --git a/web/components/shared/prompts/VariablesPanel.tsx b/web/components/shared/prompts/VariablesPanel.tsx index 6d89fc173..52b114974 100644 --- a/web/components/shared/prompts/VariablesPanel.tsx +++ b/web/components/shared/prompts/VariablesPanel.tsx @@ -1,24 +1,102 @@ +import { Row } from "@/components/layout/common"; +import { Button } from "@/components/ui/button"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { Variable } from "@/types/prompt-state"; import { isValidVariableName } from "@/utils/variables"; +import { ImportIcon, ShuffleIcon } from "lucide-react"; +import { populateVariables } from "./helpers"; +import { usePromptInputs } from "./hooks"; +import ExperimentInputSelector from "@/components/templates/prompts/experiments/experimentInputSelector"; +import { useState } from "react"; interface VariablesPanelProps { variables: Variable[]; onVariableChange: (index: number, value: string) => void; + promptVersionId: string; } export default function VariablesPanel({ variables, onVariableChange, + promptVersionId, }: VariablesPanelProps) { // - Filter Valid Variables const validVariablesWithIndices = variables .map((v, i) => ({ variable: v, originalIndex: i })) .filter(({ variable }) => isValidVariableName(variable.name)); + const { getRandomInput, hasInputs } = usePromptInputs(promptVersionId); + + const importRandom = async () => { + const res = await getRandomInput.mutateAsync(); + populateVariables({ + inputsFromBackend: res.data?.data?.[0]?.inputs ?? {}, + validVariablesWithIndices, + onVariableChange, + }); + }; + + const [openInputSelector, setOpenInputSelector] = useState(false); return (

Variables

+ + + + + +
+ +
+
+ +

+ {hasInputs + ? "Import from Production" + : "No production data available"} +

+
+
+
+ + + +
+ +
+
+ +

+ {hasInputs + ? "Randomized from production data" + : "No production data available"} +

+
+
+
+
{/* No Variables */} @@ -59,6 +137,22 @@ export default function VariablesPanel({ ))}
)} + {}} + handleAddRows={(rows) => { + const row = rows[0]; + + populateVariables({ + inputsFromBackend: row.inputs, + validVariablesWithIndices, + onVariableChange, + }); + }} + selectJustOne + /> ); } diff --git a/web/components/shared/prompts/helpers.ts b/web/components/shared/prompts/helpers.ts new file mode 100644 index 000000000..0533c0f94 --- /dev/null +++ b/web/components/shared/prompts/helpers.ts @@ -0,0 +1,22 @@ +import { Variable } from "@/types/prompt-state"; + +export const populateVariables = ({ + inputsFromBackend, + validVariablesWithIndices, + onVariableChange, +}: { + inputsFromBackend: Record; + validVariablesWithIndices: { variable: Variable; originalIndex: number }[]; + onVariableChange: (index: number, value: string) => void; +}) => { + for (const [key, value] of Object.entries(inputsFromBackend ?? {})) { + const originalIndex = validVariablesWithIndices.find( + ({ variable }) => variable.name === key + )?.originalIndex; + + console.log(originalIndex, " ORIGINAL INDEX"); + if (originalIndex !== undefined && originalIndex !== -1) { + onVariableChange(originalIndex, value); + } + } +}; diff --git a/web/components/shared/prompts/hooks.ts b/web/components/shared/prompts/hooks.ts new file mode 100644 index 000000000..ddae84243 --- /dev/null +++ b/web/components/shared/prompts/hooks.ts @@ -0,0 +1,55 @@ +import { useJawnClient } from "@/lib/clients/jawnHook"; +import { useMutation, useQuery } from "@tanstack/react-query"; +import { useMemo } from "react"; + +export const usePromptInputs = (promptVersionId: string) => { + const jawn = useJawnClient(); + + const inputs = useQuery({ + queryKey: ["promptInputs", promptVersionId], + queryFn: async () => { + return await jawn.POST( + "/v1/prompt/version/{promptVersionId}/inputs/query", + { + params: { + path: { + promptVersionId: promptVersionId ?? "unknown", + }, + }, + body: { + limit: 1, + }, + } + ); + }, + }); + + const getRandomInput = useMutation({ + mutationFn: async () => { + return await jawn.POST( + "/v1/prompt/version/{promptVersionId}/inputs/query", + { + params: { + path: { + promptVersionId: promptVersionId ?? "unknown", + }, + }, + body: { + limit: 1, + random: true, + }, + } + ); + }, + }); + + const hasInputs = useMemo(() => { + return (inputs.data?.data?.data?.length ?? 0) > 0; + }, [inputs.data]); + + return { + inputs, + getRandomInput, + hasInputs, + }; +}; diff --git a/web/components/templates/prompts/experiments/experimentInputSelector.tsx b/web/components/templates/prompts/experiments/experimentInputSelector.tsx index ee52d4591..7fbec2907 100644 --- a/web/components/templates/prompts/experiments/experimentInputSelector.tsx +++ b/web/components/templates/prompts/experiments/experimentInputSelector.tsx @@ -5,6 +5,7 @@ import useNotification from "../../../shared/notification/useNotification"; import PromptPropertyCard from "../id/promptPropertyCard"; import { Button } from "@/components/ui/button"; import { useQuery } from "@tanstack/react-query"; +import clsx from "clsx"; interface ExperimentInputSelectorProps { open: boolean; @@ -18,10 +19,18 @@ interface ExperimentInputSelectorProps { autoInputs: any[]; }[] ) => void; + selectJustOne?: boolean; } const ExperimentInputSelector = (props: ExperimentInputSelectorProps) => { - const { open, setOpen, promptVersionId, onSuccess, handleAddRows } = props; + const { + open, + setOpen, + promptVersionId, + onSuccess, + handleAddRows, + selectJustOne, + } = props; const jawn = useJawnClient(); const { setNotification } = useNotification(); @@ -130,14 +139,16 @@ const ExperimentInputSelector = (props: ExperimentInputSelectorProps) => {

Select Inputs ({inputRecords.length})

- + {!selectJustOne && ( + + )}

Select the inputs you want to include in the dataset. @@ -149,7 +160,25 @@ const ExperimentInputSelector = (props: ExperimentInputSelectorProps) => { {!isLoading && !isError && inputRecords.map((request) => ( -

  • +
  • { + if (selectJustOne) { + handleAddRows([ + { + autoInputs: request.autoInputs, + inputs: request.inputs, + inputRecordId: request.id, + }, + ]); + setOpen(false); + } + }} + > { -
    - - - -
    + {!selectJustOne && ( +
    + + + +
    + )} ); diff --git a/web/components/templates/prompts/id/promptIdPage.tsx b/web/components/templates/prompts/id/promptIdPage.tsx index 5ace7b4cc..04589cfe8 100644 --- a/web/components/templates/prompts/id/promptIdPage.tsx +++ b/web/components/templates/prompts/id/promptIdPage.tsx @@ -671,6 +671,7 @@ export default function PromptIdPage(props: PromptIdPageProps) { , VariantProps { asChild?: boolean; + asPill?: boolean; } const Button = React.forwardRef( - ({ className, variant, size, asChild = false, children, ...props }, ref) => { + ( + { + className, + variant, + size, + asChild = false, + children, + asPill = false, + ...props + }, + ref + ) => { const Comp = asChild ? Slot : "button"; return (