-
-
Notifications
You must be signed in to change notification settings - Fork 18
improved query extraction #1652
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -484,7 +484,7 @@ ${currentQuery} | |||||
|
|
||||||
| ${feedbackSection} | ||||||
|
|
||||||
| Respond with SQL only. Preserve column aliases. Valid ${connectionType} syntax.`; | ||||||
| CRITICAL: Respond with the SQL query ONLY — no explanations, no comments, no markdown, no text before or after the query. Just the raw SQL statement. Preserve column aliases. Valid ${connectionType} syntax.`; | ||||||
| } | ||||||
|
|
||||||
| private cleanQueryResponse(aiResponse: string): string { | ||||||
|
|
@@ -500,8 +500,35 @@ Respond with SQL only. Preserve column aliases. Valid ${connectionType} syntax.` | |||||
| if (parsed.query_text) { | ||||||
| return parsed.query_text; | ||||||
| } | ||||||
| } catch { | ||||||
| // Not valid JSON, return as-is | ||||||
| } catch {} | ||||||
| } | ||||||
|
|
||||||
| // If AI included explanatory text around the SQL, extract the SQL statement. | ||||||
| const sqlPrefixes = ['SELECT', 'WITH', 'SHOW', 'DESCRIBE', 'DESC', 'EXPLAIN']; | ||||||
| const upperCleaned = cleaned.toUpperCase(); | ||||||
| const startsWithSql = sqlPrefixes.some((prefix) => upperCleaned.startsWith(prefix)); | ||||||
|
|
||||||
| if (!startsWithSql) { | ||||||
| const sqlPattern = new RegExp( | ||||||
| `^(${sqlPrefixes.join('|')})\\b`, | ||||||
| 'im', | ||||||
| ); | ||||||
| const match = cleaned.match(sqlPattern); | ||||||
| if (match) { | ||||||
| const sqlStart = cleaned.indexOf(match[0]); | ||||||
|
||||||
| const sqlStart = cleaned.indexOf(match[0]); | |
| const sqlStart = match.index ?? cleaned.indexOf(match[0]); |
Copilot
AI
Mar 6, 2026
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.
The entire cleanQueryResponse method (and buildQueryCorrectionPrompt, normalizeWhitespace, mapPanelType) are duplicated verbatim across this file and generate-panel-position-with-ai.use.case.ts. This duplication means any bug fix or improvement must be applied in both places, which is error-prone. Consider extracting the shared SQL-cleaning logic into a shared utility function (e.g., in a utils file alongside check-query-is-safe.util.ts) that both use cases can import.
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.
Bug:
cleaned.indexOf(match[0])may find the wrong occurrence of the SQL keyword. When the regex matches a keyword at the start of a line (due to themflag), it might not be the first occurrence of that keyword in the text. For example, if the AI response is"The SELECT query has been fixed:\nSELECT * FROM table;", the regex correctly matchesSELECTat the start of the second line, butindexOf('SELECT')returns the position ofSELECTin the first line's explanatory text.Use
match.indexinstead ofcleaned.indexOf(match[0])— the match object from a non-global regex already includes the position of the match.