Skip to content

Commit 84d4bf7

Browse files
committed
Fix tool filtering for MCP tools
1 parent f99d3c1 commit 84d4bf7

2 files changed

Lines changed: 59 additions & 49 deletions

File tree

  • lightspeed_stack_providers/providers/inline/agents/lightspeed_inline_agent

lightspeed_stack_providers/providers/inline/agents/lightspeed_inline_agent/agents.py

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -97,34 +97,13 @@ async def create_openai_response(
9797

9898
# Apply tool filtering if enabled and tools are provided
9999
filtered_tools = tools
100-
if (
101-
tools
102-
and self.config.tools_filter.enabled
103-
and len(tools) > self.config.tools_filter.min_tools
104-
):
105-
logger.info(
106-
"Tool filtering enabled - filtering %d tools (threshold: %d)",
107-
len(tools),
108-
self.config.tools_filter.min_tools,
109-
)
100+
if tools and self.config.tools_filter.enabled:
110101
filtered_tools = await self._filter_tools_for_response(
111102
input=input,
112103
tools=tools,
113104
model=model,
114105
conversation=conversation,
115106
)
116-
logger.info(
117-
"Tool filtering complete - reduced from %d to %d tools",
118-
len(tools),
119-
len(filtered_tools) if filtered_tools else 0,
120-
)
121-
else:
122-
logger.info(
123-
"Skipping tool filtering - %d tools (threshold: %d, enabled: %s)",
124-
len(tools) if tools else 0,
125-
self.config.tools_filter.min_tools,
126-
self.config.tools_filter.enabled,
127-
)
128107

129108
# Call parent with filtered tools and temperature
130109
return await super().create_openai_response(
@@ -189,6 +168,20 @@ async def _filter_tools_for_response(
189168
logger.warning("No tool definitions found for filtering")
190169
return tools
191170

171+
if len(tools_for_filtering) <= self.config.tools_filter.min_tools:
172+
logger.info(
173+
"Skipping tool filtering - %d tools (threshold: %d)",
174+
len(tools_for_filtering),
175+
self.config.tools_filter.min_tools,
176+
)
177+
return tools
178+
179+
logger.info(
180+
"Tool filtering enabled - filtering %d tools (threshold: %d)",
181+
len(tools_for_filtering),
182+
self.config.tools_filter.min_tools,
183+
)
184+
192185
# Extract user prompt text from input
193186
if isinstance(input, str):
194187
user_prompt = input
@@ -246,28 +239,26 @@ async def _filter_tools_for_response(
246239
logger.error("Failed to parse LLM response as JSON: %s", exp)
247240
filtered_tool_names = []
248241

249-
# Filter the original tools list
242+
# Filter using expanded tool definitions
250243
if filtered_tool_names or always_included_tools:
251-
# Create a mapping from tool names to tool configs
252-
tool_name_to_config = {}
253-
for i, tool in enumerate(tools):
254-
tool_dict = tool if isinstance(tool, dict) else tool.model_dump()
255-
tool_name = self._get_tool_name_from_config(tool_dict, i)
256-
tool_name_to_config[tool_name] = tool
257-
258-
# Filter based on LLM response and always included tools
259-
filtered_tools = [
260-
tool_name_to_config[name]
261-
for name in tool_name_to_config
262-
if name in filtered_tool_names or name in always_included_tools
244+
selected_names = set(filtered_tool_names) | always_included_tools
245+
result = [
246+
{
247+
"type": "function",
248+
"name": td["tool_name"],
249+
"description": td["description"],
250+
"parameters": td.get("parameters", {}),
251+
}
252+
for td in tools_for_filtering
253+
if td["tool_name"] in selected_names
263254
]
264255

265256
logger.info(
266-
"Filtered tools count: %d removed, %d remaining",
267-
len(tools) - len(filtered_tools),
268-
len(filtered_tools),
257+
"Filtered tools: %d removed, %d remaining",
258+
len(tools_for_filtering) - len(result),
259+
len(result),
269260
)
270-
return filtered_tools
261+
return result
271262
else:
272263
logger.warning("No tools matched filtering criteria, returning empty list")
273264
return []
@@ -337,9 +328,11 @@ async def _extract_tool_definitions(
337328
}
338329
)
339330
elif tool_type == "function":
340-
name = tool_dict.get("name", f"function_{i}")
341-
description = tool_dict.get("description", "")
342-
tool_defs.append({"tool_name": name, "description": description})
331+
func = tool_dict.get("function", {})
332+
name = func.get("name", tool_dict.get("name", f"function_{i}"))
333+
description = func.get("description", tool_dict.get("description", ""))
334+
parameters = func.get("parameters", tool_dict.get("parameters", {}))
335+
tool_defs.append({"tool_name": name, "description": description, "parameters": parameters})
343336
else:
344337
logger.warning("Unknown tool type: %s", tool_type)
345338
tool_defs.append(
@@ -385,6 +378,7 @@ async def _get_mcp_tool_definitions(
385378
{
386379
"tool_name": tool_def.name,
387380
"description": tool_def.description or "",
381+
"parameters": tool_def.parameters if hasattr(tool_def, "parameters") else {},
388382
}
389383
)
390384

run.yaml

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ apis:
55
- safety
66
- agents
77
- tool_runtime
8+
- vector_io
9+
- files
810

911
external_providers_dir: ./resources/external_providers
1012

@@ -31,6 +33,16 @@ storage:
3133
backend: kv_default
3234

3335
providers:
36+
37+
files:
38+
- provider_id: meta-reference-files
39+
provider_type: inline::localfs
40+
config:
41+
storage_dir: ${env.FILES_STORAGE_DIR:=/tmp/llama_files}
42+
metadata_store:
43+
table_name: files_metadata
44+
backend: sql_default
45+
3446
inference:
3547
- provider_id: openai
3648
provider_type: remote::openai
@@ -41,7 +53,7 @@ providers:
4153
- provider_id: lightspeed_question_validity
4254
provider_type: inline::lightspeed_question_validity
4355
config:
44-
model_id: openai/gpt-4o
56+
model_id: openai/gpt-4o-mini
4557
temperature: 0.0
4658
invalid_question_response: |
4759
Hi, I'm the OpenShift Lightspeed assistant, I can help you with questions about OpenShift,
@@ -59,6 +71,11 @@ providers:
5971
- pattern: "\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b"
6072
replacement: "[REDACTED_EMAIL]"
6173

74+
tool_runtime:
75+
- provider_id: model-context-protocol
76+
provider_type: remote::model-context-protocol
77+
config: {}
78+
6279
agents:
6380
- provider_id: lightspeed_inline_agent
6481
provider_type: inline::lightspeed_inline_agent
@@ -79,11 +96,6 @@ providers:
7996
chatbot_temperature_override: 1.0
8097

8198
registered_resources:
82-
models:
83-
- model_id: gpt-4o
84-
provider_id: openai
85-
model_type: llm
86-
provider_model_id: gpt-4o
8799

88100
shields:
89101
- shield_id: lightspeed_question_validity-shield
@@ -92,7 +104,11 @@ registered_resources:
92104
provider_id: lightspeed_redaction
93105
provider_shield_id: lightspeed-redaction-shield
94106

95-
tool_groups: []
107+
tool_groups:
108+
- toolgroup_id: openshift-tools
109+
provider_id: model-context-protocol
110+
mcp_endpoint:
111+
uri: http://localhost:8401/sse
96112

97113
server:
98114
host: 0.0.0.0

0 commit comments

Comments
 (0)