Skip to content

Commit 7d5dae3

Browse files
committed
prompt looks good
1 parent 14ea593 commit 7d5dae3

File tree

6 files changed

+664
-59
lines changed

6 files changed

+664
-59
lines changed

dist/api.js

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,61 @@
11
import express from 'express';
22
import fetch from 'node-fetch';
3+
import { JSDOM } from 'jsdom';
34
import dotenv from 'dotenv';
45
// import { askGPT, initGPT } from './gpt.js';
5-
import { initOpenAI, askOpenAI } from './openai.js';
6+
import { initOpenAI, askOpenAI, manifestPrompt } from './openai.js';
67
dotenv.config();
78
const app = express();
89
const port = process.env.PORT || 3000;
910
app.use(express.json());
10-
let GPTSesion = null;
11+
let OpenAISesion = null;
1112
app.get('/initAPI', async (req, res) => {
12-
GPTSesion = await initOpenAI();
13-
if (GPTSesion) {
14-
res.status(200).send({ message: 'GPT initialized' });
13+
OpenAISesion = await initOpenAI();
14+
if (OpenAISesion) {
15+
res.status(200).send({ message: 'LLM initialized' });
1516
}
1617
else {
17-
GPTSesion = null;
18-
res.status(500).send({ error: 'GPT unavailable' });
18+
OpenAISesion = null;
19+
res.status(500).send({ error: 'LLM unavailable' });
1920
}
2021
});
2122
app.get('/generateManifest', async (req, res) => {
2223
if (!req.query.url) {
2324
res.status(400).send({ error: 'URL not specified' });
2425
return;
2526
}
26-
const request = await fetch(req.query.url.toString());
27+
if (!OpenAISesion) {
28+
res.status(500).send({ error: 'API not initialized' });
29+
return;
30+
}
31+
const request = await fetch(req.query.url.toString(), {
32+
headers: {
33+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
34+
}
35+
});
2736
let rawHTML = await request.text();
2837
let headerHTML;
2938
if (typeof rawHTML === 'string') {
3039
rawHTML = rawHTML.replace(/\r|\n/g, '').replace(/\s{2,}/g, '');
31-
headerHTML = /<head>(.*)<\/head>/.test(rawHTML) ? rawHTML.match(/<head>(.*)<\/head>/)[0] : 'Head not found';
40+
headerHTML = /<head>(.*)<\/head>/.test(rawHTML) ? rawHTML.match(/<head>(.*)<\/head>/)[0] : null;
3241
}
33-
if (!GPTSesion) {
34-
res.status(500).send({ error: 'API not initialized' });
42+
if (!headerHTML) {
43+
res.status(400).send({ error: '<head> HTML not found' });
3544
return;
3645
}
37-
if (headerHTML) {
38-
const manifest = await askOpenAI(headerHTML, GPTSesion);
39-
if (manifest) {
40-
res.status(200).send({ manifest });
41-
}
42-
else
43-
res.status(400).send({ error: 'GPT unavailable or failed to generate manifest' });
44-
}
45-
else {
46-
res.status(400).send({ error: '<head> HTML not found' });
46+
console.log(`HEAD: ${headerHTML}`);
47+
const document = new JSDOM(headerHTML).window.document;
48+
document.querySelectorAll('script').forEach((script) => script?.remove?.());
49+
document.querySelectorAll('style').forEach((style) => style?.remove?.());
50+
document.querySelectorAll('meta[http-equiv="origin-trial"],meta[http-equiv="content-type"],meta[name="google-site-verification"]').forEach((meta) => meta?.remove?.());
51+
document.querySelectorAll('link[rel="stylesheet"],link[rel="modulepreload"],link[rel="preload"],link[rel="dns-prefetch"],link[rel="preload"]').forEach((link) => link?.remove?.());
52+
const preparedHTML = document.head.innerHTML.replace(/&amp;|&{2,}|<!--|-->/g, '');
53+
const manifest = await askOpenAI(manifestPrompt(preparedHTML), OpenAISesion);
54+
if (manifest) {
55+
res.status(200).send({ manifest });
4756
}
57+
else
58+
res.status(400).send({ error: 'LLM unavailable or failed to generate manifest' });
4859
});
4960
app.post('/generateWinPackage', async (req, res) => {
5061
return;

dist/openai.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,27 @@ export async function initOpenAI() {
55
});
66
return new OpenAIApi(configuration);
77
}
8+
export function manifestPrompt(html) {
9+
const prompt = `INSTRUCTION
10+
parse this html and generate web manifest with this string properties: lang,name[max lenght 45],short_name[max lenght 12],description[max lenght 160],background_color[hex],dir,display,orientation,scope,start_url,theme_color[hex]. And array properties: categories[max lenght 3],icons[max lenght 1]. Take all information and icons from html, use only biggest icon in array of icons.
11+
HTML
12+
${html}
13+
OUTPUT FILE
14+
web app manifests in JSON format no new line or return symbols, compact: <code>`;
15+
return prompt;
16+
}
817
export async function askOpenAI(prompt, openai) {
9-
let gptAnswer = null;
18+
let davinciAnswer = null;
19+
console.log(`prompt: ${prompt}`);
1020
try {
1121
const completion = await openai.createCompletion({
12-
model: "text-davinci-003",
13-
prompt: `parse this html and generate web manifest in JSON format, silent answer with no comments or explains. Take all information and icons from html tags, use only one biggest icon in array of icons. ${prompt}`,
14-
temperature: 0.6,
22+
model: "code-davinci-002",
23+
prompt,
24+
temperature: 0.1,
25+
max_tokens: 256,
1526
});
16-
gptAnswer = completion.data;
17-
console.warn(gptAnswer);
27+
davinciAnswer = completion.data;
28+
console.log(`answer: ${JSON.stringify(davinciAnswer)}`);
1829
}
1930
catch (error) {
2031
if (error?.response) {
@@ -25,10 +36,12 @@ export async function askOpenAI(prompt, openai) {
2536
}
2637
}
2738
let manifest = null;
28-
if (gptAnswer && gptAnswer.choices[0].text)
39+
if (davinciAnswer?.choices && davinciAnswer.choices[0]?.text) {
40+
const restoredResponse = `<code>${davinciAnswer.choices[0].text}`;
2941
try {
30-
manifest = JSON.parse(gptAnswer.choices[0].text);
42+
manifest = JSON.parse(restoredResponse.match(/<code>(.*)<\/code>/)[1]);
3143
}
3244
catch (error) { }
45+
}
3346
return manifest;
3447
}

0 commit comments

Comments
 (0)