Genesis
This commit is contained in:
146
summarize_sql.js
Normal file
146
summarize_sql.js
Normal file
@@ -0,0 +1,146 @@
|
||||
// summarize_sql.js
|
||||
// Usage: node summarize_sql.js <inputfile.sql>
|
||||
// Requires: OPENAI_API_KEY in environment
|
||||
|
||||
require('dotenv').config();
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { OpenAI } = require('openai');
|
||||
|
||||
if (!process.env.OPENAI_API_KEY) {
|
||||
console.error('Error: OPENAI_API_KEY environment variable is required.');
|
||||
console.error('Please create a .env file with your OpenAI API key or set the environment variable.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY,
|
||||
});
|
||||
|
||||
if (process.argv.length < 3) {
|
||||
console.error('Usage: node summarize_sql.js <inputfile.sql>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const inputFile = process.argv[2];
|
||||
const inputDir = path.dirname(inputFile);
|
||||
const baseName = path.basename(inputFile, '.sql');
|
||||
const summaryFile = path.join(inputDir, baseName + '.summary.txt');
|
||||
|
||||
function findTableOrViewFile(schemaDotName) {
|
||||
// e.g. "Amazon.tVcsLiteUploadQueue" => tables/Amazon.tVcsLiteUploadQueue.sql
|
||||
const tablesDir = path.join(__dirname, 'tables');
|
||||
const file = path.join(tablesDir, schemaDotName + '.sql');
|
||||
if (fs.existsSync(file)) {
|
||||
return file;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function readTableOrView(schemaDotName) {
|
||||
const file = findTableOrViewFile(schemaDotName);
|
||||
if (!file) return `-- Definition for ${schemaDotName} not found.`;
|
||||
return fs.readFileSync(file, 'utf8');
|
||||
}
|
||||
|
||||
const SYSTEM_PROMPT = `
|
||||
You are a SQL expert assistant. Your task is to help the user understand the definition and logic of a given SQL stored procedure or view.
|
||||
- Focus on explaining the purpose, main logic, and important details of the procedure/view.
|
||||
- If you need to look up the definition of a table or view referenced in the code, you can call the function read_table_or_view(schemaDotName) (e.g. read_table_or_view('Amazon.tVcsLiteUploadQueue')) and you will receive the full CREATE statement for that object.
|
||||
- If you need more than one table/view definition, call read_table_or_view multiple times.
|
||||
- Be concise but thorough. Output your summary in clear, readable language.
|
||||
`;
|
||||
|
||||
async function main() {
|
||||
const sqlText = fs.readFileSync(inputFile, 'utf8');
|
||||
let messages = [
|
||||
{ role: 'system', content: SYSTEM_PROMPT },
|
||||
{ role: 'user', content: `Please summarize the following SQL stored procedure or view:\n\n${sqlText}` }
|
||||
];
|
||||
|
||||
// Function tool definition for OpenAI function-calling
|
||||
const functions = [
|
||||
{
|
||||
name: "read_table_or_view",
|
||||
description: "Get the CREATE statement for a table or view by schema.name",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
schemaDotName: {
|
||||
type: "string",
|
||||
description: "The schema and name, e.g. 'Amazon.tVcsLiteUploadQueue'"
|
||||
}
|
||||
},
|
||||
required: ["schemaDotName"]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
let summary = null;
|
||||
let maxToolCalls = 5; // Prevent infinite loops
|
||||
|
||||
while (maxToolCalls-- > 0) {
|
||||
// Log model call
|
||||
console.log('\n--- Model Call ---');
|
||||
console.log('Model:', "o4-mini");
|
||||
console.log('Messages:', JSON.stringify(messages, null, 2));
|
||||
console.log('Functions:', JSON.stringify(functions, null, 2));
|
||||
|
||||
const response = await openai.chat.completions.create({
|
||||
model: "o4-mini", // or "gpt-3.5-turbo-1106" if you don't have access to gpt-4o
|
||||
messages,
|
||||
service_tier: "flex",
|
||||
functions,
|
||||
function_call: "auto"
|
||||
});
|
||||
|
||||
const msg = response.choices[0].message;
|
||||
|
||||
if (msg.content) {
|
||||
summary = msg.content;
|
||||
break;
|
||||
} else if (msg.function_call) {
|
||||
// LLM is calling our tool
|
||||
const { name, arguments: argsJson } = msg.function_call;
|
||||
console.log('\n--- Tool Call ---');
|
||||
console.log('Function:', name);
|
||||
console.log('Arguments:', argsJson);
|
||||
if (name === "read_table_or_view") {
|
||||
let args;
|
||||
try {
|
||||
args = JSON.parse(argsJson);
|
||||
} catch (e) {
|
||||
messages.push({ role: 'assistant', content: "Error: Invalid function call arguments." });
|
||||
continue;
|
||||
}
|
||||
const def = readTableOrView(args.schemaDotName);
|
||||
// Log tool result (truncate if large)
|
||||
const defPreview = def.length > 500 ? def.slice(0, 500) + '...[truncated]' : def;
|
||||
console.log('Result:', defPreview);
|
||||
messages.push({
|
||||
role: 'function',
|
||||
name: 'read_table_or_view',
|
||||
content: def
|
||||
});
|
||||
} else {
|
||||
messages.push({ role: 'assistant', content: `Error: Unknown function ${name}` });
|
||||
}
|
||||
} else {
|
||||
messages.push({ role: 'assistant', content: "Error: No content or function call in response." });
|
||||
}
|
||||
}
|
||||
|
||||
if (!summary) {
|
||||
summary = "Error: Could not generate summary after several tool calls.";
|
||||
}
|
||||
|
||||
fs.writeFileSync(summaryFile, summary, 'utf8');
|
||||
console.log(`Summary written to ${summaryFile}`);
|
||||
}
|
||||
|
||||
main().catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
hi
|
||||
Reference in New Issue
Block a user