From b974325b1a097dbc0797cdf88ea495f638e3d558 Mon Sep 17 00:00:00 2001 From: Vincelwt Date: Fri, 24 May 2024 15:16:40 +0100 Subject: [PATCH] feat: prompt notepad (#340) --- .../backend/src/api/v1/template-versions.ts | 19 ++- packages/backend/src/api/v1/templates.ts | 41 +++--- packages/db/0015.sql | 1 + .../components/SmartViewer/Message.tsx | 43 +++--- .../components/blocks/Feedbacks/index.tsx | 50 ++++--- .../components/blocks/RunInputOutput.tsx | 2 +- .../frontend/components/prompts/Provider.tsx | 16 ++- packages/frontend/pages/prompts/[[...id]].tsx | 128 +++++++++++++++--- 8 files changed, 213 insertions(+), 87 deletions(-) create mode 100644 packages/db/0015.sql diff --git a/packages/backend/src/api/v1/template-versions.ts b/packages/backend/src/api/v1/template-versions.ts index 77cf4221..5f859e58 100644 --- a/packages/backend/src/api/v1/template-versions.ts +++ b/packages/backend/src/api/v1/template-versions.ts @@ -5,6 +5,7 @@ import postgres from "postgres" import { unCamelObject } from "@/src/utils/misc" import { checkAccess } from "@/src/utils/authorization" import { z } from "zod" +import { clearUndefined } from "@/src/utils/ingest" const versions = new Router({ prefix: "/template_versions", @@ -82,14 +83,16 @@ versions.patch( "/:id", checkAccess("prompts", "update"), async (ctx: Context) => { + console.log("ctx.request.body", ctx.request.body) const bodySchema = z.object({ content: z.array(z.any()), extra: z.any(), testValues: z.any(), isDraft: z.boolean(), + notes: z.string().optional().nullable(), }) - const { content, extra, testValues, isDraft } = bodySchema.parse( + const { content, extra, testValues, isDraft, notes } = bodySchema.parse( ctx.request.body, ) @@ -111,11 +114,15 @@ versions.patch( const [updatedTemplateVersion] = await sql` update template_version - set - content = ${sql.json(content)}, - extra = ${sql.json(unCamelObject(extra))}, - test_values = ${sql.json(testValues)}, - is_draft = ${isDraft} + set ${sql( + clearUndefined({ + content: sql.json(content), + extra: sql.json(unCamelObject(extra)), + test_values: sql.json(testValues), + is_draft: isDraft, + notes, + }), + )} where id = ${ctx.params.id} returning * diff --git a/packages/backend/src/api/v1/templates.ts b/packages/backend/src/api/v1/templates.ts index 6dae7c28..82a83e42 100644 --- a/packages/backend/src/api/v1/templates.ts +++ b/packages/backend/src/api/v1/templates.ts @@ -1,5 +1,6 @@ import { checkAccess } from "@/src/utils/authorization" import sql from "@/src/utils/db" +import { clearUndefined } from "@/src/utils/ingest" import Context from "@/src/utils/koa" import { unCamelObject } from "@/src/utils/misc" import Router from "koa-router" @@ -32,7 +33,7 @@ templates.get("/", async (ctx: Context) => { templates.post("/", checkAccess("prompts", "create"), async (ctx: Context) => { const { projectId, userId } = ctx.state - const { slug, mode, content, extra, testValues, isDraft } = ctx.request + const { slug, mode, content, extra, testValues, isDraft, notes } = ctx.request .body as { slug: string mode: string @@ -40,6 +41,7 @@ templates.post("/", checkAccess("prompts", "create"), async (ctx: Context) => { extra: any testValues: any isDraft: boolean + notes: string } const [template] = await sql` @@ -52,13 +54,16 @@ templates.post("/", checkAccess("prompts", "create"), async (ctx: Context) => { ` const [templateVersion] = await sql` - insert into template_version ${sql({ - templateId: template.id, - content: sql.json(content), - extra: sql.json(unCamelObject(extra)), - testValues: sql.json(testValues), - isDraft: isDraft, - })} returning * + insert into template_version ${sql( + clearUndefined({ + templateId: template.id, + content: sql.json(content), + extra: sql.json(unCamelObject(extra)), + testValues: sql.json(testValues), + isDraft: isDraft, + notes, + }), + )} returning * ` ctx.body = { @@ -123,21 +128,25 @@ templates.post( "/:id/versions", checkAccess("prompts", "update"), async (ctx: Context) => { - const { content, extra, testValues, isDraft } = ctx.request.body as { + const { content, extra, testValues, isDraft, notes } = ctx.request.body as { content: any[] extra: any testValues: any isDraft: boolean + notes: string } const [templateVersion] = await sql` - insert into template_version ( - template_id, content, extra, test_values, is_draft - ) values ( - ${ctx.params.id}, ${sql.json(content)}, ${sql.json(unCamelObject(extra))}, ${sql.json( - testValues, - )}, ${isDraft} - ) returning * + insert into template_version ${sql( + clearUndefined({ + templateId: ctx.params.id, + content: sql.json(content), + extra: sql.json(unCamelObject(extra)), + test_values: sql.json(testValues), + isDraft, + notes, + }), + )} returning * ` ctx.body = templateVersion diff --git a/packages/db/0015.sql b/packages/db/0015.sql new file mode 100644 index 00000000..e33235e2 --- /dev/null +++ b/packages/db/0015.sql @@ -0,0 +1 @@ +alter table template_version add column if not exists notes text; \ No newline at end of file diff --git a/packages/frontend/components/SmartViewer/Message.tsx b/packages/frontend/components/SmartViewer/Message.tsx index c73b0e9c..5627db0f 100644 --- a/packages/frontend/components/SmartViewer/Message.tsx +++ b/packages/frontend/components/SmartViewer/Message.tsx @@ -6,8 +6,6 @@ import { Code, Flex, Group, - JsonInput, - Modal, Paper, Select, Space, @@ -18,13 +16,11 @@ import { ThemeIcon, } from "@mantine/core" import { - IconCross, IconInfoCircle, IconRobot, IconTool, IconTrash, IconUser, - IconX, } from "@tabler/icons-react" import Image from "next/image" import ProtectedText from "../blocks/ProtectedText" @@ -32,7 +28,7 @@ import { RenderJson } from "./RenderJson" import { useColorScheme } from "@mantine/hooks" import { circularPro } from "@/utils/theme" -import { useEffect, useState } from "react" +import { useEffect } from "react" import { openConfirmModal } from "@mantine/modals" @@ -175,7 +171,7 @@ function ToolCallsMessage({ }} /> ) : ( - + {toolCall?.id} )} @@ -285,20 +281,25 @@ function ImageMessage({ data, codeBg, compact }) { ) } -function PropEditor({ value, onChange, editable, placeholder }) { - return editable ? ( - onChange(e.target.value)} - style={{ width: "100%" }} - /> - ) : ( - {value} +function PropEditor({ value, onChange, editable, placeholder, label }) { + return ( + + {label && {label}:} + {editable ? ( + onChange(e.target.value)} + style={{ width: "100%" }} + /> + ) : ( + {value} + )} + ) } @@ -319,6 +320,7 @@ function ChatMessageContent({ onChange={(name) => onChange({ ...data, name })} editable={editable} placeholder={"Tool name"} + label={"Name"} /> )} @@ -329,6 +331,7 @@ function ChatMessageContent({ onChange={(toolCallId) => onChange({ ...data, toolCallId })} editable={editable} placeholder={"Tool call ID"} + label={"ID"} /> )} diff --git a/packages/frontend/components/blocks/Feedbacks/index.tsx b/packages/frontend/components/blocks/Feedbacks/index.tsx index 3f7d4cff..c7354699 100644 --- a/packages/frontend/components/blocks/Feedbacks/index.tsx +++ b/packages/frontend/components/blocks/Feedbacks/index.tsx @@ -1,7 +1,15 @@ import { openUpgrade } from "@/components/layout/UpgradeModal" import { useOrg } from "@/utils/dataHooks" import { useFixedColorScheme } from "@/utils/hooks" -import { ActionIcon, Button, Group, Popover, TextInput } from "@mantine/core" +import { + ActionIcon, + Button, + Group, + Popover, + Stack, + TextInput, + Textarea, +} from "@mantine/core" import { IconMessage, IconThumbDown, IconThumbUp } from "@tabler/icons-react" import { useState } from "react" import { Feedback } from "shared" @@ -96,24 +104,28 @@ export default function Feedbacks({ - setComment(e.target.value)} - /> - + +