MCPcopy Create free account
hub / github.com/CodeGraphContext/CodeGraphContext / ai_query

Function ai_query

src/codegraphcontext/viz/server.py:560–695  ·  view source on GitHub ↗
(request: AIQueryRequest)

Source from the content-addressed store, hash-verified

558
559@app.post("/api/ai_query")
560async def ai_query(request: AIQueryRequest):
561 if not db_manager:
562 raise HTTPException(status_code=500, detail="Database not initialized")
563
564 gemini_key = os.getenv("GEMINI_API_KEY")
565 openai_key = os.getenv("OPENAI_API_KEY")
566 atlascloud_key = os.getenv("ATLASCLOUD_API_KEY") or os.getenv("ATLAS_CLOUD_API_KEY")
567
568 if not gemini_key and not openai_key and not atlascloud_key:
569 raise HTTPException(
570 status_code=400,
571 detail=(
572 "AI querying requires GEMINI_API_KEY, OPENAI_API_KEY, or ATLASCLOUD_API_KEY. "
573 "Please set one in your configuration or .env."
574 )
575 )
576
577 query = request.query
578 repo_path = request.repo_path
579
580 translation_prompt = """You are an expert graph database administrator. Translate the user's natural language question about a codebase into a valid read-only Cypher query.
581
582The graph database represents the codebase structure with the following schema:
583### Nodes & Properties:
584* **`Repository`**: `name` (string), `path` (string, absolute path), `is_dependency` (boolean)
585* **`File`**: `name` (string), `path` (string, absolute path), `relative_path` (string), `is_dependency` (boolean)
586* **`Function`**: `name` (string), `path` (string, absolute path), `line_number` (int), `end_line` (int), `args` (list of strings), `cyclomatic_complexity` (int), `decorators` (list of strings), `lang` (string), `source` (string), `is_dependency` (boolean)
587* **`Class`**: `name` (string), `path` (string, absolute path), `line_number` (int), `end_line` (int), `bases` (list of strings), `decorators` (list of strings), `lang` (string), `source` (string), `is_dependency` (boolean)
588* **`Interface`**, **`Struct`**, **`Enum`**, **`Trait`**: similar properties to Class/Function
589* **`Module`**: `name` (string)
590
591### Relationships:
592* **`CONTAINS`**: (Repository)-[:CONTAINS]->(File), (File)-[:CONTAINS]->(Function), (File)-[:CONTAINS]->(Class)
593* **`CALLS`**: (Function)-[:CALLS]->(Function)
594* **`IMPORTS`**: (File)-[:IMPORTS]->(Module)
595* **`INHERITS`**: (Class)-[:INHERITS]->(Class)
596* **`IMPLEMENTS`**: (Class)-[:IMPLEMENTS]->(Interface)
597
598### Query Writing Rules:
5991. Only write SELECT/MATCH read-only queries. Do NOT use CREATE, MERGE, DELETE, SET, REMOVE, or other modifying keywords.
6002. Return nodes using the variable names `n` and `m`, and relationships using `rel` where possible. This is critical for the visualizer.
601 Example: MATCH (n:Class)-[rel:INHERITS]->(m:Class) RETURN n, rel, m
6023. Keep the query simple and efficient. Limit results using `LIMIT 150` unless more are needed.
6034. If the user asks about dependencies or paths, try to return paths using variables, and return nodes/relationships.
6045. Make property matches case-insensitive or fuzzy if appropriate (e.g. using `toLower(n.name) CONTAINS 'auth'` or `n.name =~ '(?i).*auth.*'`).
6056. If the user is querying a specific repository, you can filter by `Repository.path` or `Repository.name` if path is supplied.
606
607Respond ONLY with a JSON object in this format:
608{
609 "cypher_query": "MATCH ... RETURN n, rel, m LIMIT 100",
610 "explanation": "Brief description of what this Cypher query does"
611}
612"""
613
614 try:
615 # Call LLM to get Cypher
616 llm_response = call_llm(translation_prompt, query)
617 parsed_response = parse_json_from_llm(llm_response)

Callers

nothing calls this directly

Calls 12

call_llmFunction · 0.85
parse_json_from_llmFunction · 0.85
_read_session_kwargsFunction · 0.85
parse_elementFunction · 0.85
itemsMethod · 0.80
getMethod · 0.65
appendMethod · 0.65
sessionMethod · 0.45
get_driverMethod · 0.45
runMethod · 0.45
valuesMethod · 0.45

Tested by

no test coverage detected