Uh oh!
There was an error while loading. Please reload this page.
MCP Server Part 7: get_dash_component tool and callback tool execution - #3749
Conversation
Thank you for your contribution to Dash! 🎉 This PR is exempt from requiring a linked issue due to its labels. |
0e54d74 to
8a41b76Compare8c1f392 to
f9b05daCompare8a41b76 to
4fb9d4aComparef9b05da to
bc340e6Compare4fb9d4a to
10a544bComparebc340e6 to
b3d4015Compared203cf9 to
e73cd17Comparee407569 to
37e92f0Compare2acb39d to
04ca2feCompare37e92f0 to
28d5fedCompare04ca2fe to
8f9d5a0Comparef098f88 to
79df12eCompare
camdecoster
left a comment
There was a problem hiding this comment.
I made a few suggestions. The one to pay attention to is the loop going through callbacks/inputs/outputs. Let me know what you think.
| if prop_filter and prop_name != prop_filter: | ||
| continue | ||
| value = callback_map.get_initial_value(f"{comp_id}.{prop_name}") |
There was a problem hiding this comment.
| value=callback_map.get_initial_value(f"{comp_id}.{prop_name}") | |
| id_and_prop=f"{comp_id}.{prop_name}" | |
| value=callback_map.get_initial_value(id_and_prop) |
| modified_by: list[str] = [] | ||
| input_to: list[str] = [] | ||
| id_and_prop = f"{comp_id}.{prop_name}" |
There was a problem hiding this comment.
| id_and_prop = f"{comp_id}.{prop_name}" |
| def call_tool(cls, tool_name: str, arguments: dict[str, Any]) -> CallToolResult: | ||
| comp_id = arguments.get("component_id", "") | ||
| if not comp_id: | ||
| raise ValueError("component_id is required") |
There was a problem hiding this comment.
| raiseValueError("component_id is required") | |
| returnCallToolResult( | |
| content=[TextContent(type="text", text="component_id is required")], | |
| isError=True, | |
| ) |
Uh oh!
There was an error while loading. Please reload this page.
| if component is None: | ||
| callback_map = get_app().mcp_callback_map |
There was a problem hiding this comment.
| ifcomponentisNone: | |
| callback_map=get_app().mcp_callback_map | |
| callback_map=get_app().mcp_callback_map | |
| ifcomponentisNone: |
| isError=True, | ||
| ) | ||
| callback_map = get_app().mcp_callback_map |
There was a problem hiding this comment.
| callback_map = get_app().mcp_callback_map |
| for cb in callback_map: | ||
| for out in cb.outputs: | ||
| if out["id_and_prop"] == id_and_prop: | ||
| modified_by.append(cb.tool_name) | ||
| for inp in cb.inputs: | ||
| if inp["id_and_prop"] == id_and_prop: | ||
| input_to.append(cb.tool_name) |
There was a problem hiding this comment.
This could get expensive for apps with a lot of callbacks, inputs, outputs. Is there a way to create and use an index for looking this up?
There was a problem hiding this comment.
Great point! The dash renderer actually implements such a mapping (but in JS obviously). I'll do the same on the python side.
f1b6cc2 to
d25123bCompareUh oh!
There was an error while loading. Please reload this page.
Summary
Wires up the full tool pipeline following the same pattern as
resources:list_tools()builds the tool list from all registered tool providerscall_tool(name, args)routes LLM calls to the appropriate callback functionAdds a static tool
get_dash_componentwhich allows LLMs to query a specific prop for a given ID.Manual verification: