Refactor code for extensability

Refactor code for extensability
This commit is contained in:
Karthik KK
2025-04-13 20:35:08 +12:00
parent 27e0aac8de
commit 2de75b8fa6
13 changed files with 770 additions and 8 deletions

View File

@@ -0,0 +1,66 @@
import { dbAll } from '../db/index.js';
import { getDatabasePath } from '../db/index.js';
/**
* Handle listing resources request
* @returns List of available resources
*/
export async function handleListResources() {
try {
const databasePath = getDatabasePath();
const resourceBaseUrl = new URL(`sqlite:///${databasePath}`);
const SCHEMA_PATH = "schema";
const result = await dbAll(
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'"
);
return {
resources: result.map((row: any) => ({
uri: new URL(`${row.name}/${SCHEMA_PATH}`, resourceBaseUrl).href,
mimeType: "application/json",
name: `"${row.name}" database schema`,
})),
};
} catch (error: any) {
throw new Error(`Error listing resources: ${error.message}`);
}
}
/**
* Handle reading a specific resource
* @param uri URI of the resource to read
* @returns Resource contents
*/
export async function handleReadResource(uri: string) {
try {
const resourceUrl = new URL(uri);
const SCHEMA_PATH = "schema";
const pathComponents = resourceUrl.pathname.split("/");
const schema = pathComponents.pop();
const tableName = pathComponents.pop();
if (schema !== SCHEMA_PATH) {
throw new Error("Invalid resource URI");
}
// Query to get column information for a table
const result = await dbAll(`PRAGMA table_info("${tableName}")`);
return {
contents: [
{
uri,
mimeType: "application/json",
text: JSON.stringify(result.map((column: any) => ({
column_name: column.name,
data_type: column.type
})), null, 2),
},
],
};
} catch (error: any) {
throw new Error(`Error reading resource: ${error.message}`);
}
}

View File

@@ -0,0 +1,170 @@
import { formatErrorResponse } from '../utils/formatUtils.js';
// Import all tool implementations
import { readQuery, writeQuery, exportQuery } from '../tools/queryTools.js';
import { createTable, alterTable, dropTable, listTables, describeTable } from '../tools/schemaTools.js';
import { appendInsight, listInsights } from '../tools/insightTools.js';
/**
* Handle listing available tools
* @returns List of available tools
*/
export function handleListTools() {
return {
tools: [
{
name: "read_query",
description: "Execute SELECT queries to read data from the database",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
},
required: ["query"],
},
},
{
name: "write_query",
description: "Execute INSERT, UPDATE, or DELETE queries",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
},
required: ["query"],
},
},
{
name: "create_table",
description: "Create new tables in the database",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
},
required: ["query"],
},
},
{
name: "alter_table",
description: "Modify existing table schema (add columns, rename tables, etc.)",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
},
required: ["query"],
},
},
{
name: "drop_table",
description: "Remove a table from the database with safety confirmation",
inputSchema: {
type: "object",
properties: {
table_name: { type: "string" },
confirm: { type: "boolean" },
},
required: ["table_name", "confirm"],
},
},
{
name: "export_query",
description: "Export query results to various formats (CSV, JSON)",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
format: { type: "string", enum: ["csv", "json"] },
},
required: ["query", "format"],
},
},
{
name: "list_tables",
description: "Get a list of all tables in the database",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "describe_table",
description: "View schema information for a specific table",
inputSchema: {
type: "object",
properties: {
table_name: { type: "string" },
},
required: ["table_name"],
},
},
{
name: "append_insight",
description: "Add a business insight to the memo",
inputSchema: {
type: "object",
properties: {
insight: { type: "string" },
},
required: ["insight"],
},
},
{
name: "list_insights",
description: "List all business insights in the memo",
inputSchema: {
type: "object",
properties: {},
},
},
],
};
}
/**
* Handle tool call requests
* @param name Name of the tool to call
* @param args Arguments for the tool
* @returns Tool execution result
*/
export async function handleToolCall(name: string, args: any) {
try {
switch (name) {
case "read_query":
return await readQuery(args.query);
case "write_query":
return await writeQuery(args.query);
case "create_table":
return await createTable(args.query);
case "alter_table":
return await alterTable(args.query);
case "drop_table":
return await dropTable(args.table_name, args.confirm);
case "export_query":
return await exportQuery(args.query, args.format);
case "list_tables":
return await listTables();
case "describe_table":
return await describeTable(args.table_name);
case "append_insight":
return await appendInsight(args.insight);
case "list_insights":
return await listInsights();
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error: any) {
return formatErrorResponse(error);
}
}