UNPKG

@websolutespa/payload-plugin-bowl-llm

Version:

LLM plugin for Bowl PayloadCms plugin

609 lines (608 loc) 24.6 kB
import { InMemoryCache } from '@websolutespa/payload-plugin-bowl'; import { options } from '../options'; import { fetchRobot } from '../utils/robot'; import { LlmKbApi } from './integrations/LlmKbApi'; import { LlmKbAzure } from './integrations/LlmKbAzure'; import { LlmKbConfluence } from './integrations/LlmKbConfluence'; import { LlmKbDropbox } from './integrations/LlmKbDropbox'; import { LlmKbGcs } from './integrations/LlmKbGcs'; import { LlmKbGithub } from './integrations/LlmKbGithub'; import { LlmKbGoogledrive } from './integrations/LlmKbGoogledrive'; import { LlmKbJira } from './integrations/LlmKbJira'; import { LlmKbS3 } from './integrations/LlmKbS3'; import { LlmKbSftp } from './integrations/LlmKbSftp'; import { LlmKbSharepoint } from './integrations/LlmKbSharepoint'; import { LlmKbSharepointCustom } from './integrations/LlmKbSharepointCustom'; import { LlmKbShopify } from './integrations/LlmKbShopify'; import { LlmKbSitemap } from './integrations/LlmKbSitemap'; import { LlmKbSlack } from './integrations/LlmKbSlack'; import { LlmKbThron } from './integrations/LlmKbThron'; import { LlmKbZendesk } from './integrations/LlmKbZendesk'; export var ExternalEndpointAuthentication; (function(ExternalEndpointAuthentication) { ExternalEndpointAuthentication["None"] = "none"; ExternalEndpointAuthentication["Basic"] = "basic"; ExternalEndpointAuthentication["Bearer"] = "bearer"; ExternalEndpointAuthentication["Custom"] = "custom"; })(ExternalEndpointAuthentication || (ExternalEndpointAuthentication = {})); const CACHE_INTEGRATIONS_ = new InMemoryCache(); const validateIntegrations = async (value, { req })=>{ if (!req) { return true; } let robotBlocks; const cacheKey = 'robot_integrations'; if (CACHE_INTEGRATIONS_.has(cacheKey)) { robotBlocks = CACHE_INTEGRATIONS_.get(cacheKey); } else { robotBlocks = await fetchRobot('api/llm/extension/integrations', 'GET'); CACHE_INTEGRATIONS_.set(cacheKey, robotBlocks); } const invalidBlocks = value.filter((item)=>!robotBlocks.some((block)=>block.id.toLowerCase() === item.blockType.toLowerCase())); if (invalidBlocks.length) { return `Integrazione non valida. Le integrazioni disponibili sono: ${robotBlocks.map((block)=>block.id).join(', ')}`; } return true; }; export const Tool = { type: 'withBlock', slug: options.slug.llmAppTool, fields: [ { type: 'withIsActive' }, { name: 'nightlyKbGeneration', type: 'checkbox', defaultValue: true }, { name: 'name', type: 'withText', required: true }, { name: 'description', type: 'textarea' }, { name: 'functionId', type: 'withText', required: true }, { name: 'functionName', type: 'withText', required: true, admin: { components: { Field: '@websolutespa/payload-plugin-bowl-llm/client#LlmTool' } } }, { name: 'functionDescription', type: 'textarea', required: true }, { name: 'waitingMessage', type: 'textarea', localized: true }, { name: 'secrets', type: 'array', fields: [ { type: 'row', fields: [ { name: 'secretId', type: 'withText' }, { name: 'secretValue', type: 'withText' } ] } ] }, { name: 'type', type: 'radio', defaultValue: 'function', admin: { layout: 'horizontal' }, options: [ { label: 'Function', value: 'function' }, { label: 'LLM chain', value: 'llmChain' } ] }, { label: 'llmChainSettings', type: 'collapsible', admin: { condition: (_, siblingData)=>siblingData?.type === 'llmChain' }, fields: [ { name: 'llmChainSettings', type: 'group', fields: [ { name: 'model', type: 'withText', admin: { components: { Field: '@websolutespa/payload-plugin-bowl-llm/client#LlmModel' } } }, { name: 'prompt', type: 'textarea' }, { name: 'temperature', type: 'number', defaultValue: 0, min: 0, max: 1 }, { name: 'outputStructure', type: 'group', fields: [ { name: 'outputType', type: 'select', options: [ { label: 'Text', value: 'text' }, { label: 'Json', value: 'json' } ] }, { name: 'outputFormat', type: 'json', admin: { condition: (_, siblingData)=>siblingData?.outputType === 'json' } } ] } ] } ] }, { name: 'dataSource', type: 'radio', defaultValue: 'knowledgebase', admin: { layout: 'horizontal' }, options: [ { label: 'Knowledgebase', value: 'knowledgebase' }, { label: 'Database', value: 'database' }, { label: 'None', value: 'none' } ] }, { label: 'apiSettings', type: 'collapsible', admin: { condition: (_, siblingData)=>siblingData?.functionName === 'api_caller' }, fields: [ { name: 'apiSettings', type: 'group', fields: [ { name: 'endpoint', type: 'withText', validate: (value, { siblingData })=>{ if (siblingData?.functionName === 'api_caller' && !value) { return 'Endpoint is required for API caller tools'; } return true; }, admin: { description: 'API endpoint URL with parameters as {paramName}', placeholder: 'https://api.example.com/users/{userId}/posts' } }, { name: 'method', type: 'select', defaultValue: 'GET', options: [ { label: 'GET', value: 'GET' }, { label: 'POST', value: 'POST' } ] }, { name: 'headers', type: 'json', admin: { description: 'Custom headers as JSON object' } }, { name: 'payload', type: 'json', admin: { description: 'Request payload as JSON object (for POST)', condition: (_, siblingData)=>siblingData?.method === 'POST' } } ] } ] }, { label: 'MCP Server Settings', type: 'collapsible', admin: { condition: (_, siblingData)=>siblingData?.functionName === 'mcp_tool' }, fields: [ { name: 'mcpSettings', type: 'group', fields: [ { name: 'mcpUrl', type: 'withText', required: true, admin: { description: 'URL of the remote MCP server', placeholder: 'http://localhost:6001/mcp/' } }, { name: 'mcpToolName', type: 'withText', required: true, admin: { description: 'Name of the tool to call on the MCP server', placeholder: 'document_retriever' } }, { name: 'mcpAuthToken', type: 'withText', admin: { description: 'Bearer token for authentication (optional)' } } ] } ] }, { label: 'dbSettings', type: 'collapsible', admin: { condition: (_, siblingData)=>siblingData?.dataSource === 'database' }, fields: [ { name: 'dbSettings', type: 'group', fields: [ { name: 'connectionString', type: 'withText' }, { name: 'additionalPrompt', type: 'textarea' }, { name: 'limit', type: 'number', defaultValue: 10, min: 1 } ] } ] }, { label: 'knowledgebaseSettings', type: 'collapsible', admin: { condition: (_, siblingData)=>siblingData?.dataSource === 'knowledgebase' }, fields: [ { name: 'searchSettings', type: 'group', fields: [ { name: 'searchType', type: 'radio', options: [ { label: 'Similarity', value: 'default' }, { label: 'Mmr', value: 'mmr' }, { label: 'Similarity score threshold', value: 'similarityScoreThreshold' }, { label: 'Mixed (experimental)', value: 'mixed' } ] }, { name: 'scoreThreshold', type: 'number', admin: { condition: (_, siblingData)=>siblingData?.searchType === 'similarityScoreThreshold' } }, { name: 'searchK', type: 'number', admin: { condition: (_, siblingData)=>siblingData?.searchType === 'default' || siblingData?.searchType === 'mmr' || siblingData?.searchType === 'mixed' } } ] }, { name: 'knowledgeBase', type: 'group', fields: [ { name: 'integrations', type: 'blocks', blocks: [ LlmKbAzure, LlmKbConfluence, LlmKbDropbox, LlmKbGcs, LlmKbGithub, LlmKbGoogledrive, LlmKbJira, LlmKbS3, LlmKbSftp, LlmKbSharepoint, LlmKbSharepointCustom, LlmKbShopify, LlmKbSitemap, LlmKbSlack, LlmKbThron, LlmKbApi, LlmKbZendesk ], validate: validateIntegrations }, { name: 'externalEndpoints', type: 'array', fields: [ { name: 'endpointUrl', type: 'withText' }, { name: 'description', type: 'withText' }, { name: 'authentication', type: 'select', options: Object.entries(ExternalEndpointAuthentication).map(([k, v])=>({ value: v, label: k })) }, { name: 'authSecret', type: 'withText', admin: { condition: (_, siblingData)=>siblingData?.authentication === "basic" || siblingData?.authentication === "bearer" || siblingData?.authentication === "custom" } }, /* * temporarily removed { name: 'postProcessor', type: 'withText', defaultValue: 'default', admin: { components: { Field: EndpointPostProcessor, }, }, }, */ { name: 'fieldsMapping', type: 'group', fields: [ { name: 'replacedFields', type: 'array', fields: [ { name: 'srcName', type: 'text' }, { name: 'destName', type: 'text' } ] }, { name: 'newFields', type: 'array', fields: [ { name: 'name', type: 'text' }, { name: 'value', type: 'text' } ] }, { name: 'deletedFields', type: 'array', fields: [ { name: 'name', type: 'text' } ] }, { name: 'metaFields', type: 'array', fields: [ { name: 'name', type: 'text' }, { name: 'description', type: 'text' }, { name: 'type', type: 'select', options: [ 'int', 'float', 'string', 'bool' ] } ] } ] } ] }, { name: 'vectorDbType', type: 'withText', admin: { components: { Field: '@websolutespa/payload-plugin-bowl-llm/client#VectorDbType' } } }, { name: 'chunkingMethod', type: 'select', defaultValue: 'recursive', options: [ { label: 'MarkdownHeader', value: 'markdownHeader' }, { label: 'Recursive (Character)', value: 'recursive' }, { label: 'Token-based', value: 'token' } ] }, { name: 'chunkSize', type: 'number', defaultValue: 3000, min: 100 }, { name: 'chunkOverlap', type: 'number', defaultValue: 300, min: 0 }, { name: 'deepLevel', type: 'number', defaultValue: 3, min: 0 }, { name: 'vectorDbFile', type: 'relationship', relationTo: options.slug.llmVectorDb, // filter out vector db files that are not related to the current app filterOptions: ({ id })=>{ return { or: [ { llmApp: { equals: id } }, // avoid validation error with legacy vector db files that are not associated with any app { llmApp: { equals: null } }, { llmApp: { equals: false } } ] }; } } ] } ] } ] }; //# sourceMappingURL=Tool.js.map