From 68837e06ee2eb2d2e778f5dd036e0df6aa7ee56b Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Tue, 7 May 2024 11:52:53 +0530 Subject: [PATCH 01/34] feat(embedding-providers): add local models --- package.json | 1 + src/lib/huggingfaceTransformer.ts | 82 ++++++ src/lib/providers.ts | 7 + tsconfig.json | 3 +- yarn.lock | 470 +++++++++++++++++++++++++++++- 5 files changed, 555 insertions(+), 8 deletions(-) create mode 100644 src/lib/huggingfaceTransformer.ts diff --git a/package.json b/package.json index ca01c44..ae20c7c 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dependencies": { "@iarna/toml": "^2.2.5", "@langchain/openai": "^0.0.25", + "@xenova/transformers": "^2.17.1", "axios": "^1.6.8", "compute-cosine-similarity": "^1.1.0", "compute-dot": "^1.1.0", diff --git a/src/lib/huggingfaceTransformer.ts b/src/lib/huggingfaceTransformer.ts new file mode 100644 index 0000000..7a959ca --- /dev/null +++ b/src/lib/huggingfaceTransformer.ts @@ -0,0 +1,82 @@ +import { Embeddings, type EmbeddingsParams } from '@langchain/core/embeddings'; +import { chunkArray } from '@langchain/core/utils/chunk_array'; + +export interface HuggingFaceTransformersEmbeddingsParams + extends EmbeddingsParams { + modelName: string; + + model: string; + + timeout?: number; + + batchSize?: number; + + stripNewLines?: boolean; +} + +export class HuggingFaceTransformersEmbeddings + extends Embeddings + implements HuggingFaceTransformersEmbeddingsParams +{ + modelName = 'Xenova/all-MiniLM-L6-v2'; + + model = 'Xenova/all-MiniLM-L6-v2'; + + batchSize = 512; + + stripNewLines = true; + + timeout?: number; + + private pipelinePromise: Promise; + + constructor(fields?: Partial) { + super(fields ?? {}); + + this.modelName = fields?.model ?? fields?.modelName ?? this.model; + this.model = this.modelName; + this.stripNewLines = fields?.stripNewLines ?? this.stripNewLines; + this.timeout = fields?.timeout; + } + + async embedDocuments(texts: string[]): Promise { + const batches = chunkArray( + this.stripNewLines ? texts.map((t) => t.replace(/\n/g, ' ')) : texts, + this.batchSize, + ); + + const batchRequests = batches.map((batch) => this.runEmbedding(batch)); + const batchResponses = await Promise.all(batchRequests); + const embeddings: number[][] = []; + + for (let i = 0; i < batchResponses.length; i += 1) { + const batchResponse = batchResponses[i]; + for (let j = 0; j < batchResponse.length; j += 1) { + embeddings.push(batchResponse[j]); + } + } + + return embeddings; + } + + async embedQuery(text: string): Promise { + const data = await this.runEmbedding([ + this.stripNewLines ? text.replace(/\n/g, ' ') : text, + ]); + return data[0]; + } + + private async runEmbedding(texts: string[]) { + const { pipeline } = await import('@xenova/transformers'); + + const pipe = await (this.pipelinePromise ??= pipeline( + 'feature-extraction', + this.model, + )); + + return this.caller.call(async () => { + const output = await pipe(texts, { pooling: 'mean', normalize: true }); + return output.tolist(); + }); + } +} diff --git a/src/lib/providers.ts b/src/lib/providers.ts index 751d23f..cd0ef78 100644 --- a/src/lib/providers.ts +++ b/src/lib/providers.ts @@ -1,6 +1,7 @@ import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai'; import { ChatOllama } from '@langchain/community/chat_models/ollama'; import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama'; +import { HuggingFaceTransformersEmbeddings } from './huggingfaceTransformer'; import { getGroqApiKey, getOllamaApiEndpoint, @@ -156,6 +157,12 @@ export const getAvailableEmbeddingModelProviders = async () => { }); return acc; }, {}); + + models['local'] = { + 'GTE Small': new HuggingFaceTransformersEmbeddings({ + modelName: 'Xenova/gte-small', + }), + }; } catch (err) { logger.error(`Error loading Ollama embeddings: ${err}`); } diff --git a/tsconfig.json b/tsconfig.json index 5bdba67..48e6042 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { "lib": ["ESNext"], - "module": "commonjs", + "module": "Node16", + "moduleResolution": "Node16", "target": "ESNext", "outDir": "dist", "sourceMap": false, diff --git a/yarn.lock b/yarn.lock index 205b0ed..6ec0ff2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,6 +38,11 @@ enabled "2.0.x" kuler "^2.0.0" +"@huggingface/jinja@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@huggingface/jinja/-/jinja-0.2.2.tgz#faeb205a9d6995089bef52655ddd8245d3190627" + integrity sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA== + "@iarna/toml@^2.2.5": version "2.2.5" resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" @@ -102,6 +107,59 @@ zod "^3.22.4" zod-to-json-schema "^3.22.3" +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + "@tsconfig/node10@^1.0.7": version "1.0.11" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" @@ -169,6 +227,11 @@ resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + "@types/mime@^1": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" @@ -189,6 +252,13 @@ dependencies: undici-types "~5.26.4" +"@types/node@>=13.7.0": + version "20.12.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.9.tgz#d7234f2e7839b55fcab5048404aef0195684adff" + integrity sha512-o93r47yu04MHumPBCFg0bMPBMNgtMg3jzbhl7e68z50+BMHmRMGDJv13eBlUgOdc9i/uoJXGMGYLtJV4ReTXEg== + dependencies: + undici-types "~5.26.4" + "@types/node@^18.11.18": version "18.19.28" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.28.tgz#c64a2c992c8ebbf61100a4570e4eebc1934ae030" @@ -246,6 +316,17 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== +"@xenova/transformers@^2.17.1": + version "2.17.1" + resolved "https://registry.yarnpkg.com/@xenova/transformers/-/transformers-2.17.1.tgz#712f7a72c76c8aa2075749382f83dc7dd4e5a9a5" + integrity sha512-zo702tQAFZXhzeD2GCYUNUqeqkoueOdiSbQWa4s0q7ZE4z8WBIwIsMMPGobpgdqjQ2u0Qulo08wuqVEUrBXjkQ== + dependencies: + "@huggingface/jinja" "^0.2.2" + onnxruntime-web "1.14.0" + sharp "^0.32.0" + optionalDependencies: + onnxruntime-node "1.14.0" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -330,17 +411,55 @@ axios@^1.6.8: form-data "^4.0.0" proxy-from-env "^1.1.0" +b4a@^1.6.4: + version "1.6.6" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.6.tgz#a4cc349a3851987c3c4ac2d7785c18744f6da9ba" + integrity sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +bare-events@^2.0.0, bare-events@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.2.2.tgz#a98a41841f98b2efe7ecc5c5468814469b018078" + integrity sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ== + +bare-fs@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-2.3.0.tgz#0872f8e33cf291c9fd527d827154f156a298d402" + integrity sha512-TNFqa1B4N99pds2a5NYHR15o0ZpdNKbAeKTE/+G6ED/UeOavv8RY3dr/Fu99HW3zU3pXpo2kDNO8Sjsm2esfOw== + dependencies: + bare-events "^2.0.0" + bare-path "^2.0.0" + bare-stream "^1.0.0" + +bare-os@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-2.3.0.tgz#718e680b139effff0624a7421c098e7a2c2d63da" + integrity sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg== + +bare-path@^2.0.0, bare-path@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-2.1.2.tgz#7a0940d34ebe65f7e179fa61ed8d49d9dc151d67" + integrity sha512-o7KSt4prEphWUHa3QUwCxUI00R86VdjiuxmJK0iNVDHYPGo+HsDaVCnqCmPbf/MiW1ok8F4p3m8RTHlWk8K2ig== + dependencies: + bare-os "^2.1.0" + +bare-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-1.0.0.tgz#25c3e56198d922187320c3f8c52d75c4051178b4" + integrity sha512-KhNUoDL40iP4gFaLSsoGE479t0jHijfYdIcxRn/XtezA2BaUD0NRf/JGRpsMq6dMNM+SrCrB0YSSo/5wBY4rOQ== + dependencies: + streamx "^2.16.1" + base-64@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA== -base64-js@^1.5.1: +base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -355,6 +474,15 @@ binary-search@^1.3.5: resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.6.tgz#e32426016a0c5092f0f3598836a1c7da3560565c" integrity sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA== +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + body-parser@1.20.2: version "1.20.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" @@ -388,6 +516,14 @@ braces@~3.0.2: dependencies: fill-range "^7.0.1" +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -429,6 +565,11 @@ chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -436,17 +577,24 @@ color-convert@^1.9.3: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@^1.0.0: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.6.0: +color-string@^1.6.0, color-string@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== @@ -462,6 +610,14 @@ color@^3.1.3: color-convert "^1.9.3" color-string "^1.6.0" +color@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + colorspace@1.1.x: version "1.1.4" resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" @@ -572,6 +728,18 @@ decamelize@1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + define-data-property@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" @@ -596,6 +764,11 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-libc@^2.0.0, detect-libc@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -629,6 +802,13 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + es-define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" @@ -661,6 +841,11 @@ eventemitter3@^4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expr-eval@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expr-eval/-/expr-eval-2.0.2.tgz#fa6f044a7b0c93fde830954eb9c5b0f7fbc7e201" @@ -703,6 +888,11 @@ express@^4.19.2: utils-merge "1.0.1" vary "~1.1.2" +fast-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + fecha@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" @@ -733,6 +923,11 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +flatbuffers@^1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/flatbuffers/-/flatbuffers-1.12.0.tgz#72e87d1726cb1b216e839ef02658aa87dcef68aa" + integrity sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ== + fn.name@1.x.x: version "1.1.0" resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" @@ -775,6 +970,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fsevents@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -796,6 +996,11 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: has-symbols "^1.0.3" hasown "^2.0.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -810,6 +1015,11 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +guid-typescript@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/guid-typescript/-/guid-typescript-1.0.9.tgz#e35f77003535b0297ea08548f5ace6adb1480ddc" + integrity sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -864,16 +1074,26 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== -inherits@2.0.4, inherits@^2.0.3: +inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -998,6 +1218,11 @@ logform@^2.3.2, logform@^2.4.0: safe-stable-stringify "^2.3.1" triple-beam "^1.3.0" +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1051,6 +1276,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1058,6 +1288,16 @@ minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimist@^1.2.0, minimist@^1.2.3: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + ml-array-mean@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/ml-array-mean/-/ml-array-mean-1.1.6.tgz#d951a700dc8e3a17b3e0a583c2c64abd0c619c56" @@ -1109,11 +1349,28 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +node-abi@^3.3.0: + version "3.62.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.62.0.tgz#017958ed120f89a3a14a7253da810f5d724e3f36" + integrity sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g== + dependencies: + semver "^7.3.5" + +node-addon-api@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" + integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== + node-domexception@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" @@ -1176,6 +1433,13 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" +once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + one-time@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" @@ -1183,6 +1447,37 @@ one-time@^1.0.0: dependencies: fn.name "1.x.x" +onnx-proto@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/onnx-proto/-/onnx-proto-4.0.4.tgz#2431a25bee25148e915906dda0687aafe3b9e044" + integrity sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA== + dependencies: + protobufjs "^6.8.8" + +onnxruntime-common@~1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz#2bb5dac5261269779aa5fb6536ca379657de8bf6" + integrity sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew== + +onnxruntime-node@1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz#c4ae6c355cfae7d83abaf36dd39a905c4a010217" + integrity sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w== + dependencies: + onnxruntime-common "~1.14.0" + +onnxruntime-web@1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz#c8cee538781b1d4c1c6b043934f4a3e6ddf1466e" + integrity sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw== + dependencies: + flatbuffers "^1.12.0" + guid-typescript "^1.0.9" + long "^4.0.0" + onnx-proto "^4.0.4" + onnxruntime-common "~1.14.0" + platform "^1.3.6" + openai@^4.26.0: version "4.31.0" resolved "https://registry.yarnpkg.com/openai/-/openai-4.31.0.tgz#5d96045c4eb244fa21f0fff0981043a2c9f09e8c" @@ -1246,11 +1541,53 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +platform@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== + +prebuild-install@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prettier@^3.2.5: version "3.2.5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== +protobufjs@^6.8.8: + version "6.11.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" + integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -1269,6 +1606,14 @@ pstree.remy@^1.1.8: resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + qs@6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -1276,6 +1621,11 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -1291,7 +1641,17 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^3.4.0, readable-stream@^3.6.0: +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -1312,7 +1672,7 @@ retry@^0.13.1: resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== -safe-buffer@5.2.1, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -1332,7 +1692,7 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -semver@^7.5.3: +semver@^7.3.5, semver@^7.5.3, semver@^7.5.4: version "7.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== @@ -1385,6 +1745,20 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sharp@^0.32.0: + version "0.32.6" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.6.tgz#6ad30c0b7cd910df65d5f355f774aa4fce45732a" + integrity sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w== + dependencies: + color "^4.2.3" + detect-libc "^2.0.2" + node-addon-api "^6.1.0" + prebuild-install "^7.1.1" + semver "^7.5.4" + simple-get "^4.0.1" + tar-fs "^3.0.4" + tunnel-agent "^0.6.0" + side-channel@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" @@ -1395,6 +1769,20 @@ side-channel@^1.0.4: get-intrinsic "^1.2.4" object-inspect "^1.13.1" +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0, simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -1419,6 +1807,16 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +streamx@^2.15.0, streamx@^2.16.1: + version "2.16.1" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.16.1.tgz#2b311bd34832f08aa6bb4d6a80297c9caef89614" + integrity sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ== + dependencies: + fast-fifo "^1.1.0" + queue-tick "^1.0.1" + optionalDependencies: + bare-events "^2.2.0" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -1426,6 +1824,11 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -1433,6 +1836,47 @@ supports-color@^5.5.0: dependencies: has-flag "^3.0.0" +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-fs@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" + integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== + dependencies: + pump "^3.0.0" + tar-stream "^3.1.5" + optionalDependencies: + bare-fs "^2.1.1" + bare-path "^2.1.0" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar-stream@^3.1.5: + version "3.1.7" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b" + integrity sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + text-hex@1.0.x: version "1.0.0" resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" @@ -1486,6 +1930,13 @@ ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -1598,6 +2049,11 @@ winston@^3.13.0: triple-beam "^1.3.0" winston-transport "^4.7.0" +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + ws@^8.16.0: version "8.16.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" From 321e60b9931d7e497e0698ba3564b52c3d6fa855 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Tue, 7 May 2024 12:33:44 +0530 Subject: [PATCH 02/34] feat(embedding-providers): load separately, add bert & bge --- src/lib/providers.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/lib/providers.ts b/src/lib/providers.ts index cd0ef78..d2e40f0 100644 --- a/src/lib/providers.ts +++ b/src/lib/providers.ts @@ -158,15 +158,26 @@ export const getAvailableEmbeddingModelProviders = async () => { return acc; }, {}); - models['local'] = { - 'GTE Small': new HuggingFaceTransformersEmbeddings({ - modelName: 'Xenova/gte-small', - }), - }; } catch (err) { logger.error(`Error loading Ollama embeddings: ${err}`); } } + try { + models['local'] = { + 'BGE Small': new HuggingFaceTransformersEmbeddings({ + modelName: 'Xenova/bge-small-en-v1.5', + }), + 'GTE Small': new HuggingFaceTransformersEmbeddings({ + modelName: 'Xenova/gte-small', + }), + 'Bert Multilingual': new HuggingFaceTransformersEmbeddings({ + modelName: 'Xenova/bert-base-multilingual-uncased' + }), + }; + } catch(err) { + logger.error(`Error loading local embeddings: ${err}`); + } + return models; }; From e042ff491b212974f804517ab1065b7402697c93 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Tue, 7 May 2024 19:39:59 +0530 Subject: [PATCH 03/34] feat(compose): remove `expose` directive --- docker-compose.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 2ca3ca5..5eef31e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,8 +3,6 @@ services: build: context: . dockerfile: searxng.dockerfile - expose: - - 4000 ports: - 4000:8080 networks: @@ -18,8 +16,6 @@ services: - SEARXNG_API_URL=http://searxng:8080 depends_on: - searxng - expose: - - 3001 ports: - 3001:3001 networks: @@ -34,12 +30,10 @@ services: - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 depends_on: - perplexica-backend - expose: - - 3000 ports: - 3000:3000 networks: - perplexica-network networks: - perplexica-network: + perplexica-network: \ No newline at end of file From 74d1df7d25bdafe6e896417ab5e9687505038978 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Tue, 7 May 2024 19:40:14 +0530 Subject: [PATCH 04/34] feat(package): bump version --- package.json | 4 ++-- ui/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ae20c7c..a4af068 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "perplexica-backend", - "version": "1.3.4", + "version": "1.4.0", "license": "MIT", "author": "ItzCrazyKns", "scripts": { "start": "node dist/app.js", "build": "tsc", - "dev": "nodemon src/app.ts", + "dev": "nodemon src/app.ts" , "format": "prettier . --check", "format:write": "prettier . --write" }, diff --git a/ui/package.json b/ui/package.json index 7775d23..a06581e 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "perplexica-frontend", - "version": "1.3.4", + "version": "1.4.0", "license": "MIT", "author": "ItzCrazyKns", "scripts": { From 2a1d6e261d2354f1f9d14323ddc423205cce476e Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Tue, 7 May 2024 19:40:33 +0530 Subject: [PATCH 05/34] feat(backend-dockerfile): use Debian based image --- backend.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend.dockerfile b/backend.dockerfile index 8bf34f0..47c5d81 100644 --- a/backend.dockerfile +++ b/backend.dockerfile @@ -1,4 +1,4 @@ -FROM node:alpine +FROM node:buster-slim ARG SEARXNG_API_URL From 0af66f8b72320b67b1a573d6a02f8ef2d2eee141 Mon Sep 17 00:00:00 2001 From: WanQuanXie Date: Wed, 8 May 2024 09:57:11 +0800 Subject: [PATCH 06/34] fix(Chat): list map element must specify a unique key --- ui/components/Chat.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/components/Chat.tsx b/ui/components/Chat.tsx index 294520b..ddd2957 100644 --- a/ui/components/Chat.tsx +++ b/ui/components/Chat.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useRef, useState } from 'react'; +import { Fragment, useEffect, useRef, useState } from 'react'; import MessageInput from './MessageInput'; import { Message } from './ChatWindow'; import MessageBox from './MessageBox'; @@ -53,7 +53,7 @@ const Chat = ({ const isLast = i === messages.length - 1; return ( - <> + )} - + ); })} {loading && !messageAppeared && } From 4f5f6be85f157b9fc0992fa1583f4cc1060e9522 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com> Date: Wed, 8 May 2024 20:05:29 +0530 Subject: [PATCH 07/34] feat(working): fix grammatical mistake --- docs/architecture/WORKING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/WORKING.md b/docs/architecture/WORKING.md index 8718b22..e39de7a 100644 --- a/docs/architecture/WORKING.md +++ b/docs/architecture/WORKING.md @@ -5,7 +5,7 @@ Curious about how Perplexica works? Don't worry, we'll cover it here. Before we We'll understand how Perplexica works by taking an example of a scenario where a user asks: "How does an A.C. work?". We'll break down the process into steps to make it easier to understand. The steps are as follows: 1. The message is sent via WS to the backend server where it invokes the chain. The chain will depend on your focus mode. For this example, let's assume we use the "webSearch" focus mode. -2. The chain is now invoked; first, the message is passed to another chain where it first predicts (using the chat history and the question) whether there is a need for sources or searching the web. If there is, it will generate a query (in accordance with the chat history) for searching the web that we'll take up later. If not, the chain will end there, and then the answer generator chain, also known as the response generator, will be started. +2. The chain is now invoked; first, the message is passed to another chain where it first predicts (using the chat history and the question) whether there is a need for sources and searching the web. If there is, it will generate a query (in accordance with the chat history) for searching the web that we'll take up later. If not, the chain will end there, and then the answer generator chain, also known as the response generator, will be started. 3. The query returned by the first chain is passed to SearXNG to search the web for information. 4. After the information is retrieved, it is based on keyword-based search. We then convert the information into embeddings and the query as well, then we perform a similarity search to find the most relevant sources to answer the query. 5. After all this is done, the sources are passed to the response generator. This chain takes all the chat history, the query, and the sources. It generates a response that is streamed to the UI. From ac4cba32c801c2ef79ed6096f285d5702e4bcb1c Mon Sep 17 00:00:00 2001 From: Chuck <403chuck@gmail.com> Date: Thu, 9 May 2024 15:53:57 +0800 Subject: [PATCH 08/34] fix(SettingsDialog): baseURL storage key --- ui/components/SettingsDialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/SettingsDialog.tsx b/ui/components/SettingsDialog.tsx index be94db2..57f79f6 100644 --- a/ui/components/SettingsDialog.tsx +++ b/ui/components/SettingsDialog.tsx @@ -89,7 +89,7 @@ const SettingsDialog = ({ setSelectedEmbeddingModelProvider(embeddingModelProvider); setSelectedEmbeddingModel(embeddingModel); setCustomOpenAIApiKey(localStorage.getItem('openAIApiKey') || ''); - setCustomOpenAIBaseURL(localStorage.getItem('openAIBaseUrl') || ''); + setCustomOpenAIBaseURL(localStorage.getItem('openAIBaseURL') || ''); setIsLoading(false); }; From 5e940914a3465fa920307a093febe4227b2a71a5 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Thu, 9 May 2024 20:39:38 +0530 Subject: [PATCH 09/34] feat(output-parsers): add list line output parser --- src/lib/outputParsers/listLineOutputParser.ts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/lib/outputParsers/listLineOutputParser.ts diff --git a/src/lib/outputParsers/listLineOutputParser.ts b/src/lib/outputParsers/listLineOutputParser.ts new file mode 100644 index 0000000..4fde080 --- /dev/null +++ b/src/lib/outputParsers/listLineOutputParser.ts @@ -0,0 +1,43 @@ +import { BaseOutputParser } from '@langchain/core/output_parsers'; + +interface LineListOutputParserArgs { + key?: string; +} + +class LineListOutputParser extends BaseOutputParser { + private key = 'questions'; + + constructor(args?: LineListOutputParserArgs) { + super(); + this.key = args.key || this.key; + } + + static lc_name() { + return 'LineListOutputParser'; + } + + lc_namespace = ['langchain', 'output_parsers', 'line_list_output_parser']; + + async parse(text: string): Promise { + const regex = /^(\s*(-|\*|\d+\.\s|\d+\)\s|\u2022)\s*)+/; + const startKeyIndex = text.indexOf(`<${this.key}>`); + const endKeyIndex = text.indexOf(``); + const questionsStartIndex = + startKeyIndex === -1 ? 0 : startKeyIndex + `<${this.key}>`.length; + const questionsEndIndex = endKeyIndex === -1 ? text.length : endKeyIndex; + const lines = text + .slice(questionsStartIndex, questionsEndIndex) + .trim() + .split('\n') + .filter((line) => line.trim() !== '') + .map((line) => line.replace(regex, '')); + + return lines; + } + + getFormatInstructions(): string { + throw new Error('Not implemented.'); + } +} + +export default LineListOutputParser; From 0f6986fc9b1f6bb131f686d439afdd1d4fc7d37d Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Thu, 9 May 2024 20:41:43 +0530 Subject: [PATCH 10/34] feat(agents): add suggestion generator agent --- src/agents/suggestionGeneratorAgent.ts | 55 ++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/agents/suggestionGeneratorAgent.ts diff --git a/src/agents/suggestionGeneratorAgent.ts b/src/agents/suggestionGeneratorAgent.ts new file mode 100644 index 0000000..59bd9ea --- /dev/null +++ b/src/agents/suggestionGeneratorAgent.ts @@ -0,0 +1,55 @@ +import { RunnableSequence, RunnableMap } from '@langchain/core/runnables'; +import ListLineOutputParser from '../lib/outputParsers/listLineOutputParser'; +import { PromptTemplate } from '@langchain/core/prompts'; +import formatChatHistoryAsString from '../utils/formatHistory'; +import { BaseMessage } from '@langchain/core/messages'; +import { BaseChatModel } from '@langchain/core/language_models/chat_models'; +import { ChatOpenAI } from '@langchain/openai'; + +const suggestionGeneratorPrompt = ` +You are an AI suggestion generator for an AI powered search engine. You will be given a conversation below. You need to generate 4-5 suggestions based on the conversation. The suggestion should be relevant to the conversation that can be used by the user to ask the chat model for more information. +You need to make sure the suggestions are relevant to the conversation and are helpful to the user. Keep a note that the user might use these suggestions to ask a chat model for more information. +Make sure the suggestions are medium in length and are informative and relevant to the conversation. + +Provide these suggestions separated by newlines between the XML tags and . For example: + + +Suggestion 1 +Suggestion 2 +Suggestion 3 + + +Conversation: +{chat_history} +`; + +type SuggestionGeneratorInput = { + chat_history: BaseMessage[]; +}; + +const outputParser = new ListLineOutputParser({ + key: 'suggestions', +}); + +const createSuggestionGeneratorChain = (llm: BaseChatModel) => { + return RunnableSequence.from([ + RunnableMap.from({ + chat_history: (input: SuggestionGeneratorInput) => + formatChatHistoryAsString(input.chat_history), + }), + PromptTemplate.fromTemplate(suggestionGeneratorPrompt), + llm, + outputParser, + ]); +}; + +const generateSuggestions = ( + input: SuggestionGeneratorInput, + llm: BaseChatModel, +) => { + (llm as ChatOpenAI).temperature = 0; + const suggestionGeneratorChain = createSuggestionGeneratorChain(llm); + return suggestionGeneratorChain.invoke(input); +}; + +export default generateSuggestions; From 09463999c2d93d9be6799a10a95e8e3a5c737cd4 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Thu, 9 May 2024 20:42:03 +0530 Subject: [PATCH 11/34] feat(routes): add suggestions route --- src/routes/index.ts | 2 ++ src/routes/suggestions.ts | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/routes/suggestions.ts diff --git a/src/routes/index.ts b/src/routes/index.ts index 04390cd..257e677 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -3,6 +3,7 @@ import imagesRouter from './images'; import videosRouter from './videos'; import configRouter from './config'; import modelsRouter from './models'; +import suggestionsRouter from './suggestions'; const router = express.Router(); @@ -10,5 +11,6 @@ router.use('/images', imagesRouter); router.use('/videos', videosRouter); router.use('/config', configRouter); router.use('/models', modelsRouter); +router.use('/suggestions', suggestionsRouter); export default router; diff --git a/src/routes/suggestions.ts b/src/routes/suggestions.ts new file mode 100644 index 0000000..10e5715 --- /dev/null +++ b/src/routes/suggestions.ts @@ -0,0 +1,46 @@ +import express from 'express'; +import generateSuggestions from '../agents/suggestionGeneratorAgent'; +import { BaseChatModel } from '@langchain/core/language_models/chat_models'; +import { getAvailableChatModelProviders } from '../lib/providers'; +import { HumanMessage, AIMessage } from '@langchain/core/messages'; +import logger from '../utils/logger'; + +const router = express.Router(); + +router.post('/', async (req, res) => { + try { + let { chat_history, chat_model, chat_model_provider } = req.body; + + chat_history = chat_history.map((msg: any) => { + if (msg.role === 'user') { + return new HumanMessage(msg.content); + } else if (msg.role === 'assistant') { + return new AIMessage(msg.content); + } + }); + + const chatModels = await getAvailableChatModelProviders(); + const provider = chat_model_provider || Object.keys(chatModels)[0]; + const chatModel = chat_model || Object.keys(chatModels[provider])[0]; + + let llm: BaseChatModel | undefined; + + if (chatModels[provider] && chatModels[provider][chatModel]) { + llm = chatModels[provider][chatModel] as BaseChatModel | undefined; + } + + if (!llm) { + res.status(500).json({ message: 'Invalid LLM model selected' }); + return; + } + + const suggestions = await generateSuggestions({ chat_history }, llm); + + res.status(200).json({ suggestions: suggestions }); + } catch (err) { + res.status(500).json({ message: 'An error has occurred.' }); + logger.error(`Error in generating suggestions: ${err.message}`); + } +}); + +export default router; From 9a7af945b04d9986e68f81eeeee15accea97ed73 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Thu, 9 May 2024 20:43:04 +0530 Subject: [PATCH 12/34] lint --- docker-compose.yaml | 2 +- package.json | 2 +- src/lib/providers.ts | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 5eef31e..f9b3757 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -36,4 +36,4 @@ services: - perplexica-network networks: - perplexica-network: \ No newline at end of file + perplexica-network: diff --git a/package.json b/package.json index a4af068..c3aa58d 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "start": "node dist/app.js", "build": "tsc", - "dev": "nodemon src/app.ts" , + "dev": "nodemon src/app.ts", "format": "prettier . --check", "format:write": "prettier . --write" }, diff --git a/src/lib/providers.ts b/src/lib/providers.ts index d2e40f0..c817f87 100644 --- a/src/lib/providers.ts +++ b/src/lib/providers.ts @@ -157,7 +157,6 @@ export const getAvailableEmbeddingModelProviders = async () => { }); return acc; }, {}); - } catch (err) { logger.error(`Error loading Ollama embeddings: ${err}`); } @@ -172,11 +171,11 @@ export const getAvailableEmbeddingModelProviders = async () => { modelName: 'Xenova/gte-small', }), 'Bert Multilingual': new HuggingFaceTransformersEmbeddings({ - modelName: 'Xenova/bert-base-multilingual-uncased' + modelName: 'Xenova/bert-base-multilingual-uncased', }), }; - } catch(err) { - logger.error(`Error loading local embeddings: ${err}`); + } catch (err) { + logger.error(`Error loading local embeddings: ${err}`); } return models; From 7eace1e6bd3b7279df09e1a9cd8c84e2a5a6ebd1 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Fri, 10 May 2024 20:55:08 +0530 Subject: [PATCH 13/34] feat(searxng-container): bind mount & add limiter --- docker-compose.yaml | 6 +-- searxng.dockerfile | 3 -- searxng/limiter.toml | 3 ++ searxng-settings.yml => searxng/settings.yml | 0 searxng/uwsgi.ini | 50 ++++++++++++++++++++ 5 files changed, 56 insertions(+), 6 deletions(-) delete mode 100644 searxng.dockerfile create mode 100644 searxng/limiter.toml rename searxng-settings.yml => searxng/settings.yml (100%) create mode 100644 searxng/uwsgi.ini diff --git a/docker-compose.yaml b/docker-compose.yaml index f9b3757..6304f34 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,10 +1,10 @@ services: searxng: - build: - context: . - dockerfile: searxng.dockerfile + image: docker.io/searxng/searxng:latest ports: - 4000:8080 + volumes: + - ./searxng:/etc/searxng:rw networks: - perplexica-network diff --git a/searxng.dockerfile b/searxng.dockerfile deleted file mode 100644 index 8bcd2b2..0000000 --- a/searxng.dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM searxng/searxng - -COPY searxng-settings.yml /etc/searxng/settings.yml \ No newline at end of file diff --git a/searxng/limiter.toml b/searxng/limiter.toml new file mode 100644 index 0000000..ae69bd3 --- /dev/null +++ b/searxng/limiter.toml @@ -0,0 +1,3 @@ +[botdetection.ip_limit] +# activate link_token method in the ip_limit method +link_token = true \ No newline at end of file diff --git a/searxng-settings.yml b/searxng/settings.yml similarity index 100% rename from searxng-settings.yml rename to searxng/settings.yml diff --git a/searxng/uwsgi.ini b/searxng/uwsgi.ini new file mode 100644 index 0000000..dd1247a --- /dev/null +++ b/searxng/uwsgi.ini @@ -0,0 +1,50 @@ +[uwsgi] +# Who will run the code +uid = searxng +gid = searxng + +# Number of workers (usually CPU count) +# default value: %k (= number of CPU core, see Dockerfile) +workers = %k + +# Number of threads per worker +# default value: 4 (see Dockerfile) +threads = 4 + +# The right granted on the created socket +chmod-socket = 666 + +# Plugin to use and interpreter config +single-interpreter = true +master = true +plugin = python3 +lazy-apps = true +enable-threads = 4 + +# Module to import +module = searx.webapp + +# Virtualenv and python path +pythonpath = /usr/local/searxng/ +chdir = /usr/local/searxng/searx/ + +# automatically set processes name to something meaningful +auto-procname = true + +# Disable request logging for privacy +disable-logging = true +log-5xx = true + +# Set the max size of a request (request-body excluded) +buffer-size = 8192 + +# No keep alive +# See https://github.com/searx/searx-docker/issues/24 +add-header = Connection: close + +# uwsgi serves the static files +static-map = /static=/usr/local/searxng/searx/static +# expires set to one day +static-expires = /* 86400 +static-gzip-all = True +offload-threads = 4 From a60145137c677a021df611e236fb8f3f478976ae Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 11 May 2024 10:23:05 +0530 Subject: [PATCH 14/34] feat(docs): add networking --- README.md | 5 ++ docs/installation/NETWORKING.md | 96 +++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 docs/installation/NETWORKING.md diff --git a/README.md b/README.md index e45e80a..4735c7f 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ - [Features](#features) - [Installation](#installation) - [Getting Started with Docker (Recommended)](#getting-started-with-docker-recommended) + - [Exposing to network](#exposing-to-network) - [Non-Docker Installation](#non-docker-installation) - [Ollama connection errors](#ollama-connection-errors) - [One-Click Deployment](#one-click-deployment) @@ -82,6 +83,10 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. **Note**: After the containers are built, you can start Perplexica directly from Docker without having to open a terminal. +#### Exposing to network + +If you wish to expose Perplexica to your network and use it accross all devices on that network you can read [NETWORKING.md](https://github.com/ItzCrazyKns/Perplexica/blob/master/docs/installation/NETWORKING.md). + ### Non-Docker Installation 1. Clone the repository and rename the `sample.config.toml` file to `config.toml` in the root directory. Ensure you complete all required fields in this file. diff --git a/docs/installation/NETWORKING.md b/docs/installation/NETWORKING.md new file mode 100644 index 0000000..25f994a --- /dev/null +++ b/docs/installation/NETWORKING.md @@ -0,0 +1,96 @@ +# Expose Perplexica to a network + +This guide will show you how to make Perplexica available over a network. Follow these steps to allow computers on the same network to interact with Perplexica. Choose the instructions that match the operating system you are using. + +## Windows + +1. Open PowerShell as Administrator + +2. Navigate to the directory containing the `docker-compose.yaml` file + +3. Stop and remove the existing Perplexica containers and images: +``` +docker compose down --rmi all +``` + +4. Open the `docker-compose.yaml` file in a text editor like Notepad++ + +5. Replace `127.0.0.1` with the IP address of the server Perplexica is running on in these two lines: +``` +args: + - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 +``` + +6. Save and close the `docker-compose.yaml` file + +7. Rebuild and restart the Perplexica container: +``` +docker compose up -d --build +``` + +## macOS + +1. Open the Terminal application + +2. Navigate to the directory with the `docker-compose.yaml` file: +``` +cd /path/to/docker-compose.yaml +``` + +3. Stop and remove existing containers and images: +``` +docker compose down --rmi all +``` + +4. Open `docker-compose.yaml` in a text editor like Sublime Text: +``` +nano docker-compose.yaml +``` + +5. Replace `127.0.0.1` with the server IP in these lines: +``` +args: + - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 +``` + +6. Save and exit the editor + +7. Rebuild and restart Perplexica: +``` +docker compose up -d --build +``` + +## Linux + +1. Open the terminal + +2. Navigate to the `docker-compose.yaml` directory: +``` +cd /path/to/docker-compose.yaml +``` + +3. Stop and remove containers and images: +``` +docker compose down --rmi all +``` + +4. Edit `docker-compose.yaml`: +``` +nano docker-compose.yaml +``` + +5. Replace `127.0.0.1` with the server IP: +``` +args: + - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 +``` + +6. Save and exit the editor + +7. Rebuild and restart Perplexica: +``` +docker compose up -d --build +``` \ No newline at end of file From 7a28be9e1a86fef4508a6f46840f12ac1e0c07fb Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 11 May 2024 12:09:08 +0530 Subject: [PATCH 15/34] feat(readme): add installation docs --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4735c7f..bb8f1dd 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ - [Features](#features) - [Installation](#installation) - [Getting Started with Docker (Recommended)](#getting-started-with-docker-recommended) - - [Exposing to network](#exposing-to-network) - [Non-Docker Installation](#non-docker-installation) - [Ollama connection errors](#ollama-connection-errors) - [One-Click Deployment](#one-click-deployment) @@ -83,10 +82,6 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. **Note**: After the containers are built, you can start Perplexica directly from Docker without having to open a terminal. -#### Exposing to network - -If you wish to expose Perplexica to your network and use it accross all devices on that network you can read [NETWORKING.md](https://github.com/ItzCrazyKns/Perplexica/blob/master/docs/installation/NETWORKING.md). - ### Non-Docker Installation 1. Clone the repository and rename the `sample.config.toml` file to `config.toml` in the root directory. Ensure you complete all required fields in this file. @@ -97,6 +92,8 @@ If you wish to expose Perplexica to your network and use it accross all devices **Note**: Using Docker is recommended as it simplifies the setup process, especially for managing environment variables and dependencies. +See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information. + ### Ollama connection errors If you're facing an Ollama connection error, it is often related to the backend not being able to connect to Ollama's API. How can you fix it? You can fix it by updating your Ollama API URL in the settings menu to the following: From 3ef39c69a76eb67278aba6af2132e69da461cbe7 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 11 May 2024 12:09:39 +0530 Subject: [PATCH 16/34] feat(chat-window): add ability to use `q` query param --- ui/components/ChatWindow.tsx | 31 +++++++++++++++++++++---- ui/components/EmptyChatMessageInput.tsx | 2 +- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ui/components/ChatWindow.tsx b/ui/components/ChatWindow.tsx index 6f58757..1cc6ae0 100644 --- a/ui/components/ChatWindow.tsx +++ b/ui/components/ChatWindow.tsx @@ -6,6 +6,7 @@ import Navbar from './Navbar'; import Chat from './Chat'; import EmptyChat from './EmptyChat'; import { toast } from 'sonner'; +import { useSearchParams } from 'next/navigation'; export type Message = { id: string; @@ -15,7 +16,7 @@ export type Message = { sources?: Document[]; }; -const useSocket = (url: string) => { +const useSocket = (url: string, setIsReady: (ready: boolean) => void) => { const [ws, setWs] = useState(null); useEffect(() => { @@ -101,9 +102,17 @@ const useSocket = (url: string) => { ws.onopen = () => { console.log('[DEBUG] open'); - setWs(ws); }; + const stateCheckInterval = setInterval(() => { + if (ws.readyState === 1) { + setIsReady(true); + clearInterval(stateCheckInterval); + } + }, 100); + + setWs(ws); + ws.onmessage = (e) => { const parsedData = JSON.parse(e.data); if (parsedData.type === 'error') { @@ -122,13 +131,18 @@ const useSocket = (url: string) => { ws?.close(); console.log('[DEBUG] closed'); }; - }, [ws, url]); + }, [ws, url, setIsReady]); return ws; }; const ChatWindow = () => { - const ws = useSocket(process.env.NEXT_PUBLIC_WS_URL!); + const searchParams = useSearchParams(); + const initialMessage = searchParams.get('q'); + + const [isReady, setIsReady] = useState(false); + const ws = useSocket(process.env.NEXT_PUBLIC_WS_URL!, setIsReady); + const [chatHistory, setChatHistory] = useState<[string, string][]>([]); const [messages, setMessages] = useState([]); const [loading, setLoading] = useState(false); @@ -250,7 +264,14 @@ const ChatWindow = () => { sendMessage(message.content); }; - return ws ? ( + useEffect(() => { + if (isReady && initialMessage) { + sendMessage(initialMessage); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isReady, initialMessage]); + + return isReady ? (
{messages.length > 0 ? ( <> diff --git a/ui/components/EmptyChatMessageInput.tsx b/ui/components/EmptyChatMessageInput.tsx index 2e3ab53..4932803 100644 --- a/ui/components/EmptyChatMessageInput.tsx +++ b/ui/components/EmptyChatMessageInput.tsx @@ -1,7 +1,7 @@ import { ArrowRight } from 'lucide-react'; import { useState } from 'react'; import TextareaAutosize from 'react-textarea-autosize'; -import { Attach, CopilotToggle, Focus } from './MessageInputActions'; +import { CopilotToggle, Focus } from './MessageInputActions'; const EmptyChatMessageInput = ({ sendMessage, From 954b4bf89ac09525d2f29d06db906aeedc7c408c Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 11 May 2024 12:14:49 +0530 Subject: [PATCH 17/34] feat(readme): add search engine guide --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index bb8f1dd..be16cc1 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ - [Getting Started with Docker (Recommended)](#getting-started-with-docker-recommended) - [Non-Docker Installation](#non-docker-installation) - [Ollama connection errors](#ollama-connection-errors) +- [Using as a Search Engine](#using-as-a-search-engine) - [One-Click Deployment](#one-click-deployment) - [Upcoming Features](#upcoming-features) - [Support Us](#support-us) @@ -104,6 +105,15 @@ On Linux: `http://private_ip_of_computer_hosting_ollama:11434` You need to edit the ports accordingly. +## Using as a Search Engine + +If you wish to use Perplexica as an alternative to traditional search engines like Google or Bing, or if you want to add a shortcut for quick access from your browser's search bar, follow these steps: + +1. Open your browser's settings. +2. Navigate to the 'Search Engines' section. +3. Add a new site search with the following URL: `http://localhost:3000/?q=%s`. Replace `localhost` with your IP address or domain name, and `3000` with the port number if Perplexica is not hosted locally. +4. Click the add button. Now, you can use Perplexica directly from your browser's search bar. + ## One-Click Deployment [![Deploy to RepoCloud](https://d16t0pc4846x52.cloudfront.net/deploylobe.svg)](https://repocloud.io/details/?app_id=267) From c852bee8ed99092d7956b913bdd611ddb8eca300 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 11 May 2024 21:19:38 +0530 Subject: [PATCH 18/34] feat(app): add suspense boundary --- ui/app/page.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/app/page.tsx b/ui/app/page.tsx index 982763a..e18aca9 100644 --- a/ui/app/page.tsx +++ b/ui/app/page.tsx @@ -1,5 +1,6 @@ import ChatWindow from '@/components/ChatWindow'; import { Metadata } from 'next'; +import { Suspense } from 'react'; export const metadata: Metadata = { title: 'Chat - Perplexica', @@ -9,7 +10,9 @@ export const metadata: Metadata = { const Home = () => { return (
- + + +
); }; From 828eeb0c776d947c4ee74fdbbf24386a33f5cdc3 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 12 May 2024 12:14:52 +0530 Subject: [PATCH 19/34] feat(app-dockerfile): add `PORT` arg --- app.dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app.dockerfile b/app.dockerfile index 105cf86..ab8bfaa 100644 --- a/app.dockerfile +++ b/app.dockerfile @@ -2,8 +2,11 @@ FROM node:alpine ARG NEXT_PUBLIC_WS_URL ARG NEXT_PUBLIC_API_URL +ARG PORT + ENV NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL} ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} +ENV PORT=${PORT} WORKDIR /home/perplexica From 9816eb1d3662c6911ba8849a721cc006437767e0 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 12 May 2024 12:15:25 +0530 Subject: [PATCH 20/34] feat(server): add bind address --- sample.config.toml | 5 +++-- src/app.ts | 5 +++-- src/config.ts | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/sample.config.toml b/sample.config.toml index 7bc8880..5342fe4 100644 --- a/sample.config.toml +++ b/sample.config.toml @@ -1,5 +1,6 @@ [GENERAL] -PORT = 3001 # Port to run the server on +PORT = 31338 # Port to run the server on +BIND_ADDRESS = "0.0.0.0" SIMILARITY_MEASURE = "cosine" # "cosine" or "dot" [API_KEYS] @@ -8,4 +9,4 @@ GROQ = "" # Groq API key - gsk_1234567890abcdef1234567890abcdef [API_ENDPOINTS] SEARXNG = "http://localhost:32768" # SearxNG API URL -OLLAMA = "" # Ollama API URL - http://host.docker.internal:11434 +OLLAMA = "" # Ollama API URL - http://127.0.0.1:11434 diff --git a/src/app.ts b/src/app.ts index b8c2371..33184bf 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,10 +3,11 @@ import express from 'express'; import cors from 'cors'; import http from 'http'; import routes from './routes'; -import { getPort } from './config'; +import { getBindAddress, getPort } from './config'; import logger from './utils/logger'; const port = getPort(); +const bindAddress = getBindAddress(); const app = express(); const server = http.createServer(app); @@ -23,7 +24,7 @@ app.get('/api', (_, res) => { res.status(200).json({ status: 'ok' }); }); -server.listen(port, () => { +server.listen(port, bindAddress, () => { logger.info(`Server is running on port ${port}`); }); diff --git a/src/config.ts b/src/config.ts index 7c0c7f1..f600f58 100644 --- a/src/config.ts +++ b/src/config.ts @@ -7,6 +7,7 @@ const configFileName = 'config.toml'; interface Config { GENERAL: { PORT: number; + BIND_ADDRESS: string; SIMILARITY_MEASURE: string; }; API_KEYS: { @@ -30,6 +31,8 @@ const loadConfig = () => export const getPort = () => loadConfig().GENERAL.PORT; +export const getBindAddress = () => loadConfig().GENERAL.BIND_ADDRESS; + export const getSimilarityMeasure = () => loadConfig().GENERAL.SIMILARITY_MEASURE; From 1b18715f8f2ccc6ec54fc80aa7f22e51b77f068d Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 12 May 2024 12:15:53 +0530 Subject: [PATCH 21/34] feat(docs): update PORT --- README.md | 17 +++-------------- docs/installation/NETWORKING.md | 33 +++++++++++++++++++++++---------- ui/.env.example | 5 +++-- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index be16cc1..81043c8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ - [Installation](#installation) - [Getting Started with Docker (Recommended)](#getting-started-with-docker-recommended) - [Non-Docker Installation](#non-docker-installation) - - [Ollama connection errors](#ollama-connection-errors) - [Using as a Search Engine](#using-as-a-search-engine) - [One-Click Deployment](#one-click-deployment) - [Upcoming Features](#upcoming-features) @@ -66,7 +65,7 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. 4. Rename the `sample.config.toml` file to `config.toml`. For Docker setups, you need only fill in the following fields: - `OPENAI`: Your OpenAI API key. **You only need to fill this if you wish to use OpenAI's models**. - - `OLLAMA`: Your Ollama API URL. You should enter it as `http://host.docker.internal:PORT_NUMBER`. If you installed Ollama on port 11434, use `http://host.docker.internal:11434`. For other ports, adjust accordingly. **You need to fill this if you wish to use Ollama's models instead of OpenAI's**. + - `OLLAMA`: Your Ollama API URL. If Ollama is hosted on the same computer as Perplexica, you should enter it as `http://127.0.0.1:PORT_NUMBER`. If you installed Ollama on port 11434, use `http://127.0.0.1:11434`. For other ports, adjust accordingly. If Ollama is running on some other server use the server's IP with port or domain in place of it. **You need to fill this if you wish to use Ollama's models instead of OpenAI's**. - `GROQ`: Your Groq API key. **You only need to fill this if you wish to use Groq's hosted models** **Note**: You can change these after starting Perplexica from the settings dialog. @@ -79,7 +78,7 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. docker compose up -d ``` -6. Wait a few minutes for the setup to complete. You can access Perplexica at http://localhost:3000 in your web browser. +6. Wait a few minutes for the setup to complete. You can access Perplexica at http://localhost:31337 in your web browser. **Note**: After the containers are built, you can start Perplexica directly from Docker without having to open a terminal. @@ -95,23 +94,13 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information. -### Ollama connection errors - -If you're facing an Ollama connection error, it is often related to the backend not being able to connect to Ollama's API. How can you fix it? You can fix it by updating your Ollama API URL in the settings menu to the following: - -On Windows: `http://host.docker.internal:11434`
-On Mac: `http://host.docker.internal:11434`
-On Linux: `http://private_ip_of_computer_hosting_ollama:11434` - -You need to edit the ports accordingly. - ## Using as a Search Engine If you wish to use Perplexica as an alternative to traditional search engines like Google or Bing, or if you want to add a shortcut for quick access from your browser's search bar, follow these steps: 1. Open your browser's settings. 2. Navigate to the 'Search Engines' section. -3. Add a new site search with the following URL: `http://localhost:3000/?q=%s`. Replace `localhost` with your IP address or domain name, and `3000` with the port number if Perplexica is not hosted locally. +3. Add a new site search with the following URL: `http://localhost:31337/?q=%s`. Replace `localhost` with your IP address or domain name, and `31337` with the port number if Perplexica is not hosted locally. 4. Click the add button. Now, you can use Perplexica directly from your browser's search bar. ## One-Click Deployment diff --git a/docs/installation/NETWORKING.md b/docs/installation/NETWORKING.md index 25f994a..29e603f 100644 --- a/docs/installation/NETWORKING.md +++ b/docs/installation/NETWORKING.md @@ -9,6 +9,7 @@ This guide will show you how to make Perplexica available over a network. Follow 2. Navigate to the directory containing the `docker-compose.yaml` file 3. Stop and remove the existing Perplexica containers and images: + ``` docker compose down --rmi all ``` @@ -16,81 +17,93 @@ docker compose down --rmi all 4. Open the `docker-compose.yaml` file in a text editor like Notepad++ 5. Replace `127.0.0.1` with the IP address of the server Perplexica is running on in these two lines: + ``` args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 ``` 6. Save and close the `docker-compose.yaml` file 7. Rebuild and restart the Perplexica container: + ``` docker compose up -d --build ``` -## macOS +## macOS 1. Open the Terminal application 2. Navigate to the directory with the `docker-compose.yaml` file: + ``` cd /path/to/docker-compose.yaml ``` 3. Stop and remove existing containers and images: + ``` docker compose down --rmi all ``` 4. Open `docker-compose.yaml` in a text editor like Sublime Text: + ``` nano docker-compose.yaml ``` 5. Replace `127.0.0.1` with the server IP in these lines: + ``` args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 ``` 6. Save and exit the editor 7. Rebuild and restart Perplexica: + ``` -docker compose up -d --build +docker compose up -d --build ``` ## Linux -1. Open the terminal +1. Open the terminal 2. Navigate to the `docker-compose.yaml` directory: + ``` cd /path/to/docker-compose.yaml ``` 3. Stop and remove containers and images: + ``` docker compose down --rmi all ``` 4. Edit `docker-compose.yaml`: + ``` nano docker-compose.yaml ``` 5. Replace `127.0.0.1` with the server IP: + ``` args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 ``` 6. Save and exit the editor 7. Rebuild and restart Perplexica: + ``` docker compose up -d --build -``` \ No newline at end of file +``` diff --git a/ui/.env.example b/ui/.env.example index 57a3ed9..4d12554 100644 --- a/ui/.env.example +++ b/ui/.env.example @@ -1,2 +1,3 @@ -NEXT_PUBLIC_WS_URL=ws://localhost:3001 -NEXT_PUBLIC_API_URL=http://localhost:3001/api \ No newline at end of file +NEXT_PUBLIC_WS_URL=ws://localhost:31338 +NEXT_PUBLIC_API_URL=http://localhost:31338/api +PORT=31337 \ No newline at end of file From b622df5a9fbacd468a8deeaa492fabd01a26ec6a Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 12 May 2024 12:16:08 +0530 Subject: [PATCH 22/34] feat(docker-compose): update ports, change network type --- docker-compose.yaml | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 6304f34..e11bf4e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,39 +1,30 @@ services: searxng: image: docker.io/searxng/searxng:latest - ports: - - 4000:8080 volumes: - ./searxng:/etc/searxng:rw - networks: - - perplexica-network + ports: + - 31336:8080 perplexica-backend: build: context: . dockerfile: backend.dockerfile args: - - SEARXNG_API_URL=http://searxng:8080 + - SEARXNG_API_URL=http://127.0.0.1:31336 depends_on: - searxng - ports: - - 3001:3001 - networks: - - perplexica-network + network_mode: host perplexica-frontend: build: context: . dockerfile: app.dockerfile args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 + - PORT=31337 depends_on: - perplexica-backend ports: - - 3000:3000 - networks: - - perplexica-network - -networks: - perplexica-network: + - 31337:31337 From 9d30224faad7b288cc112cde2ec6c694e6d4e8c6 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 12 May 2024 12:24:36 +0530 Subject: [PATCH 23/34] feat(readme): update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 81043c8..9b81615 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. **Note**: Using Docker is recommended as it simplifies the setup process, especially for managing environment variables and dependencies. -See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information. +See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information like exposing it your network, etc. ## Using as a Search Engine From 22aee27cda8d635228901cb35b54a8aed290d8a2 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 12 May 2024 12:48:01 +0530 Subject: [PATCH 24/34] feat(env): remove port --- ui/.env.example | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/.env.example b/ui/.env.example index 4d12554..9869283 100644 --- a/ui/.env.example +++ b/ui/.env.example @@ -1,3 +1,2 @@ NEXT_PUBLIC_WS_URL=ws://localhost:31338 -NEXT_PUBLIC_API_URL=http://localhost:31338/api -PORT=31337 \ No newline at end of file +NEXT_PUBLIC_API_URL=http://localhost:31338/api \ No newline at end of file From 100872f2d9da03a5a85eb710b212de93f7779461 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 12 May 2024 14:04:05 +0530 Subject: [PATCH 25/34] feat(docker-compose): revert network changes --- README.md | 13 ++++++++++++- docker-compose.yaml | 14 ++++++++++++-- sample.config.toml | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b81615..9235e4e 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - [Installation](#installation) - [Getting Started with Docker (Recommended)](#getting-started-with-docker-recommended) - [Non-Docker Installation](#non-docker-installation) + - [Ollama connection errors](#ollama-connection-errors) - [Using as a Search Engine](#using-as-a-search-engine) - [One-Click Deployment](#one-click-deployment) - [Upcoming Features](#upcoming-features) @@ -65,7 +66,7 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. 4. Rename the `sample.config.toml` file to `config.toml`. For Docker setups, you need only fill in the following fields: - `OPENAI`: Your OpenAI API key. **You only need to fill this if you wish to use OpenAI's models**. - - `OLLAMA`: Your Ollama API URL. If Ollama is hosted on the same computer as Perplexica, you should enter it as `http://127.0.0.1:PORT_NUMBER`. If you installed Ollama on port 11434, use `http://127.0.0.1:11434`. For other ports, adjust accordingly. If Ollama is running on some other server use the server's IP with port or domain in place of it. **You need to fill this if you wish to use Ollama's models instead of OpenAI's**. + - `OLLAMA`: Your Ollama API URL. You should enter it as `http://host.docker.internal:PORT_NUMBER`. If you installed Ollama on port 11434, use `http://host.docker.internal:11434`. For other ports, adjust accordingly. **You need to fill this if you wish to use Ollama's models instead of OpenAI's**. - `GROQ`: Your Groq API key. **You only need to fill this if you wish to use Groq's hosted models** **Note**: You can change these after starting Perplexica from the settings dialog. @@ -94,6 +95,16 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information like exposing it your network, etc. +### Ollama connection errors + +If you're facing an Ollama connection error, it is often related to the backend not being able to connect to Ollama's API. How can you fix it? You can fix it by updating your Ollama API URL in the settings menu to the following: + +On Windows: `http://host.docker.internal:11434`
+On Mac: `http://host.docker.internal:11434`
+On Linux: `http://private_ip_of_computer_hosting_ollama:11434` + +You need to edit the ports accordingly. + ## Using as a Search Engine If you wish to use Perplexica as an alternative to traditional search engines like Google or Bing, or if you want to add a shortcut for quick access from your browser's search bar, follow these steps: diff --git a/docker-compose.yaml b/docker-compose.yaml index e11bf4e..dc55c29 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,16 +5,21 @@ services: - ./searxng:/etc/searxng:rw ports: - 31336:8080 + networks: + - perplexica-network perplexica-backend: build: context: . dockerfile: backend.dockerfile args: - - SEARXNG_API_URL=http://127.0.0.1:31336 + - SEARXNG_API_URL=http://searxng:8080 depends_on: - searxng - network_mode: host + ports: + - 31338:31338 + networks: + - perplexica-network perplexica-frontend: build: @@ -28,3 +33,8 @@ services: - perplexica-backend ports: - 31337:31337 + networks: + - perplexica-network + +networks: + perplexica-network: \ No newline at end of file diff --git a/sample.config.toml b/sample.config.toml index 5342fe4..3c7f31b 100644 --- a/sample.config.toml +++ b/sample.config.toml @@ -9,4 +9,4 @@ GROQ = "" # Groq API key - gsk_1234567890abcdef1234567890abcdef [API_ENDPOINTS] SEARXNG = "http://localhost:32768" # SearxNG API URL -OLLAMA = "" # Ollama API URL - http://127.0.0.1:11434 +OLLAMA = "" # Ollama API URL - http://host.docker.internal:11434 From 0993c5a760bfe894ce210a714cb2ee83b8a89880 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Mon, 13 May 2024 19:58:17 +0530 Subject: [PATCH 26/34] feat(app): revert port & network changes --- app.dockerfile | 3 --- docker-compose.yaml | 13 ++++++------- sample.config.toml | 5 ++--- src/app.ts | 5 ++--- src/config.ts | 3 --- ui/.env.example | 4 ++-- 6 files changed, 12 insertions(+), 21 deletions(-) diff --git a/app.dockerfile b/app.dockerfile index ab8bfaa..105cf86 100644 --- a/app.dockerfile +++ b/app.dockerfile @@ -2,11 +2,8 @@ FROM node:alpine ARG NEXT_PUBLIC_WS_URL ARG NEXT_PUBLIC_API_URL -ARG PORT - ENV NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL} ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} -ENV PORT=${PORT} WORKDIR /home/perplexica diff --git a/docker-compose.yaml b/docker-compose.yaml index dc55c29..ac83575 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -4,7 +4,7 @@ services: volumes: - ./searxng:/etc/searxng:rw ports: - - 31336:8080 + - 4000:8080 networks: - perplexica-network @@ -17,7 +17,7 @@ services: depends_on: - searxng ports: - - 31338:31338 + - 3001:3001 networks: - perplexica-network @@ -26,15 +26,14 @@ services: context: . dockerfile: app.dockerfile args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 - - PORT=31337 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 depends_on: - perplexica-backend ports: - - 31337:31337 + - 3000:3000 networks: - perplexica-network networks: - perplexica-network: \ No newline at end of file + perplexica-network: diff --git a/sample.config.toml b/sample.config.toml index 3c7f31b..8d35666 100644 --- a/sample.config.toml +++ b/sample.config.toml @@ -1,6 +1,5 @@ [GENERAL] -PORT = 31338 # Port to run the server on -BIND_ADDRESS = "0.0.0.0" +PORT = 3001 # Port to run the server on SIMILARITY_MEASURE = "cosine" # "cosine" or "dot" [API_KEYS] @@ -9,4 +8,4 @@ GROQ = "" # Groq API key - gsk_1234567890abcdef1234567890abcdef [API_ENDPOINTS] SEARXNG = "http://localhost:32768" # SearxNG API URL -OLLAMA = "" # Ollama API URL - http://host.docker.internal:11434 +OLLAMA = "" # Ollama API URL - http://host.docker.internal:11434 \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index 33184bf..b8c2371 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,11 +3,10 @@ import express from 'express'; import cors from 'cors'; import http from 'http'; import routes from './routes'; -import { getBindAddress, getPort } from './config'; +import { getPort } from './config'; import logger from './utils/logger'; const port = getPort(); -const bindAddress = getBindAddress(); const app = express(); const server = http.createServer(app); @@ -24,7 +23,7 @@ app.get('/api', (_, res) => { res.status(200).json({ status: 'ok' }); }); -server.listen(port, bindAddress, () => { +server.listen(port, () => { logger.info(`Server is running on port ${port}`); }); diff --git a/src/config.ts b/src/config.ts index f600f58..7c0c7f1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -7,7 +7,6 @@ const configFileName = 'config.toml'; interface Config { GENERAL: { PORT: number; - BIND_ADDRESS: string; SIMILARITY_MEASURE: string; }; API_KEYS: { @@ -31,8 +30,6 @@ const loadConfig = () => export const getPort = () => loadConfig().GENERAL.PORT; -export const getBindAddress = () => loadConfig().GENERAL.BIND_ADDRESS; - export const getSimilarityMeasure = () => loadConfig().GENERAL.SIMILARITY_MEASURE; diff --git a/ui/.env.example b/ui/.env.example index 9869283..57a3ed9 100644 --- a/ui/.env.example +++ b/ui/.env.example @@ -1,2 +1,2 @@ -NEXT_PUBLIC_WS_URL=ws://localhost:31338 -NEXT_PUBLIC_API_URL=http://localhost:31338/api \ No newline at end of file +NEXT_PUBLIC_WS_URL=ws://localhost:3001 +NEXT_PUBLIC_API_URL=http://localhost:3001/api \ No newline at end of file From 0e2f4514b421058372b26a10dda6117694b016b5 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Mon, 13 May 2024 20:10:44 +0530 Subject: [PATCH 27/34] feat(readme): update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9235e4e..0cf197b 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. docker compose up -d ``` -6. Wait a few minutes for the setup to complete. You can access Perplexica at http://localhost:31337 in your web browser. +6. Wait a few minutes for the setup to complete. You can access Perplexica at http://localhost:3000 in your web browser. **Note**: After the containers are built, you can start Perplexica directly from Docker without having to open a terminal. @@ -111,7 +111,7 @@ If you wish to use Perplexica as an alternative to traditional search engines li 1. Open your browser's settings. 2. Navigate to the 'Search Engines' section. -3. Add a new site search with the following URL: `http://localhost:31337/?q=%s`. Replace `localhost` with your IP address or domain name, and `31337` with the port number if Perplexica is not hosted locally. +3. Add a new site search with the following URL: `http://localhost:3000/?q=%s`. Replace `localhost` with your IP address or domain name, and `3000` with the port number if Perplexica is not hosted locally. 4. Click the add button. Now, you can use Perplexica directly from your browser's search bar. ## One-Click Deployment From 180e204c2d6da5395011d8548ee0649107fa37a8 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Tue, 14 May 2024 19:33:54 +0530 Subject: [PATCH 28/34] feat(providers): add GPT-4 omni --- src/lib/providers.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/providers.ts b/src/lib/providers.ts index c817f87..3223193 100644 --- a/src/lib/providers.ts +++ b/src/lib/providers.ts @@ -34,6 +34,11 @@ export const getAvailableChatModelProviders = async () => { modelName: 'gpt-4-turbo', temperature: 0.7, }), + 'GPT-4 omni': new ChatOpenAI({ + openAIApiKey, + modelName: 'gpt-4o', + temperature: 0.7, + }), }; } catch (err) { logger.error(`Error loading OpenAI models: ${err}`); From 68b595023e8da06a9c87bf26c4d376ee7e9ecc5e Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 18 May 2024 13:10:09 +0530 Subject: [PATCH 29/34] feat(suggestion-generator): update prompt --- src/agents/suggestionGeneratorAgent.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/agents/suggestionGeneratorAgent.ts b/src/agents/suggestionGeneratorAgent.ts index 59bd9ea..0efdfa9 100644 --- a/src/agents/suggestionGeneratorAgent.ts +++ b/src/agents/suggestionGeneratorAgent.ts @@ -14,9 +14,9 @@ Make sure the suggestions are medium in length and are informative and relevant Provide these suggestions separated by newlines between the XML tags and . For example: -Suggestion 1 -Suggestion 2 -Suggestion 3 +Tell me more about SpaceX and their recent projects +What is the latest news on SpaceX? +Who is the CEO of SpaceX? Conversation: From 3bfaf9be2804387ce91d2f8bd4da5a88c0f78ce8 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 18 May 2024 13:10:39 +0530 Subject: [PATCH 30/34] feat(app): add suggestion generation --- src/lib/outputParsers/listLineOutputParser.ts | 2 +- ui/components/Chat.tsx | 1 + ui/components/ChatWindow.tsx | 31 +++++++++++++++++-- ui/lib/actions.ts | 22 +++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 ui/lib/actions.ts diff --git a/src/lib/outputParsers/listLineOutputParser.ts b/src/lib/outputParsers/listLineOutputParser.ts index 4fde080..57a9bbc 100644 --- a/src/lib/outputParsers/listLineOutputParser.ts +++ b/src/lib/outputParsers/listLineOutputParser.ts @@ -9,7 +9,7 @@ class LineListOutputParser extends BaseOutputParser { constructor(args?: LineListOutputParserArgs) { super(); - this.key = args.key || this.key; + this.key = args.key ?? this.key; } static lc_name() { diff --git a/ui/components/Chat.tsx b/ui/components/Chat.tsx index ddd2957..7b0c1b3 100644 --- a/ui/components/Chat.tsx +++ b/ui/components/Chat.tsx @@ -63,6 +63,7 @@ const Chat = ({ dividerRef={isLast ? dividerRef : undefined} isLast={isLast} rewrite={rewrite} + sendMessage={sendMessage} /> {!isLast && msg.role === 'assistant' && (
diff --git a/ui/components/ChatWindow.tsx b/ui/components/ChatWindow.tsx index 1cc6ae0..5f266b5 100644 --- a/ui/components/ChatWindow.tsx +++ b/ui/components/ChatWindow.tsx @@ -1,18 +1,20 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Document } from '@langchain/core/documents'; import Navbar from './Navbar'; import Chat from './Chat'; import EmptyChat from './EmptyChat'; import { toast } from 'sonner'; import { useSearchParams } from 'next/navigation'; +import { getSuggestions } from '@/lib/actions'; export type Message = { id: string; createdAt: Date; content: string; role: 'user' | 'assistant'; + suggestions?: string[]; sources?: Document[]; }; @@ -145,10 +147,15 @@ const ChatWindow = () => { const [chatHistory, setChatHistory] = useState<[string, string][]>([]); const [messages, setMessages] = useState([]); + const messagesRef = useRef([]); const [loading, setLoading] = useState(false); const [messageAppeared, setMessageAppeared] = useState(false); const [focusMode, setFocusMode] = useState('webSearch'); + useEffect(() => { + messagesRef.current = messages; + }, [messages]); + const sendMessage = async (message: string) => { if (loading) return; setLoading(true); @@ -177,7 +184,7 @@ const ChatWindow = () => { }, ]); - const messageHandler = (e: MessageEvent) => { + const messageHandler = async (e: MessageEvent) => { const data = JSON.parse(e.data); if (data.type === 'error') { @@ -239,8 +246,28 @@ const ChatWindow = () => { ['human', message], ['assistant', recievedMessage], ]); + ws?.removeEventListener('message', messageHandler); setLoading(false); + + const lastMsg = messagesRef.current[messagesRef.current.length - 1]; + + if ( + lastMsg.role === 'assistant' && + lastMsg.sources && + lastMsg.sources.length > 0 && + !lastMsg.suggestions + ) { + const suggestions = await getSuggestions(messagesRef.current); + setMessages((prev) => + prev.map((msg) => { + if (msg.id === lastMsg.id) { + return { ...msg, suggestions: suggestions }; + } + return msg; + }), + ); + } } }; diff --git a/ui/lib/actions.ts b/ui/lib/actions.ts new file mode 100644 index 0000000..d7eb71f --- /dev/null +++ b/ui/lib/actions.ts @@ -0,0 +1,22 @@ +import { Message } from '@/components/ChatWindow'; + +export const getSuggestions = async (chatHisory: Message[]) => { + const chatModel = localStorage.getItem('chatModel'); + const chatModelProvider = localStorage.getItem('chatModelProvider'); + + const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/suggestions`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + chat_history: chatHisory, + chat_model: chatModel, + chat_model_provider: chatModelProvider, + }), + }); + + const data = (await res.json()) as { suggestions: string[] }; + + return data.suggestions; +}; From fcff93a594392868c7f0111f5994da9a3a200aef Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 18 May 2024 13:10:54 +0530 Subject: [PATCH 31/34] feat(message-actions): update rewrite button --- ui/components/MessageActions/Rewrite.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/components/MessageActions/Rewrite.tsx b/ui/components/MessageActions/Rewrite.tsx index 3ae282d..3282e7d 100644 --- a/ui/components/MessageActions/Rewrite.tsx +++ b/ui/components/MessageActions/Rewrite.tsx @@ -10,9 +10,10 @@ const Rewrite = ({ return ( ); }; From c61facef13ed0c1cce3265d96c0e81d33bad6efb Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 18 May 2024 13:11:15 +0530 Subject: [PATCH 32/34] feat(message-box): display suggestions --- ui/components/MessageBox.tsx | 52 +++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/ui/components/MessageBox.tsx b/ui/components/MessageBox.tsx index 9712a23..8084d5f 100644 --- a/ui/components/MessageBox.tsx +++ b/ui/components/MessageBox.tsx @@ -4,7 +4,15 @@ import React, { MutableRefObject, useEffect, useState } from 'react'; import { Message } from './ChatWindow'; import { cn } from '@/lib/utils'; -import { BookCopy, Disc3, Share, Volume2, StopCircle } from 'lucide-react'; +import { + BookCopy, + Disc3, + Share, + Volume2, + StopCircle, + Layers3, + Plus, +} from 'lucide-react'; import Markdown from 'markdown-to-jsx'; import Copy from './MessageActions/Copy'; import Rewrite from './MessageActions/Rewrite'; @@ -21,6 +29,7 @@ const MessageBox = ({ dividerRef, isLast, rewrite, + sendMessage, }: { message: Message; messageIndex: number; @@ -29,6 +38,7 @@ const MessageBox = ({ dividerRef?: MutableRefObject; isLast: boolean; rewrite: (messageId: string) => void; + sendMessage: (message: string) => void; }) => { const [parsedMessage, setParsedMessage] = useState(message.content); const [speechMessage, setSpeechMessage] = useState(message.content); @@ -98,9 +108,9 @@ const MessageBox = ({ {loading && isLast ? null : (
- + */}
@@ -124,6 +134,42 @@ const MessageBox = ({
)} + {isLast && + message.suggestions && + message.suggestions.length > 0 && + message.role === 'assistant' && + !loading && ( + <> +
+
+
+ +

Related

+
+
+ {message.suggestions.map((suggestion, i) => ( +
+
+
{ + sendMessage(suggestion); + }} + className="cursor-pointer flex flex-row justify-between font-medium space-x-2 items-center" + > +

+ {suggestion} +

+ +
+
+ ))} +
+
+ + )}
From 64ea4b4289d41e56c52744cfcb34d99661251635 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sat, 18 May 2024 13:11:24 +0530 Subject: [PATCH 33/34] feat(package): bump version --- package.json | 2 +- ui/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c3aa58d..0308e93 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "perplexica-backend", - "version": "1.4.0", + "version": "1.5.0", "license": "MIT", "author": "ItzCrazyKns", "scripts": { diff --git a/ui/package.json b/ui/package.json index a06581e..ff61082 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "perplexica-frontend", - "version": "1.4.0", + "version": "1.5.0", "license": "MIT", "author": "ItzCrazyKns", "scripts": { From 7853c18b6feb574700ab6827645e2e73270b9d73 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns Date: Sun, 19 May 2024 11:35:28 +0530 Subject: [PATCH 34/34] feat(docs): update port --- docs/installation/NETWORKING.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/installation/NETWORKING.md b/docs/installation/NETWORKING.md index 29e603f..baad296 100644 --- a/docs/installation/NETWORKING.md +++ b/docs/installation/NETWORKING.md @@ -20,8 +20,8 @@ docker compose down --rmi all ``` args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 ``` 6. Save and close the `docker-compose.yaml` file @@ -58,8 +58,8 @@ nano docker-compose.yaml ``` args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 ``` 6. Save and exit the editor @@ -96,8 +96,8 @@ nano docker-compose.yaml ``` args: - - NEXT_PUBLIC_API_URL=http://127.0.0.1:31338/api - - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:31338 + - NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api + - NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001 ``` 6. Save and exit the editor