From 12fcaf36760578af9622945c4339009c10a336cc Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 23 Apr 2024 09:20:07 +0200 Subject: [PATCH 01/21] feat: use managed identity for storage --- infra/core/security/role.bicep | 21 ++++++++++ infra/core/storage/storage-account.bicep | 3 -- infra/main.bicep | 41 ++++++++++++++++++-- infra/main.parameters.json | 6 +++ packages/api/src/functions/chat-post.ts | 1 + packages/api/src/functions/documents-get.ts | 11 ++++-- packages/api/src/functions/documents-post.ts | 10 +++-- 7 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 infra/core/security/role.bicep diff --git a/infra/core/security/role.bicep b/infra/core/security/role.bicep new file mode 100644 index 0000000..0b30cfd --- /dev/null +++ b/infra/core/security/role.bicep @@ -0,0 +1,21 @@ +metadata description = 'Creates a role assignment for a service principal.' +param principalId string + +@allowed([ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' +]) +param principalType string = 'ServicePrincipal' +param roleDefinitionId string + +resource role 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(subscription().id, resourceGroup().id, principalId, roleDefinitionId) + properties: { + principalId: principalId + principalType: principalType + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId) + } +} diff --git a/infra/core/storage/storage-account.bicep b/infra/core/storage/storage-account.bicep index a56266a..4b6febb 100644 --- a/infra/core/storage/storage-account.bicep +++ b/infra/core/storage/storage-account.bicep @@ -60,8 +60,5 @@ resource storage 'Microsoft.Storage/storageAccounts@2022-05-01' = { } } -var sharedKey = storage.listKeys().keys[0].value - output name string = storage.name output primaryEndpoints object = storage.properties.primaryEndpoints -output connectionString string = 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${sharedKey};EndpointSuffix=core.windows.net' diff --git a/infra/main.bicep b/infra/main.bicep index 1a8d017..5bb6cce 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -52,11 +52,17 @@ param embeddingsDeploymentCapacity int = 30 param blobContainerName string = 'files' +// Id of the user or app to assign application roles +param principalId string = '' + +// Differentiates between automated and manual deployments +param isContinuousDeployment bool // Set in main.parameters.json + var abbrs = loadJsonContent('abbreviations.json') var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) var tags = { 'azd-env-name': environmentName } var finalOpenAiUrl = empty(openAiUrl) ? 'https://${openAi.outputs.name}.openai.azure.com' : openAiUrl -var finalOpenAiApiKey = empty(openAiKey) ? openAi.outputs.apiKey : openAiKey +var storageUrl = 'https://${storage.outputs.name}.blob.core.windows.net' // Organize resources in a resource group resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { @@ -96,7 +102,7 @@ module api './core/host/functions.bicep' = { AZURE_OPENAI_API_DEPLOYMENT_NAME: chatDeploymentName AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME: embeddingsDeploymentName AZURE_COSMOSDB_CONNECTION_STRING: cosmos.outputs.connectionString - AZURE_STORAGE_CONNECTION_STRING: storage.outputs.connectionString + AZURE_STORAGE_URL: storageUrl AZURE_STORAGE_CONTAINER_NAME: blobContainerName } } @@ -182,6 +188,34 @@ module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) { } } +// Managed identity roles assignation +// --------------------------------------------------------------------------- + +// User roles +module openAiRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) { +module storageRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) { + scope: resourceGroup + name: 'storage-contrib-role-user' + params: { + principalId: principalId + // Storage Blob Data Contributor + roleDefinitionId: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' + principalType: 'User' + } +} + +// System roles +module storageRoleApi 'core/security/role.bicep' = { + scope: resourceGroup + name: 'storage-role-api' + params: { + principalId: api.outputs.identityPrincipalId + // Storage Blob Data Contributor + roleDefinitionId: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' + principalType: 'ServicePrincipal' + } +} + output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId output AZURE_RESOURCE_GROUP string = resourceGroup.name @@ -194,8 +228,7 @@ output AZURE_OPENAI_API_MODEL_VERSION string = chatModelVersion output AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME string = embeddingsDeploymentName output AZURE_OPENAI_API_EMBEDDINGS_MODEL string = embeddingsModelName output AZURE_OPENAI_API_EMBEDDINGS_MODEL_VERSION string = embeddingsModelVersion -output AZURE_COSMOSDB_CONNECTION_STRING string = cosmos.outputs.connectionString -output AZURE_STORAGE_CONNECTION_STRING string = storage.outputs.connectionString +output AZURE_STORAGE_URL string = storageUrl output AZURE_STORAGE_CONTAINER_NAME string = blobContainerName output API_URL string = api.outputs.uri diff --git a/infra/main.parameters.json b/infra/main.parameters.json index 196dc90..3a06894 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -11,6 +11,9 @@ "location": { "value": "${AZURE_LOCATION}" }, + "principalId": { + "value": "${AZURE_PRINCIPAL_ID}" + }, "openAiLocation": { "value": "${AZURE_OPENAI_LOCATION=eastus2}" }, @@ -37,6 +40,9 @@ }, "mongoDbSkuName": { "value": "${AZURE_MONGODB_SKU=Free}" + }, + "isContinuousDeployment": { + "value": "${CI=false}" } } } diff --git a/packages/api/src/functions/chat-post.ts b/packages/api/src/functions/chat-post.ts index ee8b776..4bd345b 100644 --- a/packages/api/src/functions/chat-post.ts +++ b/packages/api/src/functions/chat-post.ts @@ -1,6 +1,7 @@ import { Readable } from 'node:stream'; import { Document } from '@langchain/core/documents'; import { HttpRequest, InvocationContext, HttpResponseInit, app } from '@azure/functions'; +import { DefaultAzureCredential } from '@azure/identity'; import { AzureOpenAIEmbeddings, AzureChatOpenAI } from '@langchain/azure-openai'; import { Embeddings } from '@langchain/core/embeddings'; import { BaseChatModel } from '@langchain/core/language_models/chat_models'; diff --git a/packages/api/src/functions/documents-get.ts b/packages/api/src/functions/documents-get.ts index 0683f4f..85612b2 100644 --- a/packages/api/src/functions/documents-get.ts +++ b/packages/api/src/functions/documents-get.ts @@ -3,22 +3,27 @@ import fs from 'node:fs/promises'; import { join } from 'node:path'; import { finished } from 'node:stream/promises'; import { HttpRequest, HttpResponseInit, InvocationContext, app } from '@azure/functions'; +import { DefaultAzureCredential } from '@azure/identity'; import { BlobServiceClient } from '@azure/storage-blob'; import 'dotenv/config'; import { data, notFound } from '../http-response'; async function getDocument(request: HttpRequest, context: InvocationContext): Promise { - const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; + const storageUrl = process.env.AZURE_STORAGE_URL; const containerName = process.env.AZURE_STORAGE_CONTAINER_NAME; const { fileName } = request.params; try { let fileData: Uint8Array; - if (connectionString && containerName) { + if (storageUrl && containerName) { // Retrieve the file from Azure Blob Storage context.log(`Reading blob from: "${containerName}/${fileName}"`); - const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString); + + // Use the current user identity to authenticate + // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). + const credentials = new DefaultAzureCredential(); + const blobServiceClient = new BlobServiceClient(storageUrl, credentials); const containerClient = blobServiceClient.getContainerClient(containerName); const response = await containerClient.getBlobClient(fileName).download(); diff --git a/packages/api/src/functions/documents-post.ts b/packages/api/src/functions/documents-post.ts index 1db4e66..ac80997 100644 --- a/packages/api/src/functions/documents-post.ts +++ b/packages/api/src/functions/documents-post.ts @@ -6,12 +6,13 @@ import { AzureCosmosDBVectorStore } from '@langchain/community/vectorstores/azur import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama'; import { FaissStore } from '@langchain/community/vectorstores/faiss'; import 'dotenv/config'; +import { DefaultAzureCredential } from '@azure/identity'; import { BlobServiceClient } from '@azure/storage-blob'; import { badRequest, serviceUnavailable, ok } from '../http-response'; import { ollamaEmbeddingsModel, faissStoreFolder } from '../constants'; export async function postDocuments(request: HttpRequest, context: InvocationContext): Promise { - const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; + const storageUrl = process.env.AZURE_STORAGE_URL; const containerName = process.env.AZURE_STORAGE_CONTAINER_NAME; const azureOpenAiEndpoint = process.env.AZURE_OPENAI_API_ENDPOINT; @@ -53,10 +54,13 @@ export async function postDocuments(request: HttpRequest, context: InvocationCon await store.save(faissStoreFolder); } - if (connectionString && containerName) { + if (storageUrl && containerName) { // Upload the PDF file to Azure Blob Storage context.log(`Uploading file to blob storage: "${containerName}/${filename}"`); - const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString); + // Use the current user identity to authenticate + // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). + const credentials = new DefaultAzureCredential(); + const blobServiceClient = new BlobServiceClient(storageUrl, credentials); const containerClient = blobServiceClient.getContainerClient(containerName); const blockBlobClient = containerClient.getBlockBlobClient(filename); const buffer = await file.arrayBuffer(); From 19af3304ae3d44b6d33d8b09c251f942ae0fbe2d Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 23 Apr 2024 09:22:43 +0200 Subject: [PATCH 02/21] feat: use openai managed identity --- infra/core/ai/cognitiveservices.bicep | 3 ++- infra/main.bicep | 23 ++++++++++++++++++++ packages/api/src/functions/chat-post.ts | 7 ++++-- packages/api/src/functions/documents-post.ts | 7 +++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/infra/core/ai/cognitiveservices.bicep b/infra/core/ai/cognitiveservices.bicep index a485731..83e7515 100644 --- a/infra/core/ai/cognitiveservices.bicep +++ b/infra/core/ai/cognitiveservices.bicep @@ -20,6 +20,7 @@ param networkAcls object = empty(allowedIpRules) ? { ipRules: allowedIpRules defaultAction: 'Deny' } +param disableLocalAuth bool = false resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = { name: name @@ -30,6 +31,7 @@ resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = { customSubDomainName: customSubDomainName publicNetworkAccess: publicNetworkAccess networkAcls: networkAcls + disableLocalAuth: disableLocalAuth } sku: sku } @@ -51,4 +53,3 @@ resource deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01 output endpoint string = account.properties.endpoint output id string = account.id output name string = account.name -output apiKey string = account.listKeys().key1 diff --git a/infra/main.bicep b/infra/main.bicep index 5bb6cce..4039be9 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -62,6 +62,7 @@ var abbrs = loadJsonContent('abbreviations.json') var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) var tags = { 'azd-env-name': environmentName } var finalOpenAiUrl = empty(openAiUrl) ? 'https://${openAi.outputs.name}.openai.azure.com' : openAiUrl +var finalOpenAiApiKey = empty(openAiKey) ? '' : openAiKey var storageUrl = 'https://${storage.outputs.name}.blob.core.windows.net' // Organize resources in a resource group @@ -162,6 +163,7 @@ module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) { sku: { name: openAiSkuName } + disableLocalAuth: true deployments: [ { name: chatDeploymentName @@ -193,6 +195,16 @@ module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) { // User roles module openAiRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) { + scope: resourceGroup + name: 'openai-role-user' + params: { + principalId: principalId + // Cognitive Services OpenAI User + roleDefinitionId: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' + principalType: 'User' + } +} + module storageRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) { scope: resourceGroup name: 'storage-contrib-role-user' @@ -205,6 +217,17 @@ module storageRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) } // System roles +module openAiRoleApi 'core/security/role.bicep' = { + scope: resourceGroup + name: 'openai-role-api' + params: { + principalId: api.outputs.identityPrincipalId + // Cognitive Services OpenAI User + roleDefinitionId: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' + principalType: 'ServicePrincipal' + } +} + module storageRoleApi 'core/security/role.bicep' = { scope: resourceGroup name: 'storage-role-api' diff --git a/packages/api/src/functions/chat-post.ts b/packages/api/src/functions/chat-post.ts index 4bd345b..98fa1aa 100644 --- a/packages/api/src/functions/chat-post.ts +++ b/packages/api/src/functions/chat-post.ts @@ -56,9 +56,12 @@ export async function postChat(request: HttpRequest, context: InvocationContext) let store: VectorStore; if (azureOpenAiEndpoint) { + // Use the current user identity to authenticate + // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). + const credentials = new DefaultAzureCredential(); // Initialize models and vector database - embeddings = new AzureOpenAIEmbeddings(); - model = new AzureChatOpenAI(); + embeddings = new AzureOpenAIEmbeddings({ credentials }); + model = new AzureChatOpenAI({ credentials }); store = new AzureCosmosDBVectorStore(embeddings, {}); } else { // If no environment variables are set, it means we are running locally diff --git a/packages/api/src/functions/documents-post.ts b/packages/api/src/functions/documents-post.ts index ac80997..a70efc7 100644 --- a/packages/api/src/functions/documents-post.ts +++ b/packages/api/src/functions/documents-post.ts @@ -13,6 +13,7 @@ import { ollamaEmbeddingsModel, faissStoreFolder } from '../constants'; export async function postDocuments(request: HttpRequest, context: InvocationContext): Promise { const storageUrl = process.env.AZURE_STORAGE_URL; + const safeConnectionString = process.env.AZURE_COSMOSDB_SAFE_CONNECTION_STRING; const containerName = process.env.AZURE_STORAGE_CONTAINER_NAME; const azureOpenAiEndpoint = process.env.AZURE_OPENAI_API_ENDPOINT; @@ -43,7 +44,11 @@ export async function postDocuments(request: HttpRequest, context: InvocationCon // Generate embeddings and save in database if (azureOpenAiEndpoint) { - const store = await AzureCosmosDBVectorStore.fromDocuments(documents, new AzureOpenAIEmbeddings(), {}); + // Use the current user identity to authenticate + // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). + const credentials = new DefaultAzureCredential(); + const embeddings = new AzureOpenAIEmbeddings({ credentials }); + const store = await AzureCosmosDBVectorStore.fromDocuments(documents, embeddings, {}); await store.createIndex(); await store.close(); } else { From 85ab9401e8190a9fdc676e8ca2cfd5b1cb17101b Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 23 Apr 2024 09:23:29 +0200 Subject: [PATCH 03/21] chore: add identity package --- package-lock.json | 227 +++++++++++++++++++++++++++++++++++++- packages/api/package.json | 1 + 2 files changed, 224 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 951f096..43d87fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -131,6 +131,45 @@ "node": ">=18.0.0" } }, + "node_modules/@azure/core-client": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz", + "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/@azure/core-tracing": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", + "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@azure/core-http": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.4.tgz", @@ -290,6 +329,41 @@ "node": ">=18.0" } }, + "node_modules/@azure/identity": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.1.0.tgz", + "integrity": "sha512-BhYkF8Xr2gXjyDxocm0pc9RI5J5a1jw8iW0dw6Bx95OGdYbuMyFZrrwNw4eYSqQ2BB6FZOqpJP3vjsAqRcvDhw==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.5.0", + "@azure/core-client": "^1.4.0", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.3.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^3.11.1", + "@azure/msal-node": "^2.6.6", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^8.0.0", + "stoppable": "^1.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/core-tracing": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", + "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@azure/logger": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.2.tgz", @@ -301,6 +375,38 @@ "node": ">=18.0.0" } }, + "node_modules/@azure/msal-browser": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.13.0.tgz", + "integrity": "sha512-fD906nmJei3yE7la6DZTdUtXKvpwzJURkfsiz9747Icv4pit77cegSm6prJTKLQ1fw4iiZzrrWwxnhMLrTf5gQ==", + "dependencies": { + "@azure/msal-common": "14.9.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "14.9.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.9.0.tgz", + "integrity": "sha512-yzBPRlWPnTBeixxLNI3BBIgF5/bHpbhoRVuuDBnYjCyWRavaPUsKAHUDYLqpGkBLDciA6TCc6GOxN4/S3WiSxg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.7.0.tgz", + "integrity": "sha512-wXD8LkUvHICeSWZydqg6o8Yvv+grlBEcmLGu+QEI4FcwFendbTEZrlSygnAXXSOCVaGAirWLchca35qrgpO6Jw==", + "dependencies": { + "@azure/msal-common": "14.9.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@azure/openai": { "version": "1.0.0-beta.11", "resolved": "https://registry.npmjs.org/@azure/openai/-/openai-1.0.0-beta.11.tgz", @@ -3240,6 +3346,11 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3929,6 +4040,14 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.736", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz", @@ -6314,7 +6433,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, "bin": { "is-docker": "cli.js" }, @@ -6600,7 +6718,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -6743,6 +6860,65 @@ "node": ">=0.10.0" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -7313,12 +7489,47 @@ "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==", "dev": true }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/log-symbols": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", @@ -8002,7 +8213,6 @@ "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -8144,7 +8354,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, "engines": { "node": ">=8" } @@ -9393,6 +9602,15 @@ "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -10752,6 +10970,7 @@ "license": "MIT", "dependencies": { "@azure/functions": "^4.0.0", + "@azure/identity": "^4.1.0", "@azure/storage-blob": "^12.17.0", "@langchain/azure-openai": "^0.0.7", "@langchain/community": "^0.0.48", diff --git a/packages/api/package.json b/packages/api/package.json index 0014a49..493d526 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -15,6 +15,7 @@ "license": "MIT", "dependencies": { "@azure/functions": "^4.0.0", + "@azure/identity": "^4.1.0", "@azure/storage-blob": "^12.17.0", "@langchain/azure-openai": "^0.0.7", "@langchain/community": "^0.0.48", From 931631bd1188788870ea5c0e3a2686858a6d347e Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 23 Apr 2024 09:25:37 +0200 Subject: [PATCH 04/21] fix: db connection string --- infra/main.bicep | 1 + packages/api/src/functions/documents-post.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/main.bicep b/infra/main.bicep index 4039be9..046dd54 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -253,6 +253,7 @@ output AZURE_OPENAI_API_EMBEDDINGS_MODEL string = embeddingsModelName output AZURE_OPENAI_API_EMBEDDINGS_MODEL_VERSION string = embeddingsModelVersion output AZURE_STORAGE_URL string = storageUrl output AZURE_STORAGE_CONTAINER_NAME string = blobContainerName +output AZURE_COSMOSDB_CONNECTION_STRING string = cosmos.outputs.connectionString output API_URL string = api.outputs.uri output WEBAPP_URL string = webapp.outputs.uri diff --git a/packages/api/src/functions/documents-post.ts b/packages/api/src/functions/documents-post.ts index a70efc7..73a1bf8 100644 --- a/packages/api/src/functions/documents-post.ts +++ b/packages/api/src/functions/documents-post.ts @@ -13,7 +13,6 @@ import { ollamaEmbeddingsModel, faissStoreFolder } from '../constants'; export async function postDocuments(request: HttpRequest, context: InvocationContext): Promise { const storageUrl = process.env.AZURE_STORAGE_URL; - const safeConnectionString = process.env.AZURE_COSMOSDB_SAFE_CONNECTION_STRING; const containerName = process.env.AZURE_STORAGE_CONTAINER_NAME; const azureOpenAiEndpoint = process.env.AZURE_OPENAI_API_ENDPOINT; From 0d0432451884607f0af40fa3d431037fbf5d6552 Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 23 Apr 2024 10:19:56 +0200 Subject: [PATCH 05/21] refactor: add getCredentials helper --- packages/api/src/functions/chat-post.ts | 6 ++---- packages/api/src/functions/documents-get.ts | 6 ++---- packages/api/src/functions/documents-post.ts | 10 +++------- packages/api/src/security.ts | 11 +++++++++++ 4 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 packages/api/src/security.ts diff --git a/packages/api/src/functions/chat-post.ts b/packages/api/src/functions/chat-post.ts index 98fa1aa..5427e60 100644 --- a/packages/api/src/functions/chat-post.ts +++ b/packages/api/src/functions/chat-post.ts @@ -1,7 +1,6 @@ import { Readable } from 'node:stream'; import { Document } from '@langchain/core/documents'; import { HttpRequest, InvocationContext, HttpResponseInit, app } from '@azure/functions'; -import { DefaultAzureCredential } from '@azure/identity'; import { AzureOpenAIEmbeddings, AzureChatOpenAI } from '@langchain/azure-openai'; import { Embeddings } from '@langchain/core/embeddings'; import { BaseChatModel } from '@langchain/core/language_models/chat_models'; @@ -17,6 +16,7 @@ import 'dotenv/config'; import { badRequest, data, serviceUnavailable } from '../http-response'; import { ollamaChatModel, ollamaEmbeddingsModel, faissStoreFolder } from '../constants'; import { ChatRequest, ChatResponseChunk } from '../models'; +import { getCredentials } from '../security'; const systemPrompt = `Assistant helps the Consto Real Estate company customers with questions and support requests. Be brief in your answers. Answer only in plain text format. Answer ONLY with information from the sources below. If there isn't enough information in the sources, say you don't know. Do not generate answers that don't use the sources. If asking a clarifying question to the user would help, ask the question. @@ -56,9 +56,7 @@ export async function postChat(request: HttpRequest, context: InvocationContext) let store: VectorStore; if (azureOpenAiEndpoint) { - // Use the current user identity to authenticate - // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). - const credentials = new DefaultAzureCredential(); + const credentials = getCredentials(); // Initialize models and vector database embeddings = new AzureOpenAIEmbeddings({ credentials }); model = new AzureChatOpenAI({ credentials }); diff --git a/packages/api/src/functions/documents-get.ts b/packages/api/src/functions/documents-get.ts index 85612b2..ec2b509 100644 --- a/packages/api/src/functions/documents-get.ts +++ b/packages/api/src/functions/documents-get.ts @@ -3,10 +3,10 @@ import fs from 'node:fs/promises'; import { join } from 'node:path'; import { finished } from 'node:stream/promises'; import { HttpRequest, HttpResponseInit, InvocationContext, app } from '@azure/functions'; -import { DefaultAzureCredential } from '@azure/identity'; import { BlobServiceClient } from '@azure/storage-blob'; import 'dotenv/config'; import { data, notFound } from '../http-response'; +import { getCredentials } from '../security'; async function getDocument(request: HttpRequest, context: InvocationContext): Promise { const storageUrl = process.env.AZURE_STORAGE_URL; @@ -20,9 +20,7 @@ async function getDocument(request: HttpRequest, context: InvocationContext): Pr // Retrieve the file from Azure Blob Storage context.log(`Reading blob from: "${containerName}/${fileName}"`); - // Use the current user identity to authenticate - // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). - const credentials = new DefaultAzureCredential(); + const credentials = getCredentials(); const blobServiceClient = new BlobServiceClient(storageUrl, credentials); const containerClient = blobServiceClient.getContainerClient(containerName); const response = await containerClient.getBlobClient(fileName).download(); diff --git a/packages/api/src/functions/documents-post.ts b/packages/api/src/functions/documents-post.ts index 73a1bf8..60da834 100644 --- a/packages/api/src/functions/documents-post.ts +++ b/packages/api/src/functions/documents-post.ts @@ -6,10 +6,10 @@ import { AzureCosmosDBVectorStore } from '@langchain/community/vectorstores/azur import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama'; import { FaissStore } from '@langchain/community/vectorstores/faiss'; import 'dotenv/config'; -import { DefaultAzureCredential } from '@azure/identity'; import { BlobServiceClient } from '@azure/storage-blob'; import { badRequest, serviceUnavailable, ok } from '../http-response'; import { ollamaEmbeddingsModel, faissStoreFolder } from '../constants'; +import { getCredentials } from '../security'; export async function postDocuments(request: HttpRequest, context: InvocationContext): Promise { const storageUrl = process.env.AZURE_STORAGE_URL; @@ -43,9 +43,7 @@ export async function postDocuments(request: HttpRequest, context: InvocationCon // Generate embeddings and save in database if (azureOpenAiEndpoint) { - // Use the current user identity to authenticate - // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). - const credentials = new DefaultAzureCredential(); + const credentials = getCredentials(); const embeddings = new AzureOpenAIEmbeddings({ credentials }); const store = await AzureCosmosDBVectorStore.fromDocuments(documents, embeddings, {}); await store.createIndex(); @@ -61,9 +59,7 @@ export async function postDocuments(request: HttpRequest, context: InvocationCon if (storageUrl && containerName) { // Upload the PDF file to Azure Blob Storage context.log(`Uploading file to blob storage: "${containerName}/${filename}"`); - // Use the current user identity to authenticate - // (no secrets needed, just use 'azd auth login' locally, and managed identity when deployed on Azure). - const credentials = new DefaultAzureCredential(); + const credentials = getCredentials(); const blobServiceClient = new BlobServiceClient(storageUrl, credentials); const containerClient = blobServiceClient.getContainerClient(containerName); const blockBlobClient = containerClient.getBlockBlobClient(filename); diff --git a/packages/api/src/security.ts b/packages/api/src/security.ts new file mode 100644 index 0000000..04a4c3d --- /dev/null +++ b/packages/api/src/security.ts @@ -0,0 +1,11 @@ +import { DefaultAzureCredential } from '@azure/identity'; + +let credentials: DefaultAzureCredential | undefined; + +export function getCredentials(): DefaultAzureCredential { + // Use the current user identity to authenticate. + // No secrets needed, it uses 'az loginz or 'azd auth login' locally, + // and managed identity when deployed on Azure. + credentials ||= new DefaultAzureCredential(); + return credentials; +} From aa42b13a97875d93fcece47dca2840926b2d1eae Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 23 Apr 2024 18:48:19 +0200 Subject: [PATCH 06/21] chore: remove key references --- infra/main.bicep | 7 ++----- infra/main.parameters.json | 6 ------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/infra/main.bicep b/infra/main.bicep index 046dd54..a782dc3 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -27,8 +27,6 @@ param mongoDbSkuName string = 'Free' param openAiLocation string // Set in main.parameters.json param openAiSkuName string = 'S0' param openAiUrl string = '' -@secure() -param openAiKey string = '' // Location is not relevant here as it's only for the built-in api // which is not used here. Static Web App is a global service otherwise @@ -62,7 +60,6 @@ var abbrs = loadJsonContent('abbreviations.json') var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) var tags = { 'azd-env-name': environmentName } var finalOpenAiUrl = empty(openAiUrl) ? 'https://${openAi.outputs.name}.openai.azure.com' : openAiUrl -var finalOpenAiApiKey = empty(openAiKey) ? '' : openAiKey var storageUrl = 'https://${storage.outputs.name}.blob.core.windows.net' // Organize resources in a resource group @@ -97,8 +94,8 @@ module api './core/host/functions.bicep' = { runtimeVersion: '20' appServicePlanId: appServicePlan.outputs.id storageAccountName: storage.outputs.name + managedIdentity: true appSettings: { - AZURE_OPENAI_API_KEY: finalOpenAiApiKey AZURE_OPENAI_API_ENDPOINT: finalOpenAiUrl AZURE_OPENAI_API_DEPLOYMENT_NAME: chatDeploymentName AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME: embeddingsDeploymentName @@ -107,6 +104,7 @@ module api './core/host/functions.bicep' = { AZURE_STORAGE_CONTAINER_NAME: blobContainerName } } + dependsOn: empty(openAiUrl) ? [] : [openAi] } // Compute plan for the Azure Functions API @@ -244,7 +242,6 @@ output AZURE_TENANT_ID string = tenant().tenantId output AZURE_RESOURCE_GROUP string = resourceGroup.name output AZURE_OPENAI_API_ENDPOINT string = finalOpenAiUrl -output AZURE_OPENAI_API_KEY string = finalOpenAiApiKey output AZURE_OPENAI_API_DEPLOYMENT_NAME string = chatDeploymentName output AZURE_OPENAI_API_MODEL string = chatModelName output AZURE_OPENAI_API_MODEL_VERSION string = chatModelVersion diff --git a/infra/main.parameters.json b/infra/main.parameters.json index 3a06894..383308f 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -17,12 +17,6 @@ "openAiLocation": { "value": "${AZURE_OPENAI_LOCATION=eastus2}" }, - "openAiUrl": { - "value": "${OPENAI_URL}" - }, - "openAiKey": { - "value": "${OPENAI_KEY}" - }, "chatModelName": { "value": "${AZURE_OPENAI_API_MODEL=gpt-35-turbo}" }, From 59f87c216fd71258f3df9ce9dccb06f2491e9364 Mon Sep 17 00:00:00 2001 From: sinedied Date: Wed, 24 Apr 2024 09:23:53 +0200 Subject: [PATCH 07/21] chore: update dependencies --- package-lock.json | 444 +++++++++++++++++++------------------- packages/api/package.json | 2 +- 2 files changed, 219 insertions(+), 227 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43d87fb..254bc60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -85,17 +85,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure-rest/core-client/node_modules/@azure/core-tracing": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", - "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@azure/abort-controller": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", @@ -159,17 +148,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-client/node_modules/@azure/core-tracing": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", - "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@azure/core-http": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.4.tgz", @@ -194,6 +172,18 @@ "node": ">=14.0.0" } }, + "node_modules/@azure/core-http/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@azure/core-lro": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz", @@ -259,17 +249,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-rest-pipeline/node_modules/@azure/core-tracing": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", - "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@azure/core-sse": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@azure/core-sse/-/core-sse-2.1.2.tgz", @@ -282,15 +261,14 @@ } }, "node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", - "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", + "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", "dependencies": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/core-util": { @@ -353,17 +331,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/identity/node_modules/@azure/core-tracing": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", - "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@azure/logger": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.2.tgz", @@ -442,6 +409,18 @@ "node": ">=14.0.0" } }, + "node_modules/@azure/storage-blob/node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", @@ -1221,9 +1200,9 @@ } }, "node_modules/@langchain/community": { - "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@langchain/community/-/community-0.0.48.tgz", - "integrity": "sha512-jG7dpJkgKtwbrSLsxW4mXmECopTj5tRt4+B+QcKCqZm7yEghFR44Xj5OkDWtzzsjpL47RJck5AJ8MsQnmi7WDQ==", + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@langchain/community/-/community-0.0.51.tgz", + "integrity": "sha512-TInG0nDCGIwg2iwHJkv1OYGVR2fDMYdpKRuuLlQoevvcHcCRIVlQS5d0MnAx0bWGUbVdkKpshrH8Ltpxt6fewA==", "dependencies": { "@langchain/core": "~0.1.56", "@langchain/openai": "~0.0.28", @@ -1260,6 +1239,7 @@ "@gradientai/nodejs-sdk": "^1.2.0", "@huggingface/inference": "^2.6.4", "@mozilla/readability": "*", + "@neondatabase/serverless": "*", "@opensearch-project/opensearch": "*", "@pinecone-database/pinecone": "*", "@planetscale/database": "^1.8.0", @@ -1277,7 +1257,7 @@ "@tensorflow/tfjs-converter": "*", "@tensorflow/tfjs-core": "*", "@upstash/redis": "^1.20.6", - "@upstash/vector": "^1.0.2", + "@upstash/vector": "^1.0.7", "@vercel/kv": "^0.2.3", "@vercel/postgres": "^0.5.0", "@writerai/writer-sdk": "^0.40.2", @@ -1301,7 +1281,7 @@ "firebase-admin": "^11.9.0 || ^12.0.0", "google-auth-library": "^8.9.0", "googleapis": "^126.0.1", - "hnswlib-node": "^1.4.2", + "hnswlib-node": "^3.0.0", "html-to-text": "^9.0.5", "interface-datastore": "^8.2.11", "ioredis": "^5.3.2", @@ -1397,6 +1377,9 @@ "@mozilla/readability": { "optional": true }, + "@neondatabase/serverless": { + "optional": true + }, "@opensearch-project/opensearch": { "optional": true }, @@ -1619,17 +1602,17 @@ } }, "node_modules/@langchain/community/node_modules/zod-to-json-schema": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.5.tgz", - "integrity": "sha512-+akaPo6a0zpVCCseDed504KBJUQpEW5QZw7RMneNmKw+fGaML1Z9tUNLnHHAC8x6dzVRO1eB2oEMyZRnuBZg7Q==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz", + "integrity": "sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==", "peerDependencies": { - "zod": "^3.22.4" + "zod": "^3.23.3" } }, "node_modules/@langchain/core": { - "version": "0.1.57", - "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.1.57.tgz", - "integrity": "sha512-6wOwidPkkRcANrOKl88+YYpm3jHfpg6W8EqZHQCImSAlxdEhyDSq2eeQKHOPCFCrfNWkClaNn+Wlzzz4Qwf9Tg==", + "version": "0.1.59", + "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.1.59.tgz", + "integrity": "sha512-cdLi/hH/gj1CIWVcwkOxM+QYpz5kYIBxpuRkoye3OwHry9Qa9djwlsGxpUmrv5pIbPkYd7GK9L+xTQqyYIAp6A==", "dependencies": { "ansi-styles": "^5.0.0", "camelcase": "6", @@ -1637,6 +1620,7 @@ "js-tiktoken": "^1.0.8", "langsmith": "~0.1.7", "ml-distance": "^4.0.0", + "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^9.0.0", @@ -1671,11 +1655,11 @@ } }, "node_modules/@langchain/core/node_modules/zod-to-json-schema": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.5.tgz", - "integrity": "sha512-+akaPo6a0zpVCCseDed504KBJUQpEW5QZw7RMneNmKw+fGaML1Z9tUNLnHHAC8x6dzVRO1eB2oEMyZRnuBZg7Q==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz", + "integrity": "sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==", "peerDependencies": { - "zod": "^3.22.4" + "zod": "^3.23.3" } }, "node_modules/@langchain/openai": { @@ -1694,11 +1678,11 @@ } }, "node_modules/@langchain/openai/node_modules/zod-to-json-schema": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.5.tgz", - "integrity": "sha512-+akaPo6a0zpVCCseDed504KBJUQpEW5QZw7RMneNmKw+fGaML1Z9tUNLnHHAC8x6dzVRO1eB2oEMyZRnuBZg7Q==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz", + "integrity": "sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==", "peerDependencies": { - "zod": "^3.22.4" + "zod": "^3.23.3" } }, "node_modules/@lit-labs/ssr-dom-shim": { @@ -1788,9 +1772,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.3.tgz", - "integrity": "sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz", + "integrity": "sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q==", "cpu": [ "arm" ], @@ -1801,9 +1785,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.3.tgz", - "integrity": "sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz", + "integrity": "sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w==", "cpu": [ "arm64" ], @@ -1814,9 +1798,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.3.tgz", - "integrity": "sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz", + "integrity": "sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw==", "cpu": [ "arm64" ], @@ -1827,9 +1811,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.3.tgz", - "integrity": "sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz", + "integrity": "sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ==", "cpu": [ "x64" ], @@ -1840,9 +1824,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.3.tgz", - "integrity": "sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz", + "integrity": "sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw==", "cpu": [ "arm" ], @@ -1853,9 +1837,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.14.3.tgz", - "integrity": "sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz", + "integrity": "sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg==", "cpu": [ "arm" ], @@ -1866,9 +1850,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.3.tgz", - "integrity": "sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz", + "integrity": "sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w==", "cpu": [ "arm64" ], @@ -1879,9 +1863,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.3.tgz", - "integrity": "sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz", + "integrity": "sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg==", "cpu": [ "arm64" ], @@ -1892,9 +1876,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.3.tgz", - "integrity": "sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz", + "integrity": "sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w==", "cpu": [ "ppc64" ], @@ -1905,9 +1889,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.3.tgz", - "integrity": "sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz", + "integrity": "sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng==", "cpu": [ "riscv64" ], @@ -1918,9 +1902,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.3.tgz", - "integrity": "sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz", + "integrity": "sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ==", "cpu": [ "s390x" ], @@ -1931,9 +1915,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.3.tgz", - "integrity": "sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz", + "integrity": "sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==", "cpu": [ "x64" ], @@ -1944,9 +1928,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.3.tgz", - "integrity": "sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz", + "integrity": "sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA==", "cpu": [ "x64" ], @@ -1957,9 +1941,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.3.tgz", - "integrity": "sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz", + "integrity": "sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA==", "cpu": [ "arm64" ], @@ -1970,9 +1954,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.3.tgz", - "integrity": "sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz", + "integrity": "sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w==", "cpu": [ "ia32" ], @@ -1983,9 +1967,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.3.tgz", - "integrity": "sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz", + "integrity": "sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A==", "cpu": [ "x64" ], @@ -2008,9 +1992,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.9", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.9.tgz", - "integrity": "sha512-W4W3KcqzjJ0sHg2vAq9vfml6OhsJ53TcUjUqfzzZf/EChUtwspszj/S0pzMxnfRcO55/iGq47dscXw71Fxc4Zg==", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, "dependencies": { "@types/estree": "*", @@ -2112,16 +2096,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.6.0.tgz", - "integrity": "sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", + "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/type-utils": "7.6.0", - "@typescript-eslint/utils": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/type-utils": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.3.1", @@ -2147,15 +2131,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", + "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/typescript-estree": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4" }, "engines": { @@ -2175,13 +2159,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz", - "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", + "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0" + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2192,13 +2176,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.6.0.tgz", - "integrity": "sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", + "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.6.0", - "@typescript-eslint/utils": "7.6.0", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/utils": "7.7.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2219,9 +2203,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz", - "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", + "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2232,13 +2216,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz", - "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", + "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2289,17 +2273,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.6.0.tgz", - "integrity": "sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", + "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.15", "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/typescript-estree": "7.6.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", "semver": "^7.6.0" }, "engines": { @@ -2314,12 +2298,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz", - "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", + "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", + "@typescript-eslint/types": "7.7.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -3419,9 +3403,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001610", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz", - "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==", + "version": "1.0.30001612", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", + "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", "dev": true, "funding": [ { @@ -3735,9 +3719,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", + "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", "dev": true, "dependencies": { "browserslist": "^4.23.0" @@ -4049,9 +4033,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.736", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz", - "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==", + "version": "1.4.746", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.746.tgz", + "integrity": "sha512-jeWaIta2rIG2FzHaYIhSuVWqC6KJYo7oSBX4Jv7g+aVujKztfvdpf+n6MGwZdC5hQXbax4nntykLH2juIQrfPg==", "dev": true }, "node_modules/emoji-regex": { @@ -6929,9 +6913,9 @@ } }, "node_modules/langchain": { - "version": "0.1.33", - "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.1.33.tgz", - "integrity": "sha512-IrRd839x8eAmDutHNDMHGzIjufyWt/ckJrnRB2WifIJmtLWNRNQo5jZd7toeBU0UOVOQxoPtQGYf8lR0ar7vIQ==", + "version": "0.1.35", + "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.1.35.tgz", + "integrity": "sha512-wTaTNzaAPb/umcoWxFupc0QGsEJvPB6pRE8Ecy8v4CCsn/a5O6QpfRylvJKXXWoxGG8BI4L3G+HjsXCDUNxVrQ==", "dependencies": { "@anthropic-ai/sdk": "^0.9.1", "@langchain/community": "~0.0.47", @@ -7175,11 +7159,11 @@ } }, "node_modules/langchain/node_modules/zod-to-json-schema": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.5.tgz", - "integrity": "sha512-+akaPo6a0zpVCCseDed504KBJUQpEW5QZw7RMneNmKw+fGaML1Z9tUNLnHHAC8x6dzVRO1eB2oEMyZRnuBZg7Q==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz", + "integrity": "sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==", "peerDependencies": { - "zod": "^3.22.4" + "zod": "^3.23.3" } }, "node_modules/langchainhub": { @@ -7188,9 +7172,9 @@ "integrity": "sha512-Woyb8YDHgqqTOZvWIbm2CaFDGfZ4NTSyXV687AG4vXEfoNo7cGQp7nhl7wL3ehenKWmNEmcxCLgOZzW8jE6lOQ==" }, "node_modules/langsmith": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.1.14.tgz", - "integrity": "sha512-iEzQLLB7/0nRpAwNBAR7B7N64fyByg5UsNjSvLaCCkQ9AS68PSafjB8xQkyI8QXXrGjU1dEqDRoa8m4SUuRdUw==", + "version": "0.1.18", + "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.1.18.tgz", + "integrity": "sha512-LHk0aIFAl3/iiKvUzAiM8Xdm13bRO70XERQeHCF99fL2X815Jc47nxu6m7usSuQC8sw6rirCKZbGm18cqdUEzA==", "dependencies": { "@types/uuid": "^9.0.1", "commander": "^10.0.1", @@ -7328,9 +7312,9 @@ } }, "node_modules/lit": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.2.tgz", - "integrity": "sha512-VZx5iAyMtX7CV4K8iTLdCkMaYZ7ipjJZ0JcSdJ0zIdGxxyurjIn7yuuSxNBD7QmjvcNJwr0JS4cAdAtsy7gZ6w==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.3.tgz", + "integrity": "sha512-l4slfspEsnCcHVRTvaP7YnkTZEZggNFywLEIhQaGhYDczG+tu/vlgm/KaWIEjIp+ZyV20r2JnZctMb8LeLCG7Q==", "dependencies": { "@lit/reactive-element": "^2.0.4", "lit-element": "^4.0.4", @@ -7429,9 +7413,9 @@ } }, "node_modules/lit-element": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.4.tgz", - "integrity": "sha512-98CvgulX6eCPs6TyAIQoJZBCQPo80rgXR+dVBs61cstJXqtI+USQZAbA4gFHh6L/mxBx9MrgPLHLsUgDUHAcCQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.5.tgz", + "integrity": "sha512-iTWskWZEtn9SyEf4aBG6rKT8GABZMrTWop1+jopsEOgEcugcXJGKuX5bEbkq9qfzY+XB4MAgCaSPwnNpdsNQ3Q==", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0", "@lit/reactive-element": "^2.0.4", @@ -7439,9 +7423,9 @@ } }, "node_modules/lit-html": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.2.tgz", - "integrity": "sha512-3OBZSUrPnAHoKJ9AMjRL/m01YJxQMf+TMHanNtTHG68ubjnZxK0RFl102DPzsw4mWnHibfZIBJm3LWCZ/LmMvg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.3.tgz", + "integrity": "sha512-FwIbqDD8O/8lM4vUZ4KvQZjPPNx7V1VhT7vmRB8RBAO0AU6wuTVdoXiu2CivVjEGdugvcbPNBLtPE1y0ifplHA==", "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -7897,6 +7881,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -7934,9 +7926,9 @@ "peer": true }, "node_modules/node-abi": { - "version": "3.57.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.57.0.tgz", - "integrity": "sha512-Dp+A9JWxRaKuHP35H77I4kCKesDy5HUDEmScia2FyncMTOXASMyg251F5PhFoDA5uqBrDDffiLpbqnrZmNXW+g==", + "version": "3.62.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.62.0.tgz", + "integrity": "sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==", "dependencies": { "semver": "^7.3.5" }, @@ -8359,9 +8351,9 @@ } }, "node_modules/openai": { - "version": "4.33.1", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.33.1.tgz", - "integrity": "sha512-0DH572aSxGTT1JPOXgJQ9mjiuSPg/7scPot8hLc5I1mfQxPxLXTZWJpWerKaIWOuPkR2nrB0SamGDEehH8RuWA==", + "version": "4.38.3", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.38.3.tgz", + "integrity": "sha512-mIL9WtrFNOanpx98mJ+X/wkoepcxdqqu0noWFoNQHl/yODQ47YM7NEYda7qp8JfjqpLFVxY9mQhshoS/Fqac0A==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", @@ -9162,9 +9154,9 @@ } }, "node_modules/rollup": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.3.tgz", - "integrity": "sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.16.4.tgz", + "integrity": "sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -9177,22 +9169,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.14.3", - "@rollup/rollup-android-arm64": "4.14.3", - "@rollup/rollup-darwin-arm64": "4.14.3", - "@rollup/rollup-darwin-x64": "4.14.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.14.3", - "@rollup/rollup-linux-arm-musleabihf": "4.14.3", - "@rollup/rollup-linux-arm64-gnu": "4.14.3", - "@rollup/rollup-linux-arm64-musl": "4.14.3", - "@rollup/rollup-linux-powerpc64le-gnu": "4.14.3", - "@rollup/rollup-linux-riscv64-gnu": "4.14.3", - "@rollup/rollup-linux-s390x-gnu": "4.14.3", - "@rollup/rollup-linux-x64-gnu": "4.14.3", - "@rollup/rollup-linux-x64-musl": "4.14.3", - "@rollup/rollup-win32-arm64-msvc": "4.14.3", - "@rollup/rollup-win32-ia32-msvc": "4.14.3", - "@rollup/rollup-win32-x64-msvc": "4.14.3", + "@rollup/rollup-android-arm-eabi": "4.16.4", + "@rollup/rollup-android-arm64": "4.16.4", + "@rollup/rollup-darwin-arm64": "4.16.4", + "@rollup/rollup-darwin-x64": "4.16.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.16.4", + "@rollup/rollup-linux-arm-musleabihf": "4.16.4", + "@rollup/rollup-linux-arm64-gnu": "4.16.4", + "@rollup/rollup-linux-arm64-musl": "4.16.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.16.4", + "@rollup/rollup-linux-riscv64-gnu": "4.16.4", + "@rollup/rollup-linux-s390x-gnu": "4.16.4", + "@rollup/rollup-linux-x64-gnu": "4.16.4", + "@rollup/rollup-linux-x64-musl": "4.16.4", + "@rollup/rollup-win32-arm64-msvc": "4.16.4", + "@rollup/rollup-win32-ia32-msvc": "4.16.4", + "@rollup/rollup-win32-x64-msvc": "4.16.4", "fsevents": "~2.3.2" } }, @@ -9931,9 +9923,9 @@ } }, "node_modules/terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.4.tgz", + "integrity": "sha512-xRdd0v64a8mFK9bnsKVdoNP9GQIKUAaJPTaqEQDL4w/J8WaW4sWXXoMZ+6SimPkfT5bElreXf8m9HnmPc3E1BQ==", "dev": true, "peer": true, "dependencies": { @@ -10330,9 +10322,9 @@ } }, "node_modules/vite": { - "version": "5.2.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", - "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", + "version": "5.2.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", + "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", "dev": true, "dependencies": { "esbuild": "^0.20.1", @@ -10950,9 +10942,9 @@ } }, "node_modules/zod": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", - "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "version": "3.23.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.3.tgz", + "integrity": "sha512-tPvq1B/2Yu/dh2uAIH2/BhUlUeLIUvAjr6dpL/75I0pCYefHgjhXk1o1Kob3kTU8C7yU1j396jFHlsVWFi9ogg==", "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -10973,7 +10965,7 @@ "@azure/identity": "^4.1.0", "@azure/storage-blob": "^12.17.0", "@langchain/azure-openai": "^0.0.7", - "@langchain/community": "^0.0.48", + "@langchain/community": "^0.0.51", "@langchain/core": "^0.1.51", "dotenv": "^16.4.5", "faiss-node": "^0.5.1", diff --git a/packages/api/package.json b/packages/api/package.json index 493d526..9dbaa9c 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -18,7 +18,7 @@ "@azure/identity": "^4.1.0", "@azure/storage-blob": "^12.17.0", "@langchain/azure-openai": "^0.0.7", - "@langchain/community": "^0.0.48", + "@langchain/community": "^0.0.51", "@langchain/core": "^0.1.51", "dotenv": "^16.4.5", "faiss-node": "^0.5.1", From a275842ef435b0022c58b36c4325e779cdedbc35 Mon Sep 17 00:00:00 2001 From: sinedied Date: Wed, 24 Apr 2024 09:43:03 +0200 Subject: [PATCH 08/21] docs: migrate docs to mention AI search --- README.md | 6 +++--- docs/faq.md | 2 +- docs/images/architecture.drawio.png | Bin 128335 -> 120561 bytes docs/readme.md | 6 +++--- package.json | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 44422bd..077a8f8 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ -This sample shows how to build a serverless AI chat experience with Retrieval-Augmented Generation using [LangChain.js](https://js.langchain.com/) and Azure. The application is hosted on [Azure Static Web Apps](https://learn.microsoft.com/azure/static-web-apps/overview) and [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript), with [Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/) as the vector database. You can use it as a starting point for building more complex AI applications. +This sample shows how to build a serverless AI chat experience with Retrieval-Augmented Generation using [LangChain.js](https://js.langchain.com/) and Azure. The application is hosted on [Azure Static Web Apps](https://learn.microsoft.com/azure/static-web-apps/overview) and [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript), with [Azure AI Search](https://learn.microsoft.com/azure/search/search-what-is-azure-search) as the vector database. You can use it as a starting point for building more complex AI applications. > [!TIP] > You can test this application locally without any cost using [Ollama](https://ollama.com/). Follow the instructions in the [Local Development](#local-development) section to get started. @@ -44,7 +44,7 @@ This application is made from multiple components: - A serverless API built with [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript) and using [LangChain.js](https://js.langchain.com/) to ingest the documents and generate responses to the user chat queries. The code is located in the `packages/api` folder. -- A database to store the text extracted from the documents and the vectors generated by LangChain.js, using [Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/). +- A database to store the text extracted from the documents and the vectors generated by LangChain.js, using [Azure AI Search](https://learn.microsoft.com/azure/search/search-what-is-azure-search). - A file storage to store the source documents, using [Azure Blob Storage](https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction). @@ -194,7 +194,7 @@ Here are some resources to learn more about the technologies used in this sample - [LangChain.js documentation](https://js.langchain.com) - [Generative AI For Beginners](https://github.com/microsoft/generative-ai-for-beginners) - [Azure OpenAI Service](https://learn.microsoft.com/azure/ai-services/openai/overview) -- [Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/) +- [Azure AI Search](https://learn.microsoft.com/azure/search/search-what-is-azure-search) - [Ask YouTube: LangChain.js + Azure Quickstart sample](https://github.com/Azure-Samples/langchainjs-quickstart-demo) - [Chat + Enterprise data with Azure OpenAI and Azure AI Search](https://github.com/Azure-Samples/azure-search-openai-javascript) - [Revolutionize your Enterprise Data with Chat: Next-gen Apps w/ Azure OpenAI and AI Search](https://aka.ms/entgptsearchblog) diff --git a/docs/faq.md b/docs/faq.md index b29da7d..a8b7120 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -7,7 +7,7 @@ Retrieval-Augmented Generation (RAG) is a method used in artificial intelligence At its core, RAG involves two main components: -- **Retriever**: Think "_like a search engine_", finding relevant information from a knowledgebase, usually a vector database. In this sample, we're using Azure CosmosDB for MongoDB vCore as our vector database. +- **Retriever**: Think "_like a search engine_", finding relevant information from a knowledgebase, usually a vector database. In this sample, we're using Azure AI Search as our vector database. - **Generator**: Acts like a writer, taking the prompt and information retrieved to create a response. We're using here a Large Language Model (LLM) for this task. diff --git a/docs/images/architecture.drawio.png b/docs/images/architecture.drawio.png index 23d5104bb2b1605503b6f680f8f66595a00dc2ab..6e564ff06927e09645fc942a69d1565775763eda 100644 GIT binary patch literal 120561 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
MMarD;MszWISO-h0lq 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

aVokEgF~+nra%X+VAnS81L! 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 Bnb-gT literal 128335 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 H+Fkn}MGqw3 diff --git a/docs/readme.md b/docs/readme.md index ea8f7a2..3faf20f 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -17,7 +17,7 @@ description: Build your own serverless AI Chat with Retrieval-Augmented-Generati -This sample shows how to build a serverless AI chat experience with Retrieval-Augmented Generation using [LangChain.js](https://js.langchain.com/) and Azure. The application is hosted on [Azure Static Web Apps](https://learn.microsoft.com/azure/static-web-apps/overview) and [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript), with [Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/) as the vector database. You can use it as a starting point for building more complex AI applications. +This sample shows how to build a serverless AI chat experience with Retrieval-Augmented Generation using [LangChain.js](https://js.langchain.com/) and Azure. The application is hosted on [Azure Static Web Apps](https://learn.microsoft.com/azure/static-web-apps/overview) and [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript), with [Azure AI Search](https://learn.microsoft.com/azure/search/search-what-is-azure-search) as the vector database. You can use it as a starting point for building more complex AI applications. ![Animation showing the chat app in action](./images/demo.gif) @@ -37,7 +37,7 @@ This application is made from multiple components: - A serverless API built with [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-javascript) and using [LangChain.js](https://js.langchain.com/) to ingest the documents and generate responses to the user chat queries. The code is located in the `packages/api` folder. -- A database to store the text extracted from the documents and the vectors generated by LangChain.js, using [Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/). +- A database to store the text extracted from the documents and the vectors generated by LangChain.js, using [Azure AI Search](https://learn.microsoft.com/azure/search/search-what-is-azure-search). - A file storage to store the source documents, using [Azure Blob Storage](https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction). @@ -109,7 +109,7 @@ Here are some resources to learn more about the technologies used in this sample - [LangChain.js documentation](https://js.langchain.com) - [Generative AI For Beginners](https://github.com/microsoft/generative-ai-for-beginners) - [Azure OpenAI Service](https://learn.microsoft.com/azure/ai-services/openai/overview) -- [Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/) +- [Azure AI Search](https://learn.microsoft.com/azure/search/search-what-is-azure-search) - [Ask YouTube: LangChain.js + Azure Quickstart sample](https://github.com/Azure-Samples/langchainjs-quickstart-demo) - [Chat + Enterprise data with Azure OpenAI and Azure AI Search](https://github.com/Azure-Samples/azure-search-openai-javascript) - [Revolutionize your Enterprise Data with Chat: Next-gen Apps w/ Azure OpenAI and AI Search](https://aka.ms/entgptsearchblog) diff --git a/package.json b/package.json index 391c220..48ca6fc 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "azure", "azure-functions", "azure-static-web-apps", - "azure-cosmos-db", + "azure-ai-search", "mongodb" ], "author": "Microsoft", From 8fe1e07136114148bdd1055fb477ce146d92724b Mon Sep 17 00:00:00 2001 From: sinedied Date: Wed, 24 Apr 2024 10:10:22 +0200 Subject: [PATCH 09/21] feat: replace MongoDB with AI search in infra --- .../core/database/cosmos-mongo-db-vcore.bicep | 39 -------- infra/core/search/search-services.bicep | 68 ++++++++++++++ infra/main.bicep | 90 +++++++++++++++---- infra/main.parameters.json | 4 +- 4 files changed, 143 insertions(+), 58 deletions(-) delete mode 100644 infra/core/database/cosmos-mongo-db-vcore.bicep create mode 100644 infra/core/search/search-services.bicep diff --git a/infra/core/database/cosmos-mongo-db-vcore.bicep b/infra/core/database/cosmos-mongo-db-vcore.bicep deleted file mode 100644 index 495ec2d..0000000 --- a/infra/core/database/cosmos-mongo-db-vcore.bicep +++ /dev/null @@ -1,39 +0,0 @@ -metadata description = 'Creates an Azure Cosmos DB for MongoDB vCore account with a database.' -param accountName string -@secure() -param administratorLogin string -@secure() -param administratorLoginPassword string = newGuid() -param location string = resourceGroup().location -param skuName string = 'Free' -param tags object = {} - -resource cosmos 'Microsoft.DocumentDB/mongoClusters@2023-11-15-preview' = { - name: accountName - location: location - tags: tags - properties: { - administratorLogin: administratorLogin - administratorLoginPassword: administratorLoginPassword - createMode: 'Default' - serverVersion: '6.0' - nodeGroupSpecs: [ - { - kind: 'Shard' - sku: skuName - diskSizeGB: 32 - enableHa: false - nodeCount: 1 - } - ] - } - resource firewallRule 'firewallRules' = { - name: 'AllowAll' - properties: { - startIpAddress: '0.0.0.0' - endIpAddress: '255.255.255.255' - } - } -} - -output connectionString string = replace(cosmos.properties.connectionString, ':', '${administratorLogin}:${administratorLoginPassword}') diff --git a/infra/core/search/search-services.bicep b/infra/core/search/search-services.bicep new file mode 100644 index 0000000..d9c619a --- /dev/null +++ b/infra/core/search/search-services.bicep @@ -0,0 +1,68 @@ +metadata description = 'Creates an Azure AI Search instance.' +param name string +param location string = resourceGroup().location +param tags object = {} + +param sku object = { + name: 'standard' +} + +param authOptions object = {} +param disableLocalAuth bool = false +param disabledDataExfiltrationOptions array = [] +param encryptionWithCmk object = { + enforcement: 'Unspecified' +} +@allowed([ + 'default' + 'highDensity' +]) +param hostingMode string = 'default' +param networkRuleSet object = { + bypass: 'None' + ipRules: [] +} +param partitionCount int = 1 +@allowed([ + 'enabled' + 'disabled' +]) +param publicNetworkAccess string = 'enabled' +param replicaCount int = 1 +@allowed([ + 'disabled' + 'free' + 'standard' +]) +param semanticSearch string = 'disabled' + +var searchIdentityProvider = (sku.name == 'free') ? null : { + type: 'SystemAssigned' +} + +resource search 'Microsoft.Search/searchServices@2021-04-01-preview' = { + name: name + location: location + tags: tags + // The free tier does not support managed identity + identity: searchIdentityProvider + properties: { + authOptions: authOptions + disableLocalAuth: disableLocalAuth + disabledDataExfiltrationOptions: disabledDataExfiltrationOptions + encryptionWithCmk: encryptionWithCmk + hostingMode: hostingMode + networkRuleSet: networkRuleSet + partitionCount: partitionCount + publicNetworkAccess: publicNetworkAccess + replicaCount: replicaCount + semanticSearch: semanticSearch + } + sku: sku +} + +output id string = search.id +output endpoint string = 'https://${name}.search.windows.net/' +output name string = search.name +output principalId string = !empty(searchIdentityProvider) ? search.identity.principalId : '' + diff --git a/infra/main.bicep b/infra/main.bicep index a782dc3..8b8c75b 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -14,8 +14,11 @@ param webappName string = 'webapp' param apiServiceName string = 'api' param appServicePlanName string = '' param storageAccountName string = '' -param cosmosAccountName string = '' -param mongoDbSkuName string = 'Free' +param searchServiceName string = '' + +// The free tier does not support managed identity (required) or semantic search (optional) +@allowed(['basic', 'standard', 'standard2', 'standard3', 'storage_optimized_l1', 'storage_optimized_l2']) +param searchServiceSkuName string @description('Location for the OpenAI resource group') @allowed(['australiaeast', 'canadaeast', 'eastus', 'eastus2', 'francecentral', 'japaneast', 'northcentralus', 'swedencentral', 'switzerlandnorth', 'uksouth', 'westeurope']) @@ -60,7 +63,8 @@ var abbrs = loadJsonContent('abbreviations.json') var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) var tags = { 'azd-env-name': environmentName } var finalOpenAiUrl = empty(openAiUrl) ? 'https://${openAi.outputs.name}.openai.azure.com' : openAiUrl -var storageUrl = 'https://${storage.outputs.name}.blob.core.windows.net' +var storageUrl = 'https://${storage.outputs.name}.blob.${environment().suffixes.storage}' +var searchUrl = 'https://${search.outputs.name}.search.windows.net' // Organize resources in a resource group resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { @@ -99,7 +103,7 @@ module api './core/host/functions.bicep' = { AZURE_OPENAI_API_ENDPOINT: finalOpenAiUrl AZURE_OPENAI_API_DEPLOYMENT_NAME: chatDeploymentName AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME: embeddingsDeploymentName - AZURE_COSMOSDB_CONNECTION_STRING: cosmos.outputs.connectionString + AZURE_AISEARCH_ENDPOINT: searchUrl AZURE_STORAGE_URL: storageUrl AZURE_STORAGE_CONTAINER_NAME: blobContainerName } @@ -139,18 +143,6 @@ module storage './core/storage/storage-account.bicep' = { } } -module cosmos 'core/database/cosmos-mongo-db-vcore.bicep' = { - name: 'cosmos-mongo' - scope: resourceGroup - params: { - accountName: !empty(cosmosAccountName) ? cosmosAccountName : '${abbrs.documentDBDatabaseAccounts}${resourceToken}' - administratorLogin: 'admin${resourceToken}' - skuName: mongoDbSkuName - location: location - tags: tags - } -} - module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) { name: 'openai' scope: resourceGroup @@ -188,6 +180,26 @@ module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) { } } +module search 'core/search/search-services.bicep' = { + name: 'search' + scope: resourceGroup + params: { + name: !empty(searchServiceName) ? searchServiceName : '${abbrs.searchSearchServices}-${resourceToken}' + location: location + tags: tags + disableLocalAuth: true + authOptions: { + aadOrApiKey: { + aadAuthFailureMode: 'http401WithBearerChallenge' + } + } + sku: { + name: searchServiceSkuName + } + semanticSearch: 'free' + } +} + // Managed identity roles assignation // --------------------------------------------------------------------------- @@ -214,6 +226,28 @@ module storageRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) } } +module searchIndexContribRoleUser 'core/security/role.bicep' = { + scope: resourceGroup + name: 'search-index-contrib-role-user' + params: { + principalId: principalId + // Search Index Data Contributor + roleDefinitionId: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' + principalType: 'ServicePrincipal' + } +} + +module searchContribRoleIndexerUser 'core/security/role.bicep' = { + scope: resourceGroup + name: 'search-contrib-role-user' + params: { + principalId: principalId + // Search Service Contributor + roleDefinitionId: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' + principalType: 'ServicePrincipal' + } +} + // System roles module openAiRoleApi 'core/security/role.bicep' = { scope: resourceGroup @@ -237,6 +271,28 @@ module storageRoleApi 'core/security/role.bicep' = { } } +module searchIndexContribRoleApi 'core/security/role.bicep' = { + scope: resourceGroup + name: 'search-index-contrib-role-api' + params: { + principalId: api.outputs.identityPrincipalId + // Search Index Data Contributor + roleDefinitionId: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' + principalType: 'ServicePrincipal' + } +} + +module searchContribRoleIndexerApi 'core/security/role.bicep' = { + scope: resourceGroup + name: 'search-contrib-role-api' + params: { + principalId: api.outputs.identityPrincipalId + // Search Service Contributor + roleDefinitionId: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' + principalType: 'ServicePrincipal' + } +} + output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId output AZURE_RESOURCE_GROUP string = resourceGroup.name @@ -250,7 +306,7 @@ output AZURE_OPENAI_API_EMBEDDINGS_MODEL string = embeddingsModelName output AZURE_OPENAI_API_EMBEDDINGS_MODEL_VERSION string = embeddingsModelVersion output AZURE_STORAGE_URL string = storageUrl output AZURE_STORAGE_CONTAINER_NAME string = blobContainerName -output AZURE_COSMOSDB_CONNECTION_STRING string = cosmos.outputs.connectionString +output AZURE_AISEARCH_ENDPOINT string = searchUrl output API_URL string = api.outputs.uri output WEBAPP_URL string = webapp.outputs.uri diff --git a/infra/main.parameters.json b/infra/main.parameters.json index 383308f..0e15561 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -32,8 +32,8 @@ "webappLocation": { "value": "${AZURE_WEBAPP_LOCATION=eastus2}" }, - "mongoDbSkuName": { - "value": "${AZURE_MONGODB_SKU=Free}" + "searchServiceSkuName": { + "value": "${AZURE_SEARCH_SERVICE_SKU=standard}" }, "isContinuousDeployment": { "value": "${CI=false}" From f8fb140c9052f1536daf98aeba04d490cb6668c1 Mon Sep 17 00:00:00 2001 From: sinedied Date: Wed, 24 Apr 2024 17:46:05 +0200 Subject: [PATCH 10/21] fix: infra template --- infra/main.bicep | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infra/main.bicep b/infra/main.bicep index 8b8c75b..79f9e39 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -184,7 +184,7 @@ module search 'core/search/search-services.bicep' = { name: 'search' scope: resourceGroup params: { - name: !empty(searchServiceName) ? searchServiceName : '${abbrs.searchSearchServices}-${resourceToken}' + name: !empty(searchServiceName) ? searchServiceName : '${abbrs.searchSearchServices}${resourceToken}' location: location tags: tags disableLocalAuth: true @@ -233,7 +233,7 @@ module searchIndexContribRoleUser 'core/security/role.bicep' = { principalId: principalId // Search Index Data Contributor roleDefinitionId: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' - principalType: 'ServicePrincipal' + principalType: 'User' } } @@ -244,7 +244,7 @@ module searchContribRoleIndexerUser 'core/security/role.bicep' = { principalId: principalId // Search Service Contributor roleDefinitionId: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' - principalType: 'ServicePrincipal' + principalType: 'User' } } From 0017b88ab88160c404a0f2fa3168b136f776a16a Mon Sep 17 00:00:00 2001 From: sinedied Date: Mon, 29 Apr 2024 14:36:32 +0200 Subject: [PATCH 11/21] chore: fix infra template to disable local auth --- infra/core/search/search-services.bicep | 2 +- infra/main.bicep | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/infra/core/search/search-services.bicep b/infra/core/search/search-services.bicep index d9c619a..33fd83e 100644 --- a/infra/core/search/search-services.bicep +++ b/infra/core/search/search-services.bicep @@ -47,7 +47,7 @@ resource search 'Microsoft.Search/searchServices@2021-04-01-preview' = { // The free tier does not support managed identity identity: searchIdentityProvider properties: { - authOptions: authOptions + authOptions: disableLocalAuth ? null : authOptions disableLocalAuth: disableLocalAuth disabledDataExfiltrationOptions: disabledDataExfiltrationOptions encryptionWithCmk: encryptionWithCmk diff --git a/infra/main.bicep b/infra/main.bicep index 79f9e39..8826e41 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -188,11 +188,7 @@ module search 'core/search/search-services.bicep' = { location: location tags: tags disableLocalAuth: true - authOptions: { - aadOrApiKey: { - aadAuthFailureMode: 'http401WithBearerChallenge' - } - } + authOptions: null sku: { name: searchServiceSkuName } From bf3afb5f8e7c785f1d0ed1528a2711e611259b08 Mon Sep 17 00:00:00 2001 From: sinedied Date: Mon, 29 Apr 2024 15:37:29 +0200 Subject: [PATCH 12/21] feat: migrate DB code to AI Search --- package-lock.json | 119 ++++++++++++++++--- packages/api/package.json | 8 +- packages/api/src/functions/chat-post.ts | 4 +- packages/api/src/functions/documents-post.ts | 6 +- 4 files changed, 109 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 254bc60..744767e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -172,6 +172,30 @@ "node": ">=14.0.0" } }, + "node_modules/@azure/core-http-compat": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.1.2.tgz", + "integrity": "sha512-5MnV1yqzZwgNLLjlizsU3QqOeQChkIXw781Fwh1xdAqJR5AA32IUaq6xv1BICJvfbHoa+JYcaij2HFkhLbNTJQ==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-client": "^1.3.0", + "@azure/core-rest-pipeline": "^1.3.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-http-compat/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@azure/core-http/node_modules/@azure/core-tracing": { "version": "1.0.0-preview.13", "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", @@ -391,6 +415,25 @@ "node": ">=18.0.0" } }, + "node_modules/@azure/search-documents": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@azure/search-documents/-/search-documents-12.0.0.tgz", + "integrity": "sha512-d9d53f2WWBpLHifk+LVn+AG52zuXvjgxJAdaH6kuT2qwrO1natcigtTgBM8qrI3iDYaDXsQhJSIMEgg9WKSoWA==", + "dependencies": { + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.3.0", + "@azure/core-http-compat": "^2.0.1", + "@azure/core-paging": "^1.1.1", + "@azure/core-rest-pipeline": "^1.3.0", + "@azure/core-tracing": "^1.0.0", + "@azure/logger": "^1.0.0", + "events": "^3.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@azure/storage-blob": { "version": "12.17.0", "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.17.0.tgz", @@ -1200,11 +1243,11 @@ } }, "node_modules/@langchain/community": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@langchain/community/-/community-0.0.51.tgz", - "integrity": "sha512-TInG0nDCGIwg2iwHJkv1OYGVR2fDMYdpKRuuLlQoevvcHcCRIVlQS5d0MnAx0bWGUbVdkKpshrH8Ltpxt6fewA==", + "version": "0.0.53", + "resolved": "https://registry.npmjs.org/@langchain/community/-/community-0.0.53.tgz", + "integrity": "sha512-iFqZPt4MRssGYsQoKSXWJQaYTZCC7WNuilp2JCCs3wKmJK3l6mR0eV+PDrnT+TaDHUVxt/b0rwgM0sOiy0j2jA==", "dependencies": { - "@langchain/core": "~0.1.56", + "@langchain/core": "~0.1.60", "@langchain/openai": "~0.0.28", "expr-eval": "^2.0.2", "flat": "^5.0.2", @@ -1244,7 +1287,7 @@ "@pinecone-database/pinecone": "*", "@planetscale/database": "^1.8.0", "@premai/prem-sdk": "^0.3.25", - "@qdrant/js-client-rest": "^1.2.0", + "@qdrant/js-client-rest": "^1.8.2", "@raycast/api": "^1.55.2", "@rockset/client": "^0.9.1", "@smithy/eventstream-codec": "^2.0.5", @@ -1610,9 +1653,9 @@ } }, "node_modules/@langchain/core": { - "version": "0.1.59", - "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.1.59.tgz", - "integrity": "sha512-cdLi/hH/gj1CIWVcwkOxM+QYpz5kYIBxpuRkoye3OwHry9Qa9djwlsGxpUmrv5pIbPkYd7GK9L+xTQqyYIAp6A==", + "version": "0.1.61", + "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.1.61.tgz", + "integrity": "sha512-C8OkAly+ugvXsL8TACCmFv9WTTcT4gvQaG6NbrXCOzibBCywfxxcTqEMOyg3zIKpxHEmR0DHqh0OiJRHocnsCg==", "dependencies": { "ansi-styles": "^5.0.0", "camelcase": "6", @@ -1685,6 +1728,18 @@ "zod": "^3.23.3" } }, + "node_modules/@langchain/textsplitters": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/@langchain/textsplitters/-/textsplitters-0.0.0.tgz", + "integrity": "sha512-3hPesWomnmVeYMppEGYbyv0v/sRUugUdlFBNn9m1ueJYHAIKbvCErkWxNUH3guyKKYgJVrkvZoQxcd9faucSaw==", + "dependencies": { + "@langchain/core": "~0.1", + "js-tiktoken": "^1.0.11" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz", @@ -1702,6 +1757,8 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", + "optional": true, + "peer": true, "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -2085,12 +2142,16 @@ "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "optional": true, + "peer": true }, "node_modules/@types/whatwg-url": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", + "optional": true, + "peer": true, "dependencies": { "@types/webidl-conversions": "*" } @@ -3303,6 +3364,8 @@ "version": "6.6.0", "resolved": "https://registry.npmjs.org/bson/-/bson-6.6.0.tgz", "integrity": "sha512-BVINv2SgcMjL4oYbBuCQTpE3/VKOSxrOA8Cj/wQP7izSzlBGVomdm+TcUd0Pzy0ytLSSDweCKQ6X3f5veM5LQA==", + "optional": true, + "peer": true, "engines": { "node": ">=16.20.1" } @@ -6913,14 +6976,15 @@ } }, "node_modules/langchain": { - "version": "0.1.35", - "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.1.35.tgz", - "integrity": "sha512-wTaTNzaAPb/umcoWxFupc0QGsEJvPB6pRE8Ecy8v4CCsn/a5O6QpfRylvJKXXWoxGG8BI4L3G+HjsXCDUNxVrQ==", + "version": "0.1.36", + "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.1.36.tgz", + "integrity": "sha512-NTbnCL/jKWIeEI//Nm1oG8nhW3vkYWvEMr1MPotmTThTfeKfO87eV/OAzAyh6Ruy6GFs/qofRgQZGIe6XvXTNQ==", "dependencies": { "@anthropic-ai/sdk": "^0.9.1", "@langchain/community": "~0.0.47", - "@langchain/core": "~0.1.56", + "@langchain/core": "~0.1.60", "@langchain/openai": "~0.0.28", + "@langchain/textsplitters": "~0.0.0", "binary-extensions": "^2.2.0", "js-tiktoken": "^1.0.7", "js-yaml": "^4.1.0", @@ -6949,6 +7013,7 @@ "@gomomento/sdk-web": "^1.51.1", "@google-ai/generativelanguage": "^0.2.1", "@google-cloud/storage": "^6.10.1 || ^7.7.0", + "@mendable/firecrawl-js": "^0.0.13", "@notionhq/client": "^2.2.10", "@pinecone-database/pinecone": "*", "@supabase/supabase-js": "^2.10.0", @@ -7021,6 +7086,9 @@ "@google-cloud/storage": { "optional": true }, + "@mendable/firecrawl-js": { + "optional": true + }, "@notionhq/client": { "optional": true }, @@ -7646,7 +7714,9 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true, + "peer": true }, "node_modules/meow": { "version": "13.2.0", @@ -7826,6 +7896,8 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", + "optional": true, + "peer": true, "dependencies": { "@mongodb-js/saslprep": "^1.1.5", "bson": "^6.4.0", @@ -7871,6 +7943,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", + "optional": true, + "peer": true, "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^13.0.0" @@ -8796,6 +8870,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "devOptional": true, "engines": { "node": ">=6" } @@ -9552,6 +9627,8 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "peer": true, "dependencies": { "memory-pager": "^1.0.2" } @@ -10018,6 +10095,8 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "optional": true, + "peer": true, "dependencies": { "punycode": "^2.3.0" }, @@ -10483,6 +10562,8 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "optional": true, + "peer": true, "engines": { "node": ">=12" } @@ -10597,6 +10678,8 @@ "version": "13.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "optional": true, + "peer": true, "dependencies": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" @@ -10963,14 +11046,14 @@ "dependencies": { "@azure/functions": "^4.0.0", "@azure/identity": "^4.1.0", + "@azure/search-documents": "^12.0.0", "@azure/storage-blob": "^12.17.0", "@langchain/azure-openai": "^0.0.7", - "@langchain/community": "^0.0.51", - "@langchain/core": "^0.1.51", + "@langchain/community": "^0.0.53", + "@langchain/core": "^0.1.61", "dotenv": "^16.4.5", "faiss-node": "^0.5.1", - "langchain": "^0.1.31", - "mongodb": "^6.5.0", + "langchain": "^0.1.36", "pdf-parse": "^1.1.1" }, "devDependencies": { diff --git a/packages/api/package.json b/packages/api/package.json index 9dbaa9c..be733e5 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -16,14 +16,14 @@ "dependencies": { "@azure/functions": "^4.0.0", "@azure/identity": "^4.1.0", + "@azure/search-documents": "^12.0.0", "@azure/storage-blob": "^12.17.0", "@langchain/azure-openai": "^0.0.7", - "@langchain/community": "^0.0.51", - "@langchain/core": "^0.1.51", + "@langchain/community": "^0.0.53", + "@langchain/core": "^0.1.61", "dotenv": "^16.4.5", "faiss-node": "^0.5.1", - "langchain": "^0.1.31", - "mongodb": "^6.5.0", + "langchain": "^0.1.36", "pdf-parse": "^1.1.1" }, "devDependencies": { diff --git a/packages/api/src/functions/chat-post.ts b/packages/api/src/functions/chat-post.ts index 5427e60..7282575 100644 --- a/packages/api/src/functions/chat-post.ts +++ b/packages/api/src/functions/chat-post.ts @@ -10,7 +10,7 @@ import { ChatOllama } from '@langchain/community/chat_models/ollama'; import { FaissStore } from '@langchain/community/vectorstores/faiss'; import { ChatPromptTemplate, PromptTemplate } from '@langchain/core/prompts'; import { createStuffDocumentsChain } from 'langchain/chains/combine_documents'; -import { AzureCosmosDBVectorStore } from '@langchain/community/vectorstores/azure_cosmosdb'; +import { AzureAISearchVectorStore } from '@langchain/community/vectorstores/azure_aisearch'; import { createRetrievalChain } from 'langchain/chains/retrieval'; import 'dotenv/config'; import { badRequest, data, serviceUnavailable } from '../http-response'; @@ -60,7 +60,7 @@ export async function postChat(request: HttpRequest, context: InvocationContext) // Initialize models and vector database embeddings = new AzureOpenAIEmbeddings({ credentials }); model = new AzureChatOpenAI({ credentials }); - store = new AzureCosmosDBVectorStore(embeddings, {}); + store = new AzureAISearchVectorStore(embeddings, { credentials }); } else { // If no environment variables are set, it means we are running locally context.log('No Azure OpenAI endpoint set, using Ollama models and local DB'); diff --git a/packages/api/src/functions/documents-post.ts b/packages/api/src/functions/documents-post.ts index 60da834..1ab1a19 100644 --- a/packages/api/src/functions/documents-post.ts +++ b/packages/api/src/functions/documents-post.ts @@ -2,7 +2,7 @@ import { HttpRequest, HttpResponseInit, InvocationContext, app } from '@azure/fu import { AzureOpenAIEmbeddings } from '@langchain/azure-openai'; import { PDFLoader } from 'langchain/document_loaders/fs/pdf'; import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter'; -import { AzureCosmosDBVectorStore } from '@langchain/community/vectorstores/azure_cosmosdb'; +import { AzureAISearchVectorStore } from '@langchain/community/vectorstores/azure_aisearch'; import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama'; import { FaissStore } from '@langchain/community/vectorstores/faiss'; import 'dotenv/config'; @@ -45,9 +45,7 @@ export async function postDocuments(request: HttpRequest, context: InvocationCon if (azureOpenAiEndpoint) { const credentials = getCredentials(); const embeddings = new AzureOpenAIEmbeddings({ credentials }); - const store = await AzureCosmosDBVectorStore.fromDocuments(documents, embeddings, {}); - await store.createIndex(); - await store.close(); + await AzureAISearchVectorStore.fromDocuments(documents, embeddings, { credentials }); } else { // If no environment variables are set, it means we are running locally context.log('No Azure OpenAI endpoint set, using Ollama models and local DB'); From 53e3cd6d7d18cfc3b1a839d5b8876a9e73c62974 Mon Sep 17 00:00:00 2001 From: sinedied Date: Mon, 29 Apr 2024 15:38:57 +0200 Subject: [PATCH 13/21] fix: migrate filename metadata --- packages/api/src/functions/chat-post.ts | 2 +- packages/api/src/functions/documents-post.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/src/functions/chat-post.ts b/packages/api/src/functions/chat-post.ts index 7282575..c4ab247 100644 --- a/packages/api/src/functions/chat-post.ts +++ b/packages/api/src/functions/chat-post.ts @@ -76,7 +76,7 @@ export async function postChat(request: HttpRequest, context: InvocationContext) ['system', systemPrompt], ['human', '{input}'], ]), - documentPrompt: PromptTemplate.fromTemplate('{filename}: {page_content}\n'), + documentPrompt: PromptTemplate.fromTemplate('{source}: {page_content}\n'), }); // Create the chain to retrieve the documents from the database diff --git a/packages/api/src/functions/documents-post.ts b/packages/api/src/functions/documents-post.ts index 1ab1a19..9d0e8b9 100644 --- a/packages/api/src/functions/documents-post.ts +++ b/packages/api/src/functions/documents-post.ts @@ -32,7 +32,7 @@ export async function postDocuments(request: HttpRequest, context: InvocationCon splitPages: false, }); const rawDocument = await loader.load(); - rawDocument[0].metadata.filename = filename; + rawDocument[0].metadata.source = filename; // Split the text into smaller chunks const splitter = new RecursiveCharacterTextSplitter({ From e94efb4bb843c86db76f3ca041a59e886cf82ca2 Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 12:09:23 +0200 Subject: [PATCH 14/21] chore: disable blob public access --- infra/main.bicep | 2 ++ 1 file changed, 2 insertions(+) diff --git a/infra/main.bicep b/infra/main.bicep index 8826e41..0f8371b 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -134,6 +134,8 @@ module storage './core/storage/storage-account.bicep' = { name: !empty(storageAccountName) ? storageAccountName : '${abbrs.storageStorageAccounts}${resourceToken}' location: location tags: tags + allowBlobPublicAccess: false + allowSharedKeyAccess: false containers: [ { name: blobContainerName From 9dc9883eabd765060694ca7e098cb0de3fb18bdf Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 12:09:39 +0200 Subject: [PATCH 15/21] chore: update dependency --- package-lock.json | 8 ++++---- packages/api/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 744767e..5375184 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1227,9 +1227,9 @@ } }, "node_modules/@langchain/azure-openai": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@langchain/azure-openai/-/azure-openai-0.0.7.tgz", - "integrity": "sha512-fMH/kDAe8wOQ3j5mwaqFHjxsxtAgBLAfeMoxTgev7nC/76c4wRboSY4lb4FnwilNw4EXpB2Jg/K2QV19UyPOPw==", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@langchain/azure-openai/-/azure-openai-0.0.8.tgz", + "integrity": "sha512-8ckAdL33jqPPEABwsdIYao/NZr7c47XTZZ0gj+BO//EDHuXYlAiZC0XS+iS5OI0aGqJFt0eKh/fCuCHxT4xDeQ==", "dependencies": { "@azure/core-auth": "^1.5.0", "@azure/openai": "1.0.0-beta.11", @@ -11048,7 +11048,7 @@ "@azure/identity": "^4.1.0", "@azure/search-documents": "^12.0.0", "@azure/storage-blob": "^12.17.0", - "@langchain/azure-openai": "^0.0.7", + "@langchain/azure-openai": "^0.0.8", "@langchain/community": "^0.0.53", "@langchain/core": "^0.1.61", "dotenv": "^16.4.5", diff --git a/packages/api/package.json b/packages/api/package.json index be733e5..dde7901 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -18,7 +18,7 @@ "@azure/identity": "^4.1.0", "@azure/search-documents": "^12.0.0", "@azure/storage-blob": "^12.17.0", - "@langchain/azure-openai": "^0.0.7", + "@langchain/azure-openai": "^0.0.8", "@langchain/community": "^0.0.53", "@langchain/core": "^0.1.61", "dotenv": "^16.4.5", From bfc6e30a87bb478982245ea97b9ae201b900e9ff Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 13:58:27 +0200 Subject: [PATCH 16/21] docs: add RBAC permissions --- README.md | 3 +++ docs/readme.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 077a8f8..e3dc763 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,9 @@ Note that the documents are uploaded automatically when deploying the sample to - **Azure account**. If you're new to Azure, [get an Azure account for free](https://azure.microsoft.com/free) to get free Azure credits to get started. If you're a student, you can also get free credits with [Azure for Students](https://aka.ms/azureforstudents). - **Azure subscription with access enabled for the Azure OpenAI service**. You can request access with [this form](https://aka.ms/oaiapply). +- **Azure account permissions**: + - Your Azure account must have `Microsoft.Authorization/roleAssignments/write` permissions, such as [Role Based Access Control Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator-preview), [User Access Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#user-access-administrator), or [Owner](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#owner). If you don't have subscription-level permissions, you must be granted [RBAC](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator-preview) for an existing resource group and [deploy to that existing group](docs/deploy_existing.md#resource-group). + - Your Azure account also needs `Microsoft.Resources/deployments/write` permissions on the subscription level. #### Deploy the sample diff --git a/docs/readme.md b/docs/readme.md index 3faf20f..94155a7 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -48,6 +48,9 @@ This application is made from multiple components: - [Git](https://git-scm.com/downloads) - Azure account. If you're new to Azure, [get an Azure account for free](https://azure.microsoft.com/free) to get free Azure credits to get started. If you're a student, you can also get free credits with [Azure for Students](https://aka.ms/azureforstudents). - Azure subscription with access enabled for the Azure OpenAI service. You can request access with [this form](https://aka.ms/oaiapply). +- Azure account permissions: + - Your Azure account must have `Microsoft.Authorization/roleAssignments/write` permissions, such as [Role Based Access Control Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator-preview), [User Access Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#user-access-administrator), or [Owner](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#owner). If you don't have subscription-level permissions, you must be granted [RBAC](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator-preview) for an existing resource group and [deploy to that existing group](docs/deploy_existing.md#resource-group). + - Your Azure account also needs `Microsoft.Resources/deployments/write` permissions on the subscription level. ## Setup the sample From b5d328b92c1ad753c3c61a380b935ece7d25c587 Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 14:46:46 +0200 Subject: [PATCH 17/21] chore: update chat model and reduce db cost --- infra/main.parameters.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infra/main.parameters.json b/infra/main.parameters.json index 0e15561..9f44018 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -21,7 +21,7 @@ "value": "${AZURE_OPENAI_API_MODEL=gpt-35-turbo}" }, "chatModelVersion": { - "value": "${AZURE_OPENAI_API_MODEL_VERSION=0613}" + "value": "${AZURE_OPENAI_API_MODEL_VERSION=0125}" }, "embeddingsModelName": { "value": "${AZURE_OPENAI_API_EMBEDDINGS_MODEL=text-embedding-ada-002}" @@ -33,7 +33,7 @@ "value": "${AZURE_WEBAPP_LOCATION=eastus2}" }, "searchServiceSkuName": { - "value": "${AZURE_SEARCH_SERVICE_SKU=standard}" + "value": "${AZURE_SEARCH_SERVICE_SKU=basic}" }, "isContinuousDeployment": { "value": "${CI=false}" From dcdd10ed193ca0b5b72cb0fb76315c7493b790bc Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 14:47:01 +0200 Subject: [PATCH 18/21] chore: update infra --- infra/main.bicep | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/infra/main.bicep b/infra/main.bicep index 0f8371b..bdf2aae 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -135,11 +135,10 @@ module storage './core/storage/storage-account.bicep' = { location: location tags: tags allowBlobPublicAccess: false - allowSharedKeyAccess: false containers: [ { name: blobContainerName - publicAccess: 'Container' + publicAccess: 'None' } ] } @@ -194,7 +193,6 @@ module search 'core/search/search-services.bicep' = { sku: { name: searchServiceSkuName } - semanticSearch: 'free' } } From a111701cc774519b7bbe7e58a7f2ebc8b550ab50 Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 14:58:50 +0200 Subject: [PATCH 19/21] docs: suggest default region --- README.md | 2 +- docs/readme.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3dc763..0324cdf 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ Note that the documents are uploaded automatically when deploying the sample to 1. Open a terminal and navigate to the root of the project. 2. Authenticate with Azure by running `azd auth login`. 3. Run `azd up` to deploy the application to Azure. This will provision Azure resources, deploy this sample, and build the search index based on the files found in the `./data` folder. - - You will be prompted to select a base location for the resources. Choose a location that is closest to you. + - You will be prompted to select a base location for the resources. If you're unsure of which location to choose, select `eastus2`. - By default, the OpenAI resource will be deployed to `eastus2`. You can set a different location with `azd env set AZURE_OPENAI_RESOURCE_GROUP_LOCATION `. Currently only a short list of locations is accepted. That location list is based on the [OpenAI model availability table](https://learn.microsoft.com/azure/ai-services/openai/concepts/models#standard-deployment-model-availability) and may become outdated as availability changes. The deployment process will take a few minutes. Once it's done, you'll see the URL of the web app in the terminal. diff --git a/docs/readme.md b/docs/readme.md index 94155a7..1a56444 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -68,7 +68,7 @@ You can run this project directly in your browser by using GitHub Codespaces, wh 1. Open a terminal at the root of the project. 2. Authenticate with Azure by running `azd auth login`. 3. Run `azd up` to deploy the application to Azure. This will provision Azure resources, deploy this sample, and build the search index based on the files found in the `./data` folder. - - You will be prompted to select a base location for the resources. Choose a location that is closest to you. + - You will be prompted to select a base location for the resources. If you're unsure of which location to choose, select `eastus2`. - By default, the OpenAI resource will be deployed to `eastus2`. You can set a different location with `azd env set AZURE_OPENAI_RESOURCE_GROUP_LOCATION `. Currently only a short list of locations is accepted. That location list is based on the [OpenAI model availability table](https://learn.microsoft.com/azure/ai-services/openai/concepts/models#standard-deployment-model-availability) and may become outdated as availability changes. The deployment process will take a few minutes. Once it's done, you'll see the URL of the web app in the terminal. From a21b61541ae3b005f221ab81e56ff9d319ecd229 Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 15:13:14 +0200 Subject: [PATCH 20/21] chore: revert gpt version --- infra/main.parameters.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/main.parameters.json b/infra/main.parameters.json index 9f44018..d015798 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -21,7 +21,7 @@ "value": "${AZURE_OPENAI_API_MODEL=gpt-35-turbo}" }, "chatModelVersion": { - "value": "${AZURE_OPENAI_API_MODEL_VERSION=0125}" + "value": "${AZURE_OPENAI_API_MODEL_VERSION=0613}" }, "embeddingsModelName": { "value": "${AZURE_OPENAI_API_EMBEDDINGS_MODEL=text-embedding-ada-002}" From af849b7327bc13e2e8db6e8975881acc7fbec065 Mon Sep 17 00:00:00 2001 From: sinedied Date: Tue, 30 Apr 2024 15:20:10 +0200 Subject: [PATCH 21/21] chore: fix typo --- packages/api/src/security.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api/src/security.ts b/packages/api/src/security.ts index 04a4c3d..db6af9d 100644 --- a/packages/api/src/security.ts +++ b/packages/api/src/security.ts @@ -4,7 +4,7 @@ let credentials: DefaultAzureCredential | undefined; export function getCredentials(): DefaultAzureCredential { // Use the current user identity to authenticate. - // No secrets needed, it uses 'az loginz or 'azd auth login' locally, + // No secrets needed, it uses `az login` or `azd auth login` locally, // and managed identity when deployed on Azure. credentials ||= new DefaultAzureCredential(); return credentials;