Change up refinement UI (#66)

* Remove unused ScenarioVariantCell fields

* Refine deriveNewConstructFn

* Fix prettier

* Remove migration script

* Add refine modal

* Fix prettier

* Fix diff checker overflow

* Decrease diff height

* Add more context to prompt refining

* Auto-expand prompt when refining
This commit is contained in:
arcticfly
2023-07-19 17:19:45 -07:00
committed by GitHub
parent 7d2166b305
commit e6e2c706c2
3 changed files with 116 additions and 18 deletions

View File

@@ -12,7 +12,6 @@ const CompareFunctions = ({
originalFunction: string; originalFunction: string;
newFunction?: string; newFunction?: string;
}) => { }) => {
console.log("newFunction", newFunction);
const highlightSyntax = (str: string) => { const highlightSyntax = (str: string) => {
let highlighted; let highlighted;
try { try {
@@ -25,17 +24,17 @@ const CompareFunctions = ({
}; };
return ( return (
<HStack w="full" spacing={5}> <HStack w="full" spacing={5}>
<VStack w="full" spacing={4} maxH="65vh" fontSize={12} lineHeight={1} overflowY="auto"> <VStack w="full" spacing={4} maxH="50vh" fontSize={12} lineHeight={1} overflowY="auto">
<DiffViewer <DiffViewer
oldValue={originalFunction} oldValue={originalFunction}
newValue={newFunction || originalFunction} newValue={newFunction || originalFunction}
splitView={true} splitView={true}
hideLineNumbers={true}
leftTitle="Original" leftTitle="Original"
rightTitle={newFunction ? "Modified" : "Unmodified"} rightTitle={newFunction ? "Modified" : "Unmodified"}
disableWordDiff={true} disableWordDiff={true}
compareMethod={DiffMethod.CHARS} compareMethod={DiffMethod.CHARS}
renderContent={highlightSyntax} renderContent={highlightSyntax}
showDiffOnly={false}
/> />
</VStack> </VStack>
</HStack> </HStack>

View File

@@ -11,12 +11,16 @@ import {
Text, Text,
Spinner, Spinner,
HStack, HStack,
InputGroup,
Input,
InputRightElement,
Icon,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { IoMdSend } from "react-icons/io";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { useHandledAsyncCallback } from "~/utils/hooks"; import { useHandledAsyncCallback } from "~/utils/hooks";
import { type PromptVariant } from "@prisma/client"; import { type PromptVariant } from "@prisma/client";
import { useState } from "react"; import { useState } from "react";
import AutoResizeTextArea from "../AutoResizeTextArea";
import CompareFunctions from "./CompareFunctions"; import CompareFunctions from "./CompareFunctions";
export const RefinePromptModal = ({ export const RefinePromptModal = ({
@@ -56,12 +60,20 @@ export const RefinePromptModal = ({
<Modal isOpen onClose={onClose} size={{ base: "xl", sm: "2xl", md: "7xl" }}> <Modal isOpen onClose={onClose} size={{ base: "xl", sm: "2xl", md: "7xl" }}>
<ModalOverlay /> <ModalOverlay />
<ModalContent w={1200}> <ModalContent w={1200}>
<ModalHeader>Refine Your Prompt</ModalHeader> <ModalHeader>Refine with GPT-4</ModalHeader>
<ModalCloseButton /> <ModalCloseButton />
<ModalBody maxW="unset"> <ModalBody maxW="unset">
<VStack spacing={8}> <VStack spacing={16} pt={8}>
<HStack w="full"> <InputGroup
<AutoResizeTextArea size="md"
w="full"
maxW="600"
boxShadow="0 0 40px 4px rgba(0, 0, 0, 0.1);"
borderRadius={8}
alignItems="center"
colorScheme="orange"
>
<Input
value={instructions} value={instructions}
onChange={(e) => setInstructions(e.target.value)} onChange={(e) => setInstructions(e.target.value)}
onKeyDown={(e) => { onKeyDown={(e) => {
@@ -71,12 +83,41 @@ export const RefinePromptModal = ({
getRefinedPromptFn(); getRefinedPromptFn();
} }
}} }}
placeholder="Use chain of thought" placeholder="Send instructions"
py={7}
px={4}
colorScheme="orange"
borderColor="gray.300"
borderWidth={1}
_hover={{
borderColor: "gray.300",
}}
_focus={{
borderColor: "gray.300",
}}
/> />
<Button onClick={getRefinedPromptFn}> <InputRightElement width="8" height="full">
{refiningInProgress ? <Spinner boxSize={4} /> : <Text>Submit</Text>} <Button
h="8"
w="8"
minW="unset"
size="sm"
onClick={getRefinedPromptFn}
disabled={!instructions}
variant={instructions ? "solid" : "ghost"}
mr={4}
borderRadius="8"
bgColor={instructions ? "orange.400" : "transparent"}
colorScheme="orange"
>
{refiningInProgress ? (
<Spinner boxSize={4} />
) : (
<Icon as={IoMdSend} color={instructions ? "white" : "gray.500"} boxSize={5} />
)}
</Button> </Button>
</HStack> </InputRightElement>
</InputGroup>
<CompareFunctions <CompareFunctions
originalFunction={variant.constructFn} originalFunction={variant.constructFn}
newFunction={refinedPromptFn} newFunction={refinedPromptFn}
@@ -85,13 +126,14 @@ export const RefinePromptModal = ({
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<HStack spacing={4}> <HStack spacing={4} pt={8}>
<Button onClick={onClose}>Cancel</Button>
<Button <Button
colorScheme="blue"
onClick={replaceVariant} onClick={replaceVariant}
minW={24} minW={24}
disabled={!refinedPromptFn} disabled={true}
_disabled={{
bgColor: "blue.500",
}}
> >
{replacementInProgress ? <Spinner boxSize={4} /> : <Text>Accept</Text>} {replacementInProgress ? <Spinner boxSize={4} /> : <Text>Accept</Text>}
</Button> </Button>

View File

@@ -40,6 +40,59 @@ const requestUpdatedPromptFunction = async (
) => { ) => {
const originalModel = originalVariant.model as SupportedModel; const originalModel = originalVariant.model as SupportedModel;
let newContructionFn = ""; let newContructionFn = "";
const usefulTips = `Chain of thought means asking the model to think about its answer before it gives it to you. This is useful for getting more accurate answers.
This is what a prompt looks like without using function calls:
prompt = {
model: "gpt-4",
stream: true,
messages: [
{
role: "system",
content: \`Evaluate sentiment.\`,
},
{
role: "user",
content: \`This is the user's message: \${scenario.user_message}. Return "positive" or "negative" or "neutral"\`,
},
],
};
This is what one looks like using function calls:
prompt = {
model: "gpt-3.5-turbo-0613",
stream: true,
messages: [
{
role: "system",
content: "Evaluate sentiment.",
},
{
role: "user",
content: scenario.user_message,
},
],
functions: [
{
name: "extract_sentiment",
parameters: {
type: "object",
properties: {
sentiment: {
type: "string",
description: "one of positive/negative/neutral",
},
},
},
},
],
function_call: {
name: "extract_sentiment",
},
};
`;
for (let i = 0; i < NUM_RETRIES; i++) { for (let i = 0; i < NUM_RETRIES; i++) {
try { try {
const messages: CompletionCreateParams.CreateChatCompletionRequestNonStreaming.Message[] = [ const messages: CompletionCreateParams.CreateChatCompletionRequestNonStreaming.Message[] = [
@@ -49,7 +102,7 @@ const requestUpdatedPromptFunction = async (
getApiShapeForModel(originalModel), getApiShapeForModel(originalModel),
null, null,
2, 2,
)}`, )}\n\nDo not add any assistant messages.`,
}, },
]; ];
if (newModel) { if (newModel) {
@@ -59,6 +112,10 @@ const requestUpdatedPromptFunction = async (
}); });
} }
if (instructions) { if (instructions) {
messages.push({
role: "system",
content: `Here is some useful information about prompt engineering: ${usefulTips}`,
});
messages.push({ messages.push({
role: "user", role: "user",
content: `Follow these instructions: ${instructions}`, content: `Follow these instructions: ${instructions}`,