From 79751f7622e22917e38db701d2729626b7cb6f91 Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 20 Jul 2026 17:52:54 +0800 Subject: [PATCH] chore: display non-LLM settings in integration tool details (#39295) --- .../__tests__/setting-built-in-tool.spec.tsx | 30 +++++++++++++++++-- .../agent-tools/setting-built-in-tool.tsx | 20 +++++++++---- .../provider/__tests__/tool-item.spec.tsx | 17 +++++++++-- .../components/tools/provider/tool-item.tsx | 1 + 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/web/app/components/app/configuration/config/agent/agent-tools/__tests__/setting-built-in-tool.spec.tsx b/web/app/components/app/configuration/config/agent/agent-tools/__tests__/setting-built-in-tool.spec.tsx index 946484da42c..3077d235da2 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/__tests__/setting-built-in-tool.spec.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/__tests__/setting-built-in-tool.spec.tsx @@ -61,8 +61,8 @@ const createParameter = (overrides?: Partial): ToolParameter => ( zh_Hans: 'Setting Param', }, human_description: { - en_US: 'desc', - zh_Hans: 'desc', + en_US: 'Setting description', + zh_Hans: 'Setting description', }, type: 'string', form: 'config', @@ -91,6 +91,10 @@ const createTool = (overrides?: Partial): Tool => ({ en_US: 'Info Param', zh_Hans: 'Info Param', }, + human_description: { + en_US: 'Info description', + zh_Hans: 'Info description', + }, form: 'llm', required: false, }), @@ -181,6 +185,28 @@ describe('SettingBuiltInTool', () => { expect(screen.getByTestId('mock-form')).toBeInTheDocument() }) + it('should keep the setting tab hidden when readonly by default', async () => { + renderComponent({ readonly: true }) + + expect(await screen.findByText('Info Param')).toBeInTheDocument() + expect(screen.queryByText('tools.setBuiltInTools.setting')).not.toBeInTheDocument() + }) + + it('should expose readonly setting details when explicitly enabled', async () => { + const user = userEvent.setup() + renderComponent({ readonly: true, showReadOnlySettingDetails: true }) + + expect(await screen.findByText('Info Param')).toBeInTheDocument() + await user.click(screen.getByText('tools.setBuiltInTools.setting')) + + expect(screen.getByText('Setting Param')).toBeInTheDocument() + expect(screen.getByText('tools.setBuiltInTools.string')).toBeInTheDocument() + expect(screen.getByText('Setting description')).toBeInTheDocument() + expect(screen.queryByText('Info Param')).not.toBeInTheDocument() + expect(screen.queryByTestId('mock-form')).not.toBeInTheDocument() + expect(screen.queryByRole('button', { name: 'common.operation.save' })).not.toBeInTheDocument() + }) + it('should render a masked drawer with balanced vertical offsets', async () => { const { baseElement } = renderComponent() await waitFor(() => { diff --git a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx index cb0223c7fe8..184179b694f 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx @@ -44,6 +44,7 @@ type Props = Readonly<{ toolName: string setting?: Record readonly?: boolean + showReadOnlySettingDetails?: boolean onHide: () => void onSave?: (value: Record) => void credentialId?: string @@ -58,6 +59,7 @@ const SettingBuiltInTool: FC = ({ toolName, setting = {}, readonly, + showReadOnlySettingDetails = false, onHide, onSave, credentialId, @@ -75,6 +77,8 @@ const SettingBuiltInTool: FC = ({ const infoSchemas = formSchemas.filter((item) => item.form === 'llm') const settingSchemas = formSchemas.filter((item) => item.form !== 'llm') const hasSetting = settingSchemas.length > 0 + const showSettingTab = hasSetting && (!readonly || showReadOnlySettingDetails) + const showSettingAsDetails = readonly && showReadOnlySettingDetails const [tempSetting, setTempSetting] = useState(setting) const [currType, setCurrType] = useState('info') const isInfoActive = currType === 'info' @@ -120,12 +124,12 @@ const SettingBuiltInTool: FC = ({ return type } - const infoUI = ( + const renderSchemaDetails = (schemas: typeof formSchemas) => (
- {infoSchemas.length > 0 && ( + {schemas.length > 0 && (
- {infoSchemas.map((item, index) => ( -
+ {schemas.map((item) => ( +
{item.label[language]}
{getType(item.type)}
@@ -146,6 +150,8 @@ const SettingBuiltInTool: FC = ({ )}
) + const infoUI = renderSchemaDetails(infoSchemas) + const settingDetailsUI = renderSchemaDetails(settingSchemas) const settingUI = (
= ({ {/* form */}
- {hasSetting && !readonly ? ( + {showSettingTab ? ( = ({
)}
- {isInfoActive ? infoUI : settingUI} + {isInfoActive && infoUI} + {!isInfoActive && showSettingAsDetails && settingDetailsUI} + {!isInfoActive && !showSettingAsDetails && settingUI} {!readonly && !isInfoActive && (
), @@ -34,6 +43,10 @@ describe('ToolItem', () => { fireEvent.click(screen.getByText('Tool label')) expect(screen.getByTestId('tool-detail')).toBeInTheDocument() + expect(screen.getByTestId('tool-detail')).toHaveAttribute( + 'data-show-readonly-setting-details', + 'true', + ) fireEvent.click(screen.getByRole('button', { name: 'Close details' })) expect(screen.queryByTestId('tool-detail')).not.toBeInTheDocument() diff --git a/web/app/components/tools/provider/tool-item.tsx b/web/app/components/tools/provider/tool-item.tsx index f13c4e49379..d562a9202f6 100644 --- a/web/app/components/tools/provider/tool-item.tsx +++ b/web/app/components/tools/provider/tool-item.tsx @@ -43,6 +43,7 @@ const ToolItem = ({ disabled, collection, tool, isBuiltIn, isModel }: Props) => collection={collection} toolName={tool.name} readonly + showReadOnlySettingDetails onHide={() => { setShowDetail(false) }}