@websolutespa/payload-plugin-bowl-llm
Version:
LLM plugin for Bowl PayloadCms plugin
609 lines (608 loc) • 24.6 kB
JavaScript
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