Website: update query generator to use socket requests. (#25472)

Closes: #25465 

Changes:
- Updated the query generator page to use socket requests to call the
`get-llm-generated-sql` action to bypass Heroku's 30-second request
timeout.
This commit is contained in:
Eric
2025-01-15 16:31:37 -06:00
committed by GitHub
parent f5c3cfc6c7
commit bf182bed3e
4 changed files with 45 additions and 17 deletions
@@ -25,7 +25,12 @@ module.exports = {
fn: async function ({naturalLanguageQuestion}) {
// Generate a random room name.
let roomId = await sails.helpers.strings.random();
if(this.req.isSocket) {
// Add the requesting socket to the room.
sails.sockets.join(this.req, roomId);
}
let completeTables = sails.config.builtStaticContent.schemaTables;
let prunedTables = completeTables.map((table)=>{
let newTable = _.pick(table,['name','description','platforms', 'examples']);
@@ -55,7 +60,12 @@ module.exports = {
Please respond in JSON, with the same data shape as the provided context, but with the array filtered to include only relevant tables.`;
let filteredTables = await sails.helpers.ai.prompt(schemaFiltrationPrompt, 'gpt-4o', true)
.intercept((err)=>{
return new Error(`When trying to get a subset of tables to use to generate a query for an Admin user, the Open AI API returned an error. Full error: ${require('util').inspect(err, {depth: 2})}`);
if(this.req.isSocket){
// If this request was from a socket and an error occurs, broadcast an 'error' event and unsubscribe the socket from this room.
sails.sockets.broadcast(roomId, 'error', {error: err});
sails.sockets.leave(this.req, roomId);
}
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})}`);
});
@@ -95,9 +105,22 @@ module.exports = {
}`;
let sqlReport = await sails.helpers.ai.prompt(sqlPrompt, 'o1-preview', true)
.intercept((err)=>{
return new Error(`When trying to generate a query for an Admin user, the Open AI API returned an error. Full error: ${require('util').inspect(err, {depth: 2})}`);
if(this.req.isSocket){
// If this request was from a socket and an error occurs, broadcast an 'error' event and unsubscribe the socket from this room.
sails.sockets.broadcast(roomId, 'error', {error: err});
sails.sockets.leave(this.req, roomId);
}
return new Error(`When trying to generate a query for an Admin user, an error occurred. Full error: ${require('util').inspect(err, {depth: 2})}`);
});
return sqlReport;
// If this request was from a socket, we'll broadcast a 'queryGenerated' event with the sqlReport and unsubscribe the socket
if(this.req.isSocket){
sails.sockets.broadcast(roomId, 'queryGenerated', {result: sqlReport});
sails.sockets.leave(this.req, roomId);
} else {
// Otherwise, return the JSON sqlReport.
return sqlReport;
}
}
+15 -10
View File
@@ -36,17 +36,22 @@ parasails.registerPage('query-generator', {
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
methods: {
handleSubmittingForm: async function() {
let argins = this.formData.naturalLanguageQuestion;
this.queryResult = await Cloud.getLlmGeneratedSql(argins)
.tolerate((err)=>{
this.cloudError = err;
this.syncing = false;
});
this.syncing = true;
io.socket.get('/api/v1/query-generator/get-llm-generated-sql', {naturalLanguageQuestion: this.formData.naturalLanguageQuestion}, ()=>{});
io.socket.on('queryGenerated', this._onQueryResultsReturned);
io.socket.on('error', this._onQueryGenerationError);
},
submittedQueryForm: function() {
if(!this.cloudError){
this.showGeneratedQuery = true;
}
_onQueryResultsReturned: function(response) {
this.queryResult = response.result;
this.syncing = false;
this.showGeneratedQuery = true;
// Disable the socket event listener after we display the results.
io.socket.off('queryGenerated', this._onQueryResultsReturned);
},
_onQueryGenerationError: function(response) {
this.cloudError = response.error;
this.syncing = false;
io.socket.off('error', this._onQueryGenerationError);
},
clickResetQueryGenerator: function() {
this.showGeneratedQuery = false;
+1 -1
View File
@@ -914,5 +914,5 @@ module.exports.routes = {
'POST /api/v1/deliver-deal-registration-submission': { action: 'deliver-deal-registration-submission' },
'/api/v1/unsubscribe-from-marketing-emails': { action: 'unsubscribe-from-marketing-emails' },
'POST /api/v1/customers/get-stripe-checkout-session-url': { action: 'customers/get-stripe-checkout-session-url' },
'POST /api/v1/query-generator/get-llm-generated-sql': { action: 'query-generator/get-llm-generated-sql' },
'/api/v1/query-generator/get-llm-generated-sql': { action: 'query-generator/get-llm-generated-sql' },
};
+2 -2
View File
@@ -2,10 +2,10 @@
<div purpose="page-container">
<div purpose="page-content">
<ajax-form :handle-submitting="handleSubmittingForm" :syncing.sync="syncing" :cloud-error.sync="cloudError" :form-errors.sync="formErrors" :form-data="formData" :form-rules="formRules" @submitted="submittedQueryForm()" v-if="!showGeneratedQuery">
<ajax-form :handle-submitting="handleSubmittingForm" :cloud-error.sync="cloudError" :form-errors.sync="formErrors" :form-data="formData" :form-rules="formRules" v-if="!showGeneratedQuery">
<h3 class="mb-4">Query generator</h3>
<div class="form-group">
<label for="email-address">Ask a question</label>
<label for="email-address">Ask a question about your devices to generate queries</label>
<textarea class="form-control" type="textarea" id="email-address" :class="[formErrors.naturalLanguageQuestion ? 'is-invalid' : '']" v-model.trim="formData.naturalLanguageQuestion"></textarea>
<div class="invalid-feedback" v-if="formErrors.naturalLanguageQuestion" focus-first>Ask your question.</div>
</div>