Skip to content

Commit 5748fac

Browse files
authored
Website: update query generator (#26926)
Related to: fleetdm/confidential#9884 Changes: - Updated the prompt in the `get-llm-generated-sql` action to include a note about using wildcard characters when generating queries that use the LIKE operator. - Improved error handling in the `get-llm-generated-sql` action
1 parent 6275289 commit 5748fac

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed

website/api/controllers/query-generator/get-llm-generated-sql.js

+46-10
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ module.exports = {
1818
description: 'A SQL query was generated'
1919
},
2020

21-
errorFromOpenAi: {
22-
description: 'The Open AI API reutrned an error.'
21+
couldNotGenerateQueries: {
22+
description: 'A set of queries could not be generated for a user using the provided question.',
23+
responseType: 'badRequest'
2324
}
2425
},
2526

@@ -57,17 +58,34 @@ module.exports = {
5758
return lighterTable;}))}
5859
\`\`\`
5960
60-
Please respond in JSON, with the same data shape as the provided context, but with the array filtered to include only relevant tables.`;
61+
Please respond in JSON, with the same data shape as the provided context, but with the array filtered to include only relevant tables.
62+
63+
64+
If no queries can be generated from the provided instructions do not return the datashape above and instead return this JSON in this exact data shape:
65+
66+
{
67+
"couldNotGenerateQueries": true
68+
}`;
69+
6170
let filteredTables = await sails.helpers.ai.prompt(schemaFiltrationPrompt, 'gpt-4o-mini-2024-07-18', true, 'Please only respond in valid JSON with no codefences or backticks.')
6271
.intercept((err)=>{
72+
sails.log.warn(`When trying to get a subset of tables to use to generate a query for a user, an error occurred. Full error: ${require('util').inspect(err, {depth: 2})}`);
6373
if(this.req.isSocket){
6474
// If this request was from a socket and an error occurs, broadcast an 'error' event and unsubscribe the socket from this room.
6575
sails.sockets.broadcast(roomId, 'error', {error: err});
6676
sails.sockets.leave(this.req, roomId);
6777
}
68-
return new Error(`When trying to get a subset of tables to use to generate a query for an Admin user, an error occurred. Full error: ${require('util').inspect(err, {depth: 2})}`);
78+
return 'couldNotGenerateQueries';
6979
});
7080

81+
if(filteredTables.couldNotGenerateQueries){
82+
if(this.req.isSocket){
83+
sails.sockets.broadcast(roomId, 'error', {error: 'couldNotGenerateQueries'});
84+
sails.sockets.leave(this.req, roomId);
85+
} else {
86+
throw 'couldNotGenerateQueries';
87+
}
88+
}
7189

7290
// 2024-02-26: Testing using a system prompt with a single API request.
7391
// let systemPrompt = `You are an AI that generates osquery SQL queries for IT admin questions. Use the following osquery schema as context:
@@ -120,11 +138,12 @@ module.exports = {
120138
121139
When generating the SQL:
122140
1. Please do not use the SQL "AS" operator, nor alias tables. Always reference tables by their full name.
123-
2. If this question is related to an application or program, consider using LIKE instead of something verbatim.
124-
3. If this question is not possible to ask given the tables and columns available in the provided context (the osquery schema) for a particular operating system, then use empty string.
125-
4. If this question is a "yes" or "no" question, or a "how many people" question, or a "how many hosts" question, then build the query such that a "yes" returns exactly one row and a "no" returns zero rows. In other words, if this question is about finding out which hosts match a "yes" or "no" question, then if a host does not match, do not include any rows for it.
126-
5. Use only tables that are supported for each target platform, as documented in the provided context, considering the examples if they exist, and the available columns.
127-
6. For each table that you use, only use columns that are documented for that table, as documented in the provided context.
141+
2. When generating a query that uses the "LIKE" operator, you should include wildcard characters.
142+
3. If this question is related to an application or program, consider using LIKE instead of something verbatim.
143+
4. If this question is not possible to ask given the tables and columns available in the provided context (the osquery schema) for a particular operating system, then use empty string.
144+
5. If this question is a "yes" or "no" question, or a "how many people" question, or a "how many hosts" question, then build the query such that a "yes" returns exactly one row and a "no" returns zero rows. In other words, if this question is about finding out which hosts match a "yes" or "no" question, then if a host does not match, do not include any rows for it.
145+
6. Use only tables that are supported for each target platform, as documented in the provided context, considering the examples if they exist, and the available columns.
146+
7. For each table that you use, only use columns that are documented for that table, as documented in the provided context.
128147
129148
Provided context:
130149
\`\`\`
@@ -142,6 +161,13 @@ module.exports = {
142161
"windowsCaveats": "TODO",
143162
"linuxCaveats": "TODO",
144163
"chromeOSCaveats": "TODO",
164+
}
165+
166+
167+
If no queries can be generated from the provided instructions do not return the datashape above and instead return this JSON in this exact data shape:
168+
169+
{
170+
"couldNotGenerateQueries": true
145171
}`;
146172

147173
let sqlReport = await sails.helpers.ai.prompt.with({prompt:sqlPrompt, baseModel:'o3-mini-2025-01-31', expectJson: true})
@@ -151,9 +177,19 @@ module.exports = {
151177
sails.sockets.broadcast(roomId, 'error', {error: err});
152178
sails.sockets.leave(this.req, roomId);
153179
}
154-
return new Error(`When trying to generate a query for an Admin user, an error occurred. Full error: ${require('util').inspect(err, {depth: 2})}`);
180+
sails.log.warn(`When trying to generate a query for a user, an error occurred. Full error: ${require('util').inspect(err, {depth: 2})}`);
181+
return 'couldNotGenerateQueries';
155182
});
156183

184+
if(sqlReport.couldNotGenerateQueries){
185+
if(this.req.isSocket){
186+
sails.sockets.broadcast(roomId, 'error', {error: 'couldNotGenerateQueries'});
187+
sails.sockets.leave(this.req, roomId);
188+
} else {
189+
throw 'couldNotGenerateQueries';
190+
}
191+
}
192+
157193
// If this request was from a socket, we'll broadcast a 'queryGenerated' event with the sqlReport and unsubscribe the socket
158194
if(this.req.isSocket){
159195
sails.sockets.broadcast(roomId, 'queryGenerated', {result: sqlReport});

0 commit comments

Comments
 (0)