您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

use-config.ts 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import { useStrategyProviderDetail } from '@/service/use-strategy'
  2. import useNodeCrud from '../_base/hooks/use-node-crud'
  3. import useVarList from '../_base/hooks/use-var-list'
  4. import type { AgentNodeType } from './types'
  5. import {
  6. useIsChatMode,
  7. useNodesReadOnly,
  8. } from '@/app/components/workflow/hooks'
  9. import { useCallback, useEffect, useMemo } from 'react'
  10. import { type ToolVarInputs, VarType } from '../tool/types'
  11. import { useCheckInstalled, useFetchPluginsInMarketPlaceByIds } from '@/service/use-plugins'
  12. import type { Memory, Var } from '../../types'
  13. import { VarType as VarKindType } from '../../types'
  14. import useAvailableVarList from '../_base/hooks/use-available-var-list'
  15. import produce from 'immer'
  16. import { isSupportMCP } from '@/utils/plugin-version-feature'
  17. import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
  18. import { generateAgentToolValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
  19. export type StrategyStatus = {
  20. plugin: {
  21. source: 'external' | 'marketplace'
  22. installed: boolean
  23. }
  24. isExistInPlugin: boolean
  25. }
  26. export const useStrategyInfo = (
  27. strategyProviderName?: string,
  28. strategyName?: string,
  29. ) => {
  30. const strategyProvider = useStrategyProviderDetail(
  31. strategyProviderName || '',
  32. { retry: false },
  33. )
  34. const strategy = strategyProvider.data?.declaration.strategies.find(
  35. str => str.identity.name === strategyName,
  36. )
  37. const marketplace = useFetchPluginsInMarketPlaceByIds([strategyProviderName!], {
  38. retry: false,
  39. })
  40. const strategyStatus: StrategyStatus | undefined = useMemo(() => {
  41. if (strategyProvider.isLoading || marketplace.isLoading)
  42. return undefined
  43. const strategyExist = !!strategy
  44. const isPluginInstalled = !strategyProvider.isError
  45. const isInMarketplace = !!marketplace.data?.data.plugins.at(0)
  46. return {
  47. plugin: {
  48. source: isInMarketplace ? 'marketplace' : 'external',
  49. installed: isPluginInstalled,
  50. },
  51. isExistInPlugin: strategyExist,
  52. }
  53. }, [strategy, marketplace, strategyProvider.isError, strategyProvider.isLoading])
  54. const refetch = useCallback(() => {
  55. strategyProvider.refetch()
  56. marketplace.refetch()
  57. }, [marketplace, strategyProvider])
  58. return {
  59. strategyProvider,
  60. strategy,
  61. strategyStatus,
  62. refetch,
  63. }
  64. }
  65. const useConfig = (id: string, payload: AgentNodeType) => {
  66. const { nodesReadOnly: readOnly } = useNodesReadOnly()
  67. const { inputs, setInputs } = useNodeCrud<AgentNodeType>(id, payload)
  68. // variables
  69. const { handleVarListChange, handleAddVariable } = useVarList<AgentNodeType>({
  70. inputs,
  71. setInputs,
  72. })
  73. const {
  74. strategyStatus: currentStrategyStatus,
  75. strategy: currentStrategy,
  76. strategyProvider,
  77. } = useStrategyInfo(
  78. inputs.agent_strategy_provider_name,
  79. inputs.agent_strategy_name,
  80. )
  81. const pluginId = inputs.agent_strategy_provider_name?.split('/').splice(0, 2).join('/')
  82. const pluginDetail = useCheckInstalled({
  83. pluginIds: [pluginId!],
  84. enabled: Boolean(pluginId),
  85. })
  86. const formData = useMemo(() => {
  87. const paramNameList = (currentStrategy?.parameters || []).map(item => item.name)
  88. const res = Object.fromEntries(
  89. Object.entries(inputs.agent_parameters || {}).filter(([name]) => paramNameList.includes(name)).map(([key, value]) => {
  90. return [key, value.value]
  91. }),
  92. )
  93. return res
  94. }, [inputs.agent_parameters, currentStrategy?.parameters])
  95. const onFormChange = (value: Record<string, any>) => {
  96. const res: ToolVarInputs = {}
  97. Object.entries(value).forEach(([key, val]) => {
  98. res[key] = {
  99. type: VarType.constant,
  100. value: val,
  101. }
  102. })
  103. setInputs({
  104. ...inputs,
  105. agent_parameters: res,
  106. })
  107. }
  108. const formattingToolData = (data: any) => {
  109. const settingValues = generateAgentToolValue(data.settings, toolParametersToFormSchemas(data.schemas.filter((param: { form: string }) => param.form !== 'llm') as any))
  110. const paramValues = generateAgentToolValue(data.parameters, toolParametersToFormSchemas(data.schemas.filter((param: { form: string }) => param.form === 'llm') as any), true)
  111. const res = produce(data, (draft: any) => {
  112. draft.settings = settingValues
  113. draft.parameters = paramValues
  114. })
  115. return res
  116. }
  117. const formattingLegacyData = () => {
  118. if (inputs.version)
  119. return inputs
  120. const newData = produce(inputs, (draft) => {
  121. const schemas = currentStrategy?.parameters || []
  122. Object.keys(draft.agent_parameters || {}).forEach((key) => {
  123. const targetSchema = schemas.find(schema => schema.name === key)
  124. if (targetSchema?.type === FormTypeEnum.toolSelector)
  125. draft.agent_parameters![key].value = formattingToolData(draft.agent_parameters![key].value)
  126. if (targetSchema?.type === FormTypeEnum.multiToolSelector)
  127. draft.agent_parameters![key].value = draft.agent_parameters![key].value.map((tool: any) => formattingToolData(tool))
  128. })
  129. draft.version = '2'
  130. })
  131. return newData
  132. }
  133. // formatting legacy data
  134. useEffect(() => {
  135. if (!currentStrategy)
  136. return
  137. const newData = formattingLegacyData()
  138. setInputs(newData)
  139. // eslint-disable-next-line react-hooks/exhaustive-deps
  140. }, [currentStrategy])
  141. // vars
  142. const filterMemoryPromptVar = useCallback((varPayload: Var) => {
  143. return [
  144. VarKindType.arrayObject,
  145. VarKindType.array,
  146. VarKindType.number,
  147. VarKindType.string,
  148. VarKindType.secret,
  149. VarKindType.arrayString,
  150. VarKindType.arrayNumber,
  151. VarKindType.file,
  152. VarKindType.arrayFile,
  153. ].includes(varPayload.type)
  154. }, [])
  155. const {
  156. availableVars,
  157. availableNodesWithParent,
  158. } = useAvailableVarList(id, {
  159. onlyLeafNodeVar: false,
  160. filterVar: filterMemoryPromptVar,
  161. })
  162. // single run
  163. const outputSchema = useMemo(() => {
  164. const res: any[] = []
  165. if (!inputs.output_schema)
  166. return []
  167. Object.keys(inputs.output_schema.properties).forEach((outputKey) => {
  168. const output = inputs.output_schema.properties[outputKey]
  169. res.push({
  170. name: outputKey,
  171. type: output.type === 'array'
  172. ? `Array[${output.items?.type.slice(0, 1).toLocaleUpperCase()}${output.items?.type.slice(1)}]`
  173. : `${output.type.slice(0, 1).toLocaleUpperCase()}${output.type.slice(1)}`,
  174. description: output.description,
  175. })
  176. })
  177. return res
  178. }, [inputs.output_schema])
  179. const handleMemoryChange = useCallback((newMemory?: Memory) => {
  180. const newInputs = produce(inputs, (draft) => {
  181. draft.memory = newMemory
  182. })
  183. setInputs(newInputs)
  184. }, [inputs, setInputs])
  185. const isChatMode = useIsChatMode()
  186. return {
  187. readOnly,
  188. inputs,
  189. setInputs,
  190. handleVarListChange,
  191. handleAddVariable,
  192. currentStrategy,
  193. formData,
  194. onFormChange,
  195. currentStrategyStatus,
  196. strategyProvider: strategyProvider.data,
  197. pluginDetail: pluginDetail.data?.plugins.at(0),
  198. availableVars,
  199. availableNodesWithParent,
  200. outputSchema,
  201. handleMemoryChange,
  202. isChatMode,
  203. canChooseMCPTool: isSupportMCP(inputs.meta?.version),
  204. }
  205. }
  206. export default useConfig