From 6ceee992d73cc918d2cb6c5e8564723f396b6b38 Mon Sep 17 00:00:00 2001 From: Julien Droulez Date: Tue, 10 Mar 2026 15:57:26 +0100 Subject: [PATCH 1/3] feat: use own vector store wip --- .env.sample | 6 +- k8s/projects-frontend/values.dev.yaml | 2 + k8s/projects-frontend/values.yaml | 2 + nuxt.config.ts | 4 +- package.json | 4 +- src/server/routes/api/vector-store/query.ts | 88 ++++++++ src/server/utilis/vector-db.js | 49 ++++ yarn.lock | 238 +++++++++++++++++++- 8 files changed, 380 insertions(+), 13 deletions(-) create mode 100644 src/server/routes/api/vector-store/query.ts create mode 100644 src/server/utilis/vector-db.js diff --git a/.env.sample b/.env.sample index 035f9b30f..b7679754e 100644 --- a/.env.sample +++ b/.env.sample @@ -96,4 +96,8 @@ PLAYWRIGHT_TEST_PASSWORD= # ==== GOTENBERG pdf (optional) Settings ==== # NUXT_APP_GOTENBERG_SERVER_URL=http://127.0.0.1:3333 -# NUXT_PUBLIC_APP_GOTENBERG_ENABLED='true' \ No newline at end of file +# NUXT_PUBLIC_APP_GOTENBERG_ENABLED='true' + +# ==== VECTOR DATABASE (optional) Settings ==== +# NUXT_APP_VECTOR_DB_URL=postgresql://myuser:mypassword@localhost:5432/mydb +# NUXT_APP_VECTOR_EMBEDDING_MODEL=text-embedding-3-small \ No newline at end of file diff --git a/k8s/projects-frontend/values.dev.yaml b/k8s/projects-frontend/values.dev.yaml index 62f6d3376..b3ee18f0c 100644 --- a/k8s/projects-frontend/values.dev.yaml +++ b/k8s/projects-frontend/values.dev.yaml @@ -6,6 +6,8 @@ config: NUXT_APP_GOTENBERG_SERVER_URL: 'http://projects-gotenberg' NUXT_PUBLIC_APP_GOTENBERG_ENABLED: 'true' NUXT_APP_LANGCHAIN_PROMPT: '' + NUXT_APP_VECTOR_DB_URL: '' + NUXT_APP_VECTOR_EMBEDDING_MODEL: '' domain: k8s.lp-i.dev diff --git a/k8s/projects-frontend/values.yaml b/k8s/projects-frontend/values.yaml index bc74cdd53..2901ded6f 100644 --- a/k8s/projects-frontend/values.yaml +++ b/k8s/projects-frontend/values.yaml @@ -45,6 +45,8 @@ config: NUXT_APP_GOTENBERG_SERVER_URL: '' NUXT_PUBLIC_APP_GOTENBERG_ENABLED: '' NUXT_APP_LANGCHAIN_PROMPT: '' + NUXT_APP_VECTOR_DB_URL: '' + NUXT_APP_VECTOR_EMBEDDING_MODEL: '' e2eEnv: nonSensitive: USER_ADMIN_EMAIL: testautomatatiquedministrateur1@outlook.fr diff --git a/nuxt.config.ts b/nuxt.config.ts index 41b1dfd68..ee608cde1 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -131,7 +131,7 @@ export default defineNuxtConfig({ appGeocodingApiKey: '', appOpenaiApiKey: '', appOpenaiApiPromptId: '', - appOpenaiApiPromptVersion: '', + appOpeyanaiApiPromptVersion: '', appOpenaiApiVectorStoreId: '', appMcpServerUrl: '', appSorbobotApiToken: '', @@ -139,6 +139,8 @@ export default defineNuxtConfig({ appSorbobotApiTrace: 0, appGotenbergServerUrl: '', appLangchainPrompt: '', + appVectorDbUrl: '', + appVectorEmbeddingModel: '', public: { appVersion: '', appApiOrgCode: '', diff --git a/package.json b/package.json index 729f6e4dc..0be375082 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "@ckpack/vue-color": "^1.5.0", "@hocuspocus/provider": "^2.15.0", "@intlify/vue-i18n-loader": "^4.2.0", - "@langchain/core": "^1.1.17", + "@langchain/community": "^1.1.22", + "@langchain/core": "^1.1.31", "@langchain/langgraph": "^1.1.2", "@langchain/openai": "^1.2.3", "@mdi/font": "^6", @@ -92,6 +93,7 @@ "nuxt": "^3.19.3", "nuxt-svgo": "4.2.6", "openai": "^5.23.0", + "pg": "^8.20.0", "pinia": "^3.0.3", "prosemirror-markdown": "^1.13.1", "prosemirror-model": "^1.24.1", diff --git a/src/server/routes/api/vector-store/query.ts b/src/server/routes/api/vector-store/query.ts new file mode 100644 index 000000000..b0e293b29 --- /dev/null +++ b/src/server/routes/api/vector-store/query.ts @@ -0,0 +1,88 @@ +import useVectorStore from '@/server/utils/vector-db' + +export default defineLazyEventHandler(() => { + return defineEventHandler(async (event) => { + const vectorStore = await useVectorStore() + // return 404 if not configured + if (!vectorStore) { + setResponseStatus(event, 404) + return + } + const body = await readBody<{ + query: Array<{ role: string; text: string }> + conversationId?: string + }>(event) + + const messages = body.messages || [] + let conversationId = body.conversationId || null + if (!conversationId) { + // if no conversationId, we start a new conversation + const conversation = await openai.conversations.create() + conversationId = conversation.id + } + + // console.log('\x1b[36m%s\x1b[0m', 'MESSAGES FROM FRONTEND') + // messages.forEach((message) => { + // console.log('\x1b[36m%s\x1b[0m', JSON.stringify(message, null, 2)) + // }) + + // console.log('\x1b[36m%s\x1b[0m', 'PREVIOUS MESSAGE ID') + // console.log('\x1b[36m%s\x1b[0m', previousResponseId) + + const adaptedMessages = messages.map((message) => { + return { + role: message.role, + content: message.text, + } + }) + + const prompt = { + id: appOpenaiApiPromptId, + } + if (appOpenaiApiPromptVersion) { + prompt['version'] = String(appOpenaiApiPromptVersion) + } + + const requestOptions: any = { + prompt, + //store: false, // do not store in OpenAI's servers, we do this on client side + store: true, // we want to store it to be able to use follow-up questions + input: adaptedMessages, // [{ role: 'user', content: messages[0].content }] + conversation: conversationId, + reasoning: {}, + tools: [], + } + if (appMcpServerUrl) { + requestOptions.tools.push({ + type: 'mcp', + server_label: 'projects-local-mcp', + server_description: + 'A MCP to fetch information about projects, people and groups on this Projects platform.', + server_url: appMcpServerUrl, + require_approval: 'never', + }) + } + if (appOpenaiApiVectorStoreId) { + requestOptions.tools.push({ + type: 'file_search', + vector_store_ids: [appOpenaiApiVectorStoreId], + }) + } + + // console.log('\x1b[36m%s\x1b[0m', 'OPENAI REQUEST') + // console.log(JSON.stringify(requestOptions, null, 2), 'color:#0ff;') + + const response = await openai.responses.create(requestOptions as any) + + // console.log('\x1b[36m%s\x1b[0m', 'OPENAI RESPONSE') + // console.log('OpenAI response:\n%c' + JSON.stringify(response, null, 2), 'color:#ff0;') + + const adaptedResponse = { + id: response.id, + text: response.output_text, + conversationId: conversationId, + } + + return adaptedResponse + }) +}) diff --git a/src/server/utilis/vector-db.js b/src/server/utilis/vector-db.js new file mode 100644 index 000000000..bac2a6615 --- /dev/null +++ b/src/server/utilis/vector-db.js @@ -0,0 +1,49 @@ +import { PGVectorStore } from '@langchain/community/vectorstores/pgvector' +import { OpenAIEmbeddings } from '@langchain/openai' // Or any other embedding model +// import { Client } from 'pg' + +const runtimeConfig = useRuntimeConfig() + +export default useVectorStore = async () => { + // 1. Configure the database connection + const connectionString = runtimeConfig.appVectorDbUrl + const modelName = runtimeConfig.appVectorEmbeddingModel + + let vectorStore = null + try { + if (!connectionString || !modelName) { + throw new Error('Missing required configuration for vector store.') + } + + // 2. Create a PgPool or Client instance (LangChain accepts both, but Pool is better for production) + // For simplicity in initialization, we'll pass the connection string directly to the store constructor + // which handles the connection internally for setup. + + const embeddings = new OpenAIEmbeddings({ + modelName, + }) + + // 3. Initialize the VectorStore - skip if not needed + vectorStore = await PGVectorStore.initialize({ + embeddings, + connectionString, + // Optional: Specify a custom table name if you don't want the default 'langchain_pg_embedding' + // tableName: "my_custom_table", + // Optional: Use JSONB for metadata (default is usually JSONB in newer versions) + // useJsonb: true, + }) + + console.log('Database connection established and tables initialized.') + + // 4. (Optional) Add some documents to verify it works + // const docs = [ + // new Document({ pageContent: "Hello world", metadata: { source: "test" } }), + // ]; + // await vectorStore.addDocuments(docs); + } catch (error) { + console.error('Error initializing vector store:', error) + // Handle the error as needed, e.g., fallback to an in-memory store or disable vector features + } + + return vectorStore +} diff --git a/yarn.lock b/yarn.lock index 177bc56e3..7b62cb1ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1281,20 +1281,53 @@ resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== -"@langchain/core@^1.1.17": - version "1.1.17" - resolved "https://registry.yarnpkg.com/@langchain/core/-/core-1.1.17.tgz#b5a9a9fb51e9f1963581d2f7ce1e22867865d8a6" - integrity sha512-g7/kcKbKEwNZSyyT7aT0utxn7wTOtKErqz0cL6VjrV4v/aOb9g+dKcfj17YkSm42YQmJp/rB2IXGc17vQPEBqA== +"@langchain/classic@1.0.22": + version "1.0.22" + resolved "https://registry.yarnpkg.com/@langchain/classic/-/classic-1.0.22.tgz#fa79102549d152c88090f46633db9636874a75cc" + integrity sha512-XJd5nbxM6UXYkDJc98Zo/9NkPFWy3g/XunBe8hnTOyaazxvA+5+gdJyDKVrcRfaGJskql0V5h/3XQ2f9WFzEuw== + dependencies: + "@langchain/openai" "1.2.12" + "@langchain/textsplitters" "1.0.1" + handlebars "^4.7.8" + js-yaml "^4.1.1" + jsonpointer "^5.0.1" + openapi-types "^12.1.3" + uuid "^10.0.0" + yaml "^2.2.1" + zod "^3.25.76 || ^4" + optionalDependencies: + langsmith ">=0.4.0 <1.0.0" + +"@langchain/community@^1.1.22": + version "1.1.22" + resolved "https://registry.yarnpkg.com/@langchain/community/-/community-1.1.22.tgz#940e125e6a173579b1248cabc76506241cb8d095" + integrity sha512-scpLZx8zxTpNPHe1zC0lYYoBwF385RUByKqNzgTRKWsqs0ipnF9cjiN0uEnxcZJP5j5OE+uIcwOZe1sDxWGkWw== + dependencies: + "@langchain/classic" "1.0.22" + "@langchain/openai" "1.2.12" + binary-extensions "^2.2.0" + flat "^5.0.2" + js-yaml "^4.1.1" + langsmith ">=0.4.0 <1.0.0" + math-expression-evaluator "^2.0.0" + uuid "^10.0.0" + zod "^3.25.76 || ^4" + +"@langchain/core@^1.1.31": + version "1.1.31" + resolved "https://registry.yarnpkg.com/@langchain/core/-/core-1.1.31.tgz#81882c7be8dfe138015da67b93aa73c6ab0f6962" + integrity sha512-FxsgIUONjKaRpjx59sISgmb0OMCbAetPGyhzjGa2kX0y1f8LZ5xm9VB2db7W9HYWyLvzRWcMA51Uu4OSTJmtZQ== dependencies: "@cfworker/json-schema" "^4.0.2" + "@standard-schema/spec" "^1.1.0" ansi-styles "^5.0.0" camelcase "6" decamelize "1.2.0" js-tiktoken "^1.0.12" - langsmith ">=0.4.0 <1.0.0" + langsmith ">=0.5.0 <1.0.0" mustache "^4.2.0" p-queue "^6.6.2" - uuid "^10.0.0" + uuid "^11.1.0" zod "^3.25.76 || ^4" "@langchain/langgraph-checkpoint@^1.0.0": @@ -1323,6 +1356,15 @@ "@standard-schema/spec" "1.1.0" uuid "^10.0.0" +"@langchain/openai@1.2.12": + version "1.2.12" + resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-1.2.12.tgz#6147acbc3e92c363e99b7ba3e812bb055aea1d51" + integrity sha512-Im6PPNujrfkZk4vpc9JAjbeERg+RbNtWRe3KSFOP7aNGa/yZ+XD69lxXwbsZGaZkbiUN/hwe9RYeisUfThb5wg== + dependencies: + js-tiktoken "^1.0.12" + openai "^6.24.0" + zod "^3.25.76 || ^4" + "@langchain/openai@^1.2.3": version "1.2.3" resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-1.2.3.tgz#39f4b843ea72d71bf653aa21896f151311027e27" @@ -1332,6 +1374,13 @@ openai "^6.16.0" zod "^3.25.76 || ^4" +"@langchain/textsplitters@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@langchain/textsplitters/-/textsplitters-1.0.1.tgz#292f9c93239178c248b3338acf7b68aa47aa9830" + integrity sha512-rheJlB01iVtrOUzttscutRgLybPH9qR79EyzBEbf1u97ljWyuxQfCwIWK+SjoQTM9O8M7GGLLRBSYE26Jmcoww== + dependencies: + js-tiktoken "^1.0.12" + "@lifeomic/attempt@^3.0.2": version "3.1.0" resolved "https://registry.yarnpkg.com/@lifeomic/attempt/-/attempt-3.1.0.tgz#7fc703559177b81a008b9d263e3d9a001d11d08a" @@ -2646,7 +2695,7 @@ resolved "https://registry.yarnpkg.com/@speed-highlight/core/-/core-1.2.7.tgz#eeaa7c1e7198559abbb98e4acbc93d108d35f2d3" integrity sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g== -"@standard-schema/spec@1.1.0": +"@standard-schema/spec@1.1.0", "@standard-schema/spec@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8" integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w== @@ -4400,7 +4449,7 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -binary-extensions@^2.0.0: +binary-extensions@^2.0.0, binary-extensions@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== @@ -4662,7 +4711,7 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.4.1: +chalk@^5.4.1, chalk@^5.6.2: version "5.6.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== @@ -6341,6 +6390,11 @@ flat-cache@^6.1.13: flatted "^3.3.3" hookified "^1.12.0" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + flatted@^3.2.9: version "3.3.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27" @@ -6719,6 +6773,18 @@ h3@^1.12.0, h3@^1.15.3, h3@^1.15.4: ufo "^1.6.1" uncrypto "^0.1.3" +handlebars@^4.7.8: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + happy-dom@^17.0.0: version "17.6.3" resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-17.6.3.tgz#2caa37058e6f9605f1b8b7ae03045253e6089477" @@ -7352,6 +7418,13 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +js-yaml@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -7442,6 +7515,11 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +jsonpointer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -7519,6 +7597,18 @@ langchain@^1.2.14: semver "^7.6.3" uuid "^10.0.0" +"langsmith@>=0.5.0 <1.0.0": + version "0.5.9" + resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.5.9.tgz#7cfe57302bf008d2d03f6042c0b1505581cb8573" + integrity sha512-mT88HlYTz7IZzVJP/OM7D6PAR3kzcbPGjYDJpx64ua9WiJXFqQx6YKewxIIxkVSZCb9I/9TiYvPYfZ4rawOdEg== + dependencies: + "@types/uuid" "^10.0.0" + chalk "^5.6.2" + console-table-printer "^2.12.1" + p-queue "^6.6.2" + semver "^7.6.3" + uuid "^10.0.0" + launch-editor@^2.11.1: version "2.11.1" resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.11.1.tgz#61a0b7314a42fd84a6cbb564573d9e9ffcf3d72b" @@ -7885,6 +7975,11 @@ material-colors@^1.2.6: resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg== +math-expression-evaluator@^2.0.0: + version "2.0.7" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-2.0.7.tgz#dc99a80ce2bf7f9b7df878126feb5c506c1fdf5f" + integrity sha512-uwliJZ6BPHRq4eiqNWxZBDzKUiS5RIynFFcgchqhBOloVLVBpZpNG8jRYkedLcBvhph8TnRyWEuxPqiQcwIdog== + math-intrinsics@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" @@ -8087,7 +8182,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.2.6: +minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -8209,6 +8304,11 @@ negotiator@^1.0.0: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + nitropack@^2.12.6: version "2.12.7" resolved "https://registry.yarnpkg.com/nitropack/-/nitropack-2.12.7.tgz#8c6dac6c9896c6f41374f805f077bdf6e100f93f" @@ -8624,6 +8724,16 @@ openai@^6.16.0: resolved "https://registry.yarnpkg.com/openai/-/openai-6.16.0.tgz#53661d9f6307dc7523e89637ff7c6ccd0be16c67" integrity sha512-fZ1uBqjFUjXzbGc35fFtYKEOxd20kd9fDpFeqWtsOZWiubY8CZ1NAlXHW3iathaFvqmNtCWMIsosCuyeI7Joxg== +openai@^6.24.0: + version "6.27.0" + resolved "https://registry.yarnpkg.com/openai/-/openai-6.27.0.tgz#eabaea9ce6904a8b2e6b2ac0a9d69b527d95ecf6" + integrity sha512-osTKySlrdYrLYTt0zjhY8yp0JUBmWDCN+Q+QxsV4xMQnnoVFpylgKGgxwN8sSdTNw0G4y+WUXs4eCMWpyDNWZQ== + +openapi-types@^12.1.3: + version "12.1.3" + resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3" + integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw== + optionator@^0.9.3: version "0.9.4" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" @@ -9035,6 +9145,62 @@ perfect-debounce@^2.0.0: resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-2.0.0.tgz#0ff94f1ecbe0a6bca4b1703a2ed08bbe43739aa7" integrity sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow== +pg-cloudflare@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz#386035d4bfcf1a7045b026f8b21acf5353f14d65" + integrity sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ== + +pg-connection-string@^2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.12.0.tgz#4084f917902bb2daae3dc1376fe24ac7b4eaccf2" + integrity sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.13.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.13.0.tgz#416482e9700e8f80c685a6ae5681697a413c13a3" + integrity sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA== + +pg-protocol@^1.13.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.13.0.tgz#fdaf6d020bca590d58bb991b4b16fc448efe0511" + integrity sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w== + +pg-types@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.20.0: + version "8.20.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.20.0.tgz#1a274de944cb329fd6dd77a6d371a005ba6b136d" + integrity sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA== + dependencies: + pg-connection-string "^2.12.0" + pg-pool "^3.13.0" + pg-protocol "^1.13.0" + pg-types "2.2.0" + pgpass "1.0.5" + optionalDependencies: + pg-cloudflare "^1.3.0" + +pgpass@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picocolors@^1.0.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -9402,6 +9568,28 @@ postcss@^8.4.31, postcss@^8.4.38, postcss@^8.4.43, postcss@^8.5.0, postcss@^8.5. picocolors "^1.1.1" source-map-js "^1.2.1" +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.1.tgz#c40b3da0222c500ff1e51c5d7014b60b79697c7a" + integrity sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -10422,6 +10610,11 @@ split2@^3.0.0, split2@^3.2.2: dependencies: readable-stream "^3.0.0" +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -11133,6 +11326,11 @@ ufo@1.6.1, ufo@^1.1.2, ufo@^1.5.4, ufo@^1.6.1: resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== +uglify-js@^3.1.4: + version "3.19.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" + integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== + ultrahtml@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ultrahtml/-/ultrahtml-1.6.0.tgz#0d1aad7bbfeae512438d30e799c11622127a1ac8" @@ -11367,6 +11565,11 @@ uuid@^10.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== +uuid@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== + uuid@^13.0.0: version "13.0.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-13.0.0.tgz#263dc341b19b4d755eb8fe36b78d95a6b65707e8" @@ -11803,6 +12006,11 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -11893,6 +12101,11 @@ xml-name-validator@^4.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + y-prosemirror@^1.2.11: version "1.3.7" resolved "https://registry.yarnpkg.com/y-prosemirror/-/y-prosemirror-1.3.7.tgz#f88e553da4ea33278b114cf0b6a0ea978b154e84" @@ -11959,6 +12172,11 @@ yaml@^2.0.0, yaml@^2.7.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.7.0.tgz#aef9bb617a64c937a9a748803786ad8d3ffe1e98" integrity sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA== +yaml@^2.2.1: + version "2.8.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.2.tgz#5694f25eca0ce9c3e7a9d9e00ce0ddabbd9e35c5" + integrity sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A== + yaml@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.1.tgz#1870aa02b631f7e8328b93f8bc574fac5d6c4d79" From 82db55b6ab69211b76f6bc517c544f2846ab11f0 Mon Sep 17 00:00:00 2001 From: Julien Droulez Date: Thu, 12 Mar 2026 18:27:25 +0100 Subject: [PATCH 2/3] feat: use own vector store poc --- nuxt.config.ts | 1 + package.json | 7 +- src/pages/DebugPage/Tabs/DebugOnboarding.vue | 16 ++++ src/server/routes/api/chat-lg-stream.ts | 33 ++++++++ src/server/routes/api/vector-store/ingest.ts | 59 +++++++++++++ src/server/routes/api/vector-store/query.ts | 88 -------------------- src/server/{utilis => utils}/vector-db.js | 33 ++++++-- yarn.lock | 61 +++++++++----- 8 files changed, 179 insertions(+), 119 deletions(-) create mode 100644 src/server/routes/api/vector-store/ingest.ts delete mode 100644 src/server/routes/api/vector-store/query.ts rename src/server/{utilis => utils}/vector-db.js (62%) diff --git a/nuxt.config.ts b/nuxt.config.ts index ee608cde1..aaa64ebbe 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -141,6 +141,7 @@ export default defineNuxtConfig({ appLangchainPrompt: '', appVectorDbUrl: '', appVectorEmbeddingModel: '', + appVectorEmbeddingDimensions: '', public: { appVersion: '', appApiOrgCode: '', diff --git a/package.json b/package.json index 0be375082..d904c37be 100644 --- a/package.json +++ b/package.json @@ -42,10 +42,11 @@ "@ckpack/vue-color": "^1.5.0", "@hocuspocus/provider": "^2.15.0", "@intlify/vue-i18n-loader": "^4.2.0", - "@langchain/community": "^1.1.22", - "@langchain/core": "^1.1.31", + "@langchain/community": "^1.1.23", + "@langchain/core": "^1.1.32", "@langchain/langgraph": "^1.1.2", "@langchain/openai": "^1.2.3", + "@langchain/textsplitters": "^1.0.1", "@mdi/font": "^6", "@modelcontextprotocol/sdk": "^1.20.2", "@nuxt/test-utils": "^3.19.2", @@ -85,6 +86,7 @@ "deep-chat": "^2.3.0", "es-toolkit": "^1.40.0", "highlight.js": "^11", + "install": "^0.13.0", "langchain": "^1.2.14", "leaflet": "^1", "leaflet.markercluster": "^1.5.3", @@ -93,6 +95,7 @@ "nuxt": "^3.19.3", "nuxt-svgo": "4.2.6", "openai": "^5.23.0", + "pdf-parse": "^1", "pg": "^8.20.0", "pinia": "^3.0.3", "prosemirror-markdown": "^1.13.1", diff --git a/src/pages/DebugPage/Tabs/DebugOnboarding.vue b/src/pages/DebugPage/Tabs/DebugOnboarding.vue index 7f74349b9..76c7a2cc5 100644 --- a/src/pages/DebugPage/Tabs/DebugOnboarding.vue +++ b/src/pages/DebugPage/Tabs/DebugOnboarding.vue @@ -19,6 +19,22 @@ :disabled="!usersStore.userFromApi || resetingTerms" @click="resetTermsSigned" /> +
+ +
+ + + + + + + +