Spaces:
Runtime error
Runtime error
| from typing import List | |
| import modelscope_studio.components.antd as antd | |
| import modelscope_studio.components.base as ms | |
| import gradio as gr | |
| from config import max_mcp_server_count | |
| def McpServersButton(data_source: List[dict]): | |
| state = gr.State({"data_source": data_source}) | |
| with antd.Button(value=None, variant="text", | |
| color="primary") as mcp_servers_btn: | |
| with ms.Slot("icon"): | |
| antd.Icon("ToolOutlined") | |
| with antd.Modal( | |
| width=420, | |
| footer=False, | |
| centered=True, | |
| styles=dict(footer=dict(display="none"))) as mcp_servers_modal: | |
| with ms.Slot("title"): | |
| with antd.Flex(gap="small", align="center"): | |
| ms.Text("MCP Servers") | |
| mcp_servers_switch = antd.Switch(True) | |
| antd.Typography.Text( | |
| f"最大 MCP Server 连接数:{max_mcp_server_count}", | |
| type="secondary", | |
| elem_style=dict(fontSize=12, fontWeight="normal")) | |
| with antd.List( | |
| data_source=data_source, | |
| pagination=dict(pageSize=10, | |
| hideOnSinglePage=True)) as mcp_servers_list: | |
| with ms.Slot( | |
| "renderItem", | |
| params_mapping= | |
| "(item) => ({ text: { value: item.name, disabled: item.disabled }, tag: { style: { display: item.internal ? undefined: 'none' } }, switch: { value: item.enabled, mcp: item.name, disabled: item.disabled }})" | |
| ): | |
| with antd.List.Item(): | |
| with antd.Flex(justify="space-between", | |
| elem_style=dict(width="100%")): | |
| with antd.Flex(gap="small"): | |
| antd.Typography.Text(as_item="text") | |
| antd.Tag("官方示例", color="green", as_item="tag") | |
| mcp_server_switch = antd.Switch(as_item="switch") | |
| def change_mcp_servers_switch(mcp_servers_switch_value, state_value): | |
| state_value["data_source"] = [{ | |
| **item, "disabled": | |
| not mcp_servers_switch_value | |
| } for item in state_value["data_source"]] | |
| return gr.update(value=state_value) | |
| def change_mcp_server_switch(state_value, e: gr.EventData): | |
| mcp = e._data["component"]["mcp"] | |
| enabled = e._data["payload"][0] | |
| state_value["data_source"] = [{ | |
| **item, "enabled": enabled | |
| } if item["name"] == mcp else item | |
| for item in state_value["data_source"]] | |
| return gr.update(value=state_value) | |
| def apply_state_change(state_value): | |
| has_tool_use = False | |
| disabled_tool_use = False | |
| enabled_server_count = 0 | |
| for item in state_value["data_source"]: | |
| if item.get("enabled"): | |
| if enabled_server_count >= max_mcp_server_count: | |
| item["enabled"] = False | |
| else: | |
| enabled_server_count += 1 | |
| if item.get("disabled"): | |
| disabled_tool_use = True | |
| else: | |
| has_tool_use = True | |
| if not disabled_tool_use: | |
| for item in state_value["data_source"]: | |
| if enabled_server_count >= max_mcp_server_count: | |
| item["disabled"] = not item.get("enabled", False) | |
| else: | |
| item["disabled"] = False | |
| return gr.update( | |
| data_source=state_value["data_source"], | |
| footer="没有可用的 MCP Server" | |
| if len(state_value["data_source"]) == 0 else ""), gr.update( | |
| color="primary" if has_tool_use else "default"), gr.update( | |
| value=not disabled_tool_use), gr.update(value=state_value) | |
| mcp_servers_btn.click(fn=lambda: gr.update(open=True), | |
| outputs=[mcp_servers_modal], | |
| queue=False) | |
| mcp_servers_switch.change(fn=change_mcp_servers_switch, | |
| inputs=[mcp_servers_switch, state], | |
| outputs=[state]) | |
| mcp_server_switch.change(fn=change_mcp_server_switch, | |
| inputs=[state], | |
| outputs=[state]) | |
| state.change( | |
| fn=apply_state_change, | |
| inputs=[state], | |
| outputs=[mcp_servers_list, mcp_servers_btn, mcp_servers_switch, state], | |
| queue=False) | |
| mcp_servers_modal.cancel(fn=lambda: gr.update(open=False), | |
| outputs=[mcp_servers_modal], | |
| queue=False) | |
| return state | |