lailaelkoussy commited on
Commit
5f8582c
·
1 Parent(s): 547246f

fix list entities by type bug

Browse files
Files changed (1) hide show
  1. gradio_mcp_space.py +52 -25
gradio_mcp_space.py CHANGED
@@ -433,22 +433,24 @@ Edge Relations:
433
  except Exception as e:
434
  return f"Error: {str(e)}"
435
 
436
-
437
  @observe(as_type="tool")
438
  def list_nodes_by_type(node_type: str, limit: int = 20, page: int = 1) -> str:
439
  """
440
  List nodes of a specific type in the knowledge graph.
441
-
 
 
 
442
  Args:
443
  node_type: The type of nodes to list (e.g., 'function', 'class', 'file')
444
  limit: Maximum number of nodes to return (default: 20)
445
-
446
  Returns:
447
  str: A formatted string with matching nodes
448
  """
449
  if knowledge_graph is None:
450
  return "Error: Knowledge graph not initialized"
451
-
452
  try:
453
  # Convert limit/page to int if they're strings (MCP/Gradio may pass strings)
454
  if isinstance(limit, str):
@@ -456,52 +458,77 @@ def list_nodes_by_type(node_type: str, limit: int = 20, page: int = 1) -> str:
456
  limit = int(limit)
457
  except ValueError:
458
  return f"Error: 'limit' must be an integer, got '{limit}'"
459
-
460
  if isinstance(page, str):
461
  try:
462
  page = int(page)
463
  except ValueError:
464
  return f"Error: 'page' must be an integer, got '{page}'"
465
-
466
  if limit <= 0:
467
  return "Error: limit must be a positive integer"
468
  if page < 1:
469
  return "Error: 'page' must be a positive integer (1 or greater)"
470
-
471
  g = knowledge_graph.graph
472
- matching_nodes = [
473
- {
474
- "id": node_id,
475
- "name": getattr(data['data'], 'name', 'Unknown')
476
- }
477
- for node_id, data in g.nodes(data=True)
478
- if getattr(data['data'], 'node_type', None) == node_type
479
- ]
480
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  total = len(matching_nodes)
482
  if total == 0:
483
  return f"No nodes found of type '{node_type}'."
484
-
485
  # Pagination
486
  total_pages = (total + limit - 1) // limit
487
  if page > total_pages:
488
  return f"Error: Page {page} does not exist. Total pages: {total_pages} (with {total} nodes at {limit} per page)"
489
-
490
  start_idx = (page - 1) * limit
491
  end_idx = start_idx + limit
492
  page_slice = matching_nodes[start_idx:end_idx]
493
-
494
  result = f"Nodes of type '{node_type}' (Page {page}/{total_pages}, {total} total):\n"
495
  result += "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
496
-
497
  for i, node in enumerate(page_slice, start=start_idx + 1):
498
  result += f"{i}. {node['name']}\n"
499
- result += f" ID: {node['id']}\n\n"
500
-
 
501
  # Pagination hint
502
  if page < total_pages:
503
  result += f"Use page={page + 1} to see the next page\n"
504
-
505
  return result
506
  except Exception as e:
507
  return f"Error: {str(e)}"
@@ -2043,7 +2070,7 @@ def create_gradio_app():
2043
  with gr.Row():
2044
  with gr.Column():
2045
  node_type_input = gr.Dropdown(
2046
- choices=["file", "directory", "chunk", "entity", "function", "class", "method"],
2047
  label="Node Type"
2048
  )
2049
  type_limit = gr.Slider(1, 100, value=20, step=1, label="Max Results")
@@ -2059,7 +2086,7 @@ def create_gradio_app():
2059
  with gr.Row():
2060
  with gr.Column():
2061
  search_type = gr.Dropdown(
2062
- choices=["file", "directory", "chunk", "entity", "function", "class", "method"],
2063
  label="Node Type"
2064
  )
2065
  search_name = gr.Textbox(label="Name Contains", placeholder="Enter partial name...")
 
433
  except Exception as e:
434
  return f"Error: {str(e)}"
435
 
 
436
  @observe(as_type="tool")
437
  def list_nodes_by_type(node_type: str, limit: int = 20, page: int = 1) -> str:
438
  """
439
  List nodes of a specific type in the knowledge graph.
440
+
441
+ For entities, use entity_type (e.g., 'class', 'function', 'method').
442
+ For other nodes, use node_type (e.g., 'file', 'chunk', 'directory').
443
+
444
  Args:
445
  node_type: The type of nodes to list (e.g., 'function', 'class', 'file')
446
  limit: Maximum number of nodes to return (default: 20)
447
+ page: Page number for pagination (default: 1)
448
  Returns:
449
  str: A formatted string with matching nodes
450
  """
451
  if knowledge_graph is None:
452
  return "Error: Knowledge graph not initialized"
453
+
454
  try:
455
  # Convert limit/page to int if they're strings (MCP/Gradio may pass strings)
456
  if isinstance(limit, str):
 
458
  limit = int(limit)
459
  except ValueError:
460
  return f"Error: 'limit' must be an integer, got '{limit}'"
461
+
462
  if isinstance(page, str):
463
  try:
464
  page = int(page)
465
  except ValueError:
466
  return f"Error: 'page' must be an integer, got '{page}'"
467
+
468
  if limit <= 0:
469
  return "Error: limit must be a positive integer"
470
  if page < 1:
471
  return "Error: 'page' must be a positive integer (1 or greater)"
472
+
473
  g = knowledge_graph.graph
474
+ matching_nodes = []
475
+
476
+ for node_id, data in g.nodes(data=True):
477
+ node = data['data']
478
+ current_node_type = getattr(node, 'node_type', None)
479
+ node_name = getattr(node, 'name', 'Unknown')
480
+
481
+ # For entity nodes, check entity_type instead of node_type
482
+ if current_node_type == 'entity':
483
+ entity_type = getattr(node, 'entity_type', '')
484
+
485
+ # Fallback: if entity_type is empty, check the entities dictionary
486
+ if not entity_type and node_id in knowledge_graph.entities:
487
+ entity_types = knowledge_graph.entities[node_id].get('type', [])
488
+ entity_type = entity_types[0] if entity_types else ''
489
+
490
+ if entity_type and entity_type.lower() == node_type.lower():
491
+ matching_nodes.append({
492
+ "id": node_id,
493
+ "name": node_name,
494
+ "type": f"entity ({entity_type})"
495
+ })
496
+ # For other nodes, check node_type directly
497
+ elif current_node_type == node_type:
498
+ matching_nodes.append({
499
+ "id": node_id,
500
+ "name": node_name,
501
+ "type": current_node_type
502
+ })
503
+
504
+ # Sort by name for consistent ordering
505
+ matching_nodes.sort(key=lambda x: x['name'].lower())
506
+
507
  total = len(matching_nodes)
508
  if total == 0:
509
  return f"No nodes found of type '{node_type}'."
510
+
511
  # Pagination
512
  total_pages = (total + limit - 1) // limit
513
  if page > total_pages:
514
  return f"Error: Page {page} does not exist. Total pages: {total_pages} (with {total} nodes at {limit} per page)"
515
+
516
  start_idx = (page - 1) * limit
517
  end_idx = start_idx + limit
518
  page_slice = matching_nodes[start_idx:end_idx]
519
+
520
  result = f"Nodes of type '{node_type}' (Page {page}/{total_pages}, {total} total):\n"
521
  result += "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
522
+
523
  for i, node in enumerate(page_slice, start=start_idx + 1):
524
  result += f"{i}. {node['name']}\n"
525
+ result += f" ID: {node['id']}\n"
526
+ result += f" Type: {node['type']}\n\n"
527
+
528
  # Pagination hint
529
  if page < total_pages:
530
  result += f"Use page={page + 1} to see the next page\n"
531
+
532
  return result
533
  except Exception as e:
534
  return f"Error: {str(e)}"
 
2070
  with gr.Row():
2071
  with gr.Column():
2072
  node_type_input = gr.Dropdown(
2073
+ choices=["file", "directory", "chunk", "function", "class", "method"],
2074
  label="Node Type"
2075
  )
2076
  type_limit = gr.Slider(1, 100, value=20, step=1, label="Max Results")
 
2086
  with gr.Row():
2087
  with gr.Column():
2088
  search_type = gr.Dropdown(
2089
+ choices=["file", "directory", "chunk", "function", "class", "method"],
2090
  label="Node Type"
2091
  )
2092
  search_name = gr.Textbox(label="Name Contains", placeholder="Enter partial name...")