- Notifications
You must be signed in to change notification settings - Fork27
Add database feedback#337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:staging
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Changes from4 commits
c07799d54c19024100807971f23a66914ffd606e6aef82f87f498148File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -18,18 +18,25 @@ def get_analysis( # pylint: disable=too-many-arguments, too-many-positional-arg | ||
| db_description: str, | ||
| instructions: str | None = None, | ||
| memory_context: str | None = None, | ||
| database_type: str | None = None, | ||
| ) -> dict: | ||
| """Get analysis of user query against database schema.""" | ||
| formatted_schema = self._format_schema(combined_tables) | ||
| # Add system message with database type if not already present | ||
| if not self.messages or self.messages[0].get("role") != "system": | ||
| self.messages.insert(0, { | ||
| "role": "system", | ||
| "content": f"You are a SQL expert. TARGET DATABASE: {database_type.upper() if database_type else 'UNKNOWN'}" | ||
| }) | ||
galshubeli marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| prompt = self._build_prompt( | ||
| user_query, formatted_schema, db_description, instructions, memory_context, database_type | ||
| ) | ||
| self.messages.append({"role": "user", "content": prompt}) | ||
| completion_result = completion( | ||
| model=Config.COMPLETION_MODEL, | ||
| messages=self.messages, | ||
| temperature=0, | ||
| ) | ||
| response = completion_result.choices[0].message.content | ||
| @@ -158,7 +165,8 @@ def _format_foreign_keys(self, foreign_keys: dict) -> str: | ||
| def _build_prompt( # pylint: disable=too-many-arguments, too-many-positional-arguments | ||
| self, user_input: str, formatted_schema: str, | ||
| db_description: str, instructions, memory_context: str | None = None, | ||
| database_type: str | None = None, | ||
| ) -> str: | ||
| """ | ||
| Build the prompt for Claude to analyze the query. | ||
| @@ -169,6 +177,7 @@ def _build_prompt( # pylint: disable=too-many-arguments, too-many-positional-a | ||
| db_description: Description of the database | ||
| instructions: Custom instructions for the query | ||
| memory_context: User and database memory context from previous interactions | ||
| database_type: Target database type (sqlite, postgresql, mysql, etc.) | ||
| Returns: | ||
| The formatted prompt for Claude | ||
| @@ -196,13 +205,18 @@ def _build_prompt( # pylint: disable=too-many-arguments, too-many-positional-a | ||
| prompt = f""" | ||
| You must strictly follow the instructions below. Deviations will result in a penalty to your confidence score. | ||
| TARGET DATABASE: {database_type.upper() if database_type else 'UNKNOWN'} | ||
| MANDATORY RULES: | ||
| - Always explain if you cannot fully follow the instructions. | ||
| - Always reduce the confidence score if instructions cannot be fully applied. | ||
| - Never skip explaining missing information, ambiguities, or instruction issues. | ||
| - Respond ONLY in strict JSON format, without extra text. | ||
| - If the query relates to a previous question, you MUST take into account the previous question and its answer, and answer based on the context and information provided so far. | ||
| - CRITICAL: When table or column names contain special characters (especially dashes/hyphens like '-'), you MUST wrap them in double quotes for PostgreSQL (e.g., "table-name") or backticks for MySQL (e.g., `table-name`). This is NON-NEGOTIABLE. | ||
| - CRITICAL NULL HANDLING: When using calculated columns (divisions, ratios, arithmetic) with ORDER BY or LIMIT, you MUST filter out NULL values. Add "WHERE calculated_expression IS NOT NULL" or include the NULL check in your WHERE clause. NULL values sort first in ascending order and can produce incorrect results. | ||
| - CRITICAL SELECT CLAUSE: Only return columns explicitly requested in the question. If the question asks for "the highest rate" or "the lowest value", return ONLY that calculated value, not additional columns like names or IDs unless specifically asked. Use aggregate functions (MAX, MIN, AVG) when appropriate for "highest", "lowest", "average" queries instead of ORDER BY + LIMIT. | ||
| - CRITICAL VALUE MATCHING: When multiple columns could answer a question (e.g., "continuation schools"), prefer the column whose allowed values list contains an EXACT or CLOSEST string match to the question term. For example, if the question mentions "continuation schools", prefer a column with value "Continuation School" over "Continuation High Schools". Check the column descriptions for "Optional values" lists and match question terminology to those exact value strings. | ||
| If the user is asking a follow-up or continuing question, use the conversation history and previous answers to resolve references, context, or ambiguities. Always base your analysis on the cumulative context, not just the current question. | ||
| @@ -299,6 +313,10 @@ def _build_prompt( # pylint: disable=too-many-arguments, too-many-positional-a | ||
| 12. Learn from successful query patterns in memory context and avoid failed approaches. | ||
| 13. For personal queries, FIRST check memory context for user identification. If user identity is found in memory context (user name, previous personal queries, etc.), the query IS translatable. | ||
| 14. CRITICAL PERSONALIZATION CHECK: If missing user identification/personalization is a significant or primary component of the query (e.g., "show my orders", "my account balance", "my recent purchases", "how many employees I have", "products I own") AND no user identification is available in memory context or schema, set "is_sql_translatable" to false. However, if memory context contains user identification (like user name or previous successful personal queries), then personal queries ARE translatable even if they are the primary component of the query. | ||
| 15. CRITICAL: When generating queries with calculated columns (division, multiplication, etc.) that are used in ORDER BY or compared with LIMIT, ALWAYS add NULL filtering. For example: "WHERE (column1 / column2) IS NOT NULL" before ORDER BY. This prevents NULL values (from NULL numerators or denominators) from appearing in results. | ||
| 16. SELECT CLAUSE PRECISION: Only include columns explicitly requested in the question. If a question asks "What is the highest rate?" return ONLY the rate value, not additional columns. Questions asking for "the highest/lowest/average X" should prefer aggregate functions (MAX, MIN, AVG) over ORDER BY + LIMIT, as aggregates are more concise and automatically handle what to return. | ||
| 17. VALUE-BASED COLUMN SELECTION: When choosing between similar columns (e.g., "School Type" vs "Educational Option Type"), examine the "Optional values" lists in column descriptions. Prefer the column where a value EXACTLY or MOST CLOSELY matches the terminology in the question. For example, "continuation schools" should map to a column with value "Continuation School" rather than "Continuation High Schools". This string matching takes priority over column name similarity. | ||
| 18. NULL HANDLING IN CALCULATIONS: When a query involves calculated expressions (like col1/col2) used with ORDER BY, filtering (WHERE), or LIMIT, ensure NULL values are explicitly filtered out. Use "AND (expression) IS NOT NULL" in the WHERE clause. This is especially important for division operations where either numerator or denominator can be NULL. | ||
| Again: OUTPUT ONLY VALID JSON. No explanations outside the JSON block. """ # pylint: disable=line-too-long | ||
| return prompt | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,288 @@ | ||||||||||||||||||||
| """ | ||||||||||||||||||||
| HealerAgent - Specialized agent for fixing SQL syntax errors. | ||||||||||||||||||||
| This agent focuses solely on correcting SQL queries that failed execution, | ||||||||||||||||||||
| without requiring full graph context. It uses the error message and the | ||||||||||||||||||||
| failed query to generate a corrected version. | ||||||||||||||||||||
| """ | ||||||||||||||||||||
| importjson | ||||||||||||||||||||
| importre | ||||||||||||||||||||
| fromtypingimportDict,Optional | ||||||||||||||||||||
| fromlitellmimportcompletion | ||||||||||||||||||||
| from .utilsimportparse_response | ||||||||||||||||||||
| fromapi.configimportConfig | ||||||||||||||||||||
CopilotAI | ||||||||||||||||||||
galshubeli marked this conversation as resolved.Show resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
CopilotAIDec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Theinit docstring is empty except for boilerplate text. Either add meaningful documentation about what initialization does or remove the empty docstring entirely since the method has no parameters or initialization logic.
| """ | |
| InitializetheHealerAgent. | |
| """ | |
| pass | |
CopilotAIDec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Blank line 27 contains trailing whitespace. Remove trailing whitespace from empty lines for consistency.
CopilotAIDec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Comment references "text-to-cypher PR" which is an external context that won't be meaningful to future maintainers. Consider removing this reference or explaining what validation patterns were borrowed from that work.
| SimilartoCypherValidatorinthetext-to-cypherPR. | |
| PerformschecksforpresenceofSQLkeywords,dangerousoperations,andbalancedparentheses,inspiredbycommonvalidationpatternsusedinqueryvalidators. |
CopilotAIDec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Blank line 89 contains trailing whitespace. Remove trailing whitespace from empty lines for consistency.
galshubeli marked this conversation as resolved.Show resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
CopilotAIDec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Return type annotation uses lowercase 'any' instead of 'Any'. In Python type hints, the correct type is 'Any' from the typing module (already imported). Change 'any' to 'Any'.
CopilotAIDec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Blank line 122 contains trailing whitespace. Remove trailing whitespace from empty lines for consistency.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.