You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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