Implement GUI for NodeJS+Gemini

This article can be read in about 9 minutes.
PR

The purpose 

In the article below, I enabled the use of Gemini with NodeJS.

However, since it lacks a GUI, it’s completely impractical, so I will implement one.

PR

Review

Here is the HTML I created last time.

<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Gemini</title>
 </head>
 <body>
    <script type="module" src="main.js"></script>
 </body>
</html>

JS is below.

let api_key = "Your API key"

import { GoogleGenerativeAI } from "@google/generative-ai";

const genAI = new GoogleGenerativeAI(api_key);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

const prompt = "GoogleのAIのGeminiに関して教えて。";

const result = await model.generateContent(prompt);
console.log(result.response.text());
PR

Implementation

Implement input

The following will be added to the HTML <body> tag to enable text input.

    <div>
        <label>INPUT: </label>
        <input type="text" id="input" size="100" />
    </div>
    <div>
        <button id="run">実行</button>
    </div>

In JavaScript, when the ‘Execute’ button (created above) is clicked, the prompt will be passed to the AI.

import { GoogleGenerativeAI } from "@google/generative-ai";

//Initialize
const genAI = new GoogleGenerativeAI(api_key);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

//create reply when the button is clicked
async function generateReply(){
    const prompt = document.getElementById("input").value;
    const result = await model.generateContent(prompt);
    console.log(result.response.text());
} 

//register method to click
document.getElementById("run").onclick = () => generateReply();

Implement output

The following will be added to the HTML <body> tag to create an area for displaying the output.

    <div id = output>
    </div>

In JavaScript, the reply created above will be displayed in the area above.

    //console.log(result.response.text());  //remove    
    document.getElementById("output").innerHTML = (result.response.text());  //add

Support Markdown

The current implementation works minimally, but the output isn’t formatted as expected, as shown below.

This is because the output is in Markdown format.

Here, we use the unified library to convert to and display HTML.

GitHub - unifiedjs/unified: ☔️ interface for parsing, inspecting, transforming, and serializing content through syntax trees
☔️ interface for parsing, inspecting, transforming, and serializing content through syntax trees - unifiedjs/unified

Install unified

Execute the following command to install the modules used with unified.

npm install unified
npm install remark-parse
npm install remark-rehype
npm install rehype-stringify

convert Markdown to HTML

Import modules.

import { unified } from 'unified';
import remarkParse from 'remark-parse'
import remark2rehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify';

The result.response.text(), which contains Markdown as shown below, is being converted to HTML using processor.processSync.

    const result = await model.generateContent(prompt);
    
    //add start
    const processor = unified().use(remarkParse).use(remark2rehype).use(rehypeStringify); //define process "parse markdown" → "convert to HTML" → "build"
    const html = processor.processSync(result.response.text());//convert
    //add end

    //document.getElementById("output").innerHTML = (result.response.text());  //remove
    document.getElementById("output").innerHTML = (html.value);//add
PR

Result

We are able to input text, get output from Gemini, and display it. 

PR

All code

index.tml

<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Gemini</title>
 </head>
 <body>
    <div>
        <label>INPUT: </label>
        <input type="text" id="input" size="100" />
    </div>
    <div>
        <button id="run">実行</button>
    </div>
    <script type="module" src="main.js"></script>
    <br>
    <div id = output>
    </div>
 </body>
</html>

main.js

let api_key = "Your API key"

import { GoogleGenerativeAI } from "@google/generative-ai";
import { unified } from 'unified';
import remarkParse from 'remark-parse'
import remark2rehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify';

const genAI = new GoogleGenerativeAI(api_key);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

async function generateReply(){
    const prompt = document.getElementById("input").value;
    const result = await model.generateContent(prompt);
    
    const processor = unified().use(remarkParse).use(remark2rehype).use(rehypeStringify); 
    const html = processor.processSync(result.response.text());

    document.getElementById("output").innerHTML = (html.value);
} 

document.getElementById("run").onclick = () => generateReply();
PR

Reference

GitHub - unifiedjs/unified: ☔️ interface for parsing, inspecting, transforming, and serializing content through syntax trees
☔️ interface for parsing, inspecting, transforming, and serializing content through syntax trees - unifiedjs/unified
unified.jsでMarkdownをHTMLに変換する - Qiita
unified.jsはAST(抽象構文木)を使いテキストフォーマットを変換できるライブラリです。remark(Markdown)、rehype(HTML)、retext(自然言語)といったフォーマ…

comment

Copied title and URL