|
| 1 | +const systemPrompt = `You are an expert web developer who specializes in tailwind css. |
| 2 | +A user will provide you with a low-fidelity wireframe of an application. |
| 3 | +You will return a single html file that uses HTML, tailwind css, and JavaScript to create a high fidelity website. |
| 4 | +Include any extra CSS and JavaScript in the html file. |
| 5 | +If you have any images, load them from Unsplash or use solid colored retangles. |
| 6 | +The user will provide you with notes in blue or red text, arrows, or drawings. |
| 7 | +The user may also include images of other websites as style references. Transfer the styles as best as you can, matching fonts / colors / layouts. |
| 8 | +They may also provide you with the html of a previous design that they want you to iterate from. |
| 9 | +Carry out any changes they request from you. |
| 10 | +In the wireframe, the previous design's html will appear as a white rectangle. |
| 11 | +Use creative license to make the application more fleshed out. |
| 12 | +Use JavaScript modules and unpkg to import any necessary dependencies. |
| 13 | +
|
| 14 | +Respond ONLY with the contents of the html file.` |
| 15 | + |
| 16 | +export async function POST(request: Request) { |
| 17 | + const { image, html, apiKey } = await request.json() |
| 18 | + const body: GPT4VCompletionRequest = { |
| 19 | + model: 'gpt-4-vision-preview', |
| 20 | + max_tokens: 4096, |
| 21 | + temperature: 0, |
| 22 | + messages: [ |
| 23 | + { |
| 24 | + role: 'system', |
| 25 | + content: systemPrompt, |
| 26 | + }, |
| 27 | + { |
| 28 | + role: 'user', |
| 29 | + content: [ |
| 30 | + { |
| 31 | + type: 'image_url', |
| 32 | + image_url: { |
| 33 | + url: image, |
| 34 | + detail: 'high', |
| 35 | + }, |
| 36 | + }, |
| 37 | + { |
| 38 | + type: 'text', |
| 39 | + text: 'Turn this into a single html file using tailwind.', |
| 40 | + }, |
| 41 | + { |
| 42 | + type: 'text', |
| 43 | + text: html, |
| 44 | + }, |
| 45 | + ], |
| 46 | + }, |
| 47 | + ], |
| 48 | + } |
| 49 | + |
| 50 | + let json = null |
| 51 | + try { |
| 52 | + const resp = await fetch('https://api.openai.com/v1/chat/completions', { |
| 53 | + method: 'POST', |
| 54 | + headers: { |
| 55 | + 'Content-Type': 'application/json', |
| 56 | + Authorization: `Bearer ${apiKey ? apiKey : process.env.OPENAI_API_KEY}`, |
| 57 | + }, |
| 58 | + body: JSON.stringify(body), |
| 59 | + }) |
| 60 | + json = await resp.json() |
| 61 | + } catch (e) { |
| 62 | + console.log(e) |
| 63 | + } |
| 64 | + |
| 65 | + return new Response(JSON.stringify(json), { |
| 66 | + headers: { |
| 67 | + 'content-type': 'application/json; charset=UTF-8', |
| 68 | + }, |
| 69 | + }) |
| 70 | +} |
| 71 | + |
| 72 | +type MessageContent = |
| 73 | + | string |
| 74 | + | ( |
| 75 | + | string |
| 76 | + | { |
| 77 | + type: 'image_url' |
| 78 | + image_url: |
| 79 | + | string |
| 80 | + | { |
| 81 | + url: string |
| 82 | + detail: 'low' | 'high' | 'auto' |
| 83 | + } |
| 84 | + } |
| 85 | + | { |
| 86 | + type: 'text' |
| 87 | + text: string |
| 88 | + } |
| 89 | + )[] |
| 90 | + |
| 91 | +export type GPT4VCompletionRequest = { |
| 92 | + model: 'gpt-4-vision-preview' |
| 93 | + messages: { |
| 94 | + role: 'system' | 'user' | 'assistant' | 'function' |
| 95 | + content: MessageContent |
| 96 | + name?: string | undefined |
| 97 | + }[] |
| 98 | + functions?: any[] | undefined |
| 99 | + function_call?: any | undefined |
| 100 | + stream?: boolean | undefined |
| 101 | + temperature?: number | undefined |
| 102 | + top_p?: number | undefined |
| 103 | + max_tokens?: number | undefined |
| 104 | + n?: number | undefined |
| 105 | + best_of?: number | undefined |
| 106 | + frequency_penalty?: number | undefined |
| 107 | + presence_penalty?: number | undefined |
| 108 | + logit_bias?: |
| 109 | + | { |
| 110 | + [x: string]: number |
| 111 | + } |
| 112 | + | undefined |
| 113 | + stop?: (string[] | string) | undefined |
| 114 | +} |
0 commit comments