diff --git a/.gitignore b/.gitignore index 74854739..c64960bf 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ packages/**/config/config.json skills/**/src/config.json packages/**/data/db/*.json skills/**/memory/*.json +skills/**/memory/*.db* core/data/models/*.nlp package.json.backup .python-version diff --git a/bridges/nodejs/package.json b/bridges/nodejs/package.json index 675b87db..a149914a 100644 --- a/bridges/nodejs/package.json +++ b/bridges/nodejs/package.json @@ -13,6 +13,10 @@ "url": "https://github.com/leon-ai/leon/issues" }, "dependencies": { - "axios": "1.4.0" + "axios": "1.4.0", + "lodash": "4.17.21" + }, + "devDependencies": { + "@types/lodash": "4.14.194" } } diff --git a/bridges/nodejs/src/constants.ts b/bridges/nodejs/src/constants.ts index 96ac5a5d..64c64001 100644 --- a/bridges/nodejs/src/constants.ts +++ b/bridges/nodejs/src/constants.ts @@ -12,29 +12,18 @@ const { export const INTENT_OBJECT: IntentObject = JSON.parse( fs.readFileSync(INTENT_OBJ_FILE_PATH as string, 'utf8') ) +export const SKILL_PATH = path.join( + process.cwd(), + 'skills', + INTENT_OBJECT.domain, + INTENT_OBJECT.skill +) export const SKILL_CONFIG: SkillConfigSchema = JSON.parse( fs.readFileSync( - path.join( - process.cwd(), - 'skills', - INTENT_OBJECT.domain, - INTENT_OBJECT.skill, - 'config', - INTENT_OBJECT.lang + '.json' - ), + path.join(SKILL_PATH, 'config', INTENT_OBJECT.lang + '.json'), 'utf8' ) ) export const SKILL_SRC_CONFIG: Record = JSON.parse( - fs.readFileSync( - path.join( - process.cwd(), - 'skills', - INTENT_OBJECT.domain, - INTENT_OBJECT.skill, - 'src', - 'config.json' - ), - 'utf8' - ) + fs.readFileSync(path.join(SKILL_PATH, 'src', 'config.json'), 'utf8') ).configurations diff --git a/bridges/nodejs/src/sdk/memory.ts b/bridges/nodejs/src/sdk/memory.ts new file mode 100644 index 00000000..c707d9fe --- /dev/null +++ b/bridges/nodejs/src/sdk/memory.ts @@ -0,0 +1,96 @@ +import path from 'node:path' +import fs from 'node:fs' + +import { SKILL_PATH } from '@bridge/constants' + +export class Memory { + private readonly memoryPath: string + private readonly name: string + + constructor(name: string) { + this.memoryPath = path.join(SKILL_PATH, 'memory', `${name}.json`) + this.name = name + } + + /** + * Get the memory + */ + public async getMemory(): Promise> { + return this.read() + } + + /** + * Get a value from the memory + * @param key The key to get + * @example get('key') // { name: 'Leon' } + */ + public async get(key: string): Promise { + const memory = await this.read() + + return memory[key] as T + } + + /** + * Set a value in the memory + * @param key The key to set + * @param value The value to set + * @example set('key', { name: 'Leon' }) + */ + public async set(key: string, value: T): Promise { + const memory = await this.read() + memory[key] = value + + await this.write(memory) + } + + /** + * Delete a value from the memory + * @param key The key to delete + * @example delete('key') + */ + public async delete(key: string): Promise { + const memory = await this.read() + delete memory[key] + + await this.write(memory) + } + + /** + * Clear the memory + * @example clear() + */ + public async clear(): Promise { + await this.write({}) + } + + /** + * Read the memory + */ + private async read(): Promise> { + try { + if (!fs.existsSync(this.memoryPath)) { + await this.clear() + } + + return JSON.parse(await fs.promises.readFile(this.memoryPath, 'utf-8')) + } catch (e) { + console.error(`Error while reading memory for ${this.name}:`, e) + return {} + } + } + + /** + * Write the memory + * @param memory The memory to write + */ + private async write(memory: Record): Promise { + try { + await fs.promises.writeFile( + this.memoryPath, + JSON.stringify(memory, null, 2) + ) + } catch (e) { + console.error(`Error while writing memory for ${this.name}:`, e) + } + } +} diff --git a/bridges/nodejs/src/sdk/packages/lodash.ts b/bridges/nodejs/src/sdk/packages/lodash.ts new file mode 100644 index 00000000..4747cf57 --- /dev/null +++ b/bridges/nodejs/src/sdk/packages/lodash.ts @@ -0,0 +1 @@ +export { default } from 'lodash' diff --git a/package.json b/package.json index b2aca118..412d7bd8 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "docker:check": "docker run --rm --interactive leon-ai/leon npm run check" }, "dependencies": { - "leon-nodejs-bridge": "file:./bridges/nodejs", "@aws-sdk/client-polly": "3.18.0", "@fastify/static": "6.9.0", "@ffmpeg-installer/ffmpeg": "1.1.0", diff --git a/scripts/setup/setup-binaries.js b/scripts/setup/setup-binaries.js index 24d8f1c3..d6cfad6a 100644 --- a/scripts/setup/setup-binaries.js +++ b/scripts/setup/setup-binaries.js @@ -4,6 +4,7 @@ import stream from 'node:stream' import readline from 'node:readline' import axios from 'axios' +import { command } from 'execa' import prettyBytes from 'pretty-bytes' import prettyMilliseconds from 'pretty-ms' import extractZip from 'extract-zip' @@ -11,6 +12,7 @@ import extractZip from 'extract-zip' import { BINARIES_FOLDER_NAME, GITHUB_URL, + NODEJS_BRIDGE_ROOT_PATH, NODEJS_BRIDGE_DIST_PATH, PYTHON_BRIDGE_DIST_PATH, TCP_SERVER_DIST_PATH, @@ -96,6 +98,23 @@ const setupBinaries = async (key) => { fs.promises.rm(archivePath, { recursive: true, force: true }) ]) + if (key === 'nodejs-bridge') { + try { + LogHelper.info('Installing Node.js bridge npm packages...') + + await command( + `npm install --package-lock=false --prefix ${NODEJS_BRIDGE_ROOT_PATH}`, + { + shell: true + } + ) + + LogHelper.success('Node.js bridge npm packages installed') + } catch (e) { + throw new Error(`Failed to install Node.js bridge npm packages: ${e}`) + } + } + try { LogHelper.info(`Downloading ${name}...`) @@ -142,8 +161,8 @@ const setupBinaries = async (key) => { LogHelper.success(`${name} manifest file created`) LogHelper.success(`${name} ${version} ready`) - } catch (error) { - throw new Error(`Failed to set up ${name}: ${error}`) + } catch (e) { + throw new Error(`Failed to set up ${name}: ${e}`) } } else { LogHelper.success(`${name} is already at the latest version (${version})`) diff --git a/skills/leon/age/src/actions/run.ts b/skills/leon/age/src/actions/run.ts index aeea9efa..1980efc6 100644 --- a/skills/leon/age/src/actions/run.ts +++ b/skills/leon/age/src/actions/run.ts @@ -1,11 +1,93 @@ -import * as utility from 'utility' +import utility from 'utility' import type { ActionFunction } from '@sdk/types' import { leon } from '@sdk/leon' import { Network } from '@sdk/network' import { Button } from '@sdk/aurora/button' +import { Memory } from '@sdk/memory' +import _ from '@sdk/packages/lodash' + +interface Post { + id: number + title: string + content: string + author: { + name: string + } +} export const run: ActionFunction = async function () { + const postsMemory = new Memory('posts') + const websiteLayoutMemory = new Memory('websiteLayout') + + await postsMemory.delete('1') + + await websiteLayoutMemory.set('webSiteLayout', [ + { + name: 'header', + component: '
' + }, + { + name: 'footer', + component: '