This Node.js script uses a large language model (LLM) to generate code blocks for a project by fetching code from the LLM and extracting relevant blocks. The script handles errors, resolves GitHub repository and notebook file paths, executes a git pull
command, and logs the generated code blocks to the console.
npm run import -- "add llm code cell"
const fs = require('fs')
const path = require('path')
const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || '';
const { spawnSync } = require('child_process')
async function makeCell(prompt, notebookFile, github) {
const llmCode = await importer.import("llm code")
if (!github) {
console.error('Project not specified.')
return
}
// TODO: local pull
if (!fs.existsSync(github)
&& fs.existsSync(path.join(PROFILE_PATH, github))) {
github = path.join(PROFILE_PATH, github)
}
if (github.includes('://')
&& fs.existsSync(path.basename(github).replace('.git', ''))
) {
github = path.join(PROFILE_PATH, path.basename(github).replace('.git', ''))
}
if (!fs.existsSync(github)) {
console.error('Project not found.')
return
}
if (!notebookFile) {
console.error('Notebook not specified.')
return
}
if (fs.existsSync(path.join(github, notebookFile))) {
notebookFile = path.join(github, notebookFile)
}
if (!fs.existsSync(notebookFile)) {
console.error('Notebook not found.')
return
}
let baseName = path.basename(github)
await spawnSync('git', ['pull'], {
cwd: github,
timeout: 3000,
stdio: ['pipe', 'pipe', 'pipe']
})
// TODO: compare existing project files
let q1 = 'Give the project files:\n' + fs.readdirSync(github).join('\n')
+ '\nFulfill the following instructions on the code file, only return the block of new code:'
+ '\n' + prompt
+ '\n' + 'Response with only the block of code and no summary or reasoning.'
// TODO: create new files
console.log('User: ' + q1)
let a1 = await llmCode(q1)
console.log('AI: ' + a1)
// try to extract code blocks
let code = a1.matchAll(/```(bash|javascript|code|markdown)*\n[\s\S]*?\n```/gi)
// extract code blocks from response
let codeBlocks = ''
for (let match of code) {
codeBlocks += match[0].replace(/^```(bash|javascript|code|markdown)*\n|\n```$/gi, '') + '\n'
}
if (!codeBlocks) {
codeBlocks = a1
}
if (!codeBlocks) {
console.log('Error, couldn\'t find code in:' + a1)
return
}
let q2 = 'Summarize this code:\n' + codeBlocks + '\nRespond with the code summary in beautifully crafted markdown. Do not include the original code in the response.'
console.log('User: ' + q2)
let a2 = await llmCode(q2)
console.log('AI: ' + a2)
let markdown = a2.matchAll(/```(markdown)*\n[\s\S]*?\n```/gi)
// extract code blocks from response
let markdownBlocks = ''
for (let match of markdown) {
markdownBlocks += match[0].replace(/^```(markdown)*\n|\n```$/gi, '') + '\n'
}
if (!markdownBlocks) {
markdownBlocks = a2
}
if (!markdownBlocks) {
return // should never happen
}
var notebook = JSON.parse(fs.readFileSync(notebookFile))
// TODO: initialize new notebook
if (!notebook) {
notebook = {
"cells": [],
"metadata": {
"language_info": {
"name": "javascript"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
}
notebook.cells[notebook.cells.length] = {
source: markdownBlocks.split('\n').map(line => line + '\n'),
cell_type: "markdown",
metadata: {},
outputs: [],
}
notebook.cells[notebook.cells.length] = {
source: codeBlocks.split('\n').map(line => line + '\n'),
cell_type: "code",
metadata: {
"vscode": {
"languageId": "javascript"
}
},
outputs: [],
}
// TODO: populate code files with goals
//fs.writeFileSync(path.join(github, codeFile), codeBlocks)
//updateCode(codeCell, codeBlocks)
fs.writeFileSync(notebookFile, JSON.stringify(notebook, null, 4))
// TODO: populate goals with actual code
}
module.exports = makeCell
const fs = require('fs');
const path = require('path');
const spawnSync = require('child_process').spawnSync;
const { importCode } = require('./importCode'); // assuming this is a separate module
const HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || '';
async function makeCell(prompt, notebookFile, github) {
if (!github) {
throw new Error('Project not specified.');
}
const gitRepo = await getGitRepo(github);
if (!gitRepo) {
throw new Error('Project not found.');
}
if (!notebookFile) {
throw new Error('Notebook not specified.');
}
const notebookPath = await getFilePath(notebookFile, gitRepo);
if (!notebookPath) {
throw new Error('Notebook not found.');
}
await pullGitRepo(gitRepo);
const projectFiles = await getProjectFiles(gitRepo);
const code = await generateCode(prompt, projectFiles, gitRepo);
const summary = await generateSummary(code);
const notebook = await initializeNotebook(notebookPath);
await addCellToNotebook(notebook, code, summary);
await fs.writeFileSync(notebookPath, JSON.stringify(notebook, null, 4));
return;
}
async function getGitRepo(github) {
if (github.includes('://')) {
github = github.replace('://', '');
}
return await path.join(HOME, github).includes(path.basename(github).replace('.git', ''))
? path.join(HOME, github)
: github;
}
async function getFilePath(notebookFile, gitRepo) {
return await path.join(gitRepo, notebookFile);
}
async function pullGitRepo(gitRepo) {
return await spawnSync('git', ['pull'], {
cwd: gitRepo,
timeout: 3000,
stdio: ['pipe', 'pipe', 'pipe'],
});
}
async function getProjectFiles(gitRepo) {
return await fs.readdirSync(gitRepo).join('\n');
}
async function generateCode(prompt, projectFiles, gitRepo) {
const q1 = `Give the project files:\n${projectFiles}\nFulfill the following instructions on the code file, only return the block of new code:\n${prompt}\nResponse with only the block of code and no summary or reasoning.\n`;
return await importCode(q1);
}
async function generateSummary(code) {
const q2 = `Summarize this code:\n${code}\nRespond with the code summary in beautifully crafted markdown. Do not include the original code in the response.\n`;
return await importCode(q2);
}
async function initializeNotebook(notebookPath) {
if (!fs.existsSync(notebookPath)) {
const notebook = {
"cells": [],
"metadata": {
"language_info": {
"name": "javascript"
}
},
"nbformat": 4,
"nbformat_minor": 2
};
await fs.writeFileSync(notebookPath, JSON.stringify(notebook, null, 4));
}
return await JSON.parse(fs.readFileSync(notebookPath));
}
async function addCellToNotebook(notebook, code, summary) {
notebook.cells.push({
source: summary.split('\n').map(line => line + '\n'),
cell_type: "markdown",
metadata: {},
outputs: [],
});
notebook.cells.push({
source: code.split('\n').map(line => line + '\n'),
cell_type: "code",
metadata: {
"vscode": {
"languageId": "javascript"
}
},
outputs: [],
});
return notebook;
}
module.exports = makeCell;
Code Breakdown
This is a Node.js script that appears to be designed to use a large language model (LLM) to generate code blocks for a project. Here's a high-level overview of the code:
The script starts by importing the following dependencies:
fs
(File System) for file system operationspath
for path manipulationprocess.env
to access environment variableschild_process
to use the spawnSync
function for executing shell commandsIt also defines some variables:
PROFILE_PATH
: a string representing the user's profile path (e.g., /home/user
on Linux or C:\Users\user
on Windows)llmCode
: an object representing the LLM code (imported using the importer
module, but not shown in this code snippet)makeCell
FunctionThe makeCell
function takes three parameters:
prompt
: a string prompting the LLM to generate codenotebookFile
: a string representing the path to a notebook file (optional)github
: a string representing the path to a GitHub repository (optional)Here's a step-by-step breakdown of the function:
github
or notebookFile
are not provided, the function logs an error message and returns.github
is not a valid path, the function tries to resolve it by checking the following locations:
github
directory at the root of the profile pathgithub
directory with the .git
extension removed (e.g., github.git
)github
directory with the .git
extension removed and the base name of the repositorynotebookFile
is not a valid path, the function logs an error message and returns.git pull
command in the GitHub repository directory using spawnSync
.prompt
string as input. The LLM's response is stored in the a1
variable.Overall, this script appears to be designed to automate the process of generating code blocks for a project using an LLM.