mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
* Initialize ToolJet plugin with default files and installed dependencies Created the folder structure and default files for the pinecone plugin the server/src/assets/marketplace/plugins.json file also got updated automatically and added an entry for the Pinecone plugin. Installed the specified versions of @grpc/grpc-js@^1.12.0 and @pinecone-database/pinecone@^3.0.3 packages into the project. * Update Pinecone plugin manifest with API key authentication Updated Pinecone plugin manifest to include API key authentication as an encrypted string. Added API key field with description and help text for generating the key via the Pinecone Console. Marked apiKey as a required field in the schema. * Enhance Pinecone operations.json with vector management options Amended operations.json to support various vector management operations for the Pinecone plugin. Added new fields for index, operation, and specific properties for operations like get_index_stats, list_vector_ids, fetch_vectors, upsert_vectors, update_vector, and delete_vectors. Introduced support for vector ID management, metadata, namespace, and filter options in JSON format. Updated the schema type from api to database to better reflect the plugin's functionality. * Add query operations and enhance types for Pinecone plugin Created query_operations.ts to handle Pinecone operations: getIndexStats, listVectorIds, fetchVectors, upsertVectors, updateVector, and deleteVectors. Added error handling, namespace support, and consolidated vector deletion logic. Updated types.ts with detailed SourceOptions and QueryOptions, including fields like index, ids, vectors, and pagination. Introduced types for Vector, SparseValues, and an enum for available operations, ensuring type safety. Functions for getIndexStats and listVectorIds work correctly, but other operations are not functioning as expected. * Implement Pinecone service with query operations and connection handling Updated index.ts with PineconeService to handle operations: getIndexStats, listVectorIds, fetchVectors, upsertVectors, updateVector, and deleteVectors. Added connection testing and API key handling functions. Error handling for invalid operations included. Only getIndexStats and listVectorIds are working correctly; other operations need debugging. * Fix operations and add query vector operation * Update placeholders for boolean fields Set placeholders for delete_all, include_values, and include_metadata to indicate "true (false by default)" for clearer defaults. --------- Co-authored-by: parthy007 <parthadhikari1812@gmail.com>
181 lines
5.7 KiB
TypeScript
181 lines
5.7 KiB
TypeScript
import { QueryOptions } from './types';
|
|
import { Pinecone } from '@pinecone-database/pinecone';
|
|
|
|
export async function getIndexStats(pinecone: Pinecone, options: QueryOptions): Promise<any> {
|
|
const { index } = options;
|
|
|
|
if (!index) {
|
|
throw new Error('Index name is required');
|
|
}
|
|
|
|
try {
|
|
const indexClient = pinecone.index(index);
|
|
const stats = await indexClient.describeIndexStats();
|
|
|
|
return stats;
|
|
} catch (error) {
|
|
console.error('Error fetching index stats:', error);
|
|
throw new Error(error?.message || 'An unexpected error occurred');
|
|
}
|
|
}
|
|
|
|
export async function listVectorIds(pinecone: Pinecone, options: QueryOptions): Promise<any> {
|
|
const { index, prefix, limit, paginationToken, namespace } = options;
|
|
|
|
if (!index) {
|
|
throw new Error('Index name is required');
|
|
}
|
|
|
|
try {
|
|
const indexClient = pinecone.index(index);
|
|
|
|
const listOptions = {
|
|
prefix: prefix,
|
|
limit: limit || 10,
|
|
paginationToken: paginationToken,
|
|
};
|
|
|
|
const client = namespace ? indexClient.namespace(namespace) : indexClient;
|
|
|
|
const vectors = await client.listPaginated(listOptions);
|
|
|
|
return vectors;
|
|
} catch (error) {
|
|
console.error('Error listing vector IDs:', error);
|
|
throw new Error(error?.message || 'An unexpected error occurred');
|
|
}
|
|
}
|
|
|
|
export async function fetchVectors(pinecone: Pinecone, options: QueryOptions): Promise<any> {
|
|
const { index, ids, namespace } = options;
|
|
|
|
if (!index || !ids) {
|
|
throw new Error('Index name and vector IDs are required');
|
|
}
|
|
|
|
const vectorIds = typeof ids === 'string' ? JSON.parse(ids) : ids;
|
|
|
|
try {
|
|
const indexClient = pinecone.index(index);
|
|
const client = namespace ? await indexClient.namespace(namespace) : indexClient;
|
|
const vectors = await client.fetch(vectorIds);
|
|
|
|
return vectors;
|
|
} catch (error) {
|
|
throw new Error(error?.message || 'An unexpected error occurred');
|
|
}
|
|
}
|
|
|
|
export async function upsertVectors(pinecone: Pinecone, options: QueryOptions): Promise<any> {
|
|
const { index, vectors, namespace } = options;
|
|
const parsedVectors = typeof vectors === 'string' ? JSON.parse(vectors) : vectors;
|
|
|
|
if (!index || !vectors) {
|
|
throw new Error('Index name and vectors are required');
|
|
}
|
|
|
|
parsedVectors.forEach((vector) => {
|
|
if (!vector.id || !Array.isArray(vector.values)) {
|
|
throw new Error('Each vector must have an id and a values array');
|
|
}
|
|
});
|
|
|
|
try {
|
|
const indexClient = pinecone.index(index);
|
|
const client = namespace ? await indexClient.namespace(namespace) : indexClient;
|
|
const upsertResponse = await client.upsert(parsedVectors);
|
|
if (upsertResponse === undefined) {
|
|
return 'Upsert Successful';
|
|
} else {
|
|
throw new Error('Upsert failed');
|
|
}
|
|
} catch (error) {
|
|
throw new Error(error?.message || 'An unexpected error occurred');
|
|
}
|
|
}
|
|
|
|
export async function updateVector(pinecone: Pinecone, options: QueryOptions): Promise<any> {
|
|
const { index, id, values, sparse_vector, metadata, namespace } = options;
|
|
|
|
if (!index || !id || (!values && !sparse_vector)) {
|
|
throw new Error('Index name, vector ID, and either values or sparse vector are required');
|
|
}
|
|
|
|
const valuesArray = typeof values === 'string' ? JSON.parse(values) : values;
|
|
|
|
try {
|
|
const indexClient = pinecone.index(index);
|
|
const client = namespace ? await indexClient.namespace(namespace) : indexClient;
|
|
const updateResponse = await client.update({
|
|
id,
|
|
...(valuesArray && { values: valuesArray }),
|
|
...(metadata && { metadata: JSON.parse(metadata) }),
|
|
...(sparse_vector && { sparseValues: JSON.parse(sparse_vector) }),
|
|
});
|
|
|
|
if (updateResponse === undefined) {
|
|
return 'Update Successful';
|
|
} else {
|
|
throw new Error('Update failed');
|
|
}
|
|
} catch (error) {
|
|
throw new Error(error?.message || 'An unexpected error occurred');
|
|
}
|
|
}
|
|
|
|
export async function deleteVectors(pinecone: Pinecone, options: QueryOptions): Promise<any> {
|
|
const { index, id, delete_all, namespace, filter } = options;
|
|
|
|
if (!index) {
|
|
throw new Error('Index name is required');
|
|
}
|
|
|
|
try {
|
|
const indexClient = pinecone.index(index);
|
|
const client = namespace ? await indexClient.namespace(namespace) : indexClient;
|
|
let deleteResponse;
|
|
if (delete_all && delete_all.toLowerCase() === 'true') {
|
|
deleteResponse = await client.deleteAll();
|
|
} else if (filter) {
|
|
deleteResponse = await client.deleteMany({
|
|
filter: JSON.parse(filter),
|
|
});
|
|
} else {
|
|
deleteResponse = await client.deleteMany(JSON.parse(id));
|
|
}
|
|
|
|
if (deleteResponse === undefined) {
|
|
return 'Delete Successful';
|
|
} else {
|
|
throw new Error('Delete failed');
|
|
}
|
|
} catch (error) {
|
|
throw new Error(error?.message || 'An unexpected error occurred');
|
|
}
|
|
}
|
|
|
|
export async function quertVectors(pinecone: Pinecone, options: QueryOptions): Promise<any> {
|
|
const { index, namespace, top_k, filter, include_values, include_metadata, vectors, sparse_vector } = options;
|
|
|
|
if (!index) {
|
|
throw new Error('Index is required');
|
|
}
|
|
|
|
const pineconeQueryOptions = {
|
|
topK: Number(top_k),
|
|
vector: JSON.parse(vectors),
|
|
...(filter && { filter: JSON.parse(filter) }),
|
|
...(include_values && { includeValues: include_values.toLowerCase() === 'true' }),
|
|
...(include_metadata && { includeMetadata: include_metadata.toLowerCase() === 'true' }),
|
|
...(sparse_vector && { sparseVector: JSON.parse(sparse_vector) }),
|
|
};
|
|
|
|
try {
|
|
const indexClient = pinecone.index(index);
|
|
const client = namespace ? await indexClient.namespace(namespace) : indexClient;
|
|
const queryResponse = await client.query(pineconeQueryOptions);
|
|
return queryResponse;
|
|
} catch (error) {
|
|
throw new Error(error.message);
|
|
}
|
|
}
|