Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

use-config.ts 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
  17. import { isSupportMCP } from '@/utils/plugin-version-feature'
  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 getParamVarType = useCallback((paramName: string) => {
  96. const isVariable = currentStrategy?.parameters.some(
  97. param => param.name === paramName && param.type === FormTypeEnum.any,
  98. )
  99. if (isVariable) return VarType.variable
  100. return VarType.constant
  101. }, [currentStrategy?.parameters])
  102. const onFormChange = (value: Record<string, any>) => {
  103. const res: ToolVarInputs = {}
  104. Object.entries(value).forEach(([key, val]) => {
  105. res[key] = {
  106. type: getParamVarType(key),
  107. value: val,
  108. }
  109. })
  110. setInputs({
  111. ...inputs,
  112. agent_parameters: res,
  113. })
  114. }
  115. const formattingToolData = (data: any) => {
  116. const settingValues = generateAgentToolValue(data.settings, toolParametersToFormSchemas(data.schemas.filter((param: { form: string }) => param.form !== 'llm') as any))
  117. const paramValues = generateAgentToolValue(data.parameters, toolParametersToFormSchemas(data.schemas.filter((param: { form: string }) => param.form === 'llm') as any), true)
  118. const res = produce(data, (draft: any) => {
  119. draft.settings = settingValues
  120. draft.parameters = paramValues
  121. })
  122. return res
  123. }
  124. const formattingLegacyData = () => {
  125. if (inputs.version || inputs.tool_node_version)
  126. return inputs
  127. const newData = produce(inputs, (draft) => {
  128. const schemas = currentStrategy?.parameters || []
  129. Object.keys(draft.agent_parameters || {}).forEach((key) => {
  130. const targetSchema = schemas.find(schema => schema.name === key)
  131. if (targetSchema?.type === FormTypeEnum.toolSelector)
  132. draft.agent_parameters![key].value = formattingToolData(draft.agent_parameters![key].value)
  133. if (targetSchema?.type === FormTypeEnum.multiToolSelector)
  134. draft.agent_parameters![key].value = draft.agent_parameters![key].value.map((tool: any) => formattingToolData(tool))
  135. })
  136. draft.tool_node_version = '2'
  137. })
  138. return newData
  139. }
  140. // formatting legacy data
  141. useEffect(() => {
  142. if (!currentStrategy)
  143. return
  144. const newData = formattingLegacyData()
  145. setInputs(newData)
  146. // eslint-disable-next-line react-hooks/exhaustive-deps
  147. }, [currentStrategy])
  148. // vars
  149. const filterMemoryPromptVar = useCallback((varPayload: Var) => {
  150. return [
  151. VarKindType.arrayObject,
  152. VarKindType.array,
  153. VarKindType.number,
  154. VarKindType.string,
  155. VarKindType.secret,
  156. VarKindType.arrayString,
  157. VarKindType.arrayNumber,
  158. VarKindType.file,
  159. VarKindType.arrayFile,
  160. ].includes(varPayload.type)
  161. }, [])
  162. const {
  163. availableVars,
  164. availableNodesWithParent,
  165. } = useAvailableVarList(id, {
  166. onlyLeafNodeVar: false,
  167. filterVar: filterMemoryPromptVar,
  168. })
  169. // single run
  170. const outputSchema = useMemo(() => {
  171. const res: any[] = []
  172. if (!inputs.output_schema)
  173. return []
  174. Object.keys(inputs.output_schema.properties).forEach((outputKey) => {
  175. const output = inputs.output_schema.properties[outputKey]
  176. res.push({
  177. name: outputKey,
  178. type: output.type === 'array'
  179. ? `Array[${output.items?.type.slice(0, 1).toLocaleUpperCase()}${output.items?.type.slice(1)}]`
  180. : `${output.type.slice(0, 1).toLocaleUpperCase()}${output.type.slice(1)}`,
  181. description: output.description,
  182. })
  183. })
  184. return res
  185. }, [inputs.output_schema])
  186. const handleMemoryChange = useCallback((newMemory?: Memory) => {
  187. const newInputs = produce(inputs, (draft) => {
  188. draft.memory = newMemory
  189. })
  190. setInputs(newInputs)
  191. }, [inputs, setInputs])
  192. const isChatMode = useIsChatMode()
  193. return {
  194. readOnly,
  195. inputs,
  196. setInputs,
  197. handleVarListChange,
  198. handleAddVariable,
  199. currentStrategy,
  200. formData,
  201. onFormChange,
  202. currentStrategyStatus,
  203. strategyProvider: strategyProvider.data,
  204. pluginDetail: pluginDetail.data?.plugins.at(0),
  205. availableVars,
  206. availableNodesWithParent,
  207. outputSchema,
  208. handleMemoryChange,
  209. isChatMode,
  210. canChooseMCPTool: isSupportMCP(inputs.meta?.version),
  211. }
  212. }
  213. export default useConfig