diff --git a/LocalMind-Backend/.env.example b/LocalMind-Backend/.env.example index 31364a5..07ad1d7 100644 --- a/LocalMind-Backend/.env.example +++ b/LocalMind-Backend/.env.example @@ -43,5 +43,6 @@ BACKEND_URL=http://localhost:5000 # Model Api keys OPENAI_API_KEY=your_openai_api_key_here +OPENAI_MODEL=gpt-4o-mini GOOGLE_API_KEY=your_google_api_key_here GROQ_API_KEY=your_groq_api_key_here diff --git a/LocalMind-Backend/package.json b/LocalMind-Backend/package.json index bb5d7bf..22c2507 100644 --- a/LocalMind-Backend/package.json +++ b/LocalMind-Backend/package.json @@ -50,12 +50,12 @@ "@langchain/google-genai": "^0.2.18", "@langchain/groq": "^0.2.4", "@langchain/ollama": "^0.2.4", + "@langchain/openai": "^1.2.0", "@types/cookie-parser": "^1.4.9", "@types/jsonwebtoken": "^9.0.10", "@types/mongoose": "^5.11.97", "@types/morgan": "^1.9.10", "argon2": "^0.44.0", - "bcrypt": "^5.1.1", "axios": "^1.12.2", "bcrypt": "^6.0.0", "chalk": "^5.6.2", diff --git a/LocalMind-Backend/pnpm-lock.yaml b/LocalMind-Backend/pnpm-lock.yaml index ca0197b..3dc1a21 100644 --- a/LocalMind-Backend/pnpm-lock.yaml +++ b/LocalMind-Backend/pnpm-lock.yaml @@ -13,19 +13,22 @@ importers: version: 30.2.0 '@langchain/community': specifier: ^0.3.57 - version: 0.3.57(@aws-crypto/sha256-js@5.2.0)(@aws-sdk/credential-provider-node@3.922.0)(@browserbasehq/sdk@2.6.0)(@browserbasehq/stagehand@1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(zod@4.1.12))(@ibm-cloud/watsonx-ai@1.6.13)(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@smithy/util-utf8@2.3.0)(axios@1.12.2)(d3-dsv@2.0.0)(fast-xml-parser@5.2.5)(handlebars@4.7.8)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(mongodb@6.20.0)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(playwright@1.55.0)(weaviate-client@3.9.0)(ws@8.18.3) + version: 0.3.57(@aws-crypto/sha256-js@5.2.0)(@aws-sdk/credential-provider-node@3.922.0)(@browserbasehq/sdk@2.6.0)(@browserbasehq/stagehand@1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(zod@4.1.12))(@ibm-cloud/watsonx-ai@1.6.13)(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@smithy/util-utf8@2.3.0)(axios@1.12.2)(d3-dsv@2.0.0)(fast-xml-parser@5.2.5)(handlebars@4.7.8)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(mongodb@6.20.0)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(playwright@1.55.0)(weaviate-client@3.9.0)(ws@8.18.3) '@langchain/core': specifier: ^0.3.78 - version: 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + version: 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) '@langchain/google-genai': specifier: ^0.2.18 - version: 0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) + version: 0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) '@langchain/groq': specifier: ^0.2.4 - version: 0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) + version: 0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) '@langchain/ollama': specifier: ^0.2.4 - version: 0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) + version: 0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) + '@langchain/openai': + specifier: ^1.2.0 + version: 1.2.0(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3) '@types/cookie-parser': specifier: ^1.4.9 version: 1.4.9(@types/express@5.0.3) @@ -44,6 +47,9 @@ importers: axios: specifier: ^1.12.2 version: 1.12.2(debug@4.4.3) + bcrypt: + specifier: ^6.0.0 + version: 6.0.0 chalk: specifier: ^5.6.2 version: 5.6.2 @@ -70,7 +76,7 @@ importers: version: 9.0.2 langchain: specifier: ^0.3.36 - version: 0.3.36(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(axios@1.12.2)(handlebars@4.7.8)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(ws@8.18.3) + version: 0.3.36(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(axios@1.12.2)(handlebars@4.7.8)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(ws@8.18.3) mongoose: specifier: ^8.19.1 version: 8.19.1 @@ -93,9 +99,15 @@ importers: '@babel/preset-typescript': specifier: ^7.27.1 version: 7.27.1(@babel/core@7.28.4) + '@eslint/js': + specifier: ^9.36.0 + version: 9.39.2 '@types/argon2': specifier: ^0.15.4 version: 0.15.4 + '@types/bcrypt': + specifier: ^6.0.0 + version: 6.0.0 '@types/express': specifier: ^5.0.3 version: 5.0.3 @@ -105,6 +117,12 @@ importers: '@types/nodemailer': specifier: ^7.0.3 version: 7.0.3 + eslint: + specifier: ^9.36.0 + version: 9.39.2 + globals: + specifier: ^16.4.0 + version: 16.5.0 jest: specifier: ^30.2.0 version: 30.2.0(@types/node@24.7.2)(ts-node@10.9.2(@types/node@24.7.2)(typescript@5.9.3)) @@ -123,6 +141,9 @@ importers: typescript: specifier: ^5.9.3 version: 5.9.3 + typescript-eslint: + specifier: ^8.45.0 + version: 8.51.0(eslint@9.39.2)(typescript@5.9.3) packages: @@ -496,6 +517,44 @@ packages: '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@google/generative-ai@0.24.1': resolution: {integrity: sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==} engines: {node: '>=18.0.0'} @@ -514,6 +573,22 @@ packages: engines: {node: '>=6'} hasBin: true + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + '@ibm-cloud/watsonx-ai@1.6.13': resolution: {integrity: sha512-INaaD7EKpycwQg/tsLm3QM5uvDF5mWLPQCj6GTk44gEZhgx1depvVG5bxwjfqkx1tbJMFuozz2p6VHOE21S+8g==} engines: {node: '>=18.0.0'} @@ -1042,6 +1117,12 @@ packages: peerDependencies: '@langchain/core': '>=0.3.68 <0.4.0' + '@langchain/openai@1.2.0': + resolution: {integrity: sha512-r2g5Be3Sygw7VTJ89WVM/M94RzYToNTwXf8me1v+kgKxzdHbd/8XPYDFxpXEp3REyPgUrtJs+Oplba9pkTH5ug==} + engines: {node: '>=20'} + peerDependencies: + '@langchain/core': ^1.0.0 + '@langchain/textsplitters@0.1.0': resolution: {integrity: sha512-djI4uw9rlkAb5iMhtLED+xJebDdAG935AdP4eRTB02R7OB/act55Bj9wsskhZsvuyQRpO4O1wQOp85s6T6GWmw==} engines: {node: '>=18'} @@ -1354,6 +1435,9 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/bcrypt@6.0.0': + resolution: {integrity: sha512-/oJGukuH3D2+D+3H4JWLaAsJ/ji86dhRidzZ/Od7H/i8g+aCmvkeCc6Ni/f9uxGLSQVCRZkX2/lqEFG2BvWtlQ==} + '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -1374,6 +1458,9 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/express-serve-static-core@5.1.0': resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} @@ -1395,6 +1482,9 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/jsonwebtoken@9.0.10': resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==} @@ -1477,6 +1567,65 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@typescript-eslint/eslint-plugin@8.51.0': + resolution: {integrity: sha512-XtssGWJvypyM2ytBnSnKtHYOGT+4ZwTnBVl36TA4nRO2f4PRNGz5/1OszHzcZCvcBMh+qb7I06uoCmLTRdR9og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.51.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.51.0': + resolution: {integrity: sha512-3xP4XzzDNQOIqBMWogftkwxhg5oMKApqY0BAflmLZiFYHqyhSOxv/cd/zPQLTcCXr4AkaKb25joocY0BD1WC6A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.51.0': + resolution: {integrity: sha512-Luv/GafO07Z7HpiI7qeEW5NW8HUtZI/fo/kE0YbtQEFpJRUuR0ajcWfCE5bnMvL7QQFrmT/odMe8QZww8X2nfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.51.0': + resolution: {integrity: sha512-JhhJDVwsSx4hiOEQPeajGhCWgBMBwVkxC/Pet53EpBVs7zHHtayKefw1jtPaNRXpI9RA2uocdmpdfE7T+NrizA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.51.0': + resolution: {integrity: sha512-Qi5bSy/vuHeWyir2C8u/uqGMIlIDu8fuiYWv48ZGlZ/k+PRPHtaAu7erpc7p5bzw2WNNSniuxoMSO4Ar6V9OXw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.51.0': + resolution: {integrity: sha512-0XVtYzxnobc9K0VU7wRWg1yiUrw4oQzexCG2V2IDxxCxhqBMSMbjB+6o91A+Uc0GWtgjCa3Y8bi7hwI0Tu4n5Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.51.0': + resolution: {integrity: sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.51.0': + resolution: {integrity: sha512-1qNjGqFRmlq0VW5iVlcyHBbCjPB7y6SxpBkrbhNWMy/65ZoncXCEPJxkRZL8McrseNH6lFhaxCIaX+vBuFnRng==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.51.0': + resolution: {integrity: sha512-11rZYxSe0zabiKaCP2QAwRf/dnmgFgvTmeDTtZvUvXG3UuAdg/GU02NExmmIXzz3vLGgMdtrIosI84jITQOxUA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.51.0': + resolution: {integrity: sha512-mM/JRQOzhVN1ykejrvwnBRV3+7yTKK8tVANVN3o1O0t0v7o+jqdVu9crPy5Y9dov15TJk/FTIgoUGHrTOVL3Zg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -1586,6 +1735,11 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-walk@8.3.4: resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} engines: {node: '>=0.4.0'} @@ -1599,6 +1753,9 @@ packages: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -1699,6 +1856,10 @@ packages: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} + bcrypt@6.0.0: + resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==} + engines: {node: '>= 18'} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1951,6 +2112,9 @@ packages: babel-plugin-macros: optional: true + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -2062,11 +2226,53 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} @@ -2109,6 +2315,9 @@ packages: engines: {node: '>= 10.17.0'} hasBin: true + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -2116,6 +2325,9 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-xml-parser@5.2.5: resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} hasBin: true @@ -2129,11 +2341,24 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + figlet@1.9.3: resolution: {integrity: sha512-majPgOpVtrZN1iyNGbsUP6bOtZ6eaJgg5HHh0vFvm5DJhh8dc+FJpOC4GABvMZ/A7XHAJUuJujhgUY/2jPWgMA==} engines: {node: '>= 17.0.0'} hasBin: true + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + file-type@16.5.4: resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} engines: {node: '>=10'} @@ -2153,10 +2378,21 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + follow-redirects@1.15.11: resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} @@ -2241,6 +2477,10 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -2249,6 +2489,14 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -2352,6 +2600,14 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + import-local@3.2.0: resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} engines: {node: '>=8'} @@ -2615,6 +2871,10 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -2629,6 +2889,12 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2734,6 +3000,10 @@ packages: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2745,6 +3015,10 @@ packages: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -2772,6 +3046,9 @@ packages: lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} @@ -3135,9 +3412,25 @@ packages: zod: optional: true + openai@6.15.0: + resolution: {integrity: sha512-F1Lvs5BoVvmZtzkUEVyh8mDQPPFolq4F+xdsx/DO8Hee8YF3IGAlZqUIsF+DVGhqf4aU0a3bTghsxB6OIsRy1g==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + ora@9.0.0: resolution: {integrity: sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==} engines: {node: '>=20'} @@ -3162,6 +3455,10 @@ packages: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + p-queue@6.6.2: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} @@ -3181,6 +3478,10 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} engines: {node: '>=4'} @@ -3262,6 +3563,10 @@ packages: engines: {node: '>=18'} hasBin: true + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + prettier@3.6.2: resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} engines: {node: '>=14'} @@ -3361,6 +3666,10 @@ packages: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -3595,6 +3904,10 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -3625,6 +3938,12 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-error@1.0.6: resolution: {integrity: sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA==} @@ -3689,6 +4008,10 @@ packages: tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} @@ -3709,6 +4032,13 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} + typescript-eslint@8.51.0: + resolution: {integrity: sha512-jh8ZuM5oEh2PSdyQG9YAEM1TCGuWenLSuSUhf/irbVUNW9O5FhbFVONviN2TgMTBnUmyHv7E56rYnfLZK6TkiA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -3742,6 +4072,9 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} @@ -3813,6 +4146,10 @@ packages: resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} engines: {node: '>=8'} + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} @@ -4571,14 +4908,14 @@ snapshots: transitivePeerDependencies: - encoding - '@browserbasehq/stagehand@1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(zod@4.1.12)': + '@browserbasehq/stagehand@1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(zod@4.1.12)': dependencies: '@anthropic-ai/sdk': 0.27.3 '@browserbasehq/sdk': 2.6.0 '@playwright/test': 1.55.0 deepmerge: 4.3.1 dotenv: 17.2.3 - openai: 5.12.2(ws@8.18.3)(zod@4.1.12) + openai: 6.15.0(ws@8.18.3)(zod@4.1.12) ws: 8.18.3 zod: 4.1.12 zod-to-json-schema: 3.24.6(zod@4.1.12) @@ -4611,6 +4948,52 @@ snapshots: '@epic-web/invariant@1.0.0': {} + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2)': + dependencies: + eslint: 9.39.2 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.3': + dependencies: + ajv: 6.12.6 + debug: 4.4.3(supports-color@8.1.1) + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.2': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + '@google/generative-ai@0.24.1': {} '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': @@ -4629,6 +5012,17 @@ snapshots: protobufjs: 7.5.4 yargs: 17.7.2 + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + '@ibm-cloud/watsonx-ai@1.6.13': dependencies: '@types/node': 18.19.130 @@ -4862,21 +5256,21 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} - '@langchain/community@0.3.57(@aws-crypto/sha256-js@5.2.0)(@aws-sdk/credential-provider-node@3.922.0)(@browserbasehq/sdk@2.6.0)(@browserbasehq/stagehand@1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(zod@4.1.12))(@ibm-cloud/watsonx-ai@1.6.13)(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@smithy/util-utf8@2.3.0)(axios@1.12.2)(d3-dsv@2.0.0)(fast-xml-parser@5.2.5)(handlebars@4.7.8)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(mongodb@6.20.0)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(playwright@1.55.0)(weaviate-client@3.9.0)(ws@8.18.3)': + '@langchain/community@0.3.57(@aws-crypto/sha256-js@5.2.0)(@aws-sdk/credential-provider-node@3.922.0)(@browserbasehq/sdk@2.6.0)(@browserbasehq/stagehand@1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(zod@4.1.12))(@ibm-cloud/watsonx-ai@1.6.13)(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@smithy/util-utf8@2.3.0)(axios@1.12.2)(d3-dsv@2.0.0)(fast-xml-parser@5.2.5)(handlebars@4.7.8)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(mongodb@6.20.0)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(playwright@1.55.0)(weaviate-client@3.9.0)(ws@8.18.3)': dependencies: - '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(zod@4.1.12) + '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.55.0)(deepmerge@4.3.1)(dotenv@17.2.3)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(zod@4.1.12) '@ibm-cloud/watsonx-ai': 1.6.13 - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3) - '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) + '@langchain/openai': 0.6.16(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3) + '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) binary-extensions: 2.3.0 expr-eval: 2.0.2 flat: 5.0.2 ibm-cloud-sdk-core: 5.4.3 js-yaml: 4.1.0 - langchain: 0.3.36(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(axios@1.12.2)(handlebars@4.7.8)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(ws@8.18.3) - langsmith: 0.3.73(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) - openai: 5.12.2(ws@8.18.3)(zod@4.1.12) + langchain: 0.3.36(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(axios@1.12.2)(handlebars@4.7.8)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(ws@8.18.3) + langsmith: 0.3.73(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) + openai: 6.15.0(ws@8.18.3)(zod@4.1.12) uuid: 10.0.0 zod: 3.25.76 optionalDependencies: @@ -4913,14 +5307,14 @@ snapshots: - handlebars - peggy - '@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))': + '@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))': dependencies: '@cfworker/json-schema': 4.1.1 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.3.73(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + langsmith: 0.3.73(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -4933,43 +5327,52 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))': + '@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))': dependencies: '@google/generative-ai': 0.24.1 - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) uuid: 11.1.0 - '@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))': + '@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))': dependencies: - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) groq-sdk: 0.29.0 zod: 3.25.76 transitivePeerDependencies: - encoding - '@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))': + '@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))': dependencies: - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) ollama: 0.5.18 uuid: 10.0.0 - '@langchain/openai@0.6.16(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3)': + '@langchain/openai@0.6.16(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3)': dependencies: - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) js-tiktoken: 1.0.21 openai: 5.12.2(ws@8.18.3)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - ws - '@langchain/textsplitters@0.1.0(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))': + '@langchain/openai@1.2.0(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3)': dependencies: - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) + js-tiktoken: 1.0.21 + openai: 6.15.0(ws@8.18.3)(zod@4.1.12) + zod: 4.1.12 + transitivePeerDependencies: + - ws + + '@langchain/textsplitters@0.1.0(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))': + dependencies: + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) js-tiktoken: 1.0.21 - '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))': + '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))': dependencies: - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) uuid: 10.0.0 weaviate-client: 3.9.0 transitivePeerDependencies: @@ -5428,6 +5831,10 @@ snapshots: dependencies: '@babel/types': 7.28.4 + '@types/bcrypt@6.0.0': + dependencies: + '@types/node': 24.7.2 + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 @@ -5456,6 +5863,8 @@ snapshots: dependencies: '@types/ms': 2.1.0 + '@types/estree@1.0.8': {} + '@types/express-serve-static-core@5.1.0': dependencies: '@types/node': 24.7.2 @@ -5483,6 +5892,8 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 + '@types/json-schema@7.0.15': {} + '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 2.1.0 @@ -5585,6 +5996,97 @@ snapshots: '@types/node': 24.7.2 optional: true + '@typescript-eslint/eslint-plugin@8.51.0(@typescript-eslint/parser@8.51.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.51.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.51.0 + '@typescript-eslint/type-utils': 8.51.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.51.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.51.0 + eslint: 9.39.2 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.51.0(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.51.0 + '@typescript-eslint/types': 8.51.0 + '@typescript-eslint/typescript-estree': 8.51.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.51.0 + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.2 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.51.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.51.0(typescript@5.9.3) + '@typescript-eslint/types': 8.51.0 + debug: 4.4.3(supports-color@8.1.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.51.0': + dependencies: + '@typescript-eslint/types': 8.51.0 + '@typescript-eslint/visitor-keys': 8.51.0 + + '@typescript-eslint/tsconfig-utils@8.51.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.51.0(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.51.0 + '@typescript-eslint/typescript-estree': 8.51.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.51.0(eslint@9.39.2)(typescript@5.9.3) + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.2 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.51.0': {} + + '@typescript-eslint/typescript-estree@8.51.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.51.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.51.0(typescript@5.9.3) + '@typescript-eslint/types': 8.51.0 + '@typescript-eslint/visitor-keys': 8.51.0 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 9.0.5 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.51.0(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) + '@typescript-eslint/scope-manager': 8.51.0 + '@typescript-eslint/types': 8.51.0 + '@typescript-eslint/typescript-estree': 8.51.0(typescript@5.9.3) + eslint: 9.39.2 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.51.0': + dependencies: + '@typescript-eslint/types': 8.51.0 + eslint-visitor-keys: 4.2.1 + '@ungap/structured-clone@1.3.0': {} '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -5657,6 +6159,10 @@ snapshots: mime-types: 3.0.1 negotiator: 1.0.0 + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-walk@8.3.4: dependencies: acorn: 8.15.0 @@ -5667,6 +6173,13 @@ snapshots: dependencies: humanize-ms: 1.2.1 + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -5783,6 +6296,11 @@ snapshots: dependencies: safe-buffer: 5.1.2 + bcrypt@6.0.0: + dependencies: + node-addon-api: 8.5.0 + node-gyp-build: 4.8.4 + binary-extensions@2.3.0: {} body-parser@2.2.0: @@ -6031,6 +6549,8 @@ snapshots: dedent@1.7.0: {} + deep-is@0.1.4: {} + deepmerge@4.3.1: {} defer-to-connect@2.0.1: {} @@ -6114,8 +6634,74 @@ snapshots: escape-string-regexp@4.0.0: {} + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.39.2: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.3 + '@eslint/js': 9.39.2 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@8.1.1) + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + etag@1.8.1: {} event-target-shim@5.0.1: {} @@ -6193,6 +6779,8 @@ snapshots: transitivePeerDependencies: - supports-color + fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -6203,6 +6791,8 @@ snapshots: fast-json-stable-stringify@2.1.0: {} + fast-levenshtein@2.0.6: {} + fast-xml-parser@5.2.5: dependencies: strnum: 2.1.1 @@ -6219,10 +6809,18 @@ snapshots: dependencies: pend: 1.2.0 + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + figlet@1.9.3: dependencies: commander: 14.0.1 + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + file-type@16.5.4: dependencies: readable-web-to-node-stream: 3.0.4 @@ -6253,8 +6851,20 @@ snapshots: locate-path: 5.0.0 path-exists: 4.0.0 + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + flat@5.0.2: {} + flatted@3.3.3: {} + follow-redirects@1.15.11(debug@4.4.3): optionalDependencies: debug: 4.4.3(supports-color@8.1.1) @@ -6329,6 +6939,10 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + glob@10.4.5: dependencies: foreground-child: 3.3.1 @@ -6347,6 +6961,10 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + globals@14.0.0: {} + + globals@16.5.0: {} + globby@11.1.0: dependencies: array-union: 2.1.0 @@ -6492,6 +7110,13 @@ snapshots: ignore@5.3.2: {} + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + import-local@3.2.0: dependencies: pkg-dir: 4.2.0 @@ -6924,6 +7549,10 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -6932,6 +7561,10 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} jsonpointer@5.0.1: {} @@ -6966,24 +7599,24 @@ snapshots: dependencies: json-buffer: 3.0.1 - langchain@0.3.36(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))))(axios@1.12.2)(handlebars@4.7.8)(openai@5.12.2(ws@8.18.3)(zod@4.1.12))(ws@8.18.3): + langchain@0.3.36(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(@langchain/google-genai@0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/groq@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(@langchain/ollama@0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))))(axios@1.12.2)(handlebars@4.7.8)(openai@6.15.0(ws@8.18.3)(zod@4.1.12))(ws@8.18.3): dependencies: - '@langchain/core': 0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3) - '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) + '@langchain/core': 0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) + '@langchain/openai': 0.6.16(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12)))(ws@8.18.3) + '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) js-tiktoken: 1.0.21 js-yaml: 4.1.0 jsonpointer: 5.0.1 - langsmith: 0.3.73(openai@5.12.2(ws@8.18.3)(zod@4.1.12)) + langsmith: 0.3.73(openai@6.15.0(ws@8.18.3)(zod@4.1.12)) openapi-types: 12.1.3 p-retry: 4.6.2 uuid: 10.0.0 yaml: 2.8.1 zod: 3.25.76 optionalDependencies: - '@langchain/google-genai': 0.2.18(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) - '@langchain/groq': 0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) - '@langchain/ollama': 0.2.4(@langchain/core@0.3.78(openai@5.12.2(ws@8.18.3)(zod@4.1.12))) + '@langchain/google-genai': 0.2.18(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) + '@langchain/groq': 0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) + '@langchain/ollama': 0.2.4(@langchain/core@0.3.78(openai@6.15.0(ws@8.18.3)(zod@4.1.12))) axios: 1.12.2(debug@4.4.3) handlebars: 4.7.8 transitivePeerDependencies: @@ -6993,7 +7626,7 @@ snapshots: - openai - ws - langsmith@0.3.73(openai@5.12.2(ws@8.18.3)(zod@4.1.12)): + langsmith@0.3.73(openai@6.15.0(ws@8.18.3)(zod@4.1.12)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -7003,10 +7636,15 @@ snapshots: semver: 7.7.3 uuid: 10.0.0 optionalDependencies: - openai: 5.12.2(ws@8.18.3)(zod@4.1.12) + openai: 6.15.0(ws@8.18.3)(zod@4.1.12) leven@3.1.0: {} + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + lines-and-columns@1.2.4: {} load-json-file@5.3.0: @@ -7021,6 +7659,10 @@ snapshots: dependencies: p-locate: 4.1.0 + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + lodash.camelcase@4.3.0: {} lodash.clonedeep@4.5.0: {} @@ -7039,6 +7681,8 @@ snapshots: lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} + lodash.once@4.1.1: {} log-symbols@7.0.1: @@ -7273,13 +7917,22 @@ snapshots: ws: 8.18.3 zod: 3.25.76 - openai@5.12.2(ws@8.18.3)(zod@4.1.12): + openai@6.15.0(ws@8.18.3)(zod@4.1.12): optionalDependencies: ws: 8.18.3 zod: 4.1.12 openapi-types@12.1.3: {} + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + ora@9.0.0: dependencies: chalk: 5.6.2 @@ -7308,6 +7961,10 @@ snapshots: dependencies: p-limit: 2.3.0 + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + p-queue@6.6.2: dependencies: eventemitter3: 4.0.7 @@ -7326,6 +7983,10 @@ snapshots: package-json-from-dist@1.0.1: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + parse-json@4.0.0: dependencies: error-ex: 1.3.4 @@ -7388,6 +8049,8 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + prelude-ls@1.2.1: {} + prettier@3.6.2: {} pretty-format@30.2.0: @@ -7490,6 +8153,8 @@ snapshots: dependencies: resolve-from: 5.0.0 + resolve-from@4.0.0: {} + resolve-from@5.0.0: {} resolve@1.22.10: @@ -7732,6 +8397,11 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -7760,6 +8430,10 @@ snapshots: tree-kill@1.2.2: {} + ts-api-utils@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + ts-error@1.0.6: {} ts-jest@29.4.5(@babel/core@7.28.4)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.4))(jest-util@30.2.0)(jest@30.2.0(@types/node@24.7.2)(ts-node@10.9.2(@types/node@24.7.2)(typescript@5.9.3)))(typescript@5.9.3): @@ -7831,6 +8505,10 @@ snapshots: dependencies: safe-buffer: 5.2.1 + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + type-detect@4.0.8: {} type-fest@0.21.3: {} @@ -7845,6 +8523,17 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.1 + typescript-eslint@8.51.0(eslint@9.39.2)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.51.0(@typescript-eslint/parser@8.51.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.51.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.51.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.51.0(eslint@9.39.2)(typescript@5.9.3) + eslint: 9.39.2 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + typescript@5.9.3: {} uglify-js@3.19.3: @@ -7888,6 +8577,10 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + url-parse@1.5.10: dependencies: querystringify: 2.2.0 @@ -7956,6 +8649,8 @@ snapshots: dependencies: string-width: 4.2.3 + word-wrap@1.2.5: {} + wordwrap@1.0.0: {} wrap-ansi@7.0.0: diff --git a/LocalMind-Backend/src/api/v1/LangChain/langchain.controller.ts b/LocalMind-Backend/src/api/v1/LangChain/langchain.controller.ts new file mode 100644 index 0000000..a26e9eb --- /dev/null +++ b/LocalMind-Backend/src/api/v1/LangChain/langchain.controller.ts @@ -0,0 +1,173 @@ +import { Request, Response } from 'express' +import { SendResponse } from '../utils/SendResponse.utils' +import langchainService from '../services/langchain.service' + +/** + * LangChain Controller + * + * Handles HTTP requests for LangChain-powered AI operations. + * Provides endpoints for: + * - Simple chat with system + user prompts + * - User-only prompts + * - Custom template execution + * - Streaming responses + */ +class LangChainController { + /** + * Simple chat endpoint with system and user prompts + * + * POST /api/v1/langchain/chat + * Body: { systemPrompt: string, userPrompt: string } + */ + async chat(req: Request, res: Response) { + try { + const { systemPrompt, userPrompt } = req.body + + if (!userPrompt) { + return SendResponse.error(res, 'userPrompt is required', 400) + } + + const defaultSystemPrompt = + systemPrompt || 'You are a helpful AI assistant powered by LocalMind.' + + const response = await langchainService.runSimplePrompt(defaultSystemPrompt, userPrompt) + + SendResponse.success( + res, + 'AI response generated successfully', + { + response, + systemPrompt: defaultSystemPrompt, + userPrompt, + }, + 200 + ) + } catch (error: any) { + console.error('LangChain chat error:', error) + SendResponse.error(res, 'Failed to generate AI response', 500, { error: error.message }) + } + } + + /** + * User prompt only (no system message) + * + * POST /api/v1/langchain/prompt + * Body: { prompt: string } + */ + async prompt(req: Request, res: Response) { + try { + const { prompt } = req.body + + if (!prompt) { + return SendResponse.error(res, 'prompt is required', 400) + } + + const response = await langchainService.runUserPrompt(prompt) + + SendResponse.success( + res, + 'AI response generated successfully', + { + response, + prompt, + }, + 200 + ) + } catch (error: any) { + console.error('LangChain prompt error:', error) + SendResponse.error(res, 'Failed to generate AI response', 500, { error: error.message }) + } + } + + /** + * Custom template with variables + * + * POST /api/v1/langchain/template + * Body: { template: string, variables: object } + */ + async customTemplate(req: Request, res: Response) { + try { + const { template, variables } = req.body + + if (!template) { + return SendResponse.error(res, 'template is required', 400) + } + + if (!variables || typeof variables !== 'object') { + return SendResponse.error(res, 'variables must be an object', 400) + } + + const response = await langchainService.runCustomTemplate(template, variables) + + SendResponse.success( + res, + 'Template executed successfully', + { + response, + template, + variables, + }, + 200 + ) + } catch (error: any) { + console.error('LangChain template error:', error) + SendResponse.error(res, 'Failed to execute template', 500, { error: error.message }) + } + } + + /** + * Health check endpoint to verify LangChain is configured + * + * GET /api/v1/langchain/health + */ + async healthCheck(req: Request, res: Response) { + try { + const model = langchainService.getChatModel() + + SendResponse.success( + res, + 'LangChain is configured and ready', + { + status: 'operational', + model: model.modelName, + temperature: model.temperature, + maxTokens: model.maxTokens, + }, + 200 + ) + } catch (error: any) { + SendResponse.error(res, 'LangChain is not properly configured', 500, { error: error.message }) + } + } + + /** + * Test endpoint with a simple query + * + * GET /api/v1/langchain/test + */ + async test(req: Request, res: Response) { + try { + const testPrompt = 'Say hello in one sentence and confirm you are working correctly.' + + const response = await langchainService.runSimplePrompt( + 'You are a helpful AI assistant.', + testPrompt + ) + + SendResponse.success( + res, + 'LangChain test successful', + { + testPrompt, + response, + timestamp: new Date().toISOString(), + }, + 200 + ) + } catch (error: any) { + SendResponse.error(res, 'LangChain test failed', 500, { error: error.message }) + } + } +} + +export default new LangChainController() diff --git a/LocalMind-Backend/src/api/v1/LangChain/langchain.routes.ts b/LocalMind-Backend/src/api/v1/LangChain/langchain.routes.ts new file mode 100644 index 0000000..f6b409e --- /dev/null +++ b/LocalMind-Backend/src/api/v1/LangChain/langchain.routes.ts @@ -0,0 +1,27 @@ +import { Router } from 'express' +import langchainController from './langchain.controller' + +const router: Router = Router() + +/** + * LangChain Routes + * + * Endpoints for LangChain-powered AI operations + */ + +// Health check +router.get('/v1/langchain/health', langchainController.healthCheck) + +// Test endpoint +router.get('/v1/langchain/test', langchainController.test) + +// Chat with system + user prompts +router.post('/v1/langchain/chat', langchainController.chat) + +// Simple user prompt +router.post('/v1/langchain/prompt', langchainController.prompt) + +// Custom template execution +router.post('/v1/langchain/template', langchainController.customTemplate) + +export { router as LangChainRouter } diff --git a/LocalMind-Backend/src/routes/app.ts b/LocalMind-Backend/src/routes/app.ts index 4905423..678df70 100644 --- a/LocalMind-Backend/src/routes/app.ts +++ b/LocalMind-Backend/src/routes/app.ts @@ -9,6 +9,7 @@ import { DataSetRoutes } from '../api/v1/DataSet/v1/DataSet.routes' import { userRoutes } from '../api/v1/user/user.routes' import { OllamaRouter } from '../api/v1/Ai-model/Ollama/Ollama.routes' import { GroqRouter } from '../api/v1/Ai-model/Groq/Groq.routes' +import { LangChainRouter } from '../api/v1/LangChain/langchain.routes' logger.token('time', () => new Date().toLocaleString()) @@ -19,7 +20,7 @@ app.use(express.json()) app.use(express.urlencoded({ extended: true })) // API routes -app.use('/api', GoogleRoutes, userRoutes, DataSetRoutes, OllamaRouter, GroqRouter) +app.use('/api', GoogleRoutes, userRoutes, DataSetRoutes, OllamaRouter, GroqRouter, LangChainRouter) // Serve static files from public directory (for frontend in production) const publicPath = path.join(__dirname, '../../public') diff --git a/LocalMind-Backend/src/services/langchain.service.ts b/LocalMind-Backend/src/services/langchain.service.ts new file mode 100644 index 0000000..ef2eb09 --- /dev/null +++ b/LocalMind-Backend/src/services/langchain.service.ts @@ -0,0 +1,204 @@ +import { ChatOpenAI } from '@langchain/openai' +import { ChatPromptTemplate } from '@langchain/core/prompts' +import { RunnableSequence } from '@langchain/core/runnables' +import { env } from '../constant/env.constant' + +/** + * LangChain Service for AI Processing + * + * Provides reusable LangChain utilities for: + * - OpenAI ChatGPT integration + * - Prompt template management + * - Runnable sequence chains + * - System + User prompt flows + * + * @example + * ```ts + * import langchainService from './services/langchain.service' + * + * const response = await langchainService.runSimplePrompt( + * 'You are a helpful assistant', + * 'Explain quantum computing' + * ) + * ``` + */ +class LangChainService { + private chatModel: ChatOpenAI + + constructor() { + if (!env.OPENAI_API_KEY) { + throw new Error( + 'OPENAI_API_KEY is not configured. Please set it in your .env file to use LangChain with OpenAI.' + ) + } + + this.chatModel = new ChatOpenAI({ + modelName: env.OPENAI_MODEL || 'gpt-4o-mini', + openAIApiKey: env.OPENAI_API_KEY, + temperature: 0.7, + maxTokens: 2000, + timeout: 30000, // 30 seconds + }) + } + + /** + * Get the ChatOpenAI model instance + * + * @returns {ChatOpenAI} Configured ChatOpenAI client + */ + public getChatModel(): ChatOpenAI { + return this.chatModel + } + + /** + * Run a simple prompt with system and user messages + * + * Creates a basic chain with: + * 1. System message (defines AI behavior/role) + * 2. User message (the actual query) + * 3. LLM invocation + * 4. Response parsing + * + * @param systemPrompt - Instructions for AI behavior (e.g., "You are a helpful assistant") + * @param userPrompt - The user's question or request + * @returns Promise - AI response text + * + * @throws Error if API key is missing or request fails + * + * @example + * ```ts + * const response = await langchainService.runSimplePrompt( + * 'You are a coding expert', + * 'Write a Python hello world program' + * ) + * console.log(response) // "print('Hello, World!')" + * ``` + */ + public async runSimplePrompt(systemPrompt: string, userPrompt: string): Promise { + try { + // Create prompt template with system and user messages + const promptTemplate = ChatPromptTemplate.fromMessages([ + ['system', systemPrompt], + ['user', '{userInput}'], + ]) + + // Create a runnable sequence chain + const chain = RunnableSequence.from([promptTemplate, this.chatModel]) + + // Execute the chain + const response = await chain.invoke({ + userInput: userPrompt, + }) + + // Parse and return the response + if (typeof response.content === 'string') { + return response.content + } else { + // Handle potential array content + return JSON.stringify(response.content) + } + } catch (error: any) { + throw new Error(`LangChain invocation failed: ${error.message}`) + } + } + + /** + * Run a simple prompt with just user message (no system prompt) + * + * @param userPrompt - The user's question + * @returns Promise - AI response + */ + public async runUserPrompt(userPrompt: string): Promise { + try { + const response = await this.chatModel.invoke(userPrompt) + + if (typeof response.content === 'string') { + return response.content + } else { + return JSON.stringify(response.content) + } + } catch (error: any) { + throw new Error(`LangChain invocation failed: ${error.message}`) + } + } + + /** + * Run a prompt with custom template variables + * + * @param templateString - Template with placeholders like {variable} + * @param variables - Object with variable values + * @returns Promise - AI response + * + * @example + * ```ts + * await langchainService.runCustomTemplate( + * 'Translate {text} from {fromLang} to {toLang}', + * { text: 'Hello', fromLang: 'English', toLang: 'Spanish' } + * ) + * ``` + */ + public async runCustomTemplate( + templateString: string, + variables: Record + ): Promise { + try { + const promptTemplate = ChatPromptTemplate.fromTemplate(templateString) + const chain = RunnableSequence.from([promptTemplate, this.chatModel]) + + const response = await chain.invoke(variables) + + if (typeof response.content === 'string') { + return response.content + } else { + return JSON.stringify(response.content) + } + } catch (error: any) { + throw new Error(`LangChain custom template failed: ${error.message}`) + } + } + + /** + * Stream a response token by token + * + * @param systemPrompt - System instructions + * @param userPrompt - User query + * @param onToken - Callback for each token + * @returns Promise - Complete response + */ + public async streamPrompt( + systemPrompt: string, + userPrompt: string, + onToken?: (token: string) => void + ): Promise { + try { + const promptTemplate = ChatPromptTemplate.fromMessages([ + ['system', systemPrompt], + ['user', '{userInput}'], + ]) + + const chain = RunnableSequence.from([promptTemplate, this.chatModel]) + + const stream = await chain.stream({ + userInput: userPrompt, + }) + + let fullResponse = '' + + for await (const chunk of stream) { + const content = chunk.content.toString() + fullResponse += content + + if (onToken) { + onToken(content) + } + } + + return fullResponse + } catch (error: any) { + throw new Error(`LangChain streaming failed: ${error.message}`) + } + } +} + +// Export singleton instance +export default new LangChainService() diff --git a/LocalMind-Backend/src/validator/env.ts b/LocalMind-Backend/src/validator/env.ts index ae9421e..755c227 100644 --- a/LocalMind-Backend/src/validator/env.ts +++ b/LocalMind-Backend/src/validator/env.ts @@ -6,7 +6,7 @@ export const EnvSchema = z.object({ APP_ENV: z.enum(['development', 'production', 'test']).default('development'), DEBUG: z .string() - .transform((v) => v === 'true') + .transform(v => v === 'true') .default(true), Your_Name: z.string(), YOUR_EMAIL: z.email(), @@ -16,15 +16,15 @@ export const EnvSchema = z.object({ CORS_ENABLED: z .string() - .transform((v) => v === 'true') + .transform(v => v === 'true') .default(true), RATE_LIMIT_ENABLED: z .string() - .transform((v) => v === 'true') + .transform(v => v === 'true') .default(false), ENABLE_RATE_LIMITING: z .string() - .transform((v) => v === 'true') + .transform(v => v === 'true') .default(false), JWT_SECRET: z.string(), @@ -51,5 +51,6 @@ export const EnvSchema = z.object({ GOOGLE_API_KEY: z.string().optional(), OPENAI_API_KEY: z.string().optional(), + OPENAI_MODEL: z.string().default('gpt-4o-mini'), BACKEND_URL: z.string().default('http://localhost:5000'), }) diff --git a/docs/LANGCHAIN_SETUP.md b/docs/LANGCHAIN_SETUP.md new file mode 100644 index 0000000..a499731 --- /dev/null +++ b/docs/LANGCHAIN_SETUP.md @@ -0,0 +1,467 @@ +# LangChain Integration Guide + +## Overview + +This guide explains how to use LangChain with LocalMind for advanced AI processing, including: + +- OpenAI ChatGPT integration +- Prompt template management +- Runnable sequence chains +- Streaming responses +- Custom template execution + +LangChain provides a framework for building AI applications with support for multiple LLM providers, prompt engineering, and complex AI workflows. + +## Prerequisites + +- **OpenAI API Key** - Required for ChatGPT models +- **Node.js** 18+ installed +- **LocalMind Backend** setup complete + +## Configuration + +### 1. Environment Variables + +Add these to your `.env` file in `LocalMind-Backend/`: + +```dotenv +# OpenAI Configuration +OPENAI_API_KEY=sk-your-api-key-here +OPENAI_MODEL=gpt-4o-mini +``` + +**Available Models:** + +- `gpt-4o` - Most capable, higher cost +- `gpt-4o-mini` - Balanced performance (recommended) +- `gpt-4-turbo` - Fast and capable +- `gpt-3.5-turbo` - Fastest, lower cost + +### 2. Get OpenAI API Key + +1. Go to https://platform.openai.com/api-keys +2. Click "Create new secret key" +3. Copy the key (starts with `sk-...`) +4. Paste into your `.env` file + +**Important:** Never commit API keys to version control! + +## Architecture + +### Service Layer + +**File:** `src/services/langchain.service.ts` + +The LangChain service provides: + +- `getChatModel()` - Get configured ChatOpenAI instance +- `runSimplePrompt()` - Execute system + user prompt +- `runUserPrompt()` - Execute user-only prompt +- `runCustomTemplate()` - Execute custom templates with variables +- `streamPrompt()` - Stream responses token by token + +### Controller Layer + +**File:** `src/api/v1/LangChain/langchain.controller.ts` + +HTTP endpoints for: + +- Health checks +- Test queries +- Simple chat +- Template execution + +## API Endpoints + +### GET `/api/v1/langchain/health` + +Check if LangChain is configured and operational. + +**Response:** + +```json +{ + "success": true, + "message": "LangChain is configured and ready", + "data": { + "status": "operational", + "model": "gpt-4o-mini", + "temperature": 0.7, + "maxTokens": 2000 + } +} +``` + +**Test:** + +```bash +curl http://localhost:5000/api/v1/langchain/health +``` + +--- + +### GET `/api/v1/langchain/test` + +Run a simple test query to verify the setup. + +**Response:** + +```json +{ + "success": true, + "message": "LangChain test successful", + "data": { + "testPrompt": "Say hello in one sentence and confirm you are working correctly.", + "response": "Hello! I'm working correctly and ready to assist you.", + "timestamp": "2024-01-15T10:30:00.000Z" + } +} +``` + +**Test:** + +```bash +curl http://localhost:5000/api/v1/langchain/test +``` + +--- + +### POST `/api/v1/langchain/chat` + +Chat with AI using system and user prompts. + +**Request Body:** + +```json +{ + "systemPrompt": "You are a helpful coding assistant", + "userPrompt": "Write a Python function to reverse a string" +} +``` + +**Response:** + +```json +{ + "success": true, + "message": "AI response generated successfully", + "data": { + "response": "def reverse_string(s):\n return s[::-1]", + "systemPrompt": "You are a helpful coding assistant", + "userPrompt": "Write a Python function to reverse a string" + } +} +``` + +**Test:** + +```bash +curl -X POST http://localhost:5000/api/v1/langchain/chat \ + -H "Content-Type: application/json" \ + -d '{ + "systemPrompt": "You are a helpful assistant", + "userPrompt": "Explain quantum computing in one sentence" + }' +``` + +--- + +### POST `/api/v1/langchain/prompt` + +Simple user prompt without system message. + +**Request Body:** + +```json +{ + "prompt": "What is the capital of France?" +} +``` + +**Response:** + +```json +{ + "success": true, + "message": "AI response generated successfully", + "data": { + "response": "The capital of France is Paris.", + "prompt": "What is the capital of France?" + } +} +``` + +--- + +### POST `/api/v1/langchain/template` + +Execute custom templates with variables. + +**Request Body:** + +```json +{ + "template": "Translate '{text}' from {fromLang} to {toLang}", + "variables": { + "text": "Hello, how are you?", + "fromLang": "English", + "toLang": "Spanish" + } +} +``` + +**Response:** + +```json +{ + "success": true, + "message": "Template executed successfully", + "data": { + "response": "Hola, ¿cómo estás?", + "template": "Translate '{text}' from {fromLang} to {toLang}", + "variables": { ... } + } +} +``` + +## Usage in Code + +### Example 1: Simple Chat + +```typescript +import langchainService from './services/langchain.service' + +const response = await langchainService.runSimplePrompt( + 'You are a helpful assistant', + 'Explain machine learning in simple terms' +) + +console.log(response) +``` + +### Example 2: Custom Template + +```typescript +const response = await langchainService.runCustomTemplate( + 'Write a {type} about {topic} in {style} style', + { + type: 'poem', + topic: 'artificial intelligence', + style: 'haiku', + } +) +``` + +### Example 3: Streaming Responses + +```typescript +await langchainService.streamPrompt( + 'You are a storyteller', + 'Tell me a short story about AI', + token => { + // Called for each token + process.stdout.write(token) + } +) +``` + +### Example 4: Using in Your Controller + +```typescript +import langchainService from '../services/langchain.service' + +class MyController { + async generateText(req: Request, res: Response) { + const { prompt } = req.body + + const response = await langchainService.runUserPrompt(prompt) + + res.json({ success: true, data: response }) + } +} +``` + +## Advanced Features + +### Prompt Templates + +LangChain supports complex prompt templates with: + +- **Variables:** `{variable_name}` +- **Conditional logic** +- **Multi-turn conversations** +- **Chat history management** + +### Runnable Sequences + +Chain multiple operations: + +```typescript +import { RunnableSequence } from '@langchain/core/runnables' +import { ChatPromptTemplate } from '@langchain/core/prompts' + +const prompt = ChatPromptTemplate.fromTemplate('Translate: {text}') +const chain = RunnableSequence.from([prompt, chatModel]) +const result = await chain.invoke({ text: 'Hello' }) +``` + +### Streaming + +For real-time responses: + +```typescript +const stream = await langchainService.streamPrompt( + 'You are a creative writer', + 'Write a haiku about technology' +) +``` + +## Troubleshooting + +### Issue: "OPENAI_API_KEY is not configured" + +**Solution:** + +1. Check that `.env` file exists in `LocalMind-Backend/` +2. Verify `OPENAI_API_KEY` is set correctly +3. Restart the backend server + +```bash +# Verify env loading +cd LocalMind-Backend +cat .env | grep OPENAI_API_KEY +pnpm dev +``` + +--- + +### Issue: "Request failed with status code 401" + +**Cause:** Invalid or expired API key + +**Solution:** + +1. Generate a new key at https://platform.openai.com/api-keys +2. Update `.env` with the new key +3. Restart server + +--- + +### Issue: "Rate limit exceeded" + +**Cause:** Too many API requests + +**Solution:** + +- Use a different OpenAI model with higher limits +- Implement request throttling +- Upgrade your OpenAI plan + +--- + +### Issue: "Model not found" + +**Cause:** Invalid model name in `OPENAI_MODEL` + +**Solution:** +Use a valid model name: + +```dotenv +OPENAI_MODEL=gpt-4o-mini # Recommended +# OR +OPENAI_MODEL=gpt-3.5-turbo # Faster/cheaper +``` + +--- + +### Issue: Slow responses + +**Solutions:** + +1. Use faster models: `gpt-3.5-turbo` or `gpt-4o-mini` +2. Reduce `maxTokens` in service configuration +3. Implement caching for repeated queries + +## Cost Management + +### Token Usage + +- **gpt-4o-mini:** ~$0.15 / 1M input tokens, ~$0.60 / 1M output tokens +- **gpt-3.5-turbo:** ~$0.50 / 1M input tokens, ~$1.50 / 1M output tokens +- **gpt-4o:** ~$5.00 / 1M input tokens, ~$15.00 / 1M output tokens + +### Best Practices + +1. **Set token limits:** Configure `maxTokens` in service +2. **Use cheaper models** for simple tasks +3. **Cache responses** for repeated queries +4. **Monitor usage:** Check OpenAI dashboard regularly + +## Integration with RAG + +LangChain is essential for RAG (Retrieval-Augmented Generation): + +```typescript +// Example: RAG with LangChain +import { MemoryVectorStore } from 'langchain/vectorstores/memory' +import { OpenAIEmbeddings } from '@langchain/openai' + +// 1. Create embeddings +const embeddings = new OpenAIEmbeddings() + +// 2. Store documents +const vectorStore = await MemoryVectorStore.fromTexts(['Document 1', 'Document 2'], {}, embeddings) + +// 3. Retrieve relevant context +const docs = await vectorStore.similaritySearch('query') + +// 4. Use with LangChain +const response = await langchainService.runSimplePrompt( + `Use this context: ${docs[0].pageContent}`, + 'Answer the question' +) +``` + +See [docs/RAG_SETUP.md](./RAG_SETUP.md) for full RAG implementation. + +## Security Best Practices + +1. **Never commit `.env`** - Add to `.gitignore` +2. **Use environment variables** - No hardcoded keys +3. **Rotate keys regularly** - Generate new keys monthly +4. **Implement rate limiting** - Prevent abuse +5. **Validate input** - Sanitize user prompts +6. **Monitor costs** - Set up billing alerts + +## Next Steps + +- ✅ Configure LangChain +- ⏭️ Implement RAG (Issue #21) +- ⏭️ Add streaming support in frontend +- ⏭️ Build custom AI agents +- ⏭️ Integrate with Socket.IO for real-time chat + +## Additional Resources + +- **Official Docs:** https://langchain.com/docs/ +- **API Reference:** https://api.js.langchain.com/ +- **Examples:** https://github.com/langchain-ai/langchainjs/tree/main/examples +- **OpenAI Docs:** https://platform.openai.com/docs/ + +## Code Reference + +**Files Created:** + +- `src/services/langchain.service.ts` - Core LangChain service +- `src/api/v1/LangChain/langchain.controller.ts` - HTTP controllers +- `src/api/v1/LangChain/langchain.routes.ts` - API routes +- `docs/LANGCHAIN_SETUP.md` - This documentation + +**Environment:** + +- `.env` - Configuration (OPENAI_API_KEY, OPENAI_MODEL) +- `src/validator/env.ts` - Environment validation + +--- + +**Need help?** Open an issue on [GitHub](https://github.com/NexGenStudioDev/LocalMind/issues) with the `langchain` label.