lailaelkoussy commited on
Commit
8942d03
·
1 Parent(s): 7141c1f

add pagination to list_nodes_by_type

Browse files
Files changed (1) hide show
  1. gradio_mcp_space.py +35 -9
gradio_mcp_space.py CHANGED
@@ -342,7 +342,7 @@ Node Types:
342
 
343
 
344
  @observe(as_type="tool")
345
- def list_nodes_by_type(node_type: str, limit: int = 20) -> str:
346
  """
347
  List nodes of a specific type in the knowledge graph.
348
 
@@ -357,13 +357,24 @@ def list_nodes_by_type(node_type: str, limit: int = 20) -> str:
357
  return "Error: Knowledge graph not initialized"
358
 
359
  try:
360
- # Convert limit to int if it's a string (MCP may pass strings)
361
  if isinstance(limit, str):
362
  try:
363
  limit = int(limit)
364
  except ValueError:
365
  return f"Error: 'limit' must be an integer, got '{limit}'"
366
-
 
 
 
 
 
 
 
 
 
 
 
367
  g = knowledge_graph.graph
368
  matching_nodes = [
369
  {
@@ -372,18 +383,32 @@ def list_nodes_by_type(node_type: str, limit: int = 20) -> str:
372
  }
373
  for node_id, data in g.nodes(data=True)
374
  if getattr(data['data'], 'node_type', None) == node_type
375
- ][:limit]
376
 
377
- if not matching_nodes:
 
378
  return f"No nodes found of type '{node_type}'."
379
 
380
- result = f"Nodes of type '{node_type}' ({len(matching_nodes)} results):\n"
 
 
 
 
 
 
 
 
 
381
  result += "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
382
 
383
- for i, node in enumerate(matching_nodes, 1):
384
  result += f"{i}. {node['name']}\n"
385
  result += f" ID: {node['id']}\n\n"
386
 
 
 
 
 
387
  return result
388
  except Exception as e:
389
  return f"Error: {str(e)}"
@@ -440,7 +465,7 @@ def get_neighbors(node_id: str) -> str:
440
  @observe(as_type="tool")
441
  def go_to_definition(entity_name: str) -> str:
442
  """
443
- Retrieve where an entity is declared or defined in the codebase.
444
 
445
  Locates and retrieves the declaration point for functions, classes, variables, etc.
446
 
@@ -1869,10 +1894,11 @@ def create_gradio_app():
1869
  label="Node Type"
1870
  )
1871
  type_limit = gr.Slider(1, 100, value=20, step=1, label="Max Results")
 
1872
  type_btn = gr.Button("List Nodes", variant="primary")
1873
  with gr.Column():
1874
  type_output = gr.Textbox(label="Results", lines=20, max_lines=30)
1875
- type_btn.click(fn=list_nodes_by_type, inputs=[node_type_input, type_limit], outputs=type_output)
1876
  gr.Markdown(_tool_doc_md(list_nodes_by_type))
1877
 
1878
  gr.Markdown("---")
 
342
 
343
 
344
  @observe(as_type="tool")
345
+ def list_nodes_by_type(node_type: str, limit: int = 20, page: int = 1) -> str:
346
  """
347
  List nodes of a specific type in the knowledge graph.
348
 
 
357
  return "Error: Knowledge graph not initialized"
358
 
359
  try:
360
+ # Convert limit/page to int if they're strings (MCP/Gradio may pass strings)
361
  if isinstance(limit, str):
362
  try:
363
  limit = int(limit)
364
  except ValueError:
365
  return f"Error: 'limit' must be an integer, got '{limit}'"
366
+
367
+ if isinstance(page, str):
368
+ try:
369
+ page = int(page)
370
+ except ValueError:
371
+ return f"Error: 'page' must be an integer, got '{page}'"
372
+
373
+ if limit <= 0:
374
+ return "Error: limit must be a positive integer"
375
+ if page < 1:
376
+ return "Error: 'page' must be a positive integer (1 or greater)"
377
+
378
  g = knowledge_graph.graph
379
  matching_nodes = [
380
  {
 
383
  }
384
  for node_id, data in g.nodes(data=True)
385
  if getattr(data['data'], 'node_type', None) == node_type
386
+ ]
387
 
388
+ total = len(matching_nodes)
389
+ if total == 0:
390
  return f"No nodes found of type '{node_type}'."
391
 
392
+ # Pagination
393
+ total_pages = (total + limit - 1) // limit
394
+ if page > total_pages:
395
+ return f"Error: Page {page} does not exist. Total pages: {total_pages} (with {total} nodes at {limit} per page)"
396
+
397
+ start_idx = (page - 1) * limit
398
+ end_idx = start_idx + limit
399
+ page_slice = matching_nodes[start_idx:end_idx]
400
+
401
+ result = f"Nodes of type '{node_type}' (Page {page}/{total_pages}, {total} total):\n"
402
  result += "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
403
 
404
+ for i, node in enumerate(page_slice, start=start_idx + 1):
405
  result += f"{i}. {node['name']}\n"
406
  result += f" ID: {node['id']}\n\n"
407
 
408
+ # Pagination hint
409
+ if page < total_pages:
410
+ result += f"Use page={page + 1} to see the next page\n"
411
+
412
  return result
413
  except Exception as e:
414
  return f"Error: {str(e)}"
 
465
  @observe(as_type="tool")
466
  def go_to_definition(entity_name: str) -> str:
467
  """
468
+ Retrieve chunk node(s) where entity is declared or defined in the codebase.
469
 
470
  Locates and retrieves the declaration point for functions, classes, variables, etc.
471
 
 
1894
  label="Node Type"
1895
  )
1896
  type_limit = gr.Slider(1, 100, value=20, step=1, label="Max Results")
1897
+ type_page = gr.Slider(1, 100, value=1, step=1, label="Page")
1898
  type_btn = gr.Button("List Nodes", variant="primary")
1899
  with gr.Column():
1900
  type_output = gr.Textbox(label="Results", lines=20, max_lines=30)
1901
+ type_btn.click(fn=list_nodes_by_type, inputs=[node_type_input, type_limit, type_page], outputs=type_output)
1902
  gr.Markdown(_tool_doc_md(list_nodes_by_type))
1903
 
1904
  gr.Markdown("---")