�� WyzeAssist Multi-Agent System

AI-powered legal billing analytics with advanced multi-agent architecture using LangGraph

🎯 System Architecture

�� Supervisor Agent

Orchestrates the workflow, makes routing decisions, and coordinates between specialized agents

🔍 Query Expander Agent

Expands abbreviations, clarifies ambiguous queries, and provides contextual recommendations

💾 SQL Agent

Generates optimized SQL queries, executes them safely, and provides intelligent summaries

🔌 API Endpoints

FE routing (required)

When the user searches from an active datagrid listing, always call classify first:

  1. POST /classify-intent — body: {"query": "…", "listing": "matters"} (listing = active grid: clients, matters, timekeeper, rateSets, …)
  2. If intent is wyzesearchPOST /convert-filter with the same query and stub.listing
  3. If intent is wyzeassistPOST /query?stream=true with question, firm_id, listing, and Bearer authorization / idtoken headers

Response includes next_endpoint, use_stream, and routing_message so the FE does not guess.

POST /classify-intent

Classify query intent before routing to WyzeSearch or WyzeAssist

{ "query": "my matters with low realization", "listing": "matters" }

POST /query

Main endpoint for processing legal billing queries

{ "question": "Show me timekeepers with utilization above 80%", "firm_id": "your_firm_id", "user_name": "optional_user_name", "timekeeper_id": "optional_timekeeper_id" }

Headers (required for WyzeCloud-backed features): authorization: Bearer … and idtoken: … — same as WyzeCloud; used for RBAC, rate resolver, firm config, and portfolio KPI calls. No server-side env fallback.

Streaming: Add ?stream=true to enable real-time streaming

GET /health

System health check and status information

GET /agents/status

Detailed status of all agents in the system

POST /convert-filter

Convert natural language queries to structured database filters

Portfolio: when data.table is portfolio, spread data.queryParams onto GET /firm/clients/portfolio. Do not send the raw NL query as search= (API returns 400).

{ "query": "List Relationship Manager Rhonda Compher", "stub": { "listing": "portfolio", "portfolioTab": "relationshipManager", "user": "vivek-admin", "timekeeperId": "e48a008f-a68d-5eac-b1c5-d3680bc33785", "firmId": "7f09f939-8bae-4d4a-9e45-6096d93dae00" } }

Example data.queryParams: page=1&limit=20&portfolioTab=relationshipManager&relationshipManagerName=Rhonda+Compher

{ "query": "List my matters with realization > 70%", "stub": { "listing": "matters", "user": "vivek-admin", "timekeeperId": "e48a008f-a68d-5eac-b1c5-d3680bc33785", "firmId": "7f09f939-8bae-4d4a-9e45-6096d93dae00" } }

�� Example Queries

🔍 Example Filter Queries

🔧 Features