Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

experiment new small fixes #3122

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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 @@ -63,7 +63,7 @@ const AddColumnHeader: React.FC<AddColumnHeaderProps> = ({
>
<PlusIcon className="w-5 h-5 text-slate-700 dark:text-slate-100" />
<span className="text-sm font-medium text-slate-700 dark:text-slate-100">
Add Column
Add Prompt
</span>
</Button>
</DropdownMenuTrigger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ import useOnboardingContext, {
ONBOARDING_STEPS,
} from "@/components/layout/onboardingContext";
import { generateOpenAITemplate } from "@/components/shared/CreateNewEvaluator/evaluatorHelpers";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

type TableDataType = {
index: number;
Expand Down Expand Up @@ -118,27 +124,58 @@ export function ExperimentTable({
<span className="group-hover:invisible transition-opacity duration-200">
<ListIcon className="w-4 h-4" />
</span>
<Button
variant="ghost"
className="ml-2 p-0 border rounded-md h-[22px] w-[24px] items-center justify-center absolute invisible group-hover:visible opacity-0 group-hover:opacity-100 transition-opacity duration-200"
onClick={async () => {
await Promise.all(
(promptVersionsData ?? []).map(async (pv) => {
const rows = table.getRowModel().rows;
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
className="ml-2 p-0 border rounded-md h-[22px] w-[24px] items-center justify-center absolute invisible group-hover:visible opacity-0 group-hover:opacity-100 transition-opacity duration-200"
>
<PlayIcon className="w-4 h-4 text-gray-600 dark:text-gray-300" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem
onSelect={async () => {
await Promise.all(
rows.map(async (row) => {
const cellRef = cellRefs.current[`${row.id}-${pv.id}`];
if (cellRef) {
await cellRef.runHypothesis();
}
(promptVersionsData ?? []).map(async (pv) => {
const rows = table.getRowModel().rows;
await Promise.all(
rows.map(async (row) => {
const cellRef =
cellRefs.current[`${row.id}-${pv.id}`];
if (cellRef) {
await cellRef.runHypothesis();
}
})
);
})
);
})
);
}}
>
<PlayIcon className="w-4 h-4 text-gray-600 dark:text-gray-300" />
</Button>
}}
>
Run all cells
</DropdownMenuItem>
<DropdownMenuItem
onSelect={async () => {
await Promise.all(
(promptVersionsData ?? []).map(async (pv) => {
const rows = table.getRowModel().rows;
await Promise.all(
rows.map(async (row) => {
const cellRef =
cellRefs.current[`${row.id}-${pv.id}`];
if (cellRef) {
await cellRef.runHypothesisIfRequired();
}
})
);
})
);
}}
>
Run unexecuted cells
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
),
columns: [
Expand Down Expand Up @@ -601,7 +638,7 @@ export function ExperimentTable({
className="bg-white dark:bg-black rounded-sm inline-block min-w-0 w-max h-auto"
// style={{ width: "fit-content" }}
>
<Table className="border-collapse border-t border-slate-200 dark:border-slate-800 h-[1px]">
<Table className="border-collapse border-t border-r border-b border-slate-200 dark:border-slate-800 h-[1px]">
<TableHeader>
{table.getHeaderGroups().map((headerGroup, i) => (
<TableRow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,16 @@ export const HypothesisCellRenderer = forwardRef<
setRunning(false);
};

const handleRunHypothesisIfRequired = async (e?: React.MouseEvent) => {
e?.stopPropagation();
if (!content) {
await handleRunHypothesis(e);
}
};

useImperativeHandle(ref, () => ({
runHypothesis: () => handleRunHypothesis(),
runHypothesisIfRequired: () => handleRunHypothesisIfRequired(),
}));

if (running) {
Expand Down
189 changes: 53 additions & 136 deletions web/components/templates/prompts/experiments/table/experimentsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ import AuthHeader from "../../../../shared/authHeader";
import { useExperimentTables } from "../../../../../services/hooks/prompts/experiments";
import ThemedTable from "../../../../shared/themed/table/themedTable";
import { useRouter } from "next/router";
import { PlusIcon, DocumentPlusIcon } from "@heroicons/react/24/outline";
import { PlusIcon } from "@heroicons/react/24/outline";
import useNotification from "../../../../shared/notification/useNotification";
import { usePrompts } from "../../../../../services/hooks/prompts/prompts";
import { StartFromPromptDialog } from "./components/startFromPromptDialog";
import { Dialog, DialogTrigger } from "../../../../ui/dialog";
import { Dialog } from "../../../../ui/dialog";
import { useState } from "react";
import { useJawnClient } from "../../../../../lib/clients/jawnHook";
import { getExampleExperimentPrompt } from "./helpers/basePrompt";
import { useOrg } from "@/components/layout/org/organizationContext";
import { FeatureUpgradeCard } from "@/components/shared/helicone/FeatureUpgradeCard";
import {
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { DropdownMenu } from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { ChevronDownIcon } from "lucide-react";

const ExperimentsPage = () => {
const jawn = useJawnClient();
Expand All @@ -21,80 +28,53 @@ const ExperimentsPage = () => {
const router = useRouter();
const { experiments, isLoading } = useExperimentTables();

const templateOptions = [
{ id: "text-classification", name: "Text classification" },
{ id: "knowledge-retrieval", name: "Knowledge retrieval" },
{ id: "step-by-step", name: "Step-by-step instructions" },
];

const handleStartFromScratch = async () => {
const exampleExperimentPrompt = getExampleExperimentPrompt();
const res = await jawn.POST("/v1/prompt/create", {
body: {
userDefinedId: exampleExperimentPrompt.promptName,
prompt: exampleExperimentPrompt.basePrompt,
metadata: {
createdFromUi: true,
},
},
});
if (res.error || !res.data) {
notification.setNotification("Failed to create prompt", "error");
return;
}

if (!res.data?.data?.id || !res.data?.data?.prompt_version_id) {
notification.setNotification("Failed to create prompt", "error");
return;
}

const dataset = await jawn.POST("/v1/helicone-dataset", {
body: {
datasetName: "Dataset for Experiment",
requestIds: [],
},
});
if (!dataset.data?.data?.datasetId) {
notification.setNotification("Failed to create dataset", "error");
return;
}
const experimentTableResult = await jawn.POST("/v1/experiment/table/new", {
body: {
datasetId: dataset.data?.data?.datasetId!,
promptVersionId: res.data?.data?.prompt_version_id!,
newHeliconeTemplate: JSON.stringify(exampleExperimentPrompt.basePrompt),
isMajorVersion: false,
promptSubversionMetadata: {
experimentAssigned: true,
},
experimentMetadata: {
prompt_id: res.data?.data?.id!,
prompt_version: res.data?.data?.prompt_version_id!,
experiment_name: `${exampleExperimentPrompt.promptName}_V1.0` || "",
},
experimentTableMetadata: {
datasetId: dataset.data?.data?.datasetId!,
model: exampleExperimentPrompt.basePrompt.model,
prompt_id: res.data?.data?.id!,
prompt_version: res.data?.data?.prompt_version_id!,
},
},
});
if (!experimentTableResult.data?.data?.experimentId) {
notification.setNotification("Failed to create experiment", "error");
return;
}

await router.push(
`/experiments/${experimentTableResult.data?.data?.tableId}`
);
};

const org = useOrg();

const { setNotification } = useNotification();

return (
<>
<AuthHeader title={"Experiments"} />
<AuthHeader
title={"Experiments"}
actions={
<DropdownMenu modal={false}>
<DropdownMenuTrigger asChild>
<Button variant="outline">
Start new experiment
<ChevronDownIcon className="w-4 h-4 ml-2" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="center" className="w-[200px]">
<DropdownMenuItem
onSelect={async () => {
setNotification("Creating experiment...", "info");
const res = await jawn.POST("/v2/experiment/create/empty");
if (res.error) {
notification.setNotification(
"Failed to create experiment",
"error"
);
} else {
router.push(`/experiments/${res.data?.data?.experimentId}`);
}
}}
>
Start from scratch
</DropdownMenuItem>
<DropdownMenuItem onSelect={() => setDialogOpen(true)}>
Start from prompt
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
}
/>

<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<StartFromPromptDialog
prompts={prompts as any}
onDialogClose={() => setDialogOpen(false)}
/>
</Dialog>

{org?.currentOrg?.tier === "free" ? (
<div className="flex justify-center items-center min-h-[calc(100vh-200px)]">
Expand All @@ -108,69 +88,6 @@ const ExperimentsPage = () => {
</div>
) : (
<>
<div className="mb-6 overflow-x-auto px-4">
<h3 className="text-md font-normal px-4 py-2 text-[#6B7280]">
Create a new experiment
</h3>
<div className="flex space-x-4 p-4">
<div>
<button
className="flex flex-col items-center justify-center w-40 h-32 bg-white dark:bg-slate-800 rounded-lg hover:bg-transparent transition-colors border-2 border-slate-100 dark:border-slate-700"
onClick={async () => {
const res = await jawn.POST("/v2/experiment/create/empty");
if (res.error) {
notification.setNotification(
"Failed to create experiment",
"error"
);
} else {
router.push(
`/experiments/${res.data?.data?.experimentId}`
);
}
}}
>
<PlusIcon className="w-16 h-16 text-slate-200" />
</button>
<span className="mt-2 text-sm text-[#6B7280] px-2">
Start from scratch
</span>
</div>
<div className="flex flex-col items-center justify-center space-y-1">
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogTrigger asChild>
<button className="flex flex-col items-center justify-center w-40 h-32 bg-white dark:bg-slate-800 rounded-lg hover:bg-transparent transition-colors border-2 border-slate-100 dark:border-slate-700">
<DocumentPlusIcon className="w-16 h-16 text-slate-200" />
</button>
</DialogTrigger>
<StartFromPromptDialog
prompts={prompts as any}
onDialogClose={() => setDialogOpen(false)}
/>
</Dialog>
<span className="text-sm text-[#6B7280] px-2">
Start from a prompt
</span>
</div>
{templateOptions.map((template) => (
<div key={template.id}>
<button
className="flex flex-col items-center justify-center w-40 h-32 bg-white dark:bg-slate-800 rounded-lg hover:bg-transparent transition-colors border-2 border-slate-100 dark:border-slate-700"
onClick={() =>
notification.setNotification(
"Templates are coming soon!",
"info"
)
}
></button>
<span className="mt-2 text-sm text-[#6B7280] px-2">
{template.name}
</span>
</div>
))}
</div>
</div>

<ThemedTable
defaultColumns={[
{
Expand Down
Loading