feat(memory): added pinecone block/tools

This commit is contained in:
Waleed Latif
2025-02-17 18:06:19 -08:00
parent 9f3c49866f
commit 2d77590d03
8 changed files with 366 additions and 0 deletions
+153
View File
@@ -0,0 +1,153 @@
import { PineconeIcon } from '@/components/icons'
// You'll need to create this icon
import { PineconeResponse } from '@/tools/pinecone/types'
import { BlockConfig } from '../types'
export const PineconeBlock: BlockConfig<PineconeResponse> = {
type: 'pinecone',
name: 'Pinecone',
description: 'Interact with Pinecone vector database',
category: 'tools',
bgColor: '#0D1117',
icon: PineconeIcon,
subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
layout: 'full',
options: [
{ label: 'Query', id: 'query' },
{ label: 'Upsert', id: 'upsert' },
{ label: 'Delete', id: 'delete' },
],
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
layout: 'full',
placeholder: 'Your Pinecone API key',
password: true,
},
{
id: 'environment',
title: 'Environment',
type: 'short-input',
layout: 'full',
placeholder: 'gcp-starter',
},
{
id: 'indexName',
title: 'Index Name',
type: 'short-input',
layout: 'full',
placeholder: 'my-index',
},
// Query operation fields
{
id: 'queryVector',
title: 'Query Vector',
type: 'long-input',
layout: 'full',
placeholder: '[0.1, 0.2, 0.3, ...]',
condition: { field: 'operation', value: 'query' },
},
{
id: 'topK',
title: 'Top K Results',
type: 'short-input',
layout: 'half',
placeholder: '10',
condition: { field: 'operation', value: 'query' },
},
{
id: 'includeMetadata',
title: 'Include Metadata',
type: 'switch',
layout: 'half',
value: () => 'true',
condition: { field: 'operation', value: 'query' },
},
{
id: 'includeValues',
title: 'Include Values',
type: 'switch',
layout: 'half',
value: () => 'false',
condition: { field: 'operation', value: 'query' },
},
// Upsert operation fields
{
id: 'vectors',
title: 'Vectors',
type: 'long-input',
layout: 'full',
placeholder: '[{"id": "vec1", "values": [0.1, 0.2, 0.3], "metadata": {"key": "value"}}]',
condition: { field: 'operation', value: 'upsert' },
},
// Delete operation fields
{
id: 'ids',
title: 'Vector IDs',
type: 'long-input',
layout: 'full',
placeholder: '["vec1", "vec2", ...]',
condition: { field: 'operation', value: 'delete' },
},
{
id: 'deleteAll',
title: 'Delete All Vectors',
type: 'switch',
layout: 'half',
value: () => 'false',
condition: { field: 'operation', value: 'delete' },
},
],
tools: {
access: ['pinecone_query', 'pinecone_upsert', 'pinecone_delete'],
config: {
tool: (params) => {
switch (params.operation) {
case 'query':
return 'pinecone_query'
case 'upsert':
return 'pinecone_upsert'
case 'delete':
return 'pinecone_delete'
default:
throw new Error('Invalid operation selected')
}
},
},
},
inputs: {
operation: { type: 'string', required: true },
apiKey: { type: 'string', required: true },
environment: { type: 'string', required: true },
indexName: { type: 'string', required: true },
// Query operation inputs
queryVector: { type: 'json', required: false },
topK: { type: 'number', required: false },
includeMetadata: { type: 'boolean', required: false },
includeValues: { type: 'boolean', required: false },
// Upsert operation inputs
vectors: { type: 'json', required: false },
// Delete operation inputs
ids: { type: 'json', required: false },
deleteAll: { type: 'boolean', required: false },
},
outputs: {
response: {
type: {
matches: 'any',
upsertedCount: 'any',
deletedCount: 'any',
},
},
},
}
+3
View File
@@ -10,6 +10,7 @@ import { GitHubBlock } from './blocks/github'
import { GmailBlock } from './blocks/gmail'
import { JinaBlock } from './blocks/jina'
import { NotionBlock } from './blocks/notion'
import { PineconeBlock } from './blocks/pinecone'
import { RouterBlock } from './blocks/router'
import { SerperBlock } from './blocks/serper'
import { SlackBlock } from './blocks/slack'
@@ -41,6 +42,7 @@ export {
GmailBlock,
XBlock,
StarterBlock,
PineconeBlock,
}
// Registry of all block configurations
@@ -64,6 +66,7 @@ const blocks: Record<string, BlockConfig> = {
notion: NotionBlock,
gmail: GmailBlock,
x: XBlock,
pinecone: PineconeBlock,
}
// Helper functions
+20
View File
@@ -1388,3 +1388,23 @@ export function StartIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function PineconeIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
width="256px"
height="288px"
viewBox="0 0 256 288"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
preserveAspectRatio="xMidYMid"
>
<path
d="M108.633615,254.43629 C117.713862,254.43629 125.074857,261.797284 125.074857,270.877532 C125.074857,279.957779 117.713862,287.318774 108.633615,287.318774 C99.5533677,287.318774 92.1923728,279.957779 92.1923728,270.877532 C92.1923728,261.797284 99.5533677,254.43629 108.633615,254.43629 Z M199.849665,224.438339 L216.09705,229.252379 L203.199913,272.780219 C202.072982,276.58361 198.458049,279.095992 194.500389,278.826397 L190.516677,278.552973 L190.419263,278.633409 L149.02918,275.728903 L150.180842,258.822508 L177.989056,260.709686 L159.783784,234.447622 L173.709616,224.792379 L191.938895,251.08702 L199.849665,224.438339 Z M23.0126771,194.347476 L39.9158866,195.544979 L37.935897,223.348728 L64.1501315,205.120082 L73.8271476,219.030793 L47.578736,237.278394 L74.3707554,245.173037 L69.5818063,261.427835 L25.8485266,248.543243 C22.0304448,247.418369 19.5101155,243.787479 19.7913963,239.817092 L23.0126771,194.347476 Z M132.151306,170.671396 L162.658679,207.503468 L148.909247,218.891886 L130.753266,196.972134 L124.866941,230.673893 L107.280249,227.599613 L113.172232,193.845272 L88.7296311,208.256891 L79.6674587,192.874434 L120.745504,168.674377 C124.522104,166.449492 129.355297,167.295726 132.151306,170.671396 Z M217.504528,145.960198 L232.744017,137.668804 L254.94482,178.473633 C256.889641,182.048192 256.088221,186.494171 253.017682,189.164674 L249.876622,191.878375 L217.826246,219.77131 L206.441034,206.680621 L227.988588,187.934494 L195.893546,182.152609 L198.972402,165.078949 L231.044844,170.857793 L217.504528,145.960198 Z M37.7821805,103.299272 L49.2622123,116.306888 L28.0106317,135.050179 L60.1668233,140.664193 L57.1863573,157.755303 L24.9947229,152.136967 L38.822104,177.134576 L23.6411026,185.532577 L1.08439616,144.756992 C-0.885025494,141.196884 -0.115545265,136.746375 2.93488097,134.054184 L37.7821805,103.299272 Z M146.476311,89.8796828 L176.88045,126.612847 L163.1271,137.996532 L144.975445,116.067101 L139.08912,149.778947 L121.502428,146.704666 L127.374238,113.081452 L103.025237,127.354817 L93.9976317,111.952048 L131.398812,90.0233663 L131.435631,89.880899 L131.600545,89.9023265 L135.085833,87.870141 C138.861877,85.6569913 143.68556,86.5079996 146.476311,89.8796828 Z M185.655786,71.8143168 L192.305535,55.7902703 L235.318239,73.6399229 C239.072486,75.1978811 241.2415,79.1537636 240.536356,83.1568091 L239.820231,87.1385839 L232.47517,128.919545 L215.389188,125.909819 L220.312646,97.9413879 L191.776157,113.7129 L183.390302,98.5251862 L211.981072,82.7408038 L185.655786,71.8143168 Z M103.71696,40.2373824 L104.456513,57.5706533 L76.0432671,58.785006 L97.4730368,83.2749086 L84.4165529,94.6993319 L62.9507932,70.1728358 L57.949673,98.1737132 L40.8716575,95.1191088 L49.0561498,49.3603563 C49.771444,45.3612115 53.1664633,42.3942036 57.2253811,42.2210231 L61.246149,42.0411642 L61.3363168,41.9758 L103.71696,40.2373824 Z M161.838155,3.27194826 L192.104824,40.2369789 L178.291207,51.5474574 L160.327329,29.6043227 L154.268381,63.2715157 L136.697231,60.1096121 L142.766468,26.3665075 L118.24002,40.7062765 L109.232678,25.2916494 L150.427675,1.21987397 C154.218286,-0.995121237 159.056796,-0.124957814 161.838155,3.27194826 Z"
fill="currentColor"
/>
</svg>
)
}
+6
View File
@@ -15,6 +15,9 @@ import { readUrlTool } from './jina/reader'
import { notionReadTool } from './notion/read'
import { notionWriteTool } from './notion/write'
import { chatTool as openAIChat } from './openai/chat'
import { deleteTool as pineconeDeleteTool } from './pinecone/delete'
import { queryTool as pineconeQueryTool } from './pinecone/query'
import { upsertTool as pineconeUpsertTool } from './pinecone/upsert'
import { opportunitiesTool as salesforceOpportunities } from './salesforce/opportunities'
import { searchTool as serperSearch } from './serper/search'
import { slackMessageTool } from './slack/message'
@@ -58,6 +61,9 @@ export const tools: Record<string, ToolConfig> = {
x_read: xRead,
x_search: xSearch,
x_user: xUser,
pinecone_query: pineconeQueryTool,
pinecone_upsert: pineconeUpsertTool,
pinecone_delete: pineconeDeleteTool,
}
// Get a tool by its ID
+42
View File
@@ -0,0 +1,42 @@
import { ToolConfig } from '../types'
import { PineconeParams, PineconeResponse } from './types'
export const deleteTool: ToolConfig<PineconeParams, PineconeResponse> = {
id: 'pinecone_delete',
name: 'Pinecone Delete',
description: 'Delete vectors from Pinecone index',
version: '1.0',
params: {
apiKey: { type: 'string', required: true, description: 'Pinecone API key' },
environment: { type: 'string', required: true, description: 'Pinecone environment' },
indexName: { type: 'string', required: true, description: 'Name of the Pinecone index' },
ids: { type: 'array', required: false, description: 'Array of vector IDs to delete' },
deleteAll: { type: 'boolean', required: false, description: 'Delete all vectors in the index' },
},
request: {
method: 'POST',
url: (params) =>
`https://${params.indexName}-${params.environment}.svc.${params.environment}.pinecone.io/vectors/delete`,
headers: (params) => ({
'Api-Key': params.apiKey,
'Content-Type': 'application/json',
}),
body: (params) => ({
ids: params.ids,
deleteAll: params.deleteAll,
}),
},
transformResponse: async (response) => {
return {
success: true,
output: {
deletedCount: response.ok ? 1 : 0, // Pinecone doesn't return count, so we estimate
},
}
},
transformError: (error) => `Pinecone delete failed: ${error.message}`,
}
+62
View File
@@ -0,0 +1,62 @@
import { ToolConfig } from '../types'
import { PineconeParams, PineconeResponse } from './types'
export const queryTool: ToolConfig<PineconeParams, PineconeResponse> = {
id: 'pinecone_query',
name: 'Pinecone Query',
description: 'Query vectors from Pinecone index',
version: '1.0',
params: {
apiKey: { type: 'string', required: true, description: 'Pinecone API key' },
environment: { type: 'string', required: true, description: 'Pinecone environment' },
indexName: { type: 'string', required: true, description: 'Name of the Pinecone index' },
queryVector: { type: 'array', required: true, description: 'Vector to query' },
topK: {
type: 'number',
required: false,
default: 10,
description: 'Number of results to return',
},
includeMetadata: {
type: 'boolean',
required: false,
default: true,
description: 'Include metadata in results',
},
includeValues: {
type: 'boolean',
required: false,
default: false,
description: 'Include vector values in results',
},
},
request: {
method: 'POST',
url: (params) =>
`https://${params.indexName}-${params.environment}.svc.${params.environment}.pinecone.io/vectors/query`,
headers: (params) => ({
'Api-Key': params.apiKey,
'Content-Type': 'application/json',
}),
body: (params) => ({
vector: params.queryVector,
topK: params.topK || 10,
includeMetadata: params.includeMetadata ?? true,
includeValues: params.includeValues ?? false,
}),
},
transformResponse: async (response) => {
const data = await response.json()
return {
success: true,
output: {
matches: data.matches || [],
},
}
},
transformError: (error) => `Pinecone query failed: ${error.message}`,
}
+35
View File
@@ -0,0 +1,35 @@
import { ToolResponse } from '../types'
export interface PineconeParams {
apiKey: string
environment: string
indexName: string
operation: 'query' | 'upsert' | 'delete'
// Query operation
queryVector?: number[]
topK?: number
includeMetadata?: boolean
includeValues?: boolean
// Upsert operation
vectors?: Array<{
id: string
values: number[]
metadata?: Record<string, any>
}>
// Delete operation
ids?: string[]
deleteAll?: boolean
}
export interface PineconeResponse extends ToolResponse {
output: {
matches?: Array<{
id: string
score: number
values?: number[]
metadata?: Record<string, any>
}>
upsertedCount?: number
deletedCount?: number
}
}
+45
View File
@@ -0,0 +1,45 @@
import { ToolConfig } from '../types'
import { PineconeParams, PineconeResponse } from './types'
export const upsertTool: ToolConfig<PineconeParams, PineconeResponse> = {
id: 'pinecone_upsert',
name: 'Pinecone Upsert',
description: 'Upsert vectors into Pinecone index',
version: '1.0',
params: {
apiKey: { type: 'string', required: true, description: 'Pinecone API key' },
environment: { type: 'string', required: true, description: 'Pinecone environment' },
indexName: { type: 'string', required: true, description: 'Name of the Pinecone index' },
vectors: {
type: 'array',
required: true,
description: 'Array of vectors to upsert, each with id, values, and optional metadata',
},
},
request: {
method: 'POST',
url: (params) =>
`https://${params.indexName}-${params.environment}.svc.${params.environment}.pinecone.io/vectors/upsert`,
headers: (params) => ({
'Api-Key': params.apiKey,
'Content-Type': 'application/json',
}),
body: (params) => ({
vectors: params.vectors,
}),
},
transformResponse: async (response) => {
const data = await response.json()
return {
success: true,
output: {
upsertedCount: data.upsertedCount || 0,
},
}
},
transformError: (error) => `Pinecone upsert failed: ${error.message}`,
}