diff --git a/api/prompt/text.ts b/api/prompt/text.ts deleted file mode 100644 index 486285cf..00000000 --- a/api/prompt/text.ts +++ /dev/null @@ -1,289 +0,0 @@ -import { VercelApiHandler } from "@vercel/node"; -import { Schema } from "ajv"; -import { openai } from "../_lib/_openai"; -import { stringify } from "graph-selector"; - -type PromptType = "knowledge" | "flowchart"; - -export const maxDuration = 60 * 5; // 5 minutes - -const handler: VercelApiHandler = async (req, res) => { - const { subject, promptType, accentClasses = [] } = req.body; - if (!subject || !promptType || !isPromptType(promptType)) { - res.status(400).json({ - error: "Missing required fields", - }); - return; - } - - const text = await completionFunctions[promptType](subject, accentClasses); - - res.status(200).json({ - text, - }); -}; - -export default handler; - -function isPromptType(arg: string): arg is PromptType { - return arg === "knowledge" || arg === "flowchart"; -} - -const completionFunctions = { - flowchart: getFlowchartCompletion, - knowledge: getKnowledgeCompletion, -}; - -async function getFlowchartCompletion( - subject: string, - accentClasses: string[] -) { - const temperature = 0.2; - const model = "gpt-4-0613"; - const output: Schema = { - type: "object", - properties: { - nodes: { - type: "array", - description: "List of nodes in the knowledge graph", - items: { - type: "object", - properties: { - id: { - type: "string", - description: "Unique identifier for the node in slug format", - }, - label: { - type: "string", - description: "Label for the node", - }, - classes: { - type: "string", - description: "Optional style classes for the node", - }, - }, - required: ["id", "label"], - }, - }, - edges: { - type: "array", - description: "List of edges in the knowledge graph", - items: { - type: "object", - properties: { - label: { - type: "string", - description: "Label for the edge", - }, - source: { - type: "string", - description: "Origin node ID", - }, - target: { - type: "string", - description: "Destination node ID", - }, - }, - required: ["source", "target"], - }, - }, - }, - required: ["nodes", "edges"], - }; - - let prompt = `Create a detailed flowchart to help me convey the following process. `; - - // Add accent classes if passed - if (accentClasses.length > 0) { - prompt += `You can very sparingly use these classes to accent nodes if it adds to the visualization: ${accentClasses.join( - ", " - )}. `; - } - prompt += `Process: \n`; - - const chatCompletion = await openai.chat.completions.create({ - messages: [ - { - role: "user", - content: `${prompt}${subject}`, - }, - ], - model, - function_call: { name: "flowchart" }, - temperature, - functions: [ - { - name: "flowchart", - description: `Generate a flowchart with nodes and edges.`, - parameters: output, - }, - ], - }); - - const completionValue = - chatCompletion.choices[0].message.function_call?.arguments; - if (!completionValue) { - throw new Error("No completion value"); - } - - const graph = JSON.parse(completionValue) as { - nodes: { - id: string; - label: string; - classes: string; - }[]; - edges: { - label: string; - source: string; - target: string; - }[]; - }; - - const graphStr = stringify({ - nodes: graph.nodes.map((node) => ({ - data: { - id: node.id, - label: node.label, - classes: node.classes ?? "", - }, - })), - edges: graph.edges.map((edge) => ({ - source: edge.source, - target: edge.target, - data: { - id: "", - label: edge.label ?? "", - classes: "", - }, - })), - }); - - return graphStr; -} -async function getKnowledgeCompletion( - subject: string, - accentClasses: string[] -) { - const temperature = 0.2; - - let prompt = ``; - - // Add accent classes if passed - if (accentClasses.length > 0) { - prompt += `Use the following classes extremely sparingly on nodes, only when it helps with readability: ${accentClasses.join( - ", " - )}. `; - } - prompt += `Build a detailed knowledge graph that helps me understand the following: \n`; - - const output: Schema = { - type: "object", - properties: { - nodes: { - type: "array", - description: "List of nodes in the knowledge graph", - items: { - type: "object", - properties: { - id: { - type: "string", - description: "Unique identifier for the node in slug format", - }, - label: { - type: "string", - description: "Label for the node", - }, - classes: { - type: "string", - description: "Optional style classes for the node", - }, - }, - required: ["id", "label"], - }, - }, - edges: { - type: "array", - description: "List of edges in the knowledge graph", - items: { - type: "object", - properties: { - label: { - type: "string", - description: "Label for the edge", - }, - source: { - type: "string", - description: "Origin node ID", - }, - target: { - type: "string", - description: "Destination node ID", - }, - }, - required: ["source", "target"], - }, - }, - }, - required: ["nodes", "edges"], - }; - - const chatCompletion = await openai.chat.completions.create({ - messages: [ - { - role: "user", - content: `${prompt}${subject}`, - }, - ], - model: "gpt-4-0613", - function_call: { name: "graph" }, - temperature, - functions: [ - { - name: "graph", - description: `Generate a knowledge graph with entities and relationships.`, - parameters: output, - }, - ], - }); - - const completionValue = - chatCompletion.choices[0].message.function_call?.arguments; - - if (!completionValue) { - throw new Error("No completion value"); - } - - const graph = JSON.parse(completionValue) as { - nodes: { - id: string; - label: string; - classes: string; - }[]; - edges: { - label: string; - source: string; - target: string; - }[]; - }; - - const graphStr = stringify({ - nodes: graph.nodes.map((node) => ({ - data: { - id: node.id, - label: node.label, - classes: node.classes ?? "", - }, - })), - edges: graph.edges.map((edge) => ({ - source: edge.source, - target: edge.target, - data: { - id: "", - label: edge.label ?? "", - classes: "", - }, - })), - }); - - return graphStr; -} diff --git a/app/src/lib/templates/templates.ts b/app/src/lib/templates/templates.ts index b80ab704..0c96240f 100644 --- a/app/src/lib/templates/templates.ts +++ b/app/src/lib/templates/templates.ts @@ -5,51 +5,31 @@ export type PromptType = "knowledge" | "flowchart"; type Template = { key: string; title: () => string; - promptType: PromptType; - accentClasses?: string[]; }; export const templates: Template[] = [ { key: "default", title: () => `Default`, - promptType: "flowchart", }, { key: "flowchart", title: () => `Flowchart`, - promptType: "flowchart", - accentClasses: ["color_blue", "color_green"], }, { key: "org-chart", title: () => t`Organization Chart`, - promptType: "flowchart", - accentClasses: ["color_blue", "color_orange"], }, { key: "code-flow", title: () => t`Process Diagram`, - promptType: "flowchart", - accentClasses: ["color_blue", "color_green", "color_purple"], }, { key: "mindmap", title: () => `Mind Map`, - promptType: "knowledge", - accentClasses: ["size_lg", "color_blue", "color_green", "color_orange"], }, { key: "knowledge-graph", title: () => t`Knowledge Graph`, - promptType: "knowledge", - accentClasses: [ - "color_blue", - "color_green", - "color_orange", - "color_purple", - "color_grey", - "border_dashed", - ], }, ]; diff --git a/app/src/pages/New.tsx b/app/src/pages/New.tsx index 1d06e4f1..95ac91ea 100644 --- a/app/src/pages/New.tsx +++ b/app/src/pages/New.tsx @@ -1,10 +1,9 @@ -import { Article, MagicWand, Plus, Rocket } from "phosphor-react"; -import { Button2, Input, Textarea } from "../ui/Shared"; +import { Plus, Rocket } from "phosphor-react"; +import { Button2, Input } from "../ui/Shared"; import { templates } from "../lib/templates/templates"; import { Trans, t } from "@lingui/macro"; import * as RadioGroup from "@radix-ui/react-radio-group"; -import * as Tabs from "@radix-ui/react-tabs"; -import { Fragment, useCallback, useContext, useState } from "react"; +import { useCallback, useContext, useState } from "react"; import { AppContext } from "../components/AppContextProvider"; import { languages } from "../locales/i18n"; import { getFunFlowchartName } from "../lib/getFunFlowchartName"; @@ -12,7 +11,6 @@ import { useMutation } from "react-query"; import { supabase } from "../lib/supabaseClient"; import { useHasProAccess, useUserId } from "../lib/hooks"; import { Link, useNavigate } from "react-router-dom"; -import { sample } from "../lib/sample"; import { showPaywall } from "../lib/usePaywallModalStore"; import { createUnlimitedContent, @@ -21,13 +19,10 @@ import { import { Warning } from "../components/Warning"; import { FFTheme } from "../lib/FFTheme"; import { RequestTemplate } from "../components/RequestTemplate"; -import { createExamples } from "./createExamples"; type CreateChartOptions = { name: string; template: string; - promptType: string; - subject?: string; }; export default function New2() { @@ -56,40 +51,6 @@ export default function New2() { const theme: FFTheme = importTemplate.theme; const cytoscapeStyle = importTemplate.cytoscapeStyle ?? ""; - // Prompts - if (options.subject) { - setIsAI(true); - // Scroll to End of Page - requestAnimationFrame(() => - window.scrollTo(0, document.body.scrollHeight) - ); - const startTime = performance.now(); - const response = await fetch("/api/prompt/text", { - method: "POST", - body: JSON.stringify({ - promptType: options.promptType, - subject: options.subject, - accentClasses: templateData.accentClasses, - }), - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${data.session.access_token}`, - }, - }).then((res) => res.json()); - const endTime = performance.now(); - const elapsedTime = endTime - startTime; - // TO DO: Show Error Here - if (response.text) { - content = response.text; - sample({ - template: options.template, - subject: options.subject, - runningTime: elapsedTime, - result: response.text, - }); - } - } - const chart = `${content}\n=====${JSON.stringify({ themeEditor: theme, cytoscapeStyle, @@ -126,7 +87,6 @@ export default function New2() { const data = new FormData(e.currentTarget); const name = data.get("name")?.toString(); const template = data.get("template")?.toString(); - const subject = data.get("subject")?.toString(); if (!name || !template) return; const templateObj = templates.find((t) => t.key === template); @@ -135,8 +95,6 @@ export default function New2() { const options: CreateChartOptions = { name, template, - promptType: templateObj.promptType, - subject, }; createChartMutation.mutate(options); @@ -145,7 +103,6 @@ export default function New2() { ); const language = useContext(AppContext).language; - const [examples] = useState(createExamples()); return (
-
- - -
- -
- Use Default Content - - - - Use AI - -
-
- -

- - Enter a prompt or information you would like to create a chart - from. - -

-
- - Examples:   - - {examples.map((example, index) => ( - - {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} - { - // set example in textarea - const textarea = document.querySelector( - "#ai-prompt" - ) as HTMLTextAreaElement; - if (textarea) textarea.value = example; - }} - > - {example} - - {index < examples.length - 1 && ( - | - )} - - ))} -
-