From 9479e403708931e584f3b09f2a2d66f2c77bfca8 Mon Sep 17 00:00:00 2001 From: Mohamed Marrouchi Date: Wed, 23 Oct 2024 10:50:43 +0100 Subject: [PATCH] feat: enhance llm helper support --- api/package.json | 6 ++--- api/src/channel/channel.module.ts | 2 +- .../extensions/helpers/ollama/index.helper.ts | 11 +++++++++- .../extensions/plugins/ollama/index.plugin.ts | 5 ++++- api/src/helper/helper.module.ts | 2 +- api/src/helper/lib/base-llm-helper.ts | 10 ++++++++- api/src/plugins/plugins.module.ts | 2 +- .../repositories/setting.repository.ts | 22 +++++++++++++++---- api/tsconfig.json | 2 +- 9 files changed, 48 insertions(+), 14 deletions(-) diff --git a/api/package.json b/api/package.json index f992ba1e..6d7d33a3 100644 --- a/api/package.json +++ b/api/package.json @@ -8,9 +8,9 @@ "scripts": { "postinstall": "patch-package", "build:clean": "rm -rf src/.hexabot", - "build:channels": "mkdir -p src/.hexabot/channels && find node_modules/ -name 'hexabot-channel-*' -exec cp -R {} src/.hexabot/channels/ \\;", - "build:helpers": "mkdir -p src/.hexabot/helpers && find node_modules/ -name 'hexabot-helper-*' -exec cp -R {} src/.hexabot/helpers/ \\;", - "build:plugins": "mkdir -p src/.hexabot/plugins && find node_modules/ -name 'hexabot-plugin-*' -exec cp -R {} src/.hexabot/plugins/ \\;", + "build:channels": "mkdir -p src/.hexabot/extensions/channels && find node_modules/ -name 'hexabot-channel-*' -exec cp -R {} src/.hexabot/extensions/channels/ \\;", + "build:helpers": "mkdir -p src/.hexabot/extensions/helpers && find node_modules/ -name 'hexabot-helper-*' -exec cp -R {} src/.hexabot/extensions/helpers/ \\;", + "build:plugins": "mkdir -p src/.hexabot/extensions/plugins && find node_modules/ -name 'hexabot-plugin-*' -exec cp -R {} src/.hexabot/extensions/plugins/ \\;", "build:extensions": "npm run build:channels && npm run build:helpers && npm run build:plugins", "build:prepare": "npm run build:clean && npm run build:extensions", "build": "npm run build:prepare && nest build", diff --git a/api/src/channel/channel.module.ts b/api/src/channel/channel.module.ts index 3fae41a8..61cd4570 100644 --- a/api/src/channel/channel.module.ts +++ b/api/src/channel/channel.module.ts @@ -33,7 +33,7 @@ export interface ChannelModuleOptions { // Core & under dev channels 'dist/extensions/**/*.channel.js', // Installed channels via npm - 'dist/.hexabot/channels/**/*.channel.js', + 'dist/.hexabot/extensions/channels/**/*.channel.js', ) @Module({ controllers: [WebhookController, ChannelController], diff --git a/api/src/extensions/helpers/ollama/index.helper.ts b/api/src/extensions/helpers/ollama/index.helper.ts index cdc619fd..98644135 100644 --- a/api/src/extensions/helpers/ollama/index.helper.ts +++ b/api/src/extensions/helpers/ollama/index.helper.ts @@ -59,12 +59,21 @@ export default class OllamaLlmHelper * * @param prompt - The input text from the user * @param model - The model to be used + * @param systemPrompt - The input text from the system * @returns {Promise} - The generated response from the LLM */ - async generateResponse(prompt: string, model: string): Promise { + async generateResponse( + prompt: string, + model: string, + system: string, + { keepAlive = '5m', options = {} }, + ): Promise { const response = await this.client.generate({ model, prompt, + system: system, + keep_alive: keepAlive, + options, }); return response.response ? response.response : ''; diff --git a/api/src/extensions/plugins/ollama/index.plugin.ts b/api/src/extensions/plugins/ollama/index.plugin.ts index 2d8d7b66..f25dee0f 100644 --- a/api/src/extensions/plugins/ollama/index.plugin.ts +++ b/api/src/extensions/plugins/ollama/index.plugin.ts @@ -75,7 +75,10 @@ export class OllamaPlugin extends BaseBlockPlugin { const options = this.settings .filter( - (setting) => 'subgroup' in setting && setting.subgroup === 'options', + (setting) => + 'subgroup' in setting && + setting.subgroup === 'options' && + setting.value !== null, ) .reduce((acc, { label }) => { acc[label] = args[label]; diff --git a/api/src/helper/helper.module.ts b/api/src/helper/helper.module.ts index bd8888c8..5a3e286b 100644 --- a/api/src/helper/helper.module.ts +++ b/api/src/helper/helper.module.ts @@ -18,7 +18,7 @@ import { HelperService } from './helper.service'; // Core & under dev helpers 'dist/extensions/**/*.helper.js', // Installed helpers via npm - 'dist/.hexabot/helpers/**/*.helper.js', + 'dist/.hexabot/extensions/helpers/**/*.helper.js', ) @Module({ imports: [HttpModule], diff --git a/api/src/helper/lib/base-llm-helper.ts b/api/src/helper/lib/base-llm-helper.ts index 7765738e..541bb453 100644 --- a/api/src/helper/lib/base-llm-helper.ts +++ b/api/src/helper/lib/base-llm-helper.ts @@ -34,9 +34,16 @@ export default abstract class BaseLlmHelper< * * @param prompt - The input text from the user * @param model - The model to be used + * @param systemPrompt - The input text from the system + * @param extra - Extra options * @returns {Promise} - The generated response from the LLM */ - abstract generateResponse(prompt: string, model: string): Promise; + abstract generateResponse( + prompt: string, + model: string, + systemPrompt: string, + extra?: any, + ): Promise; /** * Send a chat completion request with the conversation history. @@ -46,6 +53,7 @@ export default abstract class BaseLlmHelper< * @param prompt - The input text from the user * @param model - The model to be used * @param history - Array of messages + * @param extra - Extra options * @returns {Promise} - The generated response from the LLM */ abstract generateChatCompletion( diff --git a/api/src/plugins/plugins.module.ts b/api/src/plugins/plugins.module.ts index 4dbf2708..fec9fbd8 100644 --- a/api/src/plugins/plugins.module.ts +++ b/api/src/plugins/plugins.module.ts @@ -24,7 +24,7 @@ import { PluginService } from './plugins.service'; // Core & under dev plugins 'dist/extensions/**/*.plugin.js', // Installed plugins via npm - 'dist/.hexabot/plugins/**/*.plugin.js', + 'dist/.hexabot/extensions/plugins/**/*.plugin.js', ) @Global() @Module({ diff --git a/api/src/setting/repositories/setting.repository.ts b/api/src/setting/repositories/setting.repository.ts index beada31b..3931fcd3 100644 --- a/api/src/setting/repositories/setting.repository.ts +++ b/api/src/setting/repositories/setting.repository.ts @@ -18,6 +18,7 @@ import { I18nService } from '@/i18n/services/i18n.service'; import { BaseRepository } from '@/utils/generics/base-repository'; import { Setting } from '../schemas/setting.schema'; +import { SettingType } from '../schemas/types'; @Injectable() export class SettingRepository extends BaseRepository { @@ -43,9 +44,14 @@ export class SettingRepository extends BaseRepository { setting: Document & Setting & { _id: Types.ObjectId }, ) { - if (setting.type === 'text' && typeof setting.value !== 'string') { + if ( + (setting.type === SettingType.text || + setting.type === SettingType.textarea) && + typeof setting.value !== 'string' && + setting.value !== null + ) { throw new Error('Setting Model : Value must be a string!'); - } else if (setting.type === 'multiple_text') { + } else if (setting.type === SettingType.multiple_text) { const isStringArray = Array.isArray(setting.value) && setting.value.every((v) => { @@ -55,10 +61,18 @@ export class SettingRepository extends BaseRepository { throw new Error('Setting Model : Value must be a string array!'); } } else if ( - setting.type === 'checkbox' && - typeof setting.value !== 'boolean' + setting.type === SettingType.checkbox && + typeof setting.value !== 'boolean' && + setting.value !== null ) { throw new Error('Setting Model : Value must be a boolean!'); + } else if ( + setting.type === SettingType.number && + typeof setting.value !== 'number' && + setting.value !== null + ) { + console.log(setting); + throw new Error('Setting Model : Value must be a number!'); } } diff --git a/api/tsconfig.json b/api/tsconfig.json index 12289c34..27724e72 100644 --- a/api/tsconfig.json +++ b/api/tsconfig.json @@ -20,7 +20,7 @@ "resolveJsonModule": true, "esModuleInterop": true, "paths": { - "@/*": ["src/*"] + "@/*": ["src/*", "src/.hexabot/*"] } }, "include": [