mirror of
https://github.com/StanGirard/quivr.git
synced 2024-11-13 23:58:42 +03:00
feat: add public prompts picker (#841)
* fix: update prompt_id logic in payload * feat: add getPublicPrompts to sdk * feat: add public prompt picker
This commit is contained in:
parent
fdcdf581a8
commit
b3fb8fc3bc
@ -10,6 +10,7 @@ import { TextArea } from "@/lib/components/ui/TextArea";
|
||||
import { models, paidModels } from "@/lib/context/BrainConfigProvider/types";
|
||||
import { defineMaxTokens } from "@/lib/helpers/defineMexTokens";
|
||||
|
||||
import { PublicPrompts } from "./components/PublicPrompts";
|
||||
import { useSettingsTab } from "./hooks/useSettingsTab";
|
||||
|
||||
type SettingsTabProps = {
|
||||
@ -30,6 +31,7 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
|
||||
isDefaultBrain,
|
||||
formRef,
|
||||
promptId,
|
||||
pickPublicPrompt,
|
||||
removeBrainPrompt,
|
||||
} = useSettingsTab({ brainId });
|
||||
|
||||
@ -128,7 +130,8 @@ export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
|
||||
{...register("maxTokens")}
|
||||
/>
|
||||
</fieldset>
|
||||
<Divider text="prompt" />
|
||||
<Divider text="Custom prompt" />
|
||||
<PublicPrompts onSelect={pickPublicPrompt} />
|
||||
<Field
|
||||
label="Prompt title"
|
||||
placeholder="My awesome prompt name"
|
||||
|
@ -0,0 +1,57 @@
|
||||
import * as Accordion from "@radix-ui/react-accordion";
|
||||
import { ChangeEvent, useEffect, useState } from "react";
|
||||
|
||||
import { usePromptApi } from "@/lib/api/prompt/usePromptApi";
|
||||
import { Prompt } from "@/lib/types/Prompt";
|
||||
|
||||
type PublicPromptsProps = {
|
||||
onSelect: ({ title, content }: { title: string; content: string }) => void;
|
||||
};
|
||||
|
||||
export const PublicPrompts = ({
|
||||
onSelect,
|
||||
}: PublicPromptsProps): JSX.Element => {
|
||||
const [publicPrompts, setPublicPrompts] = useState<Prompt[]>([]);
|
||||
|
||||
const { getPublicPrompts } = usePromptApi();
|
||||
|
||||
const fetchPublicPrompts = async () => {
|
||||
setPublicPrompts(await getPublicPrompts());
|
||||
};
|
||||
|
||||
const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
|
||||
const selectedPrompt = publicPrompts.find(
|
||||
(prompt) => prompt.id === event.target.value
|
||||
);
|
||||
if (selectedPrompt) {
|
||||
onSelect({
|
||||
title: selectedPrompt.title,
|
||||
content: selectedPrompt.content,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
void fetchPublicPrompts();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Accordion.Root className="AccordionRoot" type="single" collapsible>
|
||||
<Accordion.Item className="AccordionItem" value="item-1">
|
||||
<Accordion.Trigger>Pick in public prompts</Accordion.Trigger>
|
||||
<Accordion.Content>
|
||||
<select
|
||||
onChange={handleChange}
|
||||
className="px-5 w-full py-2 dark:bg-gray-700 bg-gray-200 rounded-md"
|
||||
>
|
||||
{publicPrompts.map((prompt) => (
|
||||
<option value={prompt.id} key={prompt.id}>
|
||||
{prompt.title}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
</Accordion.Root>
|
||||
);
|
||||
};
|
@ -257,13 +257,15 @@ export const useSettingsTab = ({ brainId }: UseSettingsTabProps) => {
|
||||
promptHandler(),
|
||||
]);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
await updateBrain(brainId, {
|
||||
...otherConfigs,
|
||||
max_tokens,
|
||||
openai_api_key,
|
||||
prompt_id:
|
||||
otherConfigs["prompt_id"] !== ""
|
||||
? otherConfigs["prompt_id"]
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
@ -295,6 +297,21 @@ export const useSettingsTab = ({ brainId }: UseSettingsTabProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const pickPublicPrompt = ({
|
||||
title,
|
||||
content,
|
||||
}: {
|
||||
title: string;
|
||||
content: string;
|
||||
}): void => {
|
||||
setValue("prompt.title", title, {
|
||||
shouldDirty: true,
|
||||
});
|
||||
setValue("prompt.content", content, {
|
||||
shouldDirty: true,
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
handleSubmit,
|
||||
register,
|
||||
@ -309,5 +326,6 @@ export const useSettingsTab = ({ brainId }: UseSettingsTabProps) => {
|
||||
formRef,
|
||||
promptId,
|
||||
removeBrainPrompt,
|
||||
pickPublicPrompt,
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { CreatePromptProps, PromptUpdatableProperties } from "../prompt";
|
||||
import { usePromptApi } from "../usePromptApi";
|
||||
@ -19,6 +19,10 @@ vi.mock("@/lib/hooks", () => ({
|
||||
}));
|
||||
|
||||
describe("usePromptApi", () => {
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
it("should call createPrompt with the correct parameters", async () => {
|
||||
const prompt: CreatePromptProps = {
|
||||
title: "Test Prompt",
|
||||
@ -67,4 +71,17 @@ describe("usePromptApi", () => {
|
||||
expect(axiosPutMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosPutMock).toHaveBeenCalledWith(`/prompts/${promptId}`, prompt);
|
||||
});
|
||||
it("should call getPublicPrompts with the correct parameters", async () => {
|
||||
axiosGetMock.mockReturnValue({ data: [] });
|
||||
const {
|
||||
result: {
|
||||
current: { getPublicPrompts },
|
||||
},
|
||||
} = renderHook(() => usePromptApi());
|
||||
|
||||
await getPublicPrompts();
|
||||
|
||||
expect(axiosGetMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosGetMock).toHaveBeenCalledWith("/prompts");
|
||||
});
|
||||
});
|
||||
|
@ -32,3 +32,9 @@ export const updatePrompt = async (
|
||||
): Promise<Prompt> => {
|
||||
return (await axiosInstance.put<Prompt>(`/prompts/${promptId}`, prompt)).data;
|
||||
};
|
||||
|
||||
export const getPublicPrompts = async (
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<Prompt[]> => {
|
||||
return (await axiosInstance.get<Prompt[]>("/prompts")).data;
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
createPrompt,
|
||||
CreatePromptProps,
|
||||
getPrompt,
|
||||
getPublicPrompts,
|
||||
PromptUpdatableProperties,
|
||||
updatePrompt,
|
||||
} from "./prompt";
|
||||
@ -18,5 +19,6 @@ export const usePromptApi = () => {
|
||||
getPrompt: async (promptId: string) => getPrompt(promptId, axiosInstance),
|
||||
updatePrompt: async (promptId: string, prompt: PromptUpdatableProperties) =>
|
||||
updatePrompt(promptId, prompt, axiosInstance),
|
||||
getPublicPrompts: async () => await getPublicPrompts(axiosInstance),
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* eslint-disable max-lines */
|
||||
import { MdAdd } from "react-icons/md";
|
||||
|
||||
import { PublicPrompts } from "@/app/brains-management/[brainId]/components/BrainManagementTabs/components/SettingsTab/components/PublicPrompts";
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
import Field from "@/lib/components/ui/Field";
|
||||
import { Modal } from "@/lib/components/ui/Modal";
|
||||
@ -22,6 +23,7 @@ export const AddBrainModal = (): JSX.Element => {
|
||||
maxTokens,
|
||||
model,
|
||||
isPending,
|
||||
pickPublicPrompt,
|
||||
} = useAddBrainModal();
|
||||
|
||||
return (
|
||||
@ -116,6 +118,7 @@ export const AddBrainModal = (): JSX.Element => {
|
||||
/>
|
||||
</fieldset>
|
||||
<Divider text="Custom prompt" />
|
||||
<PublicPrompts onSelect={pickPublicPrompt} />
|
||||
<Field
|
||||
label="Prompt title"
|
||||
placeholder="My awesome prompt name"
|
||||
|
@ -123,6 +123,21 @@ export const useAddBrainModal = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const pickPublicPrompt = ({
|
||||
title,
|
||||
content,
|
||||
}: {
|
||||
title: string;
|
||||
content: string;
|
||||
}): void => {
|
||||
setValue("prompt.title", title, {
|
||||
shouldDirty: true,
|
||||
});
|
||||
setValue("prompt.content", content, {
|
||||
shouldDirty: true,
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
isShareModalOpen,
|
||||
setIsShareModalOpen,
|
||||
@ -133,5 +148,6 @@ export const useAddBrainModal = () => {
|
||||
temperature,
|
||||
maxTokens,
|
||||
isPending,
|
||||
pickPublicPrompt,
|
||||
};
|
||||
};
|
||||
|
@ -20,6 +20,7 @@
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@growthbook/growthbook-react": "^0.17.0",
|
||||
"@june-so/analytics-next": "^2.0.0",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-dialog": "^1.0.3",
|
||||
"@radix-ui/react-popover": "^1.0.6",
|
||||
"@radix-ui/react-select": "^1.2.2",
|
||||
|
@ -756,6 +756,22 @@
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
|
||||
"@radix-ui/react-accordion@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-accordion/-/react-accordion-1.1.2.tgz#738441f7343e5142273cdef94d12054c3287966f"
|
||||
integrity sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.1"
|
||||
"@radix-ui/react-collapsible" "1.0.3"
|
||||
"@radix-ui/react-collection" "1.0.3"
|
||||
"@radix-ui/react-compose-refs" "1.0.1"
|
||||
"@radix-ui/react-context" "1.0.1"
|
||||
"@radix-ui/react-direction" "1.0.1"
|
||||
"@radix-ui/react-id" "1.0.1"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.1"
|
||||
|
||||
"@radix-ui/react-arrow@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d"
|
||||
@ -764,6 +780,21 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
|
||||
"@radix-ui/react-collapsible@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz#df0e22e7a025439f13f62d4e4a9e92c4a0df5b81"
|
||||
integrity sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.1"
|
||||
"@radix-ui/react-compose-refs" "1.0.1"
|
||||
"@radix-ui/react-context" "1.0.1"
|
||||
"@radix-ui/react-id" "1.0.1"
|
||||
"@radix-ui/react-presence" "1.0.1"
|
||||
"@radix-ui/react-primitive" "1.0.3"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.1"
|
||||
"@radix-ui/react-use-layout-effect" "1.0.1"
|
||||
|
||||
"@radix-ui/react-collection@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159"
|
||||
|
Loading…
Reference in New Issue
Block a user