| module.exports.SqlAgentQuery = { | |
| name: "sql-query", | |
| plugin: function () { | |
| const { | |
| getDBClient, | |
| listSQLConnections, | |
| } = require("./SQLConnectors/index.js"); | |
| return { | |
| name: "sql-query", | |
| setup(aibitat) { | |
| aibitat.function({ | |
| super: aibitat, | |
| name: this.name, | |
| description: | |
| "Run a read-only SQL query on a `database_id` which will return up rows of data related to the query. The query must only be SELECT statements which do not modify the table data. There should be a reasonable LIMIT on the return quantity to prevent long-running or queries which crash the db.", | |
| examples: [ | |
| { | |
| prompt: "How many customers are in dvd-rentals?", | |
| call: JSON.stringify({ | |
| database_id: "dvd-rentals", | |
| sql_query: "SELECT * FROM customers", | |
| }), | |
| }, | |
| { | |
| prompt: "Can you tell me the total volume of sales last month?", | |
| call: JSON.stringify({ | |
| database_id: "sales-db", | |
| sql_query: | |
| "SELECT SUM(sale_amount) AS total_sales FROM sales WHERE sale_date >= DATEADD(month, -1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)) AND sale_date < DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)", | |
| }), | |
| }, | |
| { | |
| prompt: | |
| "Do we have anyone in the staff table for our production db named 'sam'? ", | |
| call: JSON.stringify({ | |
| database_id: "production", | |
| sql_query: | |
| "SElECT * FROM staff WHERE first_name='sam%' OR last_name='sam%'", | |
| }), | |
| }, | |
| ], | |
| parameters: { | |
| $schema: "http://json-schema.org/draft-07/schema#", | |
| type: "object", | |
| properties: { | |
| database_id: { | |
| type: "string", | |
| description: | |
| "The database identifier for which we will connect to to query the table schema. This is required to run the SQL query.", | |
| }, | |
| sql_query: { | |
| type: "string", | |
| description: | |
| "The raw SQL query to run. Should be a query which does not modify the table and will return results.", | |
| }, | |
| }, | |
| additionalProperties: false, | |
| }, | |
| required: ["database_id", "table_name"], | |
| handler: async function ({ database_id = "", sql_query = "" }) { | |
| this.super.handlerProps.log(`Using the sql-query tool.`); | |
| try { | |
| const databaseConfig = (await listSQLConnections()).find( | |
| (db) => db.database_id === database_id | |
| ); | |
| if (!databaseConfig) { | |
| this.super.handlerProps.log( | |
| `sql-query failed to find config!`, | |
| database_id | |
| ); | |
| return `No database connection for ${database_id} was found!`; | |
| } | |
| this.super.introspect( | |
| `${this.caller}: Im going to run a query on the ${database_id} to get an answer.` | |
| ); | |
| const db = getDBClient(databaseConfig.engine, databaseConfig); | |
| this.super.introspect(`Running SQL: ${sql_query}`); | |
| const result = await db.runQuery(sql_query); | |
| if (result.error) { | |
| this.super.handlerProps.log( | |
| `sql-query tool reported error`, | |
| result.error | |
| ); | |
| this.super.introspect(`Error: ${result.error}`); | |
| return `There was an error running the query: ${result.error}`; | |
| } | |
| return JSON.stringify(result); | |
| } catch (e) { | |
| console.error(e); | |
| return e.message; | |
| } | |
| }, | |
| }); | |
| }, | |
| }; | |
| }, | |
| }; | |