Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ ERROR.png
flowchart-fun.feature-reacher.json
.parcel-cache

speech*.mp4
speech*.mp4
.env*.local
stripe-scripts/
639 changes: 639 additions & 0 deletions CLAUDE.md

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
"author": "",
"license": "ISC",
"dependencies": {
"@ai-sdk/openai": "^0.0.45",
"@notionhq/client": "^0.4.13",
"@octokit/core": "^4.2.0",
"@sendgrid/mail": "^7.4.6",
"@supabase/supabase-js": "^2.31.0",
"@upstash/ratelimit": "^1.1.3",
"@vercel/kv": "^1.0.1",
"ai": "^3.3.6",
"ai": "^6.0.79",
"ajv": "^8.12.0",
"axios": "^0.27.2",
"csv-parse": "^5.3.6",
Expand All @@ -30,10 +29,10 @@
"moniker": "^0.1.2",
"multer": "1.4.5-lts.1",
"notion-to-md": "^2.5.5",
"openai": "^4.24.2",
"openai": "^4.89.1",
"shared": "workspace:*",
"stripe": "^15.5.0",
"zod": "^3.22.4",
"zod": "^3.25.76",
"zod-to-json-schema": "^3.22.3"
},
"devDependencies": {
Expand Down
48 changes: 26 additions & 22 deletions api/prompt/_shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { streamText } from "ai";
import { stripe } from "../_lib/_stripe";
import { kv } from "@vercel/kv";
import { Ratelimit } from "@upstash/ratelimit";
import { createOpenAI, type openai as OpenAI } from "@ai-sdk/openai";

export const reqSchema = z.object({
prompt: z.string().min(1),
Expand Down Expand Up @@ -90,24 +89,29 @@ export async function templateRateLimit(req: Request) {
return null;
}

export const DEFAULT_MODEL = "openai/gpt-oss-120b";

export const GATEWAY_OPTIONS = {
gateway: {
order: ["cerebras"],
},
};

export async function processRequest(
req: Request,
systemMessage: string,
content: string,
model: Parameters<typeof OpenAI.chat>[0] = "gpt-4-turbo"
model: string = DEFAULT_MODEL
) {
const { isPro, customerId } = await checkUserStatus(req);
const rateLimitResponse = await handleRateLimit(req, isPro, customerId);
if (rateLimitResponse) return rateLimitResponse;

const openai = createOpenAI({
apiKey: getOpenAiApiKey(isPro),
});

const result = await streamText({
model: openai.chat(model),
const result = streamText({
model,
system: systemMessage,
temperature: 1,
temperature: 0.1,
providerOptions: GATEWAY_OPTIONS,
messages: [
{
role: "user",
Expand All @@ -119,19 +123,6 @@ export async function processRequest(
return result.toTextStreamResponse();
}

/**
* Returns the right api key depending on the user's subscription
* so we can track usage. Bear in mind a development key is used for
* anything that's not production.
*/
function getOpenAiApiKey(isPro: boolean) {
if (isPro) {
return process.env.OPENAI_API_KEY_PRO;
}

return process.env.OPENAI_API_KEY_FREE;
}

function getIp(req: Request) {
return (
req.headers.get("x-real-ip") ||
Expand All @@ -157,3 +148,16 @@ export const systemMessageExample = `Node A
Node C
label from c to d: Node D .color_green.shape_diamond
label from d to a: (Node A)`;

export const systemMessageSyntax = `Flowchart Fun Syntax:
- Indentation creates parent→child edges (tree-shaped graph).
- Text before a colon labels the edge: "yes: Next Step" creates an edge labeled "yes".
- Reference a previously declared node by wrapping its label in parentheses: (Node Name).
- Escape these characters in node/edge labels: ( ) : # . \\
- Style nodes with classes at the end: Node A .color_blue.shape_diamond`;

export const systemMessagePitfalls = `Common mistakes to avoid:
- NEVER start a line with an edge label at the root level (no indentation). "start: Node A" on the first line is invalid because there is no parent node to draw an edge from. Create the source node first, then indent the labeled edge beneath it.
- Only reference nodes that have already been declared above. (Node X) is invalid if Node X has not appeared yet.
- Indentation must be consistent. Use spaces (not tabs). Each indent level adds children to the nearest less-indented node above.
- Do NOT wrap your output in markdown code fences (\`\`\`). Return raw Flowchart Fun syntax only.`;
17 changes: 10 additions & 7 deletions api/prompt/choose-template.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { z } from "zod";
import { templateRateLimit } from "./_shared";
import { generateObject } from "ai";
import { openai } from "@ai-sdk/openai";
import { generateText, Output } from "ai";
import { templates } from "shared";

const schema = z.object({
Expand All @@ -28,15 +27,19 @@ export default async function handler(req: Request) {
return new Response(JSON.stringify(parsed.error), { status: 400 });
}

const result = await generateObject({
model: openai("gpt-3.5-turbo"),
schema,
const result = await generateText({
model: "openai/gpt-oss-120b",
output: Output.object({ schema }),
prompt: getContent(parsed.data.prompt),
system: systemMessage,
providerOptions: {
gateway: {
order: ["cerebras"],
},
},
});

// Parse the result to ensure it matches one of the template options
const templateChoice = schema.parse(result.object);
const templateChoice = schema.parse(result.output);

return new Response(JSON.stringify({ template: templateChoice.template }), {
headers: { "Content-Type": "application/json" },
Expand Down
28 changes: 17 additions & 11 deletions api/prompt/convert.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { processRequest, reqSchema } from "./_shared";
import {
processRequest,
reqSchema,
systemMessageStyle,
systemMessageExample,
systemMessageSyntax,
systemMessagePitfalls,
} from "./_shared";

export const config = {
runtime: "edge",
};

const systemMessage = `You are the Flowchart Fun creation assistant. When I give you a document respond with a diagram in Flowchart Fun syntax. The Flowchart Fun syntax you use indentation to express a tree shaped graph. You use text before a colon to labels to edges. You link back to earlier nodes by referring to their label in parentheses. The following characters must be escaped when used in a node or edge label: (,:,#, and .\n\nYou can style nodes using classes at the end of a node. Available styles include:
- Colors: .color_blue, .color_red, .color_green, .color_yellow
- Shapes: .shape_circle, .shape_diamond, .shape_hexagon
const systemMessage = `You are the Flowchart Fun creation assistant. When I give you a document respond with a diagram in Flowchart Fun syntax.

${systemMessageSyntax}

${systemMessageStyle}

Here is a very simple graph illustrating the syntax:

Node A .color_blue
Node B .shape_circle
\\(Secret Node)
Node C .color_green
label from c to d: Node D .shape_diamond
label from d to a: (Node A)
${systemMessageExample}

${systemMessagePitfalls}

Note: Don't provide any explanation. Don't wrap your response in a code block.`;
Note: Don't provide any explanation. Don't wrap your response in a code block.`;

export default async function handler(req: Request) {
const body = await req.json();
Expand Down
14 changes: 11 additions & 3 deletions api/prompt/edit.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { processRequest, reqSchema } from "./_shared";
import {
processRequest,
reqSchema,
systemMessageStyle,
systemMessagePitfalls,
} from "./_shared";

export const config = {
runtime: "edge",
Expand All @@ -13,6 +18,8 @@ Flowchart Fun Syntax:
- Escape the following characters when used in a node or edge label: (,:,#, and \\.
- Use classes at the end of a node to apply styles. (e.g., .color_blue,.shape_circle)

${systemMessageStyle}

Example:
Node A
Node B .color_blue
Expand All @@ -21,6 +28,8 @@ Example:
label from c to d: Node D
label from d to a: (Node A)

${systemMessagePitfalls}

When editing, ensure that the Flowchart Fun syntax remains valid and consistent.`;

export default async function handler(req: Request) {
Expand All @@ -34,8 +43,7 @@ export default async function handler(req: Request) {
return processRequest(
req,
systemMessage,
getContent(parsed.data.prompt, parsed.data.document),
"gpt-4-turbo-2024-04-09"
getContent(parsed.data.prompt, parsed.data.document)
);
}

Expand Down
10 changes: 9 additions & 1 deletion api/prompt/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,26 @@ import {
reqSchema,
systemMessageExample,
systemMessageStyle,
systemMessageSyntax,
systemMessagePitfalls,
} from "./_shared";

export const config = {
runtime: "edge",
};

const systemMessage = `You are the Flowchart Fun creation assistant. When I give you a prompt, respond with a diagram in Flowchart Fun syntax. The Flowchart Fun syntax uses indentation to express a tree-shaped graph. Use text before a colon to label edges. Link back to earlier nodes by referring to their label in parentheses. The following characters must be escaped when used in a node or edge label: (,:,#, and .\n\n${systemMessageStyle}
const systemMessage = `You are the Flowchart Fun creation assistant. When I give you a prompt, respond with a diagram in Flowchart Fun syntax.

${systemMessageSyntax}

${systemMessageStyle}

Here is a very simple graph illustrating the syntax:

${systemMessageExample}

${systemMessagePitfalls}

Note: Don't provide any explanation. Don't wrap your response in a code block.`;

export default async function handler(req: Request) {
Expand Down
6 changes: 2 additions & 4 deletions app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "app",
"version": "1.63.1",
"version": "1.64.0",
"main": "module/module.js",
"license": "MIT",
"scripts": {
Expand Down Expand Up @@ -29,7 +29,6 @@
"screenshot-templates": "node scripts/screenshot-templates.mjs"
},
"dependencies": {
"@ai-sdk/openai": "^0.0.37",
"@formkit/auto-animate": "1.0.0-beta.6",
"@lingui/core": "^3.8.9",
"@lingui/react": "^3.8.9",
Expand Down Expand Up @@ -61,7 +60,6 @@
"@svgr/webpack": "^6.3.1",
"@tone-row/slang": "^1.2.35",
"@tone-row/strip-comments": "^2.0.1",
"ai": "^3.2.32",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"construct-style-sheets-polyfill": "^3.1.0",
Expand Down Expand Up @@ -94,7 +92,7 @@
"monaco-editor": "0.33.0",
"moniker": "^0.1.2",
"notion-to-md": "^2.5.5",
"openai": "^3.2.1",
"openai": "3.2.1",
"pako": "^2.1.0",
"papaparse": "^5.4.1",
"phosphor-react": "^1.3.1",
Expand Down
Binary file added app/public/pricing-screenshots/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/public/pricing-screenshots/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/public/pricing-screenshots/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/public/pricing-screenshots/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/public/template-screenshots/playful-mindmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/public/template-screenshots/thumb_playful-mindmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading