Skip to content

Commit

Permalink
Merge pull request #606 from tone-row/dev
Browse files Browse the repository at this point in the history
v1.41.0
  • Loading branch information
rob-gordon authored Oct 2, 2023
2 parents add4bf1 + fd01394 commit e060a5b
Show file tree
Hide file tree
Showing 54 changed files with 2,835 additions and 1,927 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ yarn-error.log
TODO.md
.vscode
keys
ERROR.png
ERROR.png
flowchart-fun.feature-reacher.json
6 changes: 2 additions & 4 deletions api/_lib/_openai.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Configuration, OpenAIApi } from "openai";
import { OpenAI } from "openai";

const apiKey = process.env.OPENAI_SECRET;
if (!apiKey) throw new Error("No OpenAI API key provided");

const configuration = new Configuration({
export const openai = new OpenAI({
apiKey,
});

export const openai = new OpenAIApi(configuration);
11 changes: 6 additions & 5 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
"@octokit/core": "^4.2.0",
"@sendgrid/mail": "^7.4.6",
"@supabase/supabase-js": "^2.31.0",
"ajv": "^8.12.0",
"csv-parse": "^5.3.6",
"date-fns": "^2.29.3",
"graph-selector": "^0.8.3",
"graph-selector": "^0.9.11",
"highlight.js": "^11.7.0",
"marked": "^4.1.1",
"moniker": "^0.1.2",
"notion-to-md": "^2.5.5",
"openai": "^3.2.1",
"openai": "^4.10.0",
"shared": "workspace:*",
"stripe": "^11.11.0"
},
Expand All @@ -31,11 +32,11 @@
"@types/jest": "^29.0.0",
"@types/marked": "^4.0.7",
"@types/node": "^18.16.17",
"@typescript-eslint/eslint-plugin": "^5",
"@typescript-eslint/parser": "^5",
"@typescript-eslint/eslint-plugin": "^6.2.0",
"@typescript-eslint/parser": "^6.2.0",
"@vercel/node": "^2.8.15",
"eslint": "^8.3.0",
"jest": "^29.4.3",
"typescript": "^5.1.6"
"typescript": "^5.2.2"
}
}
287 changes: 287 additions & 0 deletions api/prompt/text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
import { VercelApiHandler } from "@vercel/node";
import { Schema } from "ajv";
import { openai } from "../_lib/_openai";
import { stringify } from "graph-selector";

type PromptType = "knowledge" | "flowchart";

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;
}
Loading

2 comments on commit e060a5b

@vercel
Copy link

@vercel vercel bot commented on e060a5b Oct 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checks for Deployment have failed

@vercel
Copy link

@vercel vercel bot commented on e060a5b Oct 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.