UNPKG

@langchain/community

Version:
1 lines • 30.7 kB
{"version":3,"file":"googlevertexai.cjs","names":["Document","fields: IdDocumentInput","GoogleVertexAIConnection","fields: IndexEndpointConnectionParams","caller: AsyncCaller","GoogleAuth","options: AsyncCallerCallOptions","fields: RemoveDatapointParams","datapointIds: string[]","data: RemoveDatapointRequest","fields: UpsertDatapointParams","datapoints: IndexDatapoint[]","data: UpsertDatapointRequest","params: FindNeighborsConnectionParams","request: FindNeighborsRequest","VectorStore","embeddings: EmbeddingsInterface","args: MatchingEngineArgs","AsyncCaller","indexClientParams: IndexEndpointConnectionParams","removeClientParams: RemoveDatapointParams","upsertClientParams: UpsertDatapointParams","documents: Document[]","texts: string[]","vectors: number[][]","docsToStore: Record<string, Document>","documentMetadata: Record<string, any>","prefix: string","m: Record<string, any>","ret: Record<string, string[]>","stringArrays: Record<string, string[]>","flatMetadata: metadataType","metadata: metadataType","restrictions: this[\"FilterType\"]","restriction: Restriction","vector: number[]","document: IdDocument","ret: IndexDatapoint","params: MatchingEngineDeleteParams","query: number[]","k: number","filter?: this[\"FilterType\"]","requestQuery: FindNeighborsRequestQuery","findNeighborsParams: FindNeighborsConnectionParams","ret: [Document, number][]","doc: IdDocument","response: IndexEndpointResponse","metadatas: object[] | object","dbConfig: MatchingEngineArgs","docs: Document[]"],"sources":["../../src/vectorstores/googlevertexai.ts"],"sourcesContent":["import * as uuid from \"uuid\";\nimport flatten from \"flat\";\nimport { GoogleAuth, GoogleAuthOptions } from \"google-auth-library\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { Document, DocumentInput } from \"@langchain/core/documents\";\nimport {\n AsyncCaller,\n AsyncCallerCallOptions,\n AsyncCallerParams,\n} from \"@langchain/core/utils/async_caller\";\n\nimport { GoogleVertexAIConnection } from \"../utils/googlevertexai-connection.js\";\nimport { Docstore } from \"../stores/doc/base.js\";\nimport {\n GoogleVertexAIConnectionParams,\n GoogleResponse,\n GoogleAbstractedClientOpsMethod,\n} from \"../types/googlevertexai-types.js\";\n\n/**\n * Allows us to create IdDocument classes that contain the ID.\n */\nexport interface IdDocumentInput extends DocumentInput {\n id?: string;\n}\n\n/**\n * A Document that optionally includes the ID of the document.\n */\nexport class IdDocument extends Document implements IdDocumentInput {\n id?: string;\n\n constructor(fields: IdDocumentInput) {\n super(fields);\n this.id = fields.id;\n }\n}\n\ninterface IndexEndpointConnectionParams\n extends GoogleVertexAIConnectionParams<GoogleAuthOptions> {\n indexEndpoint: string;\n}\n\ninterface DeployedIndex {\n id: string;\n index: string;\n // There are other attributes, but we don't care about them right now\n}\n\ninterface IndexEndpointResponse extends GoogleResponse {\n data: {\n deployedIndexes: DeployedIndex[];\n publicEndpointDomainName: string;\n // There are other attributes, but we don't care about them right now\n };\n}\n\nclass IndexEndpointConnection extends GoogleVertexAIConnection<\n AsyncCallerCallOptions,\n IndexEndpointResponse,\n GoogleAuthOptions\n> {\n indexEndpoint: string;\n\n constructor(fields: IndexEndpointConnectionParams, caller: AsyncCaller) {\n super(fields, caller, new GoogleAuth(fields.authOptions));\n\n this.indexEndpoint = fields.indexEndpoint;\n }\n\n async buildUrl(): Promise<string> {\n const projectId = await this.client.getProjectId();\n const url = `https://${this.endpoint}/${this.apiVersion}/projects/${projectId}/locations/${this.location}/indexEndpoints/${this.indexEndpoint}`;\n return url;\n }\n\n buildMethod(): GoogleAbstractedClientOpsMethod {\n return \"GET\";\n }\n\n async request(\n options: AsyncCallerCallOptions\n ): Promise<IndexEndpointResponse> {\n return this._request(undefined, options);\n }\n}\n\n/**\n * Used to represent parameters that are necessary to delete documents\n * from the matching engine. These must be a list of string IDs\n */\nexport interface MatchingEngineDeleteParams {\n ids: string[];\n}\n\ninterface RemoveDatapointParams\n extends GoogleVertexAIConnectionParams<GoogleAuthOptions> {\n index: string;\n}\n\ninterface RemoveDatapointRequest {\n datapointIds: string[];\n}\n\ninterface RemoveDatapointResponse extends GoogleResponse {\n // Should be empty\n}\n\nclass RemoveDatapointConnection extends GoogleVertexAIConnection<\n AsyncCallerCallOptions,\n RemoveDatapointResponse,\n GoogleAuthOptions\n> {\n index: string;\n\n constructor(fields: RemoveDatapointParams, caller: AsyncCaller) {\n super(fields, caller, new GoogleAuth(fields.authOptions));\n\n this.index = fields.index;\n }\n\n async buildUrl(): Promise<string> {\n const projectId = await this.client.getProjectId();\n const url = `https://${this.endpoint}/${this.apiVersion}/projects/${projectId}/locations/${this.location}/indexes/${this.index}:removeDatapoints`;\n return url;\n }\n\n buildMethod(): GoogleAbstractedClientOpsMethod {\n return \"POST\";\n }\n\n async request(\n datapointIds: string[],\n options: AsyncCallerCallOptions\n ): Promise<RemoveDatapointResponse> {\n const data: RemoveDatapointRequest = {\n datapointIds,\n };\n return this._request(data, options);\n }\n}\n\ninterface UpsertDatapointParams\n extends GoogleVertexAIConnectionParams<GoogleAuthOptions> {\n index: string;\n}\n\nexport interface Restriction {\n namespace: string;\n allowList?: string[];\n denyList?: string[];\n}\n\ninterface CrowdingTag {\n crowdingAttribute: string;\n}\n\ninterface IndexDatapoint {\n datapointId: string;\n featureVector: number[];\n restricts?: Restriction[];\n crowdingTag?: CrowdingTag;\n}\n\ninterface UpsertDatapointRequest {\n datapoints: IndexDatapoint[];\n}\n\ninterface UpsertDatapointResponse extends GoogleResponse {\n // Should be empty\n}\n\nclass UpsertDatapointConnection extends GoogleVertexAIConnection<\n AsyncCallerCallOptions,\n UpsertDatapointResponse,\n GoogleAuthOptions\n> {\n index: string;\n\n constructor(fields: UpsertDatapointParams, caller: AsyncCaller) {\n super(fields, caller, new GoogleAuth(fields.authOptions));\n\n this.index = fields.index;\n }\n\n async buildUrl(): Promise<string> {\n const projectId = await this.client.getProjectId();\n const url = `https://${this.endpoint}/${this.apiVersion}/projects/${projectId}/locations/${this.location}/indexes/${this.index}:upsertDatapoints`;\n return url;\n }\n\n buildMethod(): GoogleAbstractedClientOpsMethod {\n return \"POST\";\n }\n\n async request(\n datapoints: IndexDatapoint[],\n options: AsyncCallerCallOptions\n ): Promise<UpsertDatapointResponse> {\n const data: UpsertDatapointRequest = {\n datapoints,\n };\n return this._request(data, options);\n }\n}\n\ninterface FindNeighborsConnectionParams\n extends GoogleVertexAIConnectionParams<GoogleAuthOptions> {\n indexEndpoint: string;\n\n deployedIndexId: string;\n}\n\ninterface FindNeighborsRequestQuery {\n datapoint: {\n datapointId: string;\n featureVector: number[];\n restricts?: Restriction[];\n };\n neighborCount: number;\n}\n\ninterface FindNeighborsRequest {\n deployedIndexId: string;\n queries: FindNeighborsRequestQuery[];\n}\n\ninterface FindNeighborsResponseNeighbor {\n datapoint: {\n datapointId: string;\n crowdingTag: {\n crowdingTagAttribute: string;\n };\n };\n distance: number;\n}\n\ninterface FindNeighborsResponseNearestNeighbor {\n id: string;\n neighbors: FindNeighborsResponseNeighbor[];\n}\n\ninterface FindNeighborsResponse extends GoogleResponse {\n data: {\n nearestNeighbors: FindNeighborsResponseNearestNeighbor[];\n };\n}\n\nclass FindNeighborsConnection\n extends GoogleVertexAIConnection<\n AsyncCallerCallOptions,\n FindNeighborsResponse,\n GoogleAuthOptions\n >\n implements FindNeighborsConnectionParams\n{\n indexEndpoint: string;\n\n deployedIndexId: string;\n\n constructor(params: FindNeighborsConnectionParams, caller: AsyncCaller) {\n super(params, caller, new GoogleAuth(params.authOptions));\n\n this.indexEndpoint = params.indexEndpoint;\n this.deployedIndexId = params.deployedIndexId;\n }\n\n async buildUrl(): Promise<string> {\n const projectId = await this.client.getProjectId();\n const url = `https://${this.endpoint}/${this.apiVersion}/projects/${projectId}/locations/${this.location}/indexEndpoints/${this.indexEndpoint}:findNeighbors`;\n return url;\n }\n\n buildMethod(): GoogleAbstractedClientOpsMethod {\n return \"POST\";\n }\n\n async request(\n request: FindNeighborsRequest,\n options: AsyncCallerCallOptions\n ): Promise<FindNeighborsResponse> {\n return this._request(request, options);\n }\n}\n\n/**\n * Information about the Matching Engine public API endpoint.\n * Primarily exported to allow for testing.\n */\nexport interface PublicAPIEndpointInfo {\n apiEndpoint?: string;\n\n deployedIndexId?: string;\n}\n\n/**\n * Parameters necessary to configure the Matching Engine.\n */\nexport interface MatchingEngineArgs\n extends GoogleVertexAIConnectionParams<GoogleAuthOptions>,\n IndexEndpointConnectionParams,\n UpsertDatapointParams {\n docstore: Docstore;\n\n callerParams?: AsyncCallerParams;\n\n callerOptions?: AsyncCallerCallOptions;\n\n apiEndpoint?: string;\n\n deployedIndexId?: string;\n}\n\n/**\n * A class that represents a connection to a Google Vertex AI Matching Engine\n * instance.\n */\nexport class MatchingEngine extends VectorStore implements MatchingEngineArgs {\n declare FilterType: Restriction[];\n\n /**\n * Docstore that retains the document, stored by ID\n */\n docstore: Docstore;\n\n /**\n * The host to connect to for queries and upserts.\n */\n apiEndpoint: string;\n\n apiVersion = \"v1\";\n\n endpoint = \"us-central1-aiplatform.googleapis.com\";\n\n location = \"us-central1\";\n\n /**\n * The id for the index endpoint\n */\n indexEndpoint: string;\n\n /**\n * The id for the index\n */\n index: string;\n\n /**\n * Explicitly set Google Auth credentials if you cannot get them from google auth application-default login\n * This is useful for serverless or autoscaling environments like Fargate\n */\n authOptions: GoogleAuthOptions;\n\n /**\n * The id for the \"deployed index\", which is an identifier in the\n * index endpoint that references the index (but is not the index id)\n */\n deployedIndexId: string;\n\n callerParams: AsyncCallerParams;\n\n callerOptions: AsyncCallerCallOptions;\n\n caller: AsyncCaller;\n\n indexEndpointClient: IndexEndpointConnection;\n\n removeDatapointClient: RemoveDatapointConnection;\n\n upsertDatapointClient: UpsertDatapointConnection;\n\n constructor(embeddings: EmbeddingsInterface, args: MatchingEngineArgs) {\n super(embeddings, args);\n\n this.embeddings = embeddings;\n this.docstore = args.docstore;\n\n this.apiEndpoint = args.apiEndpoint ?? this.apiEndpoint;\n this.deployedIndexId = args.deployedIndexId ?? this.deployedIndexId;\n\n this.apiVersion = args.apiVersion ?? this.apiVersion;\n this.endpoint = args.endpoint ?? this.endpoint;\n this.location = args.location ?? this.location;\n this.indexEndpoint = args.indexEndpoint ?? this.indexEndpoint;\n this.index = args.index ?? this.index;\n this.authOptions = args.authOptions ?? this.authOptions;\n\n this.callerParams = args.callerParams ?? this.callerParams;\n this.callerOptions = args.callerOptions ?? this.callerOptions;\n this.caller = new AsyncCaller(this.callerParams || {});\n\n const indexClientParams: IndexEndpointConnectionParams = {\n endpoint: this.endpoint,\n location: this.location,\n apiVersion: this.apiVersion,\n indexEndpoint: this.indexEndpoint,\n authOptions: this.authOptions,\n };\n this.indexEndpointClient = new IndexEndpointConnection(\n indexClientParams,\n this.caller\n );\n\n const removeClientParams: RemoveDatapointParams = {\n endpoint: this.endpoint,\n location: this.location,\n apiVersion: this.apiVersion,\n index: this.index,\n authOptions: this.authOptions,\n };\n this.removeDatapointClient = new RemoveDatapointConnection(\n removeClientParams,\n this.caller\n );\n\n const upsertClientParams: UpsertDatapointParams = {\n endpoint: this.endpoint,\n location: this.location,\n apiVersion: this.apiVersion,\n index: this.index,\n authOptions: this.authOptions,\n };\n this.upsertDatapointClient = new UpsertDatapointConnection(\n upsertClientParams,\n this.caller\n );\n }\n\n _vectorstoreType(): string {\n return \"googlevertexai\";\n }\n\n async addDocuments(documents: Document[]): Promise<void> {\n const texts: string[] = documents.map((doc) => doc.pageContent);\n const vectors: number[][] = await this.embeddings.embedDocuments(texts);\n return this.addVectors(vectors, documents);\n }\n\n async addVectors(vectors: number[][], documents: Document[]): Promise<void> {\n if (vectors.length !== documents.length) {\n throw new Error(`Vectors and metadata must have the same length`);\n }\n const datapoints: IndexDatapoint[] = vectors.map((vector, idx) =>\n this.buildDatapoint(vector, documents[idx])\n );\n const options = {};\n const response = await this.upsertDatapointClient.request(\n datapoints,\n options\n );\n if (Object.keys(response?.data ?? {}).length === 0) {\n // Nothing in the response in the body means we saved it ok\n const idDoc = documents as IdDocument[];\n const docsToStore: Record<string, Document> = {};\n idDoc.forEach((doc) => {\n if (doc.id) {\n docsToStore[doc.id] = doc;\n }\n });\n await this.docstore.add(docsToStore);\n }\n }\n\n // TODO: Refactor this into a utility type and use with pinecone as well?\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n cleanMetadata(documentMetadata: Record<string, any>): {\n [key: string]: string | number | boolean | string[] | null;\n } {\n type metadataType = {\n [key: string]: string | number | boolean | string[] | null;\n };\n\n function getStringArrays(\n prefix: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n m: Record<string, any>\n ): Record<string, string[]> {\n let ret: Record<string, string[]> = {};\n\n Object.keys(m).forEach((key) => {\n const newPrefix = prefix.length > 0 ? `${prefix}.${key}` : key;\n const val = m[key];\n if (!val) {\n // Ignore it\n } else if (Array.isArray(val)) {\n // Make sure everything in the array is a string\n ret[newPrefix] = val.map((v) => `${v}`);\n } else if (typeof val === \"object\") {\n const subArrays = getStringArrays(newPrefix, val);\n ret = { ...ret, ...subArrays };\n }\n });\n\n return ret;\n }\n\n const stringArrays: Record<string, string[]> = getStringArrays(\n \"\",\n documentMetadata\n );\n\n const flatMetadata: metadataType = flatten(documentMetadata);\n Object.keys(flatMetadata).forEach((key) => {\n Object.keys(stringArrays).forEach((arrayKey) => {\n const matchKey = `${arrayKey}.`;\n if (key.startsWith(matchKey)) {\n delete flatMetadata[key];\n }\n });\n });\n\n const metadata: metadataType = {\n ...flatMetadata,\n ...stringArrays,\n };\n return metadata;\n }\n\n /**\n * Given the metadata from a document, convert it to an array of Restriction\n * objects that may be passed to the Matching Engine and stored.\n * The default implementation flattens any metadata and includes it as\n * an \"allowList\". Subclasses can choose to convert some of these to\n * \"denyList\" items or to add additional restrictions (for example, to format\n * dates into a different structure or to add additional restrictions\n * based on the date).\n * @param documentMetadata - The metadata from a document\n * @returns a Restriction[] (or an array of a subclass, from the FilterType)\n */\n metadataToRestrictions(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n documentMetadata: Record<string, any>\n ): this[\"FilterType\"] {\n const metadata = this.cleanMetadata(documentMetadata);\n\n const restrictions: this[\"FilterType\"] = [];\n for (const key of Object.keys(metadata)) {\n // Make sure the value is an array (or that we'll ignore it)\n let valArray;\n const val = metadata[key];\n if (val === null) {\n valArray = null;\n } else if (Array.isArray(val) && val.length > 0) {\n valArray = val;\n } else {\n valArray = [`${val}`];\n }\n\n // Add to the restrictions if we do have a valid value\n if (valArray) {\n // Determine if this key is for the allowList or denyList\n // TODO: get which ones should be on the deny list\n const listType = \"allowList\";\n\n // Create the restriction\n const restriction: Restriction = {\n namespace: key,\n [listType]: valArray,\n };\n\n // Add it to the restriction list\n restrictions.push(restriction);\n }\n }\n return restrictions;\n }\n\n /**\n * Create an index datapoint for the vector and document id.\n * If an id does not exist, create it and set the document to its value.\n * @param vector\n * @param document\n */\n buildDatapoint(vector: number[], document: IdDocument): IndexDatapoint {\n if (!document.id) {\n document.id = uuid.v4();\n }\n const ret: IndexDatapoint = {\n datapointId: document.id,\n featureVector: vector,\n };\n const restrictions = this.metadataToRestrictions(document.metadata);\n if (restrictions?.length > 0) {\n ret.restricts = restrictions;\n }\n return ret;\n }\n\n async delete(params: MatchingEngineDeleteParams): Promise<void> {\n const options = {};\n await this.removeDatapointClient.request(params.ids, options);\n }\n\n async similaritySearchVectorWithScore(\n query: number[],\n k: number,\n filter?: this[\"FilterType\"]\n ): Promise<[Document, number][]> {\n // Format the query into the request\n const deployedIndexId = await this.getDeployedIndexId();\n const requestQuery: FindNeighborsRequestQuery = {\n neighborCount: k,\n datapoint: {\n datapointId: `0`,\n featureVector: query,\n },\n };\n if (filter) {\n requestQuery.datapoint.restricts = filter;\n }\n const request: FindNeighborsRequest = {\n deployedIndexId,\n queries: [requestQuery],\n };\n\n // Build the connection.\n // Has to be done here, since we defer getting the endpoint until\n // we need it.\n const apiEndpoint = await this.getPublicAPIEndpoint();\n const findNeighborsParams: FindNeighborsConnectionParams = {\n endpoint: apiEndpoint,\n indexEndpoint: this.indexEndpoint,\n apiVersion: this.apiVersion,\n location: this.location,\n deployedIndexId,\n authOptions: this.authOptions,\n };\n const connection = new FindNeighborsConnection(\n findNeighborsParams,\n this.caller\n );\n\n // Make the call\n const options = {};\n const response = await connection.request(request, options);\n\n // Get the document for each datapoint id and return them\n const nearestNeighbors = response?.data?.nearestNeighbors ?? [];\n const nearestNeighbor = nearestNeighbors[0];\n const neighbors = nearestNeighbor?.neighbors ?? [];\n const ret: [Document, number][] = await Promise.all(\n neighbors.map(async (neighbor) => {\n const id = neighbor?.datapoint?.datapointId;\n const distance = neighbor?.distance;\n let doc: IdDocument;\n try {\n doc = await this.docstore.search(id);\n } catch (xx) {\n // Documents that are in the index are returned, even if they\n // are not in the document store, to allow for some way to get\n // the id so they can be deleted.\n console.error(xx);\n console.warn(\n [\n `Document with id \"${id}\" is missing from the backing docstore.`,\n `This can occur if you clear the docstore without deleting from the corresponding Matching Engine index.`,\n `To resolve this, you should call .delete() with this id as part of the \"ids\" parameter.`,\n ].join(\"\\n\")\n );\n doc = new Document({ pageContent: `Missing document ${id}` });\n }\n doc.id ??= id;\n return [doc, distance];\n })\n );\n\n return ret;\n }\n\n /**\n * For this index endpoint, figure out what API Endpoint URL and deployed\n * index ID should be used to do upserts and queries.\n * Also sets the `apiEndpoint` and `deployedIndexId` property for future use.\n * @return The URL\n */\n async determinePublicAPIEndpoint(): Promise<PublicAPIEndpointInfo> {\n const response: IndexEndpointResponse =\n await this.indexEndpointClient.request(this.callerOptions);\n\n // Get the endpoint\n const publicEndpointDomainName = response?.data?.publicEndpointDomainName;\n this.apiEndpoint = publicEndpointDomainName;\n\n // Determine which of the deployed indexes match the index id\n // and get the deployed index id. The list of deployed index ids\n // contain the \"index name\" or path, but not the index id by itself,\n // so we need to extract it from the name\n const indexPathPattern = /projects\\/.+\\/locations\\/.+\\/indexes\\/(.+)$/;\n const deployedIndexes = response?.data?.deployedIndexes ?? [];\n const deployedIndex = deployedIndexes.find((index) => {\n const deployedIndexPath = index.index;\n const match = deployedIndexPath.match(indexPathPattern);\n if (match) {\n const [, potentialIndexId] = match;\n if (potentialIndexId === this.index) {\n return true;\n }\n }\n return false;\n });\n if (deployedIndex) {\n this.deployedIndexId = deployedIndex.id;\n }\n\n return {\n apiEndpoint: this.apiEndpoint,\n deployedIndexId: this.deployedIndexId,\n };\n }\n\n async getPublicAPIEndpoint(): Promise<string> {\n return (\n this.apiEndpoint ?? (await this.determinePublicAPIEndpoint()).apiEndpoint\n );\n }\n\n async getDeployedIndexId(): Promise<string> {\n return (\n this.deployedIndexId ??\n (await this.determinePublicAPIEndpoint()).deployedIndexId\n );\n }\n\n static async fromTexts(\n texts: string[],\n metadatas: object[] | object,\n embeddings: EmbeddingsInterface,\n dbConfig: MatchingEngineArgs\n ): Promise<VectorStore> {\n const docs: Document[] = texts.map(\n (text, index): Document => ({\n pageContent: text,\n metadata: Array.isArray(metadatas) ? metadatas[index] : metadatas,\n })\n );\n return this.fromDocuments(docs, embeddings, dbConfig);\n }\n\n static async fromDocuments(\n docs: Document[],\n embeddings: EmbeddingsInterface,\n dbConfig: MatchingEngineArgs\n ): Promise<VectorStore> {\n const ret = new MatchingEngine(embeddings, dbConfig);\n await ret.addDocuments(docs);\n return ret;\n }\n}\n"],"mappings":"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"}