parent
9c22bee991
commit
713ed26971
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { INodeParams, INodeCredential } from '../src/Interface'
|
||||||
|
|
||||||
|
class PostgresUrl implements INodeCredential {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
description: string
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'Postgres URL'
|
||||||
|
this.name = 'PostgresUrl'
|
||||||
|
this.version = 1.0
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'Postgres URL',
|
||||||
|
name: 'postgresUrl',
|
||||||
|
type: 'string',
|
||||||
|
placeholder: 'postgresql://localhost/mydb'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { credClass: PostgresUrl }
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { INodeParams, INodeCredential } from '../src/Interface'
|
||||||
|
|
||||||
|
class SlackApi implements INodeCredential {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
description: string
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'Slack API'
|
||||||
|
this.name = 'slackApi'
|
||||||
|
this.version = 1.0
|
||||||
|
this.description =
|
||||||
|
'Refer to <a target="_blank" href="https://github.com/modelcontextprotocol/servers/tree/main/src/slack">official guide</a> on how to get botToken and teamId on Slack'
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'Bot Token',
|
||||||
|
name: 'botToken',
|
||||||
|
type: 'password'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Team ID',
|
||||||
|
name: 'teamId',
|
||||||
|
type: 'string',
|
||||||
|
placeholder: '<SLACK_TEAM_ID>'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { credClass: SlackApi }
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { z } from 'zod'
|
||||||
|
import { INode } from '../../../src/Interface'
|
||||||
|
import { DynamicStructuredTool } from '../CustomTool/core'
|
||||||
|
|
||||||
|
const code = `
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// Format date as YYYY-MM-DD
|
||||||
|
const date = now.toISOString().split('T')[0];
|
||||||
|
|
||||||
|
// Get time in HH:MM:SS format
|
||||||
|
const time = now.toTimeString().split(' ')[0];
|
||||||
|
|
||||||
|
// Get day of week
|
||||||
|
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||||
|
const day = days[now.getDay()];
|
||||||
|
|
||||||
|
// Get timezone information
|
||||||
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
const timezoneOffset = now.getTimezoneOffset();
|
||||||
|
const timezoneOffsetHours = Math.abs(Math.floor(timezoneOffset / 60));
|
||||||
|
const timezoneOffsetMinutes = Math.abs(timezoneOffset % 60);
|
||||||
|
const timezoneOffsetFormatted =
|
||||||
|
(timezoneOffset <= 0 ? '+' : '-') +
|
||||||
|
timezoneOffsetHours.toString().padStart(2, '0') + ':' +
|
||||||
|
timezoneOffsetMinutes.toString().padStart(2, '0');
|
||||||
|
|
||||||
|
return {
|
||||||
|
date,
|
||||||
|
time,
|
||||||
|
day,
|
||||||
|
timezone,
|
||||||
|
timezoneOffset: timezoneOffsetFormatted,
|
||||||
|
iso8601: now.toISOString(),
|
||||||
|
unix_timestamp: Math.floor(now.getTime() / 1000)
|
||||||
|
};
|
||||||
|
`
|
||||||
|
|
||||||
|
class CurrentDateTime_Tools implements INode {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
description: string
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
baseClasses: string[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'CurrentDateTime'
|
||||||
|
this.name = 'currentDateTime'
|
||||||
|
this.version = 1.0
|
||||||
|
this.type = 'CurrentDateTime'
|
||||||
|
this.icon = 'currentDateTime.svg'
|
||||||
|
this.category = 'Tools'
|
||||||
|
this.description = 'Get todays day, date and time.'
|
||||||
|
this.baseClasses = [this.type, 'Tool']
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(): Promise<any> {
|
||||||
|
const obj = {
|
||||||
|
name: 'current_date_time',
|
||||||
|
description: 'Useful to get current day, date and time.',
|
||||||
|
schema: z.object({}),
|
||||||
|
code: code
|
||||||
|
}
|
||||||
|
|
||||||
|
let dynamicStructuredTool = new DynamicStructuredTool(obj)
|
||||||
|
|
||||||
|
return dynamicStructuredTool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { nodeClass: CurrentDateTime_Tools }
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-timezone"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M20.884 10.554a9 9 0 1 0 -10.337 10.328" /><path d="M3.6 9h16.8" /><path d="M3.6 15h6.9" /><path d="M11.5 3a17 17 0 0 0 -1.502 14.954" /><path d="M12.5 3a17 17 0 0 1 2.52 7.603" /><path d="M18 18m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" /><path d="M18 16.5v1.5l.5 .5" /></svg>
|
||||||
|
After Width: | Height: | Size: 588 B |
|
|
@ -0,0 +1,108 @@
|
||||||
|
import { Tool } from '@langchain/core/tools'
|
||||||
|
import { ICommonObject, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
|
||||||
|
import { getCredentialData, getCredentialParam, getNodeModulesPackagePath } from '../../../../src/utils'
|
||||||
|
import { MCPToolkit } from '../core'
|
||||||
|
|
||||||
|
class BraveSearch_MCP implements INode {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
description: string
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
baseClasses: string[]
|
||||||
|
documentation: string
|
||||||
|
credential: INodeParams
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'Brave Search MCP'
|
||||||
|
this.name = 'braveSearchMCP'
|
||||||
|
this.version = 1.0
|
||||||
|
this.type = 'BraveSearch MCP Tool'
|
||||||
|
this.icon = 'brave.svg'
|
||||||
|
this.category = 'Tools (MCP)'
|
||||||
|
this.description = 'MCP server that integrates the Brave Search API - a real-time API to access web search capabilities'
|
||||||
|
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search'
|
||||||
|
this.credential = {
|
||||||
|
label: 'Connect Credential',
|
||||||
|
name: 'credential',
|
||||||
|
type: 'credential',
|
||||||
|
credentialNames: ['braveSearchApi']
|
||||||
|
}
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'Available Actions',
|
||||||
|
name: 'mcpActions',
|
||||||
|
type: 'asyncMultiOptions',
|
||||||
|
loadMethod: 'listActions',
|
||||||
|
refresh: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
this.baseClasses = ['Tool']
|
||||||
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
loadMethods = {
|
||||||
|
listActions: async (nodeData: INodeData, options: ICommonObject): Promise<INodeOptionsValue[]> => {
|
||||||
|
try {
|
||||||
|
const toolset = await this.getTools(nodeData, options)
|
||||||
|
toolset.sort((a: any, b: any) => a.name.localeCompare(b.name))
|
||||||
|
|
||||||
|
return toolset.map(({ name, ...rest }) => ({
|
||||||
|
label: name.toUpperCase(),
|
||||||
|
name: name,
|
||||||
|
description: rest.description || name
|
||||||
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'No Available Actions',
|
||||||
|
name: 'error',
|
||||||
|
description: 'No available actions, please check your API key and refresh'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
|
const tools = await this.getTools(nodeData, options)
|
||||||
|
|
||||||
|
const _mcpActions = nodeData.inputs?.mcpActions
|
||||||
|
let mcpActions = []
|
||||||
|
if (_mcpActions) {
|
||||||
|
try {
|
||||||
|
mcpActions = typeof _mcpActions === 'string' ? JSON.parse(_mcpActions) : _mcpActions
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing mcp actions:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tools.filter((tool: any) => mcpActions.includes(tool.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTools(nodeData: INodeData, options: ICommonObject): Promise<Tool[]> {
|
||||||
|
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||||
|
const braveApiKey = getCredentialParam('braveApiKey', credentialData, nodeData)
|
||||||
|
const packagePath = getNodeModulesPackagePath('@modelcontextprotocol/server-brave-search/dist/index.js')
|
||||||
|
|
||||||
|
const serverParams = {
|
||||||
|
command: 'node',
|
||||||
|
args: [packagePath],
|
||||||
|
env: {
|
||||||
|
BRAVE_API_KEY: braveApiKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const toolkit = new MCPToolkit(serverParams, 'stdio')
|
||||||
|
await toolkit.initialize()
|
||||||
|
|
||||||
|
const tools = toolkit.tools ?? []
|
||||||
|
|
||||||
|
return tools as Tool[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { nodeClass: BraveSearch_MCP }
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M26.2866 9.22667L26.8999 7.73333C26.8999 7.73333 26.1333 6.9 25.1866 5.96C24.2399 5.02 22.2466 5.56 22.2466 5.56L19.9999 3H11.9999L9.73325 5.58C9.73325 5.58 7.73325 5.03333 6.79325 5.97333C5.85325 6.91333 5.07992 7.75333 5.07992 7.75333L5.69326 9.24667L4.91992 11.4533C4.91992 11.4533 7.20659 20.12 7.46659 21.1533C7.99992 23.2267 8.35326 24.0333 9.84659 25.1C11.3399 26.1667 14.0466 27.9733 14.5133 28.2533C14.9415 28.6183 15.4515 28.8745 15.9999 29C16.4933 29 17.0466 28.5267 17.4999 28.2533C17.9533 27.98 20.6533 26.14 22.1666 25.1C23.6799 24.06 23.9999 23.2467 24.5333 21.1533L27.0799 11.4533L26.2866 9.22667Z" fill="#FF6520" stroke="#FF6520" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12.4735 21.0133C11.7428 20.2529 11.1071 19.4067 10.5801 18.4933C10.4452 18.1438 10.3942 17.7674 10.4312 17.3946C10.4683 17.0217 10.5924 16.6628 10.7935 16.3466C10.8686 16.1363 10.8707 15.9067 10.7993 15.695C10.728 15.4833 10.5873 15.3019 10.4001 15.18C10.2068 14.9666 8.5868 13.2533 8.21346 12.8533C7.84013 12.4533 7.4668 12.2866 7.4668 11.52C7.4668 10.7533 10.3801 7.22665 10.3801 7.22665C10.3801 7.22665 12.8468 7.69998 13.1801 7.69998C13.7659 7.59152 14.3397 7.42629 14.8935 7.20665C15.2496 7.07842 15.6223 7.00208 16.0001 6.97998L14.8935 7.19998C15.2499 7.07402 15.6226 6.99993 16.0001 6.97998C16.3777 6.99993 16.7503 7.07402 17.1068 7.19998C17.6605 7.41963 18.2344 7.58485 18.8201 7.69331C19.1535 7.69331 21.6201 7.21998 21.6201 7.21998C21.6201 7.21998 24.5335 10.7466 24.5335 11.5133C24.5335 12.28 24.1601 12.46 23.7868 12.8466C23.4135 13.2333 21.7868 14.96 21.6001 15.1733C21.4129 15.2952 21.2723 15.4767 21.2009 15.6884C21.1295 15.9 21.1316 16.1296 21.2068 16.34C21.4079 16.6561 21.532 17.0151 21.569 17.3879C21.6061 17.7608 21.5551 18.1371 21.4201 18.4866C20.8932 19.4001 20.2574 20.2463 19.5268 21.0066" fill="white"/>
|
||||||
|
<path d="M21.46 9.87996C20.6375 9.74822 19.8011 9.72803 18.9733 9.81996C18.3639 9.94895 17.7696 10.1411 17.2 10.3933C17.1266 10.5266 17.0466 10.5266 17.1266 11.02C17.2066 11.5133 17.6733 13.82 17.7133 14.2333C17.7533 14.6466 17.8533 14.9 17.4 15.0266C16.926 15.1471 16.4451 15.2384 15.96 15.3C15.4749 15.2378 14.9941 15.1465 14.52 15.0266C14.0866 14.9266 14.1666 14.6466 14.2066 14.2333C14.2466 13.82 14.7 11.5133 14.8 11.02C14.9 10.5266 14.8 10.5266 14.72 10.3933C14.1516 10.1379 13.5569 9.94565 12.9466 9.81996C12.1193 9.71801 11.2814 9.73823 10.46 9.87996M16 19.1666V15.3333V19.1666ZM19.4266 20.72C19.6066 20.84 19.5066 21.0533 19.3333 21.1533C19.16 21.2533 16.9466 22.9866 16.7466 23.1866C16.5466 23.3866 16.22 23.68 16 23.68C15.78 23.68 15.4666 23.36 15.2533 23.1866C15.04 23.0133 12.8266 21.2733 12.6666 21.1533C12.5066 21.0333 12.3933 20.82 12.5733 20.72C12.7533 20.62 13.32 20.3266 14.0866 19.9133C14.6912 19.5865 15.3338 19.3357 16 19.1666C16.6661 19.3357 17.3087 19.5865 17.9133 19.9133L19.4266 20.72Z" fill="white"/>
|
||||||
|
<path d="M21.46 9.87996C20.6375 9.74822 19.8011 9.72803 18.9733 9.81996C18.3639 9.94895 17.7696 10.1411 17.2 10.3933C17.1266 10.5266 17.0466 10.5266 17.1266 11.02C17.2066 11.5133 17.6733 13.82 17.7133 14.2333C17.7533 14.6466 17.8533 14.9 17.4 15.0266C16.926 15.1471 16.4451 15.2384 15.96 15.3C15.4749 15.2378 14.9941 15.1465 14.52 15.0266C14.0866 14.9266 14.1666 14.6466 14.2066 14.2333C14.2466 13.82 14.7 11.5133 14.8 11.02C14.9 10.5266 14.8 10.5266 14.72 10.3933C14.1516 10.1379 13.5569 9.94565 12.9466 9.81996C12.1193 9.71801 11.2814 9.73823 10.46 9.87996M16 19.1666V15.3333M16 19.1666C15.3338 19.3357 14.6912 19.5865 14.0866 19.9133C13.32 20.3266 12.7533 20.62 12.5733 20.72C12.3933 20.82 12.5066 21.0333 12.6666 21.1533C12.8266 21.2733 15.04 23.0133 15.2533 23.1866C15.4666 23.36 15.78 23.68 16 23.68C16.22 23.68 16.5466 23.3866 16.7466 23.1866C16.9466 22.9866 19.16 21.2533 19.3333 21.1533C19.5066 21.0533 19.6066 20.84 19.4266 20.72L17.9133 19.9133C17.3087 19.5865 16.6661 19.3357 16 19.1666Z" stroke="#FF6520" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M18.839 21.7606C18.9867 21.672 19.1161 21.4053 18.9627 21.299L17.6582 20.6046C17.143 20.3149 16.5426 20.0811 15.9749 19.9313C15.4073 20.0811 14.8069 20.336 14.2917 20.6256C13.6383 20.9919 13.1932 21.2524 13.0398 21.341C12.8864 21.4297 13.0212 21.6543 13.1575 21.7606C13.2939 21.867 15.1801 23.4091 15.3619 23.5627C15.5438 23.7163 15.8108 23.9999 15.9983 23.9999C16.1858 23.9999 16.4641 23.74 16.6346 23.5627C16.805 23.3855 18.6913 21.8493 18.839 21.7606Z" fill="white"/>
|
||||||
|
<path d="M18.839 21.7606C18.9867 21.672 19.1161 21.4053 18.9627 21.299L17.6582 20.6046C17.143 20.3149 16.5426 20.0811 15.9749 19.9313C15.4073 20.0811 14.8069 20.336 14.2917 20.6256C13.6383 20.9919 13.1932 21.2524 13.0398 21.341C12.8864 21.4297 13.0212 21.6543 13.1575 21.7606C13.2939 21.867 15.1801 23.4091 15.3619 23.5627C15.5438 23.7163 15.8108 23.9999 15.9983 23.9999C16.1858 23.9999 16.4641 23.74 16.6346 23.5627C16.805 23.3855 18.6913 21.8493 18.839 21.7606Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
|
|
@ -0,0 +1,114 @@
|
||||||
|
import { Tool } from '@langchain/core/tools'
|
||||||
|
import { ICommonObject, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
|
||||||
|
import { getCredentialData, getCredentialParam, getNodeModulesPackagePath } from '../../../../src/utils'
|
||||||
|
import { MCPToolkit } from '../core'
|
||||||
|
|
||||||
|
class Github_MCP implements INode {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
description: string
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
baseClasses: string[]
|
||||||
|
documentation: string
|
||||||
|
credential: INodeParams
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'Github MCP'
|
||||||
|
this.name = 'githubMCP'
|
||||||
|
this.version = 1.0
|
||||||
|
this.type = 'Github MCP Tool'
|
||||||
|
this.icon = 'github.svg'
|
||||||
|
this.category = 'Tools (MCP)'
|
||||||
|
this.description = 'MCP Server for the GitHub API'
|
||||||
|
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/github'
|
||||||
|
this.credential = {
|
||||||
|
label: 'Connect Credential',
|
||||||
|
name: 'credential',
|
||||||
|
type: 'credential',
|
||||||
|
credentialNames: ['githubApi']
|
||||||
|
}
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'Available Actions',
|
||||||
|
name: 'mcpActions',
|
||||||
|
type: 'asyncMultiOptions',
|
||||||
|
loadMethod: 'listActions',
|
||||||
|
refresh: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
this.baseClasses = ['Tool']
|
||||||
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
loadMethods = {
|
||||||
|
listActions: async (nodeData: INodeData, options: ICommonObject): Promise<INodeOptionsValue[]> => {
|
||||||
|
try {
|
||||||
|
const toolset = await this.getTools(nodeData, options)
|
||||||
|
toolset.sort((a: any, b: any) => a.name.localeCompare(b.name))
|
||||||
|
|
||||||
|
return toolset.map(({ name, ...rest }) => ({
|
||||||
|
label: name.toUpperCase(),
|
||||||
|
name: name,
|
||||||
|
description: rest.description || name
|
||||||
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error listing actions:', error)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'No Available Actions',
|
||||||
|
name: 'error',
|
||||||
|
description: 'No available actions, please check your Github Access Token and refresh'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
|
const tools = await this.getTools(nodeData, options)
|
||||||
|
|
||||||
|
const _mcpActions = nodeData.inputs?.mcpActions
|
||||||
|
let mcpActions = []
|
||||||
|
if (_mcpActions) {
|
||||||
|
try {
|
||||||
|
mcpActions = typeof _mcpActions === 'string' ? JSON.parse(_mcpActions) : _mcpActions
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing mcp actions:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tools.filter((tool: any) => mcpActions.includes(tool.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTools(nodeData: INodeData, options: ICommonObject): Promise<Tool[]> {
|
||||||
|
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||||
|
const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
|
||||||
|
|
||||||
|
if (!accessToken) {
|
||||||
|
throw new Error('Missing Github Access Token')
|
||||||
|
}
|
||||||
|
|
||||||
|
const packagePath = getNodeModulesPackagePath('@modelcontextprotocol/server-github/dist/index.js')
|
||||||
|
|
||||||
|
const serverParams = {
|
||||||
|
command: 'node',
|
||||||
|
args: [packagePath],
|
||||||
|
env: {
|
||||||
|
GITHUB_PERSONAL_ACCESS_TOKEN: accessToken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const toolkit = new MCPToolkit(serverParams, 'stdio')
|
||||||
|
await toolkit.initialize()
|
||||||
|
|
||||||
|
const tools = toolkit.tools ?? []
|
||||||
|
|
||||||
|
return tools as Tool[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { nodeClass: Github_MCP }
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_115_14646)">
|
||||||
|
<path d="M13.9788 7C13.3909 6.0801 12.5809 5.32307 11.6234 4.79876C10.6658 4.27445 9.59167 3.99974 8.5 4C8.0144 4.83956 7.72314 5.77729 7.64765 6.74423C7.57215 7.71117 7.71434 8.68274 8.06375 9.5875C7.37968 10.5949 7.00951 11.7824 7 13V14C7 15.5913 7.63214 17.1174 8.75736 18.2426C9.88258 19.3679 11.4087 20 13 20H19C20.5913 20 22.1174 19.3679 23.2426 18.2426C24.3679 17.1174 25 15.5913 25 14V13C24.9905 11.7824 24.6203 10.5949 23.9363 9.5875C24.2857 8.68274 24.4278 7.71117 24.3524 6.74423C24.2769 5.77729 23.9856 4.83956 23.5 4C22.4083 3.99974 21.3342 4.27445 20.3766 4.79876C19.4191 5.32307 18.6091 6.0801 18.0212 7H13.9788Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12 29V24C12 21.7909 13.7909 20 16 20V20C18.2091 20 20 21.7909 20 24V29" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12 26H10C8.93913 26 7.92172 25.5786 7.17157 24.8284C6.42143 24.0783 6 23.0609 6 22C6 20.9391 5.57857 19.9217 4.82843 19.1716C4.07828 18.4214 3.06087 18 2 18" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12 26H10C7.79086 26 6 24.2091 6 22V22C6 19.7909 4.20914 18 2 18V18" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_115_14646">
|
||||||
|
<rect width="32" height="32" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,111 @@
|
||||||
|
import { Tool } from '@langchain/core/tools'
|
||||||
|
import { ICommonObject, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
|
||||||
|
import { getCredentialData, getCredentialParam, getNodeModulesPackagePath } from '../../../../src/utils'
|
||||||
|
import { MCPToolkit } from '../core'
|
||||||
|
|
||||||
|
class PostgreSQL_MCP implements INode {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
description: string
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
baseClasses: string[]
|
||||||
|
credential: INodeParams
|
||||||
|
documentation: string
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'PostgreSQL MCP'
|
||||||
|
this.name = 'postgreSQLMCP'
|
||||||
|
this.version = 1.0
|
||||||
|
this.type = 'PostgreSQL MCP Tool'
|
||||||
|
this.icon = 'postgres.svg'
|
||||||
|
this.category = 'Tools (MCP)'
|
||||||
|
this.description = 'MCP server that provides read-only access to PostgreSQL databases'
|
||||||
|
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/postgres'
|
||||||
|
this.credential = {
|
||||||
|
label: 'Connect Credential',
|
||||||
|
name: 'credential',
|
||||||
|
type: 'credential',
|
||||||
|
credentialNames: ['PostgresUrl']
|
||||||
|
}
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'Available Actions',
|
||||||
|
name: 'mcpActions',
|
||||||
|
type: 'asyncMultiOptions',
|
||||||
|
loadMethod: 'listActions',
|
||||||
|
refresh: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
this.baseClasses = ['Tool']
|
||||||
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
loadMethods = {
|
||||||
|
listActions: async (nodeData: INodeData, options: ICommonObject): Promise<INodeOptionsValue[]> => {
|
||||||
|
try {
|
||||||
|
const toolset = await this.getTools(nodeData, options)
|
||||||
|
toolset.sort((a: any, b: any) => a.name.localeCompare(b.name))
|
||||||
|
|
||||||
|
return toolset.map(({ name, ...rest }) => ({
|
||||||
|
label: name.toUpperCase(),
|
||||||
|
name: name,
|
||||||
|
description: rest.description || name
|
||||||
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error listing actions:', error)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'No Available Actions',
|
||||||
|
name: 'error',
|
||||||
|
description: 'No available actions, please check your postgres url and refresh'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
|
const tools = await this.getTools(nodeData, options)
|
||||||
|
|
||||||
|
const _mcpActions = nodeData.inputs?.mcpActions
|
||||||
|
let mcpActions = []
|
||||||
|
if (_mcpActions) {
|
||||||
|
try {
|
||||||
|
mcpActions = typeof _mcpActions === 'string' ? JSON.parse(_mcpActions) : _mcpActions
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing mcp actions:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tools.filter((tool: any) => mcpActions.includes(tool.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTools(nodeData: INodeData, options: ICommonObject): Promise<Tool[]> {
|
||||||
|
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||||
|
const postgresUrl = getCredentialParam('postgresUrl', credentialData, nodeData)
|
||||||
|
|
||||||
|
if (!postgresUrl) {
|
||||||
|
throw new Error('No postgres url provided')
|
||||||
|
}
|
||||||
|
|
||||||
|
const packagePath = getNodeModulesPackagePath('@modelcontextprotocol/server-postgres/dist/index.js')
|
||||||
|
|
||||||
|
const serverParams = {
|
||||||
|
command: 'node',
|
||||||
|
args: [packagePath, postgresUrl]
|
||||||
|
}
|
||||||
|
|
||||||
|
const toolkit = new MCPToolkit(serverParams, 'stdio')
|
||||||
|
await toolkit.initialize()
|
||||||
|
|
||||||
|
const tools = toolkit.tools ?? []
|
||||||
|
|
||||||
|
return tools as Tool[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { nodeClass: PostgreSQL_MCP }
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.8 KiB |
|
|
@ -0,0 +1,116 @@
|
||||||
|
import { Tool } from '@langchain/core/tools'
|
||||||
|
import { ICommonObject, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
|
||||||
|
import { getCredentialData, getCredentialParam, getNodeModulesPackagePath } from '../../../../src/utils'
|
||||||
|
import { MCPToolkit } from '../core'
|
||||||
|
|
||||||
|
class Slack_MCP implements INode {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
version: number
|
||||||
|
description: string
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
baseClasses: string[]
|
||||||
|
documentation: string
|
||||||
|
credential: INodeParams
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'Slack MCP'
|
||||||
|
this.name = 'slackMCP'
|
||||||
|
this.version = 1.0
|
||||||
|
this.type = 'Slack MCP Tool'
|
||||||
|
this.icon = 'slack.svg'
|
||||||
|
this.category = 'Tools (MCP)'
|
||||||
|
this.description = 'MCP Server for the Slack API'
|
||||||
|
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/slack'
|
||||||
|
this.credential = {
|
||||||
|
label: 'Connect Credential',
|
||||||
|
name: 'credential',
|
||||||
|
type: 'credential',
|
||||||
|
credentialNames: ['slackApi']
|
||||||
|
}
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'Available Actions',
|
||||||
|
name: 'mcpActions',
|
||||||
|
type: 'asyncMultiOptions',
|
||||||
|
loadMethod: 'listActions',
|
||||||
|
refresh: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
this.baseClasses = ['Tool']
|
||||||
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
loadMethods = {
|
||||||
|
listActions: async (nodeData: INodeData, options: ICommonObject): Promise<INodeOptionsValue[]> => {
|
||||||
|
try {
|
||||||
|
const toolset = await this.getTools(nodeData, options)
|
||||||
|
toolset.sort((a: any, b: any) => a.name.localeCompare(b.name))
|
||||||
|
|
||||||
|
return toolset.map(({ name, ...rest }) => ({
|
||||||
|
label: name.toUpperCase(),
|
||||||
|
name: name,
|
||||||
|
description: rest.description || name
|
||||||
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error listing actions:', error)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'No Available Actions',
|
||||||
|
name: 'error',
|
||||||
|
description: 'No available actions, please check your Slack Bot Token and refresh'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
|
const tools = await this.getTools(nodeData, options)
|
||||||
|
|
||||||
|
const _mcpActions = nodeData.inputs?.mcpActions
|
||||||
|
let mcpActions = []
|
||||||
|
if (_mcpActions) {
|
||||||
|
try {
|
||||||
|
mcpActions = typeof _mcpActions === 'string' ? JSON.parse(_mcpActions) : _mcpActions
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing mcp actions:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tools.filter((tool: any) => mcpActions.includes(tool.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTools(nodeData: INodeData, options: ICommonObject): Promise<Tool[]> {
|
||||||
|
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||||
|
const botToken = getCredentialParam('botToken', credentialData, nodeData)
|
||||||
|
const teamId = getCredentialParam('teamId', credentialData, nodeData)
|
||||||
|
|
||||||
|
if (!botToken || !teamId) {
|
||||||
|
throw new Error('Missing Credentials')
|
||||||
|
}
|
||||||
|
|
||||||
|
const packagePath = getNodeModulesPackagePath('@modelcontextprotocol/server-slack/dist/index.js')
|
||||||
|
|
||||||
|
const serverParams = {
|
||||||
|
command: 'node',
|
||||||
|
args: [packagePath],
|
||||||
|
env: {
|
||||||
|
SLACK_BOT_TOKEN: botToken,
|
||||||
|
SLACK_TEAM_ID: teamId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const toolkit = new MCPToolkit(serverParams, 'stdio')
|
||||||
|
await toolkit.initialize()
|
||||||
|
|
||||||
|
const tools = toolkit.tools ?? []
|
||||||
|
|
||||||
|
return tools as Tool[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { nodeClass: Slack_MCP }
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<svg enable-background="new 0 0 2447.6 2452.5" viewBox="0 0 2447.6 2452.5" xmlns="http://www.w3.org/2000/svg"><g clip-rule="evenodd" fill-rule="evenodd"><path d="m897.4 0c-135.3.1-244.8 109.9-244.7 245.2-.1 135.3 109.5 245.1 244.8 245.2h244.8v-245.1c.1-135.3-109.5-245.1-244.9-245.3.1 0 .1 0 0 0m0 654h-652.6c-135.3.1-244.9 109.9-244.8 245.2-.2 135.3 109.4 245.1 244.7 245.3h652.7c135.3-.1 244.9-109.9 244.8-245.2.1-135.4-109.5-245.2-244.8-245.3z" fill="#36c5f0"/><path d="m2447.6 899.2c.1-135.3-109.5-245.1-244.8-245.2-135.3.1-244.9 109.9-244.8 245.2v245.3h244.8c135.3-.1 244.9-109.9 244.8-245.3zm-652.7 0v-654c.1-135.2-109.4-245-244.7-245.2-135.3.1-244.9 109.9-244.8 245.2v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.3z" fill="#2eb67d"/><path d="m1550.1 2452.5c135.3-.1 244.9-109.9 244.8-245.2.1-135.3-109.5-245.1-244.8-245.2h-244.8v245.2c-.1 135.2 109.5 245 244.8 245.2zm0-654.1h652.7c135.3-.1 244.9-109.9 244.8-245.2.2-135.3-109.4-245.1-244.7-245.3h-652.7c-135.3.1-244.9 109.9-244.8 245.2-.1 135.4 109.4 245.2 244.7 245.3z" fill="#ecb22e"/><path d="m0 1553.2c-.1 135.3 109.5 245.1 244.8 245.2 135.3-.1 244.9-109.9 244.8-245.2v-245.2h-244.8c-135.3.1-244.9 109.9-244.8 245.2zm652.7 0v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.2v-653.9c.2-135.3-109.4-245.1-244.7-245.3-135.4 0-244.9 109.8-244.8 245.1 0 0 0 .1 0 0" fill="#e01e5a"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,104 @@
|
||||||
|
import { CallToolRequest, CallToolResultSchema, ListToolsResult, ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js'
|
||||||
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
||||||
|
import { StdioClientTransport, StdioServerParameters } from '@modelcontextprotocol/sdk/client/stdio.js'
|
||||||
|
import { BaseToolkit, tool, Tool } from '@langchain/core/tools'
|
||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export class MCPToolkit extends BaseToolkit {
|
||||||
|
tools: Tool[] = []
|
||||||
|
_tools: ListToolsResult | null = null
|
||||||
|
model_config: any
|
||||||
|
transport: StdioClientTransport | null = null
|
||||||
|
client: Client | null = null
|
||||||
|
constructor(serverParams: StdioServerParameters | any, transport: 'stdio' | 'sse') {
|
||||||
|
super()
|
||||||
|
if (transport === 'stdio') {
|
||||||
|
this.transport = new StdioClientTransport(serverParams as StdioServerParameters)
|
||||||
|
} else {
|
||||||
|
//this.transport = new SSEClientTransport(serverParams.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async initialize() {
|
||||||
|
if (this._tools === null) {
|
||||||
|
this.client = new Client(
|
||||||
|
{
|
||||||
|
name: 'langchain-js-client',
|
||||||
|
version: '1.0.0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
capabilities: {}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (this.transport === null) {
|
||||||
|
throw new Error('Transport is not initialized')
|
||||||
|
}
|
||||||
|
await this.client.connect(this.transport)
|
||||||
|
this._tools = await this.client.request({ method: 'tools/list' }, ListToolsResultSchema)
|
||||||
|
|
||||||
|
this.tools = await this.get_tools()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_tools(): Promise<Tool[]> {
|
||||||
|
if (this._tools === null || this.client === null) {
|
||||||
|
throw new Error('Must initialize the toolkit first')
|
||||||
|
}
|
||||||
|
const toolsPromises = this._tools.tools.map(async (tool: any) => {
|
||||||
|
if (this.client === null) {
|
||||||
|
throw new Error('Client is not initialized')
|
||||||
|
}
|
||||||
|
return await MCPTool({
|
||||||
|
client: this.client,
|
||||||
|
name: tool.name,
|
||||||
|
description: tool.description || '',
|
||||||
|
argsSchema: createSchemaModel(tool.inputSchema)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return Promise.all(toolsPromises)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function MCPTool({
|
||||||
|
client,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
argsSchema
|
||||||
|
}: {
|
||||||
|
client: Client
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
argsSchema: any
|
||||||
|
}): Promise<Tool> {
|
||||||
|
return tool(
|
||||||
|
async (input): Promise<string> => {
|
||||||
|
const req: CallToolRequest = { method: 'tools/call', params: { name: name, arguments: input } }
|
||||||
|
const res = await client.request(req, CallToolResultSchema)
|
||||||
|
const content = res.content
|
||||||
|
const contentString = JSON.stringify(content)
|
||||||
|
return contentString
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
description: description,
|
||||||
|
schema: argsSchema
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSchemaModel(
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object'
|
||||||
|
properties?: import('zod').objectOutputType<{}, import('zod').ZodTypeAny, 'passthrough'> | undefined
|
||||||
|
} & { [k: string]: unknown }
|
||||||
|
): any {
|
||||||
|
if (inputSchema.type !== 'object' || !inputSchema.properties) {
|
||||||
|
throw new Error('Invalid schema type or missing properties')
|
||||||
|
}
|
||||||
|
|
||||||
|
const schemaProperties = Object.entries(inputSchema.properties).reduce((acc, [key, _]) => {
|
||||||
|
acc[key] = z.any()
|
||||||
|
return acc
|
||||||
|
}, {} as Record<string, import('zod').ZodTypeAny>)
|
||||||
|
|
||||||
|
return z.object(schemaProperties)
|
||||||
|
}
|
||||||
|
|
@ -59,6 +59,11 @@
|
||||||
"@langchain/xai": "^0.0.1",
|
"@langchain/xai": "^0.0.1",
|
||||||
"@mendable/firecrawl-js": "^0.0.28",
|
"@mendable/firecrawl-js": "^0.0.28",
|
||||||
"@mistralai/mistralai": "0.1.3",
|
"@mistralai/mistralai": "0.1.3",
|
||||||
|
"@modelcontextprotocol/sdk": "^1.6.1",
|
||||||
|
"@modelcontextprotocol/server-brave-search": "^0.6.2",
|
||||||
|
"@modelcontextprotocol/server-github": "^2025.1.23",
|
||||||
|
"@modelcontextprotocol/server-postgres": "^0.6.2",
|
||||||
|
"@modelcontextprotocol/server-slack": "^2025.1.17",
|
||||||
"@notionhq/client": "^2.2.8",
|
"@notionhq/client": "^2.2.8",
|
||||||
"@opensearch-project/opensearch": "^1.2.0",
|
"@opensearch-project/opensearch": "^1.2.0",
|
||||||
"@pinecone-database/pinecone": "4.0.0",
|
"@pinecone-database/pinecone": "4.0.0",
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ export interface IUsedTool {
|
||||||
toolInput: object
|
toolInput: object
|
||||||
toolOutput: string | object
|
toolOutput: string | object
|
||||||
sourceDocuments?: ICommonObject[]
|
sourceDocuments?: ICommonObject[]
|
||||||
|
error?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMultiAgentNode {
|
export interface IMultiAgentNode {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import {
|
||||||
} from 'langchain/agents'
|
} from 'langchain/agents'
|
||||||
import { formatLogToString } from 'langchain/agents/format_scratchpad/log'
|
import { formatLogToString } from 'langchain/agents/format_scratchpad/log'
|
||||||
import { IUsedTool } from './Interface'
|
import { IUsedTool } from './Interface'
|
||||||
|
import { getErrorMessage } from './error'
|
||||||
|
|
||||||
export const SOURCE_DOCUMENTS_PREFIX = '\n\n----FLOWISE_SOURCE_DOCUMENTS----\n\n'
|
export const SOURCE_DOCUMENTS_PREFIX = '\n\n----FLOWISE_SOURCE_DOCUMENTS----\n\n'
|
||||||
export const ARTIFACTS_PREFIX = '\n\n----FLOWISE_ARTIFACTS----\n\n'
|
export const ARTIFACTS_PREFIX = '\n\n----FLOWISE_ARTIFACTS----\n\n'
|
||||||
|
|
@ -463,7 +464,21 @@ export class AgentExecutor extends BaseChain<ChainValues, AgentExecutorOutput> {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
observation = await new ExceptionTool().call(observation, runManager?.getChild())
|
observation = await new ExceptionTool().call(observation, runManager?.getChild())
|
||||||
|
usedTools.push({
|
||||||
|
tool: tool.name,
|
||||||
|
toolInput: action.toolInput as any,
|
||||||
|
toolOutput: '',
|
||||||
|
error: getErrorMessage(e)
|
||||||
|
})
|
||||||
return { action, observation: observation ?? '' }
|
return { action, observation: observation ?? '' }
|
||||||
|
} else {
|
||||||
|
usedTools.push({
|
||||||
|
tool: tool.name,
|
||||||
|
toolInput: action.toolInput as any,
|
||||||
|
toolOutput: '',
|
||||||
|
error: getErrorMessage(e)
|
||||||
|
})
|
||||||
|
return { action, observation: getErrorMessage(e) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeof observation === 'string' && observation.includes(SOURCE_DOCUMENTS_PREFIX)) {
|
if (typeof observation === 'string' && observation.includes(SOURCE_DOCUMENTS_PREFIX)) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
type ErrorWithMessage = {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const isErrorWithMessage = (error: unknown): error is ErrorWithMessage => {
|
||||||
|
return (
|
||||||
|
typeof error === 'object' && error !== null && 'message' in error && typeof (error as Record<string, unknown>).message === 'string'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const toErrorWithMessage = (maybeError: unknown): ErrorWithMessage => {
|
||||||
|
if (isErrorWithMessage(maybeError)) return maybeError
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new Error(JSON.stringify(maybeError))
|
||||||
|
} catch {
|
||||||
|
// fallback in case there's an error stringifying the maybeError
|
||||||
|
// like with circular references for example.
|
||||||
|
return new Error(String(maybeError))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getErrorMessage = (error: unknown) => {
|
||||||
|
return toErrorWithMessage(error).message
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ import { createPortal } from 'react-dom'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { Dialog, DialogContent, DialogTitle } from '@mui/material'
|
import { Box, Dialog, DialogContent, DialogTitle, Typography } from '@mui/material'
|
||||||
import ReactJson from 'flowise-react-json-view'
|
import ReactJson from 'flowise-react-json-view'
|
||||||
|
|
||||||
const SourceDocDialog = ({ show, dialogProps, onCancel }) => {
|
const SourceDocDialog = ({ show, dialogProps, onCancel }) => {
|
||||||
|
|
@ -32,6 +32,25 @@ const SourceDocDialog = ({ show, dialogProps, onCancel }) => {
|
||||||
{dialogProps.title ?? 'Source Documents'}
|
{dialogProps.title ?? 'Source Documents'}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
{data.error && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 2,
|
||||||
|
borderRadius: 1,
|
||||||
|
bgcolor: 'error.light',
|
||||||
|
color: 'error.dark',
|
||||||
|
overflowX: 'auto',
|
||||||
|
wordBreak: 'break-word'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant='body2' fontWeight='medium'>
|
||||||
|
Error:
|
||||||
|
</Typography>
|
||||||
|
<Typography variant='body2' sx={{ whiteSpace: 'pre-wrap' }}>
|
||||||
|
{data.error}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
<ReactJson
|
<ReactJson
|
||||||
theme={customization.isDarkMode ? 'ocean' : 'rjv-default'}
|
theme={customization.isDarkMode ? 'ocean' : 'rjv-default'}
|
||||||
style={{ padding: 10, borderRadius: 10 }}
|
style={{ padding: 10, borderRadius: 10 }}
|
||||||
|
|
|
||||||
|
|
@ -1214,10 +1214,30 @@ const ViewMessagesDialog = ({ show, dialogProps, onCancel }) => {
|
||||||
key={index}
|
key={index}
|
||||||
label={tool.tool}
|
label={tool.tool}
|
||||||
component='a'
|
component='a'
|
||||||
sx={{ mr: 1, mt: 1 }}
|
sx={{
|
||||||
|
mr: 1,
|
||||||
|
mt: 1,
|
||||||
|
borderColor: tool.error
|
||||||
|
? 'error.main'
|
||||||
|
: undefined,
|
||||||
|
color: tool.error
|
||||||
|
? 'error.main'
|
||||||
|
: undefined
|
||||||
|
}}
|
||||||
variant='outlined'
|
variant='outlined'
|
||||||
clickable
|
clickable
|
||||||
icon={<IconTool size={15} />}
|
icon={
|
||||||
|
<IconTool
|
||||||
|
size={15}
|
||||||
|
color={
|
||||||
|
tool.error
|
||||||
|
? theme.palette
|
||||||
|
.error
|
||||||
|
.main
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
onSourceDialogClick(
|
onSourceDialogClick(
|
||||||
tool,
|
tool,
|
||||||
|
|
@ -1407,9 +1427,24 @@ const ViewMessagesDialog = ({ show, dialogProps, onCancel }) => {
|
||||||
key={index}
|
key={index}
|
||||||
label={tool.tool}
|
label={tool.tool}
|
||||||
component='a'
|
component='a'
|
||||||
sx={{ mr: 1, mt: 1 }}
|
sx={{
|
||||||
|
mr: 1,
|
||||||
|
mt: 1,
|
||||||
|
borderColor: tool.error ? 'error.main' : undefined,
|
||||||
|
color: tool.error ? 'error.main' : undefined
|
||||||
|
}}
|
||||||
variant='outlined'
|
variant='outlined'
|
||||||
clickable
|
clickable
|
||||||
|
icon={
|
||||||
|
<IconTool
|
||||||
|
size={15}
|
||||||
|
color={
|
||||||
|
tool.error
|
||||||
|
? theme.palette.error.main
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
onClick={() => onSourceDialogClick(tool, 'Used Tools')}
|
onClick={() => onSourceDialogClick(tool, 'Used Tools')}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1677,10 +1677,24 @@ export const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, preview
|
||||||
key={index}
|
key={index}
|
||||||
label={tool.tool}
|
label={tool.tool}
|
||||||
component='a'
|
component='a'
|
||||||
sx={{ mr: 1, mt: 1 }}
|
sx={{
|
||||||
|
mr: 1,
|
||||||
|
mt: 1,
|
||||||
|
borderColor: tool.error ? 'error.main' : undefined,
|
||||||
|
color: tool.error ? 'error.main' : undefined
|
||||||
|
}}
|
||||||
variant='outlined'
|
variant='outlined'
|
||||||
clickable
|
clickable
|
||||||
icon={<IconTool size={15} />}
|
icon={
|
||||||
|
<IconTool
|
||||||
|
size={15}
|
||||||
|
color={
|
||||||
|
tool.error
|
||||||
|
? theme.palette.error.main
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
onClick={() => onSourceDialogClick(tool, 'Used Tools')}
|
onClick={() => onSourceDialogClick(tool, 'Used Tools')}
|
||||||
/>
|
/>
|
||||||
) : null
|
) : null
|
||||||
|
|
@ -1808,10 +1822,20 @@ export const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, preview
|
||||||
key={index}
|
key={index}
|
||||||
label={tool.tool}
|
label={tool.tool}
|
||||||
component='a'
|
component='a'
|
||||||
sx={{ mr: 1, mt: 1 }}
|
sx={{
|
||||||
|
mr: 1,
|
||||||
|
mt: 1,
|
||||||
|
borderColor: tool.error ? 'error.main' : undefined,
|
||||||
|
color: tool.error ? 'error.main' : undefined
|
||||||
|
}}
|
||||||
variant='outlined'
|
variant='outlined'
|
||||||
clickable
|
clickable
|
||||||
icon={<IconTool size={15} />}
|
icon={
|
||||||
|
<IconTool
|
||||||
|
size={15}
|
||||||
|
color={tool.error ? theme.palette.error.main : undefined}
|
||||||
|
/>
|
||||||
|
}
|
||||||
onClick={() => onSourceDialogClick(tool, 'Used Tools')}
|
onClick={() => onSourceDialogClick(tool, 'Used Tools')}
|
||||||
/>
|
/>
|
||||||
) : null
|
) : null
|
||||||
|
|
|
||||||
578
pnpm-lock.yaml
578
pnpm-lock.yaml
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue