Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom OpenAI base URL and switch to base64 URL encod… #72

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
21 changes: 21 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## 这是一个使用 tldraw 和 gpt-4-vision API 来根据你绘制的线框生成 HTML 的应用程序。

我目前正在开发一个托管版本的 draw-a-ui。你可以在 draw-a-ui.com 加入等待名单。它的核心将始终是开源的,并在这里提供。

## 应用程序演示

这个应用程序通过将当前画布的 SVG 转换为 PNG,并将该 PNG 发送给 gpt-4-vision,并指示返回一个带有 tailwind 的单个 HTML 文件来工作。

免责声明:这是一个演示,不适用于生产环境。它没有任何授权,所以如果你部署它,你会破产。

## 入门
这是一个 Next.js 应用程序。要开始,请在项目根目录运行以下命令。你将需要一个具有 GPT-4 Vision API 访问权限的 OpenAI API 密钥。

注意这使用 Next.js 14,需要 node 版本高于 18.17。在此了解更多。

```bash
echo "OPENAI_API_KEY=sk-your-key" > .env.local
npm install
npm run dev
```
在浏览器中打开 http://localhost:3000 查看结果。
25 changes: 22 additions & 3 deletions app/api/toHtml/route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import axios from 'axios';

const systemPrompt = `You are an expert tailwind developer. A user will provide you with a
low-fidelity wireframe of an application and you will return
a single html file that uses tailwind to create the website. Use creative license to make the application more fleshed out.
if you need to insert an image, use placehold.co to create a placeholder image. Respond only with the html file.`;


async function encodeImageFromUrl(imageUrl: string): Promise<string> {
const response = await axios.get(imageUrl, { responseType: 'arraybuffer' });
if (response.status !== 200) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const base64 = Buffer.from(response.data, 'binary').toString('base64');
return base64;
}


export async function POST(request: Request) {
const { image } = await request.json();
const imageBase64 = await encodeImageFromUrl(image);
console.log(imageBase64);
const body: GPT4VCompletionRequest = {
model: "gpt-4-vision-preview",
max_tokens: 4096,
Expand All @@ -18,17 +33,21 @@ export async function POST(request: Request) {
content: [
{
type: "image_url",
image_url: { url: image, detail: "high" },
image_url: { url: 'data:image/jpeg;base64,'+imageBase64, detail: "high" },
},
{
type: "text",
text: "Turn this into a single html file using tailwind.",
},
"Turn this into a single html file using tailwind.",

],
},
],
};

let json = null;
try {
const resp = await fetch("https://api.openai.com/v1/chat/completions", {
const resp = await fetch(process.env.OPENAI_BASE_URL+"/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Expand Down
91 changes: 91 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"dependencies": {
"@tldraw/tldraw": "2.0.0-alpha.17",
"axios": "^1.6.2",
"canvas-size": "^1.2.6",
"next": "14.0.1",
"prismjs": "^1.29.0",
Expand Down