Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions backend/services/tool_configuration_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,34 +500,42 @@ async def list_all_tools(tenant_id: str):
for tool in tools_info:
tool_name = tool.get("name")

# Merge description_zh from SDK for local tools
if tool.get("source") == "local" and tool_name in local_tool_descriptions:
sdk_info = local_tool_descriptions[tool_name]
# Always use SDK inputs for local tools to stay in sync with current tool code
is_local = tool.get("source") == "local"
sdk_info = local_tool_descriptions.get(tool_name) if is_local else None

if is_local and sdk_info:
description_zh = sdk_info.get("description_zh")

# Merge params description_zh from SDK (independent of tool-level description_zh)
params = tool.get("params", [])
if params:
for param in params:
if not param.get("description_zh"):
# Find matching param in SDK
for sdk_param in sdk_info.get("params", []):
if sdk_param.get("name") == param.get("name"):
param["description_zh"] = sdk_param.get("description_zh")
break

# Use SDK full input schema for local tools to keep runtime inputs
# aligned with current tool code (instead of stale DB snapshots).
# Merge SDK inputs: use DB as base, merge description_zh for existing keys,
# add new keys from SDK. This ensures new inputs like kds_list appear even
# if the DB record was created before the field was added to the SDK.
inputs_str = tool.get("inputs", "{}")
try:
inputs = json.loads(inputs_str) if isinstance(inputs_str, str) else inputs_str
inputs = json.loads(inputs_str) if isinstance(inputs_str, str) else (inputs_str or {})
sdk_inputs = sdk_info.get("inputs", {})

if isinstance(inputs, dict):
for key, value in inputs.items():
if isinstance(value, dict) and not value.get("description_zh"):
# Find matching input in SDK
sdk_inputs = sdk_info.get("inputs", {})
if key in sdk_inputs:
value["description_zh"] = sdk_inputs[key].get("description_zh")
if isinstance(value, dict) and key in sdk_inputs:
sdk_desc_zh = sdk_inputs[key].get("description_zh")
if sdk_desc_zh:
value["description_zh"] = sdk_desc_zh

for key, sdk_value in sdk_inputs.items():
if key not in inputs:
inputs[key] = sdk_value

inputs_str = json.dumps(inputs, ensure_ascii=False)
except (json.JSONDecodeError, TypeError):
pass
Expand Down
11 changes: 5 additions & 6 deletions backend/utils/tool_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,17 @@ def get_local_tools_description_zh() -> Dict[str, Dict]:
"description_zh": param_description_zh
})

# Store complete inputs definition for runtime alignment
tool_inputs = getattr(tool_class, 'inputs', {})
inputs_description_zh = {}
inputs_complete = {}
if isinstance(tool_inputs, dict):
for key, value in tool_inputs.items():
if isinstance(value, dict) and value.get("description_zh"):
inputs_description_zh[key] = {
"description_zh": value.get("description_zh")
}
if isinstance(value, dict):
inputs_complete[key] = value

result[tool_name] = {
"description_zh": description_zh,
"params": init_params_list,
"inputs": inputs_description_zh
"inputs": inputs_complete
}
return result
Loading
Loading