feature: Integrate Astra Vectorstore

This commit is contained in:
hakeemsyd 2024-01-12 00:31:21 +05:00 committed by Ilango
parent 4364537595
commit 4b9b30bf7a
4 changed files with 227 additions and 0 deletions

View File

@ -0,0 +1,34 @@
import { INodeParams, INodeCredential } from '../src/Interface'
class AstraApi implements INodeCredential {
label: string
name: string
version: number
description: string
inputs: INodeParams[]
constructor() {
this.label = 'Astra API'
this.name = 'AstraApi'
this.version = 1.0
this.inputs = [
{
label: 'Colection Name',
name: 'collectionName',
type: 'string'
},
{
label: 'Astra DB Application Token',
name: 'applicationToken',
type: 'password'
},
{
label: 'Astra DB Api Endpoint',
name: 'dbEndPoint',
type: 'string'
}
]
}
}
module.exports = { credClass: AstraApi }

View File

@ -0,0 +1,190 @@
import { flatten } from 'lodash'
import { Embeddings } from 'langchain/embeddings/base'
import { Document } from 'langchain/document'
import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { getBaseClasses, getCredentialData } from '../../../src/utils'
import { AstraDBVectorStore, AstraLibArgs } from '@langchain/community/vectorstores/astradb'
class Astra_VectorStores implements INode {
label: string
name: string
version: number
description: string
type: string
icon: string
category: string
badge: string
baseClasses: string[]
inputs: INodeParams[]
credential: INodeParams
outputs: INodeOutputsValue[]
constructor() {
this.label = 'Astra'
this.name = 'Astra'
this.version = 1.0
this.type = 'Astra'
this.icon = 'astra.svg'
this.category = 'Vector Stores'
this.description = `Upsert embedded data and perform similarity search upon query using DataStax Astra DB, a serverless vector database thats perfect for managing mission-critical AI workloads`
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
this.badge = 'NEW'
this.credential = {
label: 'Connect Credential',
name: 'credential',
type: 'credential',
credentialNames: ['AstraApi']
}
this.inputs = [
{
label: 'Document',
name: 'document',
type: 'Document',
list: true,
optional: true
},
{
label: 'Embeddings',
name: 'embeddings',
type: 'Embeddings'
},
{
label: 'Vector Dimension',
name: 'vectorDimension',
type: 'number',
placeholder: '1536',
optional: true,
description: 'Dimension used for storing vector embedding'
},
{
label: 'Similarity Metric',
name: 'similarityMetric',
type: 'string',
placeholder: 'cosine',
optional: true,
description: 'cosine | euclidean | dot_product'
},
{
label: 'Top K',
name: 'topK',
description: 'Number of top results to fetch. Default to 4',
placeholder: '4',
type: 'number',
additionalParams: true,
optional: true
}
]
this.outputs = [
{
label: 'Astra Retriever',
name: 'retriever',
baseClasses: this.baseClasses
},
{
label: 'Astra Vector Store',
name: 'vectorStore',
baseClasses: [this.type, ...getBaseClasses(AstraDBVectorStore)]
}
]
}
//@ts-ignore
vectorStoreMethods = {
async upsert(nodeData: INodeData, options: ICommonObject): Promise<void> {
const docs = nodeData.inputs?.document as Document[]
const embeddings = nodeData.inputs?.embeddings as Embeddings
const vectorDimension = nodeData.inputs?.vectorDimension as number
const similarityMetric = nodeData.inputs?.similarityMetric as 'cosine' | 'euclidean' | 'dot_product' | undefined
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
const expectedSimilarityMetric = ['cosine', 'euclidean', 'dot_product']
if (similarityMetric && !expectedSimilarityMetric.includes(similarityMetric)) {
throw new Error(`Invalid Similarity Metric should be one of 'cosine' | 'euclidean' | 'dot_product'`)
}
const clientConfig = {
token: credentialData?.applicationToken ?? 'dummy',
endpoint: credentialData?.dbEndPoint ?? 'dummy'
}
const astraConfig: AstraLibArgs = {
...clientConfig,
collection: credentialData.collectionName ?? 'flowise_test',
collectionOptions: {
vector: {
dimension: vectorDimension ?? 1536,
metric: similarityMetric ?? 'cosine'
}
}
}
const flattenDocs = docs && docs.length ? flatten(docs) : []
const finalDocs = []
for (let i = 0; i < flattenDocs.length; i += 1) {
if (flattenDocs[i] && flattenDocs[i].pageContent) {
finalDocs.push(new Document(flattenDocs[i]))
}
}
try {
await AstraDBVectorStore.fromDocuments(finalDocs, embeddings, astraConfig)
} catch (e) {
throw new Error(e)
}
}
}
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
const docs = nodeData.inputs?.document as Document[]
const embeddings = nodeData.inputs?.embeddings as Embeddings
const vectorDimension = nodeData.inputs?.vectorDimension as number
const similarityMetric = nodeData.inputs?.similarityMetric as 'cosine' | 'euclidean' | 'dot_product' | undefined
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
const k = topK ? parseFloat(topK) : 4
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
const expectedSimilarityMetric = ['cosine', 'euclidean', 'dot_product']
if (similarityMetric && !expectedSimilarityMetric.includes(similarityMetric)) {
throw new Error(`Invalid Similarity Metric should be one of 'cosine' | 'euclidean' | 'dot_product'`)
}
const clientConfig = {
token: credentialData?.applicationToken ?? 'dummy',
endpoint: credentialData?.dbEndPoint ?? 'dummy'
}
const astraConfig: AstraLibArgs = {
...clientConfig,
collection: credentialData.collectionName ?? 'flowise_test',
collectionOptions: {
vector: {
dimension: vectorDimension ?? 1536,
metric: similarityMetric ?? 'cosine'
}
}
}
const flattenDocs = docs && docs.length ? flatten(docs) : []
const finalDocs = []
for (let i = 0; i < flattenDocs.length; i += 1) {
if (flattenDocs[i] && flattenDocs[i].pageContent) {
finalDocs.push(new Document(flattenDocs[i]))
}
}
const vectorStore = await AstraDBVectorStore.fromExistingIndex(embeddings, astraConfig)
if (output === 'retriever') {
const retriever = vectorStore.asRetriever(k)
return retriever
} else if (output === 'vectorStore') {
;(vectorStore as any).k = k
return vectorStore
}
return vectorStore
}
}
module.exports = { nodeClass: Astra_VectorStores }

View File

@ -0,0 +1 @@
<svg width="11.41em" height="1.06em" viewBox="0 0 183 17" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M109.189 2.94031V0H95.0865L91.2567 2.94031V6.97789L95.0865 9.9182H107.377V14.0627H92.0184V17H106.502L110.332 14.0627V9.9182L106.502 6.97789H94.2112V2.94031H109.189Z" fill="currentColor"></path><path d="M35.3706 0H32.6803L22.8126 17H26.2247L34.0316 3.55466L41.8293 17H45.2383L35.3706 0Z" fill="currentColor"></path><path d="M64.7034 0H45.6284V2.94031H53.6902V17H56.6416V2.94031H64.7034V0Z" fill="currentColor"></path><path d="M134.146 0H115.074V2.94031H123.132V17H126.087V2.94031H134.146V0Z" fill="currentColor"></path><path d="M15.2453 0H0V17H15.2453L19.075 14.0597V2.94031L15.2453 0ZM2.95447 2.94031H16.1206V14.0627H2.95447V2.94031Z" fill="currentColor"></path><path d="M169.034 8.5L167.327 5.55969V5.56275L164.099 0H160.687L165.622 8.5L160.687 17H164.099L167.327 11.4403L169.034 8.5Z" fill="currentColor"></path><path d="M173.887 8.5L175.594 5.55969V5.56275L178.825 0H182.234L177.302 8.5L182.234 17H178.825L175.594 11.4403L173.887 8.5Z" fill="currentColor"></path><path d="M74.9611 0H77.6515L87.5191 17H84.1071L76.3001 3.55466L68.5024 17H65.0934L74.9611 0Z" fill="currentColor"></path><path d="M144.403 0H147.094L156.961 17H153.552L145.742 3.55466L137.948 17H134.536L144.403 0Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -19,6 +19,7 @@
"@aws-sdk/client-bedrock-runtime": "3.422.0",
"@aws-sdk/client-dynamodb": "^3.360.0",
"@aws-sdk/client-s3": "^3.427.0",
"@datastax/astra-db-ts": "^0.1.2",
"@dqbd/tiktoken": "^1.0.7",
"@elastic/elasticsearch": "^8.9.0",
"@getzep/zep-js": "^0.9.0",
@ -26,6 +27,7 @@
"@gomomento/sdk-core": "^1.51.1",
"@google-ai/generativelanguage": "^0.2.1",
"@huggingface/inference": "^2.6.1",
"@langchain/community": "^0.0.16",
"@langchain/google-genai": "^0.0.6",
"@langchain/mistralai": "^0.0.6",
"@notionhq/client": "^2.2.8",