From f4a42dbd2457d263bab930f54ed13bf1dce9abbb Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Tue, 30 May 2023 00:23:08 +0100 Subject: [PATCH 1/4] add code to generate html pages. --- IntelliNode/function/Gen.js | 24 +++++++++++++++++- IntelliNode/function/TextAnalyzer.js | 4 +-- .../resource/templates/html_page_prompt.in | 14 ++++++++++ .../sentiment_prompt.in} | 0 .../summary_prompt.in} | 0 IntelliNode/test/Gen.test.js | 19 +++++++++++++- IntelliNode/utils/SystemHelper.js | 20 +++++++++------ images/model_output/register-page.png | Bin 0 -> 42777 bytes 8 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 IntelliNode/resource/templates/html_page_prompt.in rename IntelliNode/resource/{systems/sentiment_system.in => templates/sentiment_prompt.in} (100%) rename IntelliNode/resource/{systems/summary_system.in => templates/summary_prompt.in} (100%) create mode 100644 images/model_output/register-page.png diff --git a/IntelliNode/function/Gen.js b/IntelliNode/function/Gen.js index 914e0b6..f86cb1d 100644 --- a/IntelliNode/function/Gen.js +++ b/IntelliNode/function/Gen.js @@ -6,7 +6,8 @@ const ImageModelInput = require("../model/input/ImageModelInput"); const Text2SpeechInput = require("../model/input/Text2SpeechInput"); const { Chatbot, SupportedChatModels } = require("../function/Chatbot"); const { ChatGPTInput, ChatGPTMessage } = require("../model/input/ChatModelInput"); - +const SystemHelper = require("../utils/SystemHelper"); +const fs = require('fs'); class Gen { static async get_marketing_desc(prompt, openaiKey) { @@ -53,6 +54,27 @@ class Gen { const audioContent = await speechModel.generateSpeech(input); return audioContent; } + + static async generate_html_page(text, openaiKey) { + // load and fill the template + const promptTemplate = new SystemHelper().loadPrompt("html_page"); + const prompt = promptTemplate.replace("${text}", text); + + // prepare the bot + const chatbot = new Chatbot(openaiKey); + const input = new ChatGPTInput('generate only html, css and javascript based on the user request in the following format {"html": "", "message":""}', + { maxTokens: 2000, model: 'gpt-4' }); + // set the user message with the template + input.addUserMessage(prompt); + const responses = await chatbot.chat(input); + return JSON.parse(responses[0].trim()); + } + + static async save_html_page(text, folder, file_name, openaiKey) { + const htmlCode = await Gen.generate_html_page(text, openaiApiKey); + fs.writeFileSync(`${folder}/${file_name}.html`, htmlCode["html"]); + } + } module.exports = { Gen }; \ No newline at end of file diff --git a/IntelliNode/function/TextAnalyzer.js b/IntelliNode/function/TextAnalyzer.js index f575dc1..ed42fc2 100644 --- a/IntelliNode/function/TextAnalyzer.js +++ b/IntelliNode/function/TextAnalyzer.js @@ -24,7 +24,7 @@ class TextAnalyzer { } async summarize(text, options = {}) { - const summaryPromptTemplate = this.systemHelper.loadSystem("summary"); + const summaryPromptTemplate = this.systemHelper.loadPrompt("summary"); const prompt = summaryPromptTemplate.replace("${text}", text); const modelInput = new LanguageModelInput({ prompt, @@ -37,7 +37,7 @@ class TextAnalyzer { } async sentimentAnalysis(text, options = {}) { - const mode = this.systemHelper.loadSystem("sentiment"); + const mode = this.systemHelper.loadPrompt("sentiment"); const prompt = `${mode}\n\nAnalyze the sentiment of the following text: ${text}\n\nSentiment: `; const modelInput = new LanguageModelInput({ diff --git a/IntelliNode/resource/templates/html_page_prompt.in b/IntelliNode/resource/templates/html_page_prompt.in new file mode 100644 index 0000000..178f438 --- /dev/null +++ b/IntelliNode/resource/templates/html_page_prompt.in @@ -0,0 +1,14 @@ +Generate website, javascript and css in one page based on the user request. + +Output example: +{"html": "....", "message"":"the page ready for render"} + +Output example for unrelated request: +{"html": "", "message":"the request does not fit in one page"} + +If an image generated, add the image description in alt to use for image generation using DALL·E 2: +<image description to use with DALL·E 2> + +user request: ${text} + +output: \ No newline at end of file diff --git a/IntelliNode/resource/systems/sentiment_system.in b/IntelliNode/resource/templates/sentiment_prompt.in similarity index 100% rename from IntelliNode/resource/systems/sentiment_system.in rename to IntelliNode/resource/templates/sentiment_prompt.in diff --git a/IntelliNode/resource/systems/summary_system.in b/IntelliNode/resource/templates/summary_prompt.in similarity index 100% rename from IntelliNode/resource/systems/summary_system.in rename to IntelliNode/resource/templates/summary_prompt.in diff --git a/IntelliNode/test/Gen.test.js b/IntelliNode/test/Gen.test.js index 15cca5c..4aabddb 100644 --- a/IntelliNode/test/Gen.test.js +++ b/IntelliNode/test/Gen.test.js @@ -1,6 +1,7 @@ -const Gen = require("../function/Gen"); +const { Gen } = require("../function/Gen"); require("dotenv").config(); const assert = require("assert"); +const fs = require('fs'); const openaiApiKey = process.env.OPENAI_API_KEY; @@ -35,9 +36,25 @@ async function testGenerateSpeechSynthesis() { assert(speech.length > 0, "Test passed"); } + +async function testGenerateHtmlPage() { + const tempDir = '../temp'; + if (!fs.existsSync(tempDir)) { + fs.mkdirSync(tempDir); + } + + const text = "a registration page with flat modern theme."; + const htmlCode = await Gen.generate_html_page(text, openaiApiKey); + + fs.writeFileSync(`${tempDir}/generated_page_test.html`, htmlCode["html"]); + + assert(htmlCode["html"].length > 0, "Test passed"); +} + (async () => { await testGetMarketingDesc(); await testGetBlogPost(); await testGenerateImageFromDesc(); await testGenerateSpeechSynthesis(); + await testGenerateHtmlPage(); })(); \ No newline at end of file diff --git a/IntelliNode/utils/SystemHelper.js b/IntelliNode/utils/SystemHelper.js index a5b2a0f..8c83f12 100644 --- a/IntelliNode/utils/SystemHelper.js +++ b/IntelliNode/utils/SystemHelper.js @@ -3,18 +3,22 @@ const path = require("path"); class SystemHelper { constructor() { - this.systemsPath = path.join(__dirname, "..", "resource", "systems"); + this.systemsPath = path.join(__dirname, "..", "resource", "templates"); } - loadSystem(file_type) { + loadPrompt(file_type) { if (file_type === "sentiment") { - const sentimentSystemPath = path.join(this.systemsPath, "sentiment_system.in"); - const sentimentSystem = fs.readFileSync(sentimentSystemPath, "utf8"); - return sentimentSystem; + const sentimentSystemPath = path.join(this.systemsPath, "sentiment_prompt.in"); + const promptTemplate = fs.readFileSync(sentimentSystemPath, "utf8"); + return promptTemplate; } else if (file_type === "summary") { - const summarySystemPath = path.join(this.systemsPath, "summary_system.in"); - const summarySystem = fs.readFileSync(summarySystemPath, "utf8"); - return summarySystem; + const summarySystemPath = path.join(this.systemsPath, "summary_prompt.in"); + const promptTemplate = fs.readFileSync(summarySystemPath, "utf8"); + return promptTemplate; + } else if (file_type === "html_page") { + const promptPath = path.join(this.systemsPath, "html_page_prompt.in"); + const promptTemplate = fs.readFileSync(promptPath, "utf8"); + return promptTemplate; } else { throw new Error(`File type '${file_type}' not supported`); } diff --git a/images/model_output/register-page.png b/images/model_output/register-page.png new file mode 100644 index 0000000000000000000000000000000000000000..5b2d846cb57c6b299474dbef3bafc5b399f4732a GIT binary patch literal 42777 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 Date: Tue, 30 May 2023 00:44:07 +0100 Subject: [PATCH 2/4] prepare for publish --- IntelliNode/README.md | 17 +++++++++-------- IntelliNode/function/Gen.js | 7 +++++-- IntelliNode/package.json | 2 +- IntelliNode/test/Gen.test.js | 8 +++++++- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/IntelliNode/README.md b/IntelliNode/README.md index be2e101..aaa49f5 100644 --- a/IntelliNode/README.md +++ b/IntelliNode/README.md @@ -39,7 +39,6 @@ const { SemanticSearch } = require('intellinode'); ```js const search = new SemanticSearch(apiKey); // pivotItem: item to search. -// searchArray: array of strings to search through. const results = await search.getTopMatches(pivotItem, searchArray, numberOfMatches); const filteredArray = search.filterTopMatches(results, searchArray) ``` @@ -50,14 +49,16 @@ const { Gen } = require('intellinode'); ``` 2. call: ```js -// one line to generate marketing description -const marketingDesc = await Gen.get_marketing_desc('gaming chair', openaiApiKey); - -// or one line to generate blog post +// one line to generate blog post const blogPost = await Gen.get_blog_post(prompt, openaiApiKey); - -// or generate images from production description -const image = await Gen.generate_image_from_desc(prompt, openaiApiKey, stabilityApiKey, true); +``` +```js +// or generate images from description +const image = await Gen.generate_image_from_desc(prompt, openaiApiKey, stabilityApiKey); +``` +```js +// or generate html page code +await Gen.save_html_page(text, folder, file_name, openaiKey); ``` ## Models Access diff --git a/IntelliNode/function/Gen.js b/IntelliNode/function/Gen.js index f86cb1d..438e98a 100644 --- a/IntelliNode/function/Gen.js +++ b/IntelliNode/function/Gen.js @@ -8,6 +8,7 @@ const { Chatbot, SupportedChatModels } = require("../function/Chatbot"); const { ChatGPTInput, ChatGPTMessage } = require("../model/input/ChatModelInput"); const SystemHelper = require("../utils/SystemHelper"); const fs = require('fs'); +const path = require('path'); class Gen { static async get_marketing_desc(prompt, openaiKey) { @@ -71,8 +72,10 @@ class Gen { } static async save_html_page(text, folder, file_name, openaiKey) { - const htmlCode = await Gen.generate_html_page(text, openaiApiKey); - fs.writeFileSync(`${folder}/${file_name}.html`, htmlCode["html"]); + const htmlCode = await Gen.generate_html_page(text, openaiKey); + const folderPath = path.join(folder, file_name + '.html'); + fs.writeFileSync(folderPath, htmlCode['html']); + return true; } } diff --git a/IntelliNode/package.json b/IntelliNode/package.json index 8e2e6e0..c166ea1 100644 --- a/IntelliNode/package.json +++ b/IntelliNode/package.json @@ -1,6 +1,6 @@ { "name": "intellinode", - "version": "0.0.18", + "version": "0.0.19", "description": "Access various AI models, such as ChatGPT, Diffusion, Cohere, Google, and others", "main": "index.js", "keywords": ["AI", "ChatGPT", "GPT4", "stable diffusion", "openai", "huggingface", "language models", "image generation", "speech synthesis", "semantic search"], diff --git a/IntelliNode/test/Gen.test.js b/IntelliNode/test/Gen.test.js index 4aabddb..39ef1d9 100644 --- a/IntelliNode/test/Gen.test.js +++ b/IntelliNode/test/Gen.test.js @@ -3,7 +3,6 @@ require("dotenv").config(); const assert = require("assert"); const fs = require('fs'); - const openaiApiKey = process.env.OPENAI_API_KEY; const stabilityApiKey = process.env.STABILITY_API_KEY; const googleApiKey = process.env.GOOGLE_API_KEY; @@ -51,10 +50,17 @@ async function testGenerateHtmlPage() { assert(htmlCode["html"].length > 0, "Test passed"); } +async function testSaveHTML() { + prompt = "a registration page with flat modern theme." + status = await Gen.save_html_page(prompt, folder='../temp', file_name='test_register', openaiKeyclea=openaiApiKey); + assert.strictEqual(status, true, "Test passed"); +} + (async () => { await testGetMarketingDesc(); await testGetBlogPost(); await testGenerateImageFromDesc(); await testGenerateSpeechSynthesis(); await testGenerateHtmlPage(); + await testSaveHTML(); })(); \ No newline at end of file From b0822e6f7737e2120c47bc618e79e4281a3bcc5c Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Tue, 30 May 2023 00:44:57 +0100 Subject: [PATCH 3/4] update the example --- IntelliNode/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/IntelliNode/README.md b/IntelliNode/README.md index aaa49f5..1eef947 100644 --- a/IntelliNode/README.md +++ b/IntelliNode/README.md @@ -58,6 +58,7 @@ const image = await Gen.generate_image_from_desc(prompt, openaiApiKey, stability ``` ```js // or generate html page code +text = 'a registration page with flat modern theme.' await Gen.save_html_page(text, folder, file_name, openaiKey); ``` From 58128f9e9b80ffaba138452ce8cbd9aa401f1374 Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Tue, 30 May 2023 00:48:26 +0100 Subject: [PATCH 4/4] update readme examples --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bf70a50..015958e 100644 --- a/README.md +++ b/README.md @@ -120,11 +120,13 @@ const { Gen } = require('intellinode'); ``` call: ```js -// one line to generate marketing description -const marketingDesc = await Gen.get_marketing_desc('gaming chair', openaiApiKey); - -// or generate images from products description -const image = await Gen.generate_image_from_desc(prompt, openaiApiKey, stabilityApiKey, true); +// one line to generate blog post +const blogPost = await Gen.get_blog_post(prompt, openaiApiKey); +``` +```js +// or generate html page code +text = 'a registration page with flat modern theme.' +await Gen.save_html_page(text, folder, file_name, openaiKey); ``` For more examples, check [the samples](https://github.com/Barqawiz/IntelliNode/tree/main/samples/command_sample).