diff --git a/.trae/rules/rule.md b/.trae/rules/rule.md index 1d820e5..6342d13 100644 --- a/.trae/rules/rule.md +++ b/.trae/rules/rule.md @@ -9,5 +9,6 @@ alwaysApply: true 3. **代码修改** - 任何时候,当存在字段格式不对,变量名不对,表使用不对等,禁止做兼容修改,必须按唯一性修改。比如约定字段是string,正确:只能传string;错误:可以传int。 比如约定字段名是data,正确:只能传data;错误:可以传sourceData或者data。 4. **语言** - 永远使用中文跟用户沟通,专有名词可以用英文。 5. **文档** - 在用户没有明确要求先提供文档时,禁止创建文档。避免生产垃圾文件。用户明确要求提供文档时,才创建文档。 +6. **注释** - 你生成的代码,尽可能完善中文注释。注释的格式需要按照Go语言的注释规范。要描述清楚代码的功能,参数,返回值,异常等。 diff --git a/src/components/ExternalToolEditor.tsx b/src/components/ExternalToolEditor.tsx index c72c12a..7d800c3 100644 --- a/src/components/ExternalToolEditor.tsx +++ b/src/components/ExternalToolEditor.tsx @@ -1,5 +1,6 @@ -import { CopyOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; +import { CopyOutlined, DownOutlined, MinusCircleOutlined, PlusOutlined, RightOutlined } from '@ant-design/icons'; import { App as AntApp, Button, Card, Form, Input, Modal, Select, Space } from 'antd'; +import { useEffect, useRef, useState } from 'react'; import { AgentAPI, ExternalToolApi, ExternalToolApiRouting, ExternalToolPlugin, ExternalToolPluginPayload } from '../api'; interface Props { @@ -137,6 +138,43 @@ export default function ExternalToolEditor({ open, agentId, plugin, onClose, onS const { message } = AntApp.useApp(); const [form] = Form.useForm(); const isEditing = Boolean(plugin); + const apis = Form.useWatch('apis', form) || []; + const [expandedApiIndexes, setExpandedApiIndexes] = useState([]); + const previousApiCountRef = useRef(0); + + useEffect(() => { + if (!open) { + previousApiCountRef.current = 0; + setExpandedApiIndexes([]); + return; + } + + const apiCount = apis.length; + if (apiCount < 1) { + previousApiCountRef.current = 0; + setExpandedApiIndexes([]); + return; + } + + const previousApiCount = previousApiCountRef.current; + if (previousApiCount === 0) { + setExpandedApiIndexes(apiCount === 1 ? [0] : []); + } else if (previousApiCount === 1 && apiCount > 1) { + setExpandedApiIndexes([]); + } else if (apiCount === 1) { + setExpandedApiIndexes([0]); + } else { + setExpandedApiIndexes((current) => current.filter((index) => index < apiCount)); + } + + previousApiCountRef.current = apiCount; + }, [apis.length, open]); + + const toggleApiCard = (index: number) => { + setExpandedApiIndexes((current) => + current.includes(index) ? current.filter((item) => item !== index) : [...current, index], + ); + }; const handleSubmit = async () => { try { @@ -264,149 +302,167 @@ export default function ExternalToolEditor({ open, agentId, plugin, onClose, onS - {fields.map((field, index) => ( - + {fields.map((field, index) => { + const isExpanded = expandedApiIndexes.includes(index); + + return ( + } - onClick={() => { - const currentApis = form.getFieldValue('apis') || []; - const apiToCopy = currentApis[field.name]; - if (apiToCopy) { - add({ - ...apiToCopy, - name: `${apiToCopy.name}-copy`, - }); - } - }} + onClick={() => toggleApiCard(index)} + style={{ padding: 0, fontWeight: 500 }} + icon={isExpanded ? : } > - 复制 + {`API ${index + 1}`} - {fields.length > 1 ? ( - - ) : null} - - } - > -
- - - - - - -
- - - - - - -
- - - - - - {(routingFields, { add: addUseWhen, remove: removeUseWhen }, { errors }) => ( - -
-
- useWhen -
至少一项,描述什么情况下应该调用这个 API。
-
- -
- {routingFields.map((routingField) => ( - - - - - -
- {routingFields.map((routingField) => ( - - - - - + + {routingFields.map((routingField) => ( + + + + + + + {routingFields.map((routingField) => ( + + + + +