index.tsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import { apiInterceptors, getAgents, getAppStrategy, getPromptList, getResourceType } from '@/client/api';
  2. import { IAgent, IDetail } from '@/types/app';
  3. import { QuestionCircleOutlined } from '@ant-design/icons';
  4. import { useRequest } from 'ahooks';
  5. import { Checkbox, Form, Space, Tooltip } from 'antd';
  6. import cls from 'classnames';
  7. import { concat } from 'lodash';
  8. import React, { useEffect, useMemo, useRef, useState } from 'react';
  9. import { useTranslation } from 'react-i18next';
  10. import { agentIcon, resourceTypeIcon } from '../../config';
  11. import DetailsCard from './DetailsCard';
  12. interface AgentSelectProps {
  13. agents: IAgent[];
  14. selectedTab: string;
  15. setSelectedTab: React.Dispatch<React.SetStateAction<string>>;
  16. value?: any;
  17. onChange?: (value: any) => void;
  18. }
  19. // 自定义agent选择
  20. const AgentSelect: React.FC<AgentSelectProps> = ({ value, onChange, agents, selectedTab, setSelectedTab }) => {
  21. return (
  22. <Checkbox.Group
  23. className='grid grid-cols-4 gap-4'
  24. onChange={(value: string[]) => {
  25. onChange?.(value);
  26. }}
  27. value={value}
  28. >
  29. {agents.map(item => {
  30. return (
  31. <div
  32. className={`flex grow h-8 items-center px-3 border ${
  33. item.name === selectedTab ? 'border-[#0c75fc]' : 'border-[#d6d8da]'
  34. } rounded-md hover:border-[#0c75fc] cursor-pointer`}
  35. key={item.name}
  36. onClick={() => {
  37. setSelectedTab(item.name || '');
  38. }}
  39. >
  40. <Checkbox value={item.name} />
  41. <div className='flex items-center flex-1 justify-between'>
  42. <div>
  43. <span className='ml-2 mr-1'>{agentIcon[item.name || '']}</span>
  44. <span className='text-sm text-[rgba(0,10,26,0.68)] dark:text-[rgba(255,255,255,0.85)]'>
  45. {item.label}
  46. </span>
  47. </div>
  48. <Tooltip title={item.desc}>
  49. <QuestionCircleOutlined className='text-sm' />
  50. </Tooltip>
  51. </div>
  52. </div>
  53. );
  54. })}
  55. </Checkbox.Group>
  56. );
  57. };
  58. const AutoPlan: React.FC<{
  59. initValue: any;
  60. updateData: (data: any) => void;
  61. classNames?: string;
  62. }> = ({ initValue, updateData, classNames }) => {
  63. const { t, i18n } = useTranslation();
  64. const [form] = Form.useForm();
  65. const agentName = Form.useWatch('agent_name', form);
  66. // 选中的agent
  67. const [selectedTab, setSelectedTab] = useState<string>('');
  68. const details = useRef<IDetail[]>([]);
  69. const language = i18n.language === 'en';
  70. // 获取agents, strategy, sourceType;
  71. const { data, loading } = useRequest(async () => {
  72. const res = await Promise.all([
  73. apiInterceptors(getAgents()),
  74. apiInterceptors(getAppStrategy()),
  75. apiInterceptors(getResourceType()),
  76. ]);
  77. const [, agents] = res?.[0] || [];
  78. details.current =
  79. agents?.map(item => {
  80. return {
  81. agent_name: item.name,
  82. llm_strategy: '',
  83. llm_strategy_value: '',
  84. prompt_template: '',
  85. resources: [],
  86. };
  87. }) || [];
  88. form.setFieldsValue({
  89. agent_name: initValue?.map((item: any) => item.agent_name),
  90. });
  91. setSelectedTab(initValue?.map((item: any) => item.agent_name)?.[0] || agents?.[0]?.name || '');
  92. return res ?? [];
  93. });
  94. // 获取prompt提示语列表
  95. const { data: promptData } = useRequest(async () => {
  96. const [, res] = await apiInterceptors(
  97. getPromptList({
  98. page: 1,
  99. page_size: 100000,
  100. }),
  101. );
  102. return res ?? { items: [] };
  103. });
  104. // 模型策略options
  105. const modelStrategyOptions: any[] = useMemo(() => {
  106. const [, strategy] = data?.[1] || [];
  107. if (strategy?.length) {
  108. return strategy.map(item => {
  109. return {
  110. label: language ? item.name : item.name_cn,
  111. value: item.value,
  112. };
  113. });
  114. }
  115. return [];
  116. }, [data]);
  117. // 资源类型options
  118. const resourceTypeOptions: Record<string, any>[] = useMemo(() => {
  119. const [, sourceType] = data?.[2] || [];
  120. if (sourceType?.length) {
  121. const formatterSourceType = sourceType.map(item => {
  122. return {
  123. label: (
  124. <Space>
  125. {resourceTypeIcon[item]}
  126. {item}
  127. </Space>
  128. ),
  129. value: item,
  130. };
  131. });
  132. return concat(
  133. [
  134. {
  135. label: (
  136. <div className='flex items-center text-sm'>
  137. {resourceTypeIcon['all']}
  138. <span className='ml-2 text-[rgba(0,10,26,0.68)] dark:text-[#ffffffD9]'>{t('All')}</span>
  139. </div>
  140. ),
  141. value: 'all',
  142. },
  143. ],
  144. formatterSourceType,
  145. );
  146. }
  147. return [];
  148. }, [data]);
  149. // 实时返回数据给消费组件
  150. useEffect(() => {
  151. updateData([loading, details.current.filter(detail => agentName?.includes(detail.agent_name))]);
  152. }, [loading, agentName, updateData]);
  153. return (
  154. <div className={cls(classNames)}>
  155. <Form form={form} style={{ width: '100%' }} labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
  156. <Form.Item
  157. label={`${t('choose')} agent`}
  158. name='agent_name'
  159. required
  160. rules={[{ required: true, message: t('please_choose') + ' agent' }]}
  161. >
  162. <AgentSelect agents={data?.[0]?.[1] || []} selectedTab={selectedTab} setSelectedTab={setSelectedTab} />
  163. </Form.Item>
  164. </Form>
  165. {data?.[0]?.[1]?.map(item => (
  166. <DetailsCard
  167. key={item.name}
  168. classNames={item.name === selectedTab ? 'block' : 'hidden'}
  169. updateData={(data: any) => {
  170. details.current = details.current.map(detail => {
  171. if (detail.agent_name === data?.agent_name) {
  172. return {
  173. ...detail,
  174. ...data,
  175. };
  176. }
  177. return {
  178. ...detail,
  179. };
  180. });
  181. updateData([loading, details.current.filter(detail => agentName?.includes(detail.agent_name))]);
  182. }}
  183. initValue={initValue}
  184. name={item.name}
  185. modelStrategyOptions={modelStrategyOptions}
  186. resourceTypeOptions={resourceTypeOptions}
  187. promptList={promptData?.items || []}
  188. />
  189. ))}
  190. </div>
  191. );
  192. };
  193. export default AutoPlan;