Skip to content

Commit

Permalink
improved code generation for gpt-4-turbo
Browse files Browse the repository at this point in the history
  • Loading branch information
jbilcke committed Apr 3, 2024
1 parent 3be5f7d commit 5f171b8
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
15 changes: 14 additions & 1 deletion src/engine/prompts/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,27 @@ ${instructions.script.map((instruction) => `- ${instruction}`).join('\n')}
Code formatting rules:
- we use 1 space for indentation
- code is compressed, all JS variables have maximum 3 characters
- we must store everything in appData, so please begin your code with \`var app = window.appData || {};\`
- this is not a tutorial or a demo, but the final project
Here is the current page structure:
\`\`\`html
${
// to save space, we only give essential info to the model
DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['div', 'button', 'canvas'],
ALLOWED_ATTR: ['classname', 'id', 'width', 'height'],
}).replace(/(^[ \t]*\n)/gm, '') // remove all empty lines, too
}<script>var app={};`
}
<script>
window.appData = {};
</script>
\`\`\`
Your turn! (remember we want the FINAL version)
# Output
\`\`\`javascript
`

export const scriptPrompt = genericScript('appData')
2 changes: 1 addition & 1 deletion src/engine/prompts/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Brief: A startup website called Aisy about a new cool SaaS product for creators
Spec: {
"summary": "Website of startup called Aisy, selling an AI tool for making movies",
"layout": "A classic SaaS product launch page, with a header section, a main content section, and a footer",
"art direction": "The design is fresh and sleek, with a sans serif font abd original colors on the theme of AI and movies (purple, black, grey, red)",
"art direction": "The design is fresh and sleek, with a sans serif font and original colors on the theme of AI and movies (purple, black, grey, red)",
"text content": "Page contains marketing content to explain why people should use Aisy to generate movies. Text is concise and to the point, with punch lines for titles. It should make us wish we purchased the product.",
"interactivity": "no javascript needed",
"js modules": "no library available",
Expand Down
49 changes: 35 additions & 14 deletions src/providers/openai/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,19 @@ export const imagineHTML = async (
return mocks.html
}

const raw = await imagineString(prompt, presets.html, model, apiKey)
let raw = await imagineString(prompt, presets.html, model, apiKey)

raw = raw
.replaceAll("```html\n", "")
.replaceAll("```html", "")

console.log('imagineHTML> raw:', raw)
// we remove everything after the last ```
raw = raw.split('```')[0].trim()

// const toStrip = `<div ${raw}`
const toStrip = `${raw}`

const toStrip = `<div ${raw}`
console.log('imagineHTML> raw:', raw)

// we don't care about hallucinated image src
const toPurify = toStrip.replace(/src="[^"]+/g, 'src="')
Expand Down Expand Up @@ -122,23 +130,32 @@ Object.values(libraries).map(({ prod }) => prod).join('\n')
window.appData = {};
${output}`.trim()
*/
let script = `<script>
window.appData = {};
var app = window.appData;
${output}`.trim()
// for some reason the LLM sometimes generates JS code with ‘ instead of '
script = script.replace('‘', "'")

// for some reason the LLM sometimes believe it is in a Markdown file
// so we remove this extra garbage
script = script.split('```')[0].trim()
let script = `${output}`.trim()

// we remove all the output markdown
script = script
.replaceAll('```html\n', '')
.replaceAll('```html', '')
.replaceAll('```javascript\n', '')
.replaceAll('```javascript\n', '')
.replaceAll('```javascript', '')

// for some reason the LLM sometimes generates JS code with ‘ instead of '
.replaceAll('‘', "'")

// we remove everything after the last ```
script = (script.split('```').shift() || "").trim()

if (!script.startsWith('<script>')) {
script = `<script>${script}`
}
// it is imperative that we ignore everything that might have been added after the main script
script = (script.split('</script>').shift() || "").trim()

// todo: should be done in a better way
if (!script.endsWith('</script>')) {
script += '</script>'
script = `${script}</script>`
}

return script
Expand Down Expand Up @@ -176,14 +193,18 @@ export const imagineJSON = async <T>(
.replaceAll("[```json", "")
.replaceAll("{{```json", "")
.replaceAll("{```json", "")
.replaceAll("```json\n", "")
.replaceAll("```json", "")
.replaceAll("[[```", "")
.replaceAll("[```", "")
.replaceAll("{{```", "")
.replaceAll("{```", "")
.replaceAll("{json", "")
.replaceAll("[json", "")
.replaceAll("```", "")

// we remove everything after the last ```
raw = raw.split('```')[0].trim()

// try to fix the LLM adding commas at the end of each line
const regex = /\,(?!\s*?[\{\[\"\'\w])/g
const input = raw.replace(regex, '')
Expand Down

0 comments on commit 5f171b8

Please sign in to comment.