|
| 1 | +"""genie-analyzer — LLM-powered deep analysis of Genie Space configurations. |
| 2 | +
|
| 3 | +Extracted from: |
| 4 | + - backend/routers/analysis.py (fetch, analyze, stream, query, SQL endpoints) |
| 5 | + - backend/services/analyzer.py (GenieSpaceAnalyzer, section analysis, synthesis) |
| 6 | + - backend/synthesizer.py (cross-section synthesis) |
| 7 | + - backend/services/genie_client.py (space fetching) |
| 8 | +
|
| 9 | +Streaming: Yes (SSE for multi-section analysis) |
| 10 | +LLM: Yes (section analysis + synthesis) |
| 11 | +""" |
| 12 | + |
| 13 | +from __future__ import annotations |
| 14 | + |
| 15 | +from dbx_agent_app import AgentRequest, AgentResponse, app_agent |
| 16 | + |
| 17 | + |
| 18 | +@app_agent( |
| 19 | + name="genie-analyzer", |
| 20 | + description=( |
| 21 | + "Deep LLM-powered analysis of Genie Space configurations. Evaluates " |
| 22 | + "each section (tables, instructions, SQL snippets, etc.) against a " |
| 23 | + "checklist, synthesizes findings, and provides actionable recommendations." |
| 24 | + ), |
| 25 | +) |
| 26 | +async def analyzer(request: AgentRequest) -> AgentResponse: |
| 27 | + """Route incoming agent requests to analysis tools.""" |
| 28 | + # TODO: Parse intent from request.messages and dispatch to tools |
| 29 | + ... |
| 30 | + |
| 31 | + |
| 32 | +# ── Tools ──────────────────────────────────────────────────────────────────── |
| 33 | + |
| 34 | + |
| 35 | +@analyzer.tool( |
| 36 | + description=( |
| 37 | + "Fetch and parse a Genie Space by ID. Returns the space data " |
| 38 | + "and list of sections with their data." |
| 39 | + ), |
| 40 | +) |
| 41 | +async def fetch_space(genie_space_id: str) -> dict: |
| 42 | + """Source: backend/routers/analysis.py::fetch_space""" |
| 43 | + # Uses genie_client.get_serialized_space (moved as-is) |
| 44 | + raise NotImplementedError("Phase 4: move genie_client + analyzer here") |
| 45 | + |
| 46 | + |
| 47 | +@analyzer.tool( |
| 48 | + description=( |
| 49 | + "Analyze a single section of a Genie Space configuration. " |
| 50 | + "Returns findings, score, and recommendations for that section." |
| 51 | + ), |
| 52 | +) |
| 53 | +async def analyze_section( |
| 54 | + section_name: str, |
| 55 | + section_data: dict | list | None, |
| 56 | + full_space: dict, |
| 57 | +) -> dict: |
| 58 | + """Source: backend/services/analyzer.py::GenieSpaceAnalyzer.analyze_section""" |
| 59 | + raise NotImplementedError("Phase 4: move analyzer.py here") |
| 60 | + |
| 61 | + |
| 62 | +@analyzer.tool( |
| 63 | + description=( |
| 64 | + "Analyze all sections with cross-sectional synthesis. Returns " |
| 65 | + "section analyses plus a synthesis result for full analysis." |
| 66 | + ), |
| 67 | +) |
| 68 | +async def analyze_all( |
| 69 | + sections: list[dict], |
| 70 | + full_space: dict, |
| 71 | +) -> dict: |
| 72 | + """Source: backend/routers/analysis.py::analyze_all_sections""" |
| 73 | + raise NotImplementedError("Phase 4: move analyzer.py + synthesizer.py here") |
| 74 | + |
| 75 | + |
| 76 | +@analyzer.tool( |
| 77 | + description=( |
| 78 | + "Query a Genie Space with a natural language question. " |
| 79 | + "Returns the generated SQL if successful." |
| 80 | + ), |
| 81 | +) |
| 82 | +async def query_genie(genie_space_id: str, question: str) -> dict: |
| 83 | + """Source: backend/services/genie_client.py::query_genie_for_sql""" |
| 84 | + raise NotImplementedError("Phase 4: move genie_client.query_genie_for_sql here") |
| 85 | + |
| 86 | + |
| 87 | +@analyzer.tool( |
| 88 | + description=( |
| 89 | + "Execute a read-only SQL query on a Databricks SQL Warehouse. " |
| 90 | + "Returns tabular results limited to 1000 rows." |
| 91 | + ), |
| 92 | +) |
| 93 | +async def execute_sql(sql: str, warehouse_id: str | None = None) -> dict: |
| 94 | + """Source: backend/sql_executor.py::execute_sql |
| 95 | +
|
| 96 | + Phase 8: Replace with databricks_tools_core.sql.execute_sql |
| 97 | + """ |
| 98 | + raise NotImplementedError("Phase 4: move sql_executor.py (then Phase 8: replace with AI Dev Kit)") |
| 99 | + |
| 100 | + |
| 101 | +@analyzer.tool( |
| 102 | + description="Parse pasted Genie Space JSON from the API response.", |
| 103 | +) |
| 104 | +async def parse_space_json(json_content: str) -> dict: |
| 105 | + """Source: backend/routers/analysis.py::parse_space_json""" |
| 106 | + raise NotImplementedError("Phase 4: move parse logic here") |
| 107 | + |
| 108 | + |
| 109 | +# ── Standalone entry point ─────────────────────────────────────────────────── |
| 110 | + |
| 111 | +app = analyzer.app |
0 commit comments