From e03a92e7ecb22230a885d5ce537980bcb68a32a0 Mon Sep 17 00:00:00 2001 From: Stephen Adamson Date: Sat, 15 Nov 2025 23:02:19 +0000 Subject: [PATCH] update output --- mcp_codebase.py | 172 ++++++++++++++++++++++++------------------------ 1 file changed, 87 insertions(+), 85 deletions(-) diff --git a/mcp_codebase.py b/mcp_codebase.py index b91a6e3..e603ae2 100644 --- a/mcp_codebase.py +++ b/mcp_codebase.py @@ -5007,7 +5007,7 @@ def _build_enhanced_result(chunk_text: str, meta: dict, score: float, graph: Opt def _get_result_graph_context(meta: dict, graph: Optional[LocalGraph] = None) -> dict: - """Get relevant graph context for a search result with cross-file awareness.""" + """Get MOST relevant graph context - optimized for LLM tokens.""" if graph is None or graph.graph.number_of_nodes() == 0: return {} @@ -5032,61 +5032,68 @@ def _get_result_graph_context(meta: dict, graph: Optional[LocalGraph] = None) -> node_id = f"svelte::component::{file_path}::{entity_name}" if node_id and node_id in graph.graph: - # Get direct relationships WITH file info - neighbors = list(graph.neighbors(node_id)) - if neighbors: - context['relationships'] = [] - context['cross_file_deps'] = [] # NEW: Track cross-file dependencies + # PRIORITY 1: Cross-file dependencies (highest value for LLM) + cross_file_rels = [] + incoming_cross_file = [] - for neighbor_id, neighbor_data in neighbors[:10]: # Show more neighbors + # Outgoing cross-file relationships + for neighbor_id, neighbor_data in graph.neighbors(node_id): + neighbor_file = neighbor_data.get('file', '') + if neighbor_file and neighbor_file != file_path: edge_data = graph.graph.edges[node_id, neighbor_id] rel_type = edge_data.get('type', 'related') neighbor_name = neighbor_data.get('name', neighbor_id.split('::')[-1]) - neighbor_file = neighbor_data.get('file', '') neighbor_type = neighbor_data.get('type', '') - # Build compact relationship string with file info - if neighbor_file and neighbor_file != file_path: - # Cross-file relationship - show file - rel_str = f"{rel_type}:{neighbor_name}@{neighbor_file}" - context['cross_file_deps'].append(rel_str) + # Compress representation based on relationship importance + if rel_type in ['extends', 'implements', 'calls']: + # High-value relationships - keep full info + cross_file_rels.append(f"{rel_type}:{neighbor_type}:{neighbor_name}@{neighbor_file}") else: - # Same-file relationship - omit file for brevity - rel_str = f"{rel_type}:{neighbor_name}" + # Medium-value - compress type + cross_file_rels.append(f"{rel_type}:{neighbor_name}@{neighbor_file}") - context['relationships'].append(rel_str) - - # NEW: Find reverse dependencies (what depends on THIS entity) - incoming = [] + # PRIORITY 2: Reverse dependencies (what uses this entity) for predecessor in graph.graph.predecessors(node_id): pred_data = graph.graph.nodes[predecessor] pred_file = pred_data.get('file', '') pred_name = pred_data.get('name', '') - edge_data = graph.graph.edges[predecessor, node_id] - rel_type = edge_data.get('type', 'related') - # Only show cross-file incoming dependencies + # Only show cross-file incoming (same-file is less valuable) if pred_file and pred_file != file_path: - incoming.append(f"{rel_type}:{pred_name}@{pred_file}") + edge_data = graph.graph.edges[predecessor, node_id] + rel_type = edge_data.get('type', 'related') - if incoming: - context['used_by'] = incoming[:10] + if rel_type in ['calls', 'extends', 'implements']: + incoming_cross_file.append(f"{rel_type}:{pred_name}@{pred_file}") - # Get file-level context (same as before) - file_node_id = f"file::{file_path}" - if file_node_id in graph.graph: - file_neighbors = list(graph.neighbors(file_node_id)) - if file_neighbors: - context['file_entities'] = [] - for neighbor_id, neighbor_data in file_neighbors[:5]: - neighbor_type = neighbor_data.get('type', '') - neighbor_name = neighbor_data.get('name', '') - if neighbor_type and neighbor_name and neighbor_name != entity_name: - context['file_entities'].append(f"{neighbor_type}:{neighbor_name}") + # Apply aggressive limits for token conservation + if cross_file_rels: + # Sort by relationship importance + priority_order = {'extends': 0, 'implements': 1, 'calls': 2} + cross_file_rels.sort(key=lambda x: priority_order.get(x.split(':')[0], 99)) + context['xfile'] = cross_file_rels[:6] # Only top 6 cross-file deps + + if incoming_cross_file: + context['used_by'] = incoming_cross_file[:4] # Only top 4 reverse deps + + # PRIORITY 3: Critical same-file context (only if cross-file is sparse) + if not context.get('xfile') and not context.get('used_by'): + file_node_id = f"file::{file_path}" + if file_node_id in graph.graph: + file_entities = [] + for neighbor_id, neighbor_data in graph.neighbors(file_node_id): + neighbor_type = neighbor_data.get('type', '') + neighbor_name = neighbor_data.get('name', '') + if (neighbor_type in ['class', 'struct', 'interface', 'component'] and + neighbor_name != entity_name): + file_entities.append(f"{neighbor_type}:{neighbor_name}") + + if file_entities: + context['file'] = file_entities[:3] # Only top 3 same-file entities return context - def _extract_docstring(chunk_text: str) -> str: """Extract docstring or comments from chunk text.""" lines = chunk_text.split('\n') @@ -5125,74 +5132,69 @@ def _extract_docstring(chunk_text: str) -> str: def _format_enhanced_results(results: List[Dict], query: str, result_type: str) -> str: - """Format enhanced results with dense LLM-optimized context.""" + """Ultra-compact formatting optimized for LLM token usage.""" if not results: return f"# {result_type.title()}: {query}\nNo results found.\n" lines = [ f"# {result_type.title()}: {query}", - f"results[{len(results)}]{{file,line,type,name,score,content,context}}:" + f"Found {len(results)} results:" ] - for result in results: - context_parts = [] + for i, result in enumerate(results, 1): + # Extract core info + file_path = result.get('file', '') + line_num = result.get('line', '') + entity_type = result.get('type', 'code') + entity_name = result.get('name', '') + score = result.get('score', 0.0) + content = result.get('content', '')[:350] # Strict content limit - # Graph context as dense key:value pairs graph_context = result.get('graph_context', {}) - # Cross-file dependencies (highest value) - if graph_context.get('cross_file_deps'): - deps = '|'.join(graph_context['cross_file_deps'][:8]) - context_parts.append(f"xfile:{deps}") + # Build ultra-compact context string + context_parts = [] - # All relationships - if graph_context.get('relationships'): - rels = '|'.join(graph_context['relationships'][:12]) - context_parts.append(f"rels:{rels}") + # Cross-file deps (highest priority) + if graph_context.get('xfile'): + # Compress further: remove file paths, keep only key info + compressed_deps = [] + for dep in graph_context['xfile'][:4]: # Only top 4 + parts = dep.split('@')[0] # Remove file path + compressed_deps.append(parts) + context_parts.append(f"deps:{'|'.join(compressed_deps)}") - # Reverse dependencies + # Reverse deps if graph_context.get('used_by'): - used = '|'.join(graph_context['used_by'][:6]) - context_parts.append(f"used:{used}") + compressed_used = [] + for used in graph_context['used_by'][:3]: # Only top 3 + parts = used.split('@')[0] # Remove file path + compressed_used.append(parts) + context_parts.append(f"used:{'|'.join(compressed_used)}") - # File context - if graph_context.get('file_entities'): - entities = '|'.join(graph_context['file_entities'][:10]) - context_parts.append(f"file:{entities}") + # Same-file context (lowest priority) + if graph_context.get('file') and not context_parts: + context_parts.append(f"file:{'|'.join(graph_context['file'][:2])}") - # Docstring (if valuable) + context_str = " ".join(context_parts) + + # Ultra-compact row format + row = f"{i}. {file_path}:{line_num} {entity_type}:{entity_name} (score:{score:.2f})" + if context_str: + row += f" [{context_str}]" + + lines.append(row) + lines.append(f" Content: {content}") + + # Add docstring only if highly relevant and short docstring = result.get('docstring', '') - if docstring and len(docstring) > 10: # Only include substantial docs - context_parts.append(f"doc:{docstring[:200]}") + if docstring and len(docstring) < 100 and any(keyword in query.lower() for keyword in ['how', 'what', 'why', 'documentation']): + lines.append(f" Docs: {docstring}") - context_str = ";".join(context_parts) - - # Minimal row with essential info - row = [ - result.get('file', ''), - result.get('line', ''), - result.get('type', 'code'), - result.get('name', ''), - f"{result.get('score', 0.0):.2f}", - result.get('content', '')[:500], # More content tokens - context_str - ] - - # Efficient escaping - escaped_row = [] - for field in row: - field_str = str(field) - if ',' in field_str or ';' in field_str: - escaped = field_str.replace('"', '\\"') - escaped_row.append(f'"{escaped}"') - else: - escaped_row.append(field_str) - - lines.append(" " + ",".join(escaped_row)) + lines.append("") # Empty line between results return "\n".join(lines) - def _extract_clean_content(chunk_text: str) -> str: """Extract clean content from chunk text by removing duplicate metadata.""" lines = chunk_text.split('\n')