update output

This commit is contained in:
2025-11-15 23:02:19 +00:00
parent 4580638cfd
commit e03a92e7ec
+87 -85
View File
@@ -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')