插 件 开 发

前置

  • nodejs有一定了解和使用

插件实例

此插件中存在注释用来帮助开发插件
ddg搜索插件仅为演示,如果要高精度搜索还需要爬虫或api实现

mcp 服务器目前调用方式为 llm的工具,未来会增加其他调用方式(如果需要

neo4j仅实现了插入功能,其他功能由于时间关系未实现, 如果有需要的用户可以提交Pr

支持

  • 支持自定义工作流节点
  • 支持自定义文件解析
  • 支持更换底层知识库引擎(原qdrant)
  • 支持知识库相关功能重写

  • 看下面之前请确认您已经看过上面三个仓库,这样您才知道下面的修改位置

工作流自定义节点

NODE_DEFINE

  • 用于自定义节点配置
  • 节点组件定义,节点验证,节点配置解析三合一
  • 实现节点配置时请确认您已经看过valibot文档并对其了解

如何设置输入/输出

  • 输入/输出参数是一个二维数组,用来方便设置

如果是一维数组的话,假如存在两个动态参数,那么就没法知道起始点和终点,无法正确插入和删除

  • 初始化时设置默认的输入/输出
 config: {
              type: 'demo1',
              inputs:[[{label:'测试',value:'test'}]]
            },
  • 字符串模板的动态参数,使用hook,在值变化时,获取变化值并解析返回
  Action.valueChange({
                // undefined表示监听自身 
                list: [undefined],
                debounceTime: 100,
                when: ([value]: string[], field) => {
                  // xxx{{xxx}}
                  field.context.changeHandleByTemplate(field, value, 1);
                },
              }),

调用changeHandleByTemplate表示解析输入值,并将变量插入到数组的第1项中,value为字符串

  • 动态设置输入/输出
 Action.valueChange({
                // undefined表示监听自身
                list: [undefined],
                debounceTime: 100,
                when: ([value]: string[], field) => {
                  // xxx{{xxx}}
                  (field.context as ComponentContext).changeHandleData(field, 'input', 1, [{ label: '测试', value: 'test' }]);
                },
              }),

runner

  • runner实现时需要继承extends input.provider.workflow.NodeRunnerBase否则很多方法和参数不方便获取
  • 在类的方法中获得实例
let instance=  this.injector.get(input.provider.root.xxxx)
  • 在类的属性构造时获取
class Demo{
 xxxInstance=input.inject(input.provider.root.xxxx)
}

获得配置(定义工作流节点时输入的)

this.getParsedNode(NODE_DEFINE(input.componentDefine))

模板解析

  • 字符串模板解析为正确输入
let instance = this.injector.get(input.provider.root.ChatService);
const chatInput = this.#chatUtil.interpolate(data.data.value, this.inputValueObject$());
  • data.data.value 定义的模板
  • this.inputValueObject$() 获得由其他节点提供的输入数据

返回多出口结果

  • 用于使用不同出口时,返回不同的数据,出口定义可参考上面的设置输出
return async (outputName:string) => {
return { value: 'demo' ,extra:undefine};
};
  • value表示返回的值,extra为一些额外的数据,可用于后面的节点或显示用,可选

服务重写/调用

  • input.provider.root 根级服务,可以在任意服务中调用(这里指工作流节点内,知识库)
  • input.provider.knowledge 知识库级,只能在知识库级中调用,无法在别处使用

重写

{
// 要重写的
provide: input.provider.root.FileParserToken,
// 替换或者是追加(只有FileParserToken可以追加)
multi: true,
// 重写为指定类,会自动初始化
useClass: class {}
// 重写为某个对象,不会实例化,与useClass冲突
useValue:{}
}
  • 如果要重写的是InjectionToken类型的,那么在useClass中不可以extends 这个token

调用

  • 在类的方法中获得实例
let instance=  this.injector.get(input.provider.root.xxxx)
  • 在类的属性构造时获取
class Demo{
 xxxInstance=input.inject(input.provider.root.xxxx)
}

其他

  • 关于插件的相关问题欢迎在此反馈