From 1ad9746b2bbad9a0abc42adaec280fbc1370bc3a Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 24 Feb 2025 11:10:23 -0800 Subject: [PATCH] feat(pinecone): added pinecone search by vector tool & fixed dropdown tag for evaluator --- blocks/blocks/pinecone.ts | 55 ++++++++++++++++++++++-- components/ui/tag-dropdown.tsx | 8 +++- tools/index.ts | 2 + tools/pinecone/searchVector.ts | 78 ++++++++++++++++++++++++++++++++++ tools/pinecone/types.ts | 9 ++++ 5 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 tools/pinecone/searchVector.ts diff --git a/blocks/blocks/pinecone.ts b/blocks/blocks/pinecone.ts index 72d3f28e46..cc0c05e005 100644 --- a/blocks/blocks/pinecone.ts +++ b/blocks/blocks/pinecone.ts @@ -20,7 +20,8 @@ export const PineconeBlock: BlockConfig = { options: [ { label: 'Generate Embeddings', id: 'generate' }, { label: 'Upsert Text', id: 'upsert_text' }, - { label: 'Search Text', id: 'search_text' }, + { label: 'Search With Text', id: 'search_text' }, + { label: 'Search With Vector', id: 'search_vector' }, { label: 'Fetch Vectors', id: 'fetch' }, ], }, @@ -153,6 +154,50 @@ export const PineconeBlock: BlockConfig = { placeholder: '["vec1", "vec2"]', condition: { field: 'operation', value: 'fetch' }, }, + // Add vector search fields + { + id: 'indexHost', + title: 'Index Host', + type: 'short-input', + layout: 'full', + placeholder: 'https://index-name-abc123.svc.project-id.pinecone.io', + condition: { field: 'operation', value: 'search_vector' }, + }, + { + id: 'namespace', + title: 'Namespace', + type: 'short-input', + layout: 'full', + placeholder: 'default', + condition: { field: 'operation', value: 'search_vector' }, + }, + { + id: 'vector', + title: 'Query Vector', + type: 'long-input', + layout: 'full', + placeholder: '[0.1, 0.2, 0.3, ...]', + condition: { field: 'operation', value: 'search_vector' }, + }, + { + id: 'topK', + title: 'Top K Results', + type: 'short-input', + layout: 'full', + placeholder: '10', + condition: { field: 'operation', value: 'search_vector' }, + }, + { + id: 'options', + title: 'Options', + type: 'checkbox-list', + layout: 'full', + options: [ + { id: 'includeValues', label: 'Include Values' }, + { id: 'includeMetadata', label: 'Include Metadata' }, + ], + condition: { field: 'operation', value: 'search_vector' }, + }, // Common fields { id: 'apiKey', @@ -169,6 +214,7 @@ export const PineconeBlock: BlockConfig = { 'pinecone_generate_embeddings', 'pinecone_upsert_text', 'pinecone_search_text', + 'pinecone_search_vector', 'pinecone_fetch', ], config: { @@ -182,6 +228,8 @@ export const PineconeBlock: BlockConfig = { return 'pinecone_search_text' case 'fetch': return 'pinecone_fetch' + case 'search_vector': + return 'pinecone_search_vector' default: throw new Error('Invalid operation selected') } @@ -192,8 +240,6 @@ export const PineconeBlock: BlockConfig = { inputs: { operation: { type: 'string', required: true }, apiKey: { type: 'string', required: true }, - environment: { type: 'string', required: false }, - indexName: { type: 'string', required: false }, indexHost: { type: 'string', required: false }, namespace: { type: 'string', required: false }, // Generate embeddings inputs @@ -210,6 +256,9 @@ export const PineconeBlock: BlockConfig = { rerank: { type: 'json', required: false }, // Fetch inputs ids: { type: 'json', required: false }, + vector: { type: 'json', required: false }, + includeValues: { type: 'boolean', required: false }, + includeMetadata: { type: 'boolean', required: false }, }, outputs: { diff --git a/components/ui/tag-dropdown.tsx b/components/ui/tag-dropdown.tsx index 68b0273d2e..905231b913 100644 --- a/components/ui/tag-dropdown.tsx +++ b/components/ui/tag-dropdown.tsx @@ -81,7 +81,9 @@ export const TagDropdown: React.FC = ({ // First check for evaluator metrics if (sourceBlock.type === 'evaluator') { try { - const metricsValue = sourceBlock.subBlocks?.metrics?.value as unknown as Metric[] + const metricsValue = useSubBlockStore + .getState() + .getValue(activeSourceBlockId, 'metrics') as unknown as Metric[] if (Array.isArray(metricsValue)) { return { tags: metricsValue.map( @@ -148,7 +150,9 @@ export const TagDropdown: React.FC = ({ if (sourceBlock.type === 'evaluator') { try { - const metricsValue = sourceBlock.subBlocks?.metrics?.value as unknown as Metric[] + const metricsValue = useSubBlockStore + .getState() + .getValue(edge.source, 'metrics') as unknown as Metric[] if (Array.isArray(metricsValue)) { return metricsValue.map( (metric) => `${normalizedBlockName}.response.${metric.name.toLowerCase()}` diff --git a/tools/index.ts b/tools/index.ts index 43c8fdb7cf..6b33390df1 100644 --- a/tools/index.ts +++ b/tools/index.ts @@ -21,6 +21,7 @@ import { embeddingsTool as openAIEmbeddings } from './openai/embeddings' import { fetchTool as pineconeFetchTool } from './pinecone/fetch' import { generateEmbeddingsTool as pineconeGenerateEmbeddingsTool } from './pinecone/generate' import { searchTextTool as pineconeSearchTextTool } from './pinecone/searchText' +import { searchVectorTool as pineconeSearchVectorTool } from './pinecone/searchVector' import { upsertTextTool as pineconeUpsertTextTool } from './pinecone/upsertText' import { opportunitiesTool as salesforceOpportunities } from './salesforce/opportunities' import { searchTool as serperSearch } from './serper/search' @@ -69,6 +70,7 @@ export const tools: Record = { pinecone_fetch: pineconeFetchTool, pinecone_generate_embeddings: pineconeGenerateEmbeddingsTool, pinecone_search_text: pineconeSearchTextTool, + pinecone_search_vector: pineconeSearchVectorTool, pinecone_upsert_text: pineconeUpsertTextTool, github_pr: prTool, github_comment: commentTool, diff --git a/tools/pinecone/searchVector.ts b/tools/pinecone/searchVector.ts new file mode 100644 index 0000000000..6c8c2ba1c4 --- /dev/null +++ b/tools/pinecone/searchVector.ts @@ -0,0 +1,78 @@ +import { ToolConfig } from '../types' +import { PineconeResponse, PineconeSearchVectorParams } from './types' + +export const searchVectorTool: ToolConfig = { + id: 'pinecone_search_vector', + name: 'Pinecone Search Vector', + description: 'Search for similar vectors in a Pinecone index', + version: '1.0', + + params: { + apiKey: { + type: 'string', + required: true, + requiredForToolCall: true, + description: 'Pinecone API key', + }, + indexHost: { + type: 'string', + required: true, + requiredForToolCall: true, + description: 'Full Pinecone index host URL', + }, + namespace: { type: 'string', required: false, description: 'Namespace to search in' }, + vector: { type: 'array', required: true, description: 'Vector to search for' }, + topK: { type: 'number', required: false, description: 'Number of results to return' }, + filter: { type: 'object', required: false, description: 'Filter to apply to the search' }, + includeValues: { + type: 'boolean', + required: false, + description: 'Include vector values in response', + }, + includeMetadata: { + type: 'boolean', + required: false, + description: 'Include metadata in response', + }, + }, + + request: { + method: 'POST', + url: (params) => `${params.indexHost}/query`, + headers: (params) => ({ + 'Api-Key': params.apiKey, + 'Content-Type': 'application/json', + Accept: 'application/json', + }), + body: (params) => ({ + namespace: params.namespace, + vector: typeof params.vector === 'string' ? JSON.parse(params.vector) : params.vector, + topK: params.topK ? parseInt(params.topK.toString()) : 10, + filter: params.filter + ? typeof params.filter === 'string' + ? JSON.parse(params.filter) + : params.filter + : undefined, + includeValues: true, //TODO: Make this dynamic + includeMetadata: true, //TODO: Make this dynamic + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + return { + success: true, + output: { + matches: data.matches.map((match: any) => ({ + id: match.id, + score: match.score, + values: match.values, + metadata: match.metadata, + })), + namespace: data.namespace, + }, + } + }, + + transformError: (error) => `Pinecone vector search failed: ${error.message}`, +} diff --git a/tools/pinecone/types.ts b/tools/pinecone/types.ts index 089709502f..4907359b5e 100644 --- a/tools/pinecone/types.ts +++ b/tools/pinecone/types.ts @@ -150,3 +150,12 @@ export interface PineconeParams { metadata?: Record }> } + +// Search Vector +export interface PineconeSearchVectorParams extends PineconeBaseParams { + vector: number[] | string + topK?: number | string + filter?: Record | string + includeValues?: boolean + includeMetadata?: boolean +}