@memberjunction/query-gen 0.0.1 → 2.126.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +34 -0
- package/COORDINATOR.md +768 -0
- package/IMPLEMENTATION_PLAN.md +1753 -0
- package/LLM_ENTITY_GROUPING_PLAN.md +977 -0
- package/README.md +675 -29
- package/dist/cli/commands/export.d.ts +15 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +178 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +19 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +282 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +17 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +193 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/config.d.ts +51 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +142 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +57 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/EntityGrouper.d.ts +74 -0
- package/dist/core/EntityGrouper.d.ts.map +1 -0
- package/dist/core/EntityGrouper.js +246 -0
- package/dist/core/EntityGrouper.js.map +1 -0
- package/dist/core/MetadataExporter.d.ts +59 -0
- package/dist/core/MetadataExporter.d.ts.map +1 -0
- package/dist/core/MetadataExporter.js +151 -0
- package/dist/core/MetadataExporter.js.map +1 -0
- package/dist/core/QueryDatabaseWriter.d.ts +50 -0
- package/dist/core/QueryDatabaseWriter.d.ts.map +1 -0
- package/dist/core/QueryDatabaseWriter.js +152 -0
- package/dist/core/QueryDatabaseWriter.js.map +1 -0
- package/dist/core/QueryFixer.d.ts +48 -0
- package/dist/core/QueryFixer.d.ts.map +1 -0
- package/dist/core/QueryFixer.js +115 -0
- package/dist/core/QueryFixer.js.map +1 -0
- package/dist/core/QueryRefiner.d.ts +94 -0
- package/dist/core/QueryRefiner.d.ts.map +1 -0
- package/dist/core/QueryRefiner.js +267 -0
- package/dist/core/QueryRefiner.js.map +1 -0
- package/dist/core/QueryTester.d.ts +70 -0
- package/dist/core/QueryTester.d.ts.map +1 -0
- package/dist/core/QueryTester.js +243 -0
- package/dist/core/QueryTester.js.map +1 -0
- package/dist/core/QueryWriter.d.ts +57 -0
- package/dist/core/QueryWriter.d.ts.map +1 -0
- package/dist/core/QueryWriter.js +184 -0
- package/dist/core/QueryWriter.js.map +1 -0
- package/dist/core/QuestionGenerator.d.ts +58 -0
- package/dist/core/QuestionGenerator.d.ts.map +1 -0
- package/dist/core/QuestionGenerator.js +145 -0
- package/dist/core/QuestionGenerator.js.map +1 -0
- package/dist/data/schema.d.ts +230 -0
- package/dist/data/schema.d.ts.map +1 -0
- package/dist/data/schema.js +6 -0
- package/dist/data/schema.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/PromptNames.d.ts +32 -0
- package/dist/prompts/PromptNames.d.ts.map +1 -0
- package/dist/prompts/PromptNames.js +35 -0
- package/dist/prompts/PromptNames.js.map +1 -0
- package/dist/utils/category-builder.d.ts +28 -0
- package/dist/utils/category-builder.d.ts.map +1 -0
- package/dist/utils/category-builder.js +90 -0
- package/dist/utils/category-builder.js.map +1 -0
- package/dist/utils/entity-helpers.d.ts +49 -0
- package/dist/utils/entity-helpers.d.ts.map +1 -0
- package/dist/utils/entity-helpers.js +189 -0
- package/dist/utils/entity-helpers.js.map +1 -0
- package/dist/utils/error-handlers.d.ts +19 -0
- package/dist/utils/error-handlers.d.ts.map +1 -0
- package/dist/utils/error-handlers.js +41 -0
- package/dist/utils/error-handlers.js.map +1 -0
- package/dist/utils/graph-helpers.d.ts +51 -0
- package/dist/utils/graph-helpers.d.ts.map +1 -0
- package/dist/utils/graph-helpers.js +82 -0
- package/dist/utils/graph-helpers.js.map +1 -0
- package/dist/utils/prompt-helpers.d.ts +25 -0
- package/dist/utils/prompt-helpers.d.ts.map +1 -0
- package/dist/utils/prompt-helpers.js +66 -0
- package/dist/utils/prompt-helpers.js.map +1 -0
- package/dist/utils/query-helpers.d.ts +23 -0
- package/dist/utils/query-helpers.d.ts.map +1 -0
- package/dist/utils/query-helpers.js +34 -0
- package/dist/utils/query-helpers.js.map +1 -0
- package/dist/utils/user-helpers.d.ts +15 -0
- package/dist/utils/user-helpers.d.ts.map +1 -0
- package/dist/utils/user-helpers.js +32 -0
- package/dist/utils/user-helpers.js.map +1 -0
- package/dist/vectors/EmbeddingService.d.ts +58 -0
- package/dist/vectors/EmbeddingService.d.ts.map +1 -0
- package/dist/vectors/EmbeddingService.js +90 -0
- package/dist/vectors/EmbeddingService.js.map +1 -0
- package/dist/vectors/SimilaritySearch.d.ts +51 -0
- package/dist/vectors/SimilaritySearch.d.ts.map +1 -0
- package/dist/vectors/SimilaritySearch.js +85 -0
- package/dist/vectors/SimilaritySearch.js.map +1 -0
- package/docs/API.md +1040 -0
- package/docs/ARCHITECTURE.md +1120 -0
- package/examples/advanced-usage.ts +401 -0
- package/examples/basic-usage.ts +285 -0
- package/package.json +48 -6
- package/src/cli/commands/export.ts +173 -0
- package/src/cli/commands/generate.ts +330 -0
- package/src/cli/commands/validate.ts +185 -0
- package/src/cli/config.ts +203 -0
- package/src/cli/index.ts +63 -0
- package/src/core/EntityGrouper.ts +318 -0
- package/src/core/MetadataExporter.ts +148 -0
- package/src/core/QueryDatabaseWriter.ts +187 -0
- package/src/core/QueryFixer.ts +153 -0
- package/src/core/QueryRefiner.ts +382 -0
- package/src/core/QueryTester.ts +264 -0
- package/src/core/QueryWriter.ts +239 -0
- package/src/core/QuestionGenerator.ts +199 -0
- package/src/data/golden-queries.json +1371 -0
- package/src/data/schema.ts +252 -0
- package/src/index.ts +49 -0
- package/src/prompts/PromptNames.ts +36 -0
- package/src/utils/category-builder.ts +97 -0
- package/src/utils/entity-helpers.ts +203 -0
- package/src/utils/error-handlers.ts +41 -0
- package/src/utils/graph-helpers.ts +99 -0
- package/src/utils/prompt-helpers.ts +79 -0
- package/src/utils/query-helpers.ts +32 -0
- package/src/utils/user-helpers.ts +39 -0
- package/src/vectors/EmbeddingService.ts +109 -0
- package/src/vectors/SimilaritySearch.ts +108 -0
- package/tsconfig.json +39 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* QueryDatabaseWriter - Write validated queries directly to the database
|
|
4
|
+
*
|
|
5
|
+
* Creates Query entities in the database. QueryFields and QueryParameters
|
|
6
|
+
* are automatically extracted by QueryEntity.server.ts using AI analysis
|
|
7
|
+
* of the SQL template during the Save() operation.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.QueryDatabaseWriter = void 0;
|
|
11
|
+
const core_1 = require("@memberjunction/core");
|
|
12
|
+
const error_handlers_1 = require("../utils/error-handlers");
|
|
13
|
+
const query_helpers_1 = require("../utils/query-helpers");
|
|
14
|
+
/**
|
|
15
|
+
* QueryDatabaseWriter class
|
|
16
|
+
* Writes validated queries directly to the database
|
|
17
|
+
*/
|
|
18
|
+
class QueryDatabaseWriter {
|
|
19
|
+
categoryCache = new Map();
|
|
20
|
+
constructor() {
|
|
21
|
+
// No config needed - category info comes from ValidatedQuery
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Write validated queries to the database
|
|
25
|
+
*
|
|
26
|
+
* Creates Query entities. QueryFields and QueryParameters are automatically
|
|
27
|
+
* extracted by QueryEntity.server.ts using AI analysis of the SQL template.
|
|
28
|
+
* This happens asynchronously during the Save() operation.
|
|
29
|
+
*
|
|
30
|
+
* Errors for individual queries are logged but don't stop the batch process.
|
|
31
|
+
*
|
|
32
|
+
* @param validatedQueries - Array of validated queries to write
|
|
33
|
+
* @param contextUser - User context for entity operations
|
|
34
|
+
* @returns Write result with success status and per-query results
|
|
35
|
+
*/
|
|
36
|
+
async writeQueriesToDatabase(validatedQueries, contextUser) {
|
|
37
|
+
const md = new core_1.Metadata();
|
|
38
|
+
const results = [];
|
|
39
|
+
// Process each query
|
|
40
|
+
for (const vq of validatedQueries) {
|
|
41
|
+
try {
|
|
42
|
+
// Get or create the category for this query (with caching)
|
|
43
|
+
const categoryId = await this.getCategoryId(vq.category, contextUser);
|
|
44
|
+
// Create Query entity ONLY (NO manual fields/params creation)
|
|
45
|
+
// QueryEntity.server.ts will automatically:
|
|
46
|
+
// - Detect Nunjucks syntax
|
|
47
|
+
// - Extract parameters using AI
|
|
48
|
+
// - Create QueryParameter records
|
|
49
|
+
// - Create QueryField records
|
|
50
|
+
// - Set UsesTemplate flag
|
|
51
|
+
const query = await md.GetEntityObject('Queries', contextUser);
|
|
52
|
+
query.NewRecord();
|
|
53
|
+
query.Name = (0, query_helpers_1.generateQueryName)(vq.businessQuestion);
|
|
54
|
+
query.CategoryID = categoryId;
|
|
55
|
+
query.UserQuestion = vq.businessQuestion.userQuestion;
|
|
56
|
+
query.Description = vq.businessQuestion.description;
|
|
57
|
+
query.TechnicalDescription = vq.businessQuestion.technicalDescription;
|
|
58
|
+
query.SQL = vq.query.sql;
|
|
59
|
+
query.OriginalSQL = vq.query.sql;
|
|
60
|
+
query.Status = 'Pending';
|
|
61
|
+
const saved = await query.Save();
|
|
62
|
+
if (!saved) {
|
|
63
|
+
throw new Error(`Failed to save query: ${query.LatestResult?.Message}`);
|
|
64
|
+
}
|
|
65
|
+
results.push(`✓ ${query.Name} (ID: ${query.ID}) - AI extraction queued`);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
results.push(`✗ ${vq.businessQuestion.userQuestion}: ${(0, error_handlers_1.extractErrorMessage)(error, 'Database Write')}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
results
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get or create category ID from QueryCategoryInfo
|
|
78
|
+
* Uses caching to avoid repeated lookups/creations
|
|
79
|
+
* Ensures parent categories exist before creating children
|
|
80
|
+
*/
|
|
81
|
+
async getCategoryId(category, contextUser) {
|
|
82
|
+
// Check cache first (by path for uniqueness)
|
|
83
|
+
if (this.categoryCache.has(category.path)) {
|
|
84
|
+
return this.categoryCache.get(category.path);
|
|
85
|
+
}
|
|
86
|
+
// If this category has a parent, ensure parent exists first
|
|
87
|
+
let parentId = null;
|
|
88
|
+
if (category.parentName) {
|
|
89
|
+
// Create parent category info (it's a root category)
|
|
90
|
+
const parentCategory = {
|
|
91
|
+
name: category.parentName,
|
|
92
|
+
parentName: null,
|
|
93
|
+
description: 'Automatically generated queries from query-gen tool',
|
|
94
|
+
path: category.parentName
|
|
95
|
+
};
|
|
96
|
+
parentId = await this.getCategoryId(parentCategory, contextUser);
|
|
97
|
+
}
|
|
98
|
+
// Find or create this category
|
|
99
|
+
const categoryId = await this.findOrCreateCategory(category.name, parentId, category.description, contextUser);
|
|
100
|
+
// Cache for future use
|
|
101
|
+
this.categoryCache.set(category.path, categoryId);
|
|
102
|
+
return categoryId;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Find or create a query category
|
|
106
|
+
*
|
|
107
|
+
* Searches for an existing category with the given name and parent, or creates it if not found.
|
|
108
|
+
*
|
|
109
|
+
* @param categoryName - Name of the category to find or create
|
|
110
|
+
* @param parentCategoryId - Parent category ID (null for root categories)
|
|
111
|
+
* @param description - Description for new categories
|
|
112
|
+
* @param contextUser - User context for entity operations
|
|
113
|
+
* @returns Category ID
|
|
114
|
+
*/
|
|
115
|
+
async findOrCreateCategory(categoryName, parentCategoryId, description, contextUser) {
|
|
116
|
+
const rv = new core_1.RunView();
|
|
117
|
+
// Build filter to match both name and parent
|
|
118
|
+
let filter = `Name='${categoryName.replace(/'/g, "''")}'`;
|
|
119
|
+
if (parentCategoryId) {
|
|
120
|
+
filter += ` AND ParentID='${parentCategoryId}'`;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
filter += ` AND ParentID IS NULL`;
|
|
124
|
+
}
|
|
125
|
+
const result = await rv.RunView({
|
|
126
|
+
EntityName: 'Query Categories',
|
|
127
|
+
ExtraFilter: filter,
|
|
128
|
+
ResultType: 'entity_object'
|
|
129
|
+
}, contextUser);
|
|
130
|
+
if (!result.Success) {
|
|
131
|
+
throw new Error(`Failed to search for category: ${result.ErrorMessage}`);
|
|
132
|
+
}
|
|
133
|
+
// If found, return existing category ID
|
|
134
|
+
if (result.Results && result.Results.length > 0) {
|
|
135
|
+
return result.Results[0].ID;
|
|
136
|
+
}
|
|
137
|
+
// Category doesn't exist, create it
|
|
138
|
+
const md = new core_1.Metadata();
|
|
139
|
+
const category = await md.GetEntityObject('Query Categories', contextUser);
|
|
140
|
+
category.NewRecord();
|
|
141
|
+
category.Name = categoryName;
|
|
142
|
+
category.ParentID = parentCategoryId;
|
|
143
|
+
category.Description = description;
|
|
144
|
+
const saved = await category.Save();
|
|
145
|
+
if (!saved) {
|
|
146
|
+
throw new Error(`Failed to create category: ${category.LatestResult?.Message}`);
|
|
147
|
+
}
|
|
148
|
+
return category.ID;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.QueryDatabaseWriter = QueryDatabaseWriter;
|
|
152
|
+
//# sourceMappingURL=QueryDatabaseWriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryDatabaseWriter.js","sourceRoot":"","sources":["../../src/core/QueryDatabaseWriter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QueryFixer - Fixes SQL queries that fail execution
|
|
3
|
+
*
|
|
4
|
+
* Uses the SQL Query Fixer AI prompt to analyze errors and generate
|
|
5
|
+
* corrected SQL queries with updated metadata.
|
|
6
|
+
*/
|
|
7
|
+
import { UserInfo } from '@memberjunction/core';
|
|
8
|
+
import { GeneratedQuery, EntityMetadataForPrompt, BusinessQuestion } from '../data/schema';
|
|
9
|
+
import { QueryGenConfig } from '../cli/config';
|
|
10
|
+
/**
|
|
11
|
+
* QueryFixer class
|
|
12
|
+
* Fixes SQL queries that fail to execute
|
|
13
|
+
*/
|
|
14
|
+
export declare class QueryFixer {
|
|
15
|
+
private contextUser;
|
|
16
|
+
private config;
|
|
17
|
+
constructor(contextUser: UserInfo, config: QueryGenConfig);
|
|
18
|
+
/**
|
|
19
|
+
* Fix a SQL query that failed to execute
|
|
20
|
+
* Uses AI to analyze the error and generate a corrected query
|
|
21
|
+
*
|
|
22
|
+
* @param query - The query that failed
|
|
23
|
+
* @param errorMessage - The error message from execution
|
|
24
|
+
* @param entityMetadata - Entity metadata for context
|
|
25
|
+
* @param businessQuestion - Original business question for context
|
|
26
|
+
* @returns Corrected SQL query with updated metadata
|
|
27
|
+
*/
|
|
28
|
+
fixQuery(query: GeneratedQuery, errorMessage: string, entityMetadata: EntityMetadataForPrompt[], businessQuestion: BusinessQuestion): Promise<GeneratedQuery>;
|
|
29
|
+
/**
|
|
30
|
+
* Find prompt by name in AIEngine cache
|
|
31
|
+
* Throws if prompt not found
|
|
32
|
+
*/
|
|
33
|
+
private findPromptByName;
|
|
34
|
+
/**
|
|
35
|
+
* Execute the SQL Query Fixer AI prompt
|
|
36
|
+
* Parses JSON response and validates structure
|
|
37
|
+
*/
|
|
38
|
+
private executePrompt;
|
|
39
|
+
/**
|
|
40
|
+
* Validate fixed query structure
|
|
41
|
+
* Ensures query has proper metadata
|
|
42
|
+
*
|
|
43
|
+
* @param query - Fixed query to validate
|
|
44
|
+
* @throws Error if query structure is invalid
|
|
45
|
+
*/
|
|
46
|
+
private validateFixedQuery;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=QueryFixer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryFixer.d.ts","sourceRoot":"","sources":["../../src/core/QueryFixer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,QAAQ,EAAa,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C;;;GAGG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;gBADN,WAAW,EAAE,QAAQ,EACrB,MAAM,EAAE,cAAc;IAGhC;;;;;;;;;OASG;IACG,QAAQ,CACZ,KAAK,EAAE,cAAc,EACrB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,uBAAuB,EAAE,EACzC,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;IA+B1B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;OAGG;YACW,aAAa;IAuC3B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;CAW3B"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* QueryFixer - Fixes SQL queries that fail execution
|
|
4
|
+
*
|
|
5
|
+
* Uses the SQL Query Fixer AI prompt to analyze errors and generate
|
|
6
|
+
* corrected SQL queries with updated metadata.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.QueryFixer = void 0;
|
|
10
|
+
const aiengine_1 = require("@memberjunction/aiengine");
|
|
11
|
+
const core_1 = require("@memberjunction/core");
|
|
12
|
+
const error_handlers_1 = require("../utils/error-handlers");
|
|
13
|
+
const PromptNames_1 = require("../prompts/PromptNames");
|
|
14
|
+
const prompt_helpers_1 = require("../utils/prompt-helpers");
|
|
15
|
+
/**
|
|
16
|
+
* QueryFixer class
|
|
17
|
+
* Fixes SQL queries that fail to execute
|
|
18
|
+
*/
|
|
19
|
+
class QueryFixer {
|
|
20
|
+
contextUser;
|
|
21
|
+
config;
|
|
22
|
+
constructor(contextUser, config) {
|
|
23
|
+
this.contextUser = contextUser;
|
|
24
|
+
this.config = config;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fix a SQL query that failed to execute
|
|
28
|
+
* Uses AI to analyze the error and generate a corrected query
|
|
29
|
+
*
|
|
30
|
+
* @param query - The query that failed
|
|
31
|
+
* @param errorMessage - The error message from execution
|
|
32
|
+
* @param entityMetadata - Entity metadata for context
|
|
33
|
+
* @param businessQuestion - Original business question for context
|
|
34
|
+
* @returns Corrected SQL query with updated metadata
|
|
35
|
+
*/
|
|
36
|
+
async fixQuery(query, errorMessage, entityMetadata, businessQuestion) {
|
|
37
|
+
try {
|
|
38
|
+
// Ensure AIEngine is configured
|
|
39
|
+
const aiEngine = aiengine_1.AIEngine.Instance;
|
|
40
|
+
await aiEngine.Config(false, this.contextUser);
|
|
41
|
+
// Find the SQL Query Fixer prompt
|
|
42
|
+
const prompt = this.findPromptByName(aiEngine, PromptNames_1.PROMPT_SQL_QUERY_FIXER);
|
|
43
|
+
// Prepare prompt data
|
|
44
|
+
const promptData = {
|
|
45
|
+
originalSQL: query.sql,
|
|
46
|
+
errorMessage,
|
|
47
|
+
parameters: query.parameters,
|
|
48
|
+
entityMetadata,
|
|
49
|
+
userQuestion: businessQuestion.userQuestion,
|
|
50
|
+
description: businessQuestion.description,
|
|
51
|
+
};
|
|
52
|
+
// Execute AI prompt to fix the query
|
|
53
|
+
const fixedQuery = await this.executePrompt(prompt, promptData);
|
|
54
|
+
// Validate the fixed query structure
|
|
55
|
+
this.validateFixedQuery(fixedQuery);
|
|
56
|
+
return fixedQuery;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new Error((0, error_handlers_1.extractErrorMessage)(error, 'QueryFixer.fixQuery'));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Find prompt by name in AIEngine cache
|
|
64
|
+
* Throws if prompt not found
|
|
65
|
+
*/
|
|
66
|
+
findPromptByName(aiEngine, promptName) {
|
|
67
|
+
const prompt = aiEngine.Prompts.find((p) => p.Name === promptName);
|
|
68
|
+
if (!prompt) {
|
|
69
|
+
throw new Error(`Prompt '${promptName}' not found in AIEngine cache`);
|
|
70
|
+
}
|
|
71
|
+
return prompt;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Execute the SQL Query Fixer AI prompt
|
|
75
|
+
* Parses JSON response and validates structure
|
|
76
|
+
*/
|
|
77
|
+
async executePrompt(prompt, promptData) {
|
|
78
|
+
// The SQL Query Fixer template returns { newSQL, reasoning }
|
|
79
|
+
const result = await (0, prompt_helpers_1.executePromptWithOverrides)(prompt, promptData, this.contextUser, this.config);
|
|
80
|
+
if (!result || !result.success) {
|
|
81
|
+
throw new Error(`AI prompt execution failed: ${result?.errorMessage || 'Unknown error'}`);
|
|
82
|
+
}
|
|
83
|
+
if (!result.result) {
|
|
84
|
+
throw new Error('AI prompt returned no result');
|
|
85
|
+
}
|
|
86
|
+
// Log the reasoning
|
|
87
|
+
if (this.config.verbose && result.result.reasoning) {
|
|
88
|
+
(0, core_1.LogStatus)(`Query fix reasoning: ${result.result.reasoning}`);
|
|
89
|
+
}
|
|
90
|
+
// Return GeneratedQuery format, preserving original parameters
|
|
91
|
+
return {
|
|
92
|
+
sql: result.result.newSQL,
|
|
93
|
+
parameters: promptData.parameters,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Validate fixed query structure
|
|
98
|
+
* Ensures query has proper metadata
|
|
99
|
+
*
|
|
100
|
+
* @param query - Fixed query to validate
|
|
101
|
+
* @throws Error if query structure is invalid
|
|
102
|
+
*/
|
|
103
|
+
validateFixedQuery(query) {
|
|
104
|
+
// Validate SQL is present
|
|
105
|
+
if (!query.sql || query.sql.trim().length === 0) {
|
|
106
|
+
throw new Error('Fixed query has empty SQL');
|
|
107
|
+
}
|
|
108
|
+
// Validate parameters array
|
|
109
|
+
if (!Array.isArray(query.parameters)) {
|
|
110
|
+
throw new Error('Fixed query parameters must be an array');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.QueryFixer = QueryFixer;
|
|
115
|
+
//# sourceMappingURL=QueryFixer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryFixer.js","sourceRoot":"","sources":["../../src/core/QueryFixer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QueryRefiner - Iteratively improves queries based on evaluation feedback
|
|
3
|
+
*
|
|
4
|
+
* Uses evaluation and refinement AI prompts to assess if queries answer
|
|
5
|
+
* the business question correctly and improve them through iterations.
|
|
6
|
+
*/
|
|
7
|
+
import { UserInfo } from '@memberjunction/core';
|
|
8
|
+
import { GeneratedQuery, BusinessQuestion, EntityMetadataForPrompt, RefinedQuery } from '../data/schema';
|
|
9
|
+
import { QueryTester } from './QueryTester';
|
|
10
|
+
import { QueryGenConfig } from '../cli/config';
|
|
11
|
+
/**
|
|
12
|
+
* QueryRefiner class
|
|
13
|
+
* Iteratively refines queries based on evaluation feedback
|
|
14
|
+
*/
|
|
15
|
+
export declare class QueryRefiner {
|
|
16
|
+
private tester;
|
|
17
|
+
private contextUser;
|
|
18
|
+
private config;
|
|
19
|
+
private entityMetadata;
|
|
20
|
+
constructor(tester: QueryTester, contextUser: UserInfo, config: QueryGenConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Refine a query through evaluation and improvement iterations
|
|
23
|
+
*
|
|
24
|
+
* Loops up to maxRefinements times, testing and evaluating each iteration.
|
|
25
|
+
* Returns when query passes evaluation or max refinements reached.
|
|
26
|
+
*
|
|
27
|
+
* @param query - Initial generated query
|
|
28
|
+
* @param businessQuestion - Original business question
|
|
29
|
+
* @param entityMetadata - Entity metadata for refinement
|
|
30
|
+
* @param maxRefinements - Maximum refinement iterations (default: 3)
|
|
31
|
+
* @returns Refined query with test results and evaluation
|
|
32
|
+
*/
|
|
33
|
+
refineQuery(query: GeneratedQuery, businessQuestion: BusinessQuestion, entityMetadata: EntityMetadataForPrompt[], maxRefinements?: number): Promise<RefinedQuery>;
|
|
34
|
+
/**
|
|
35
|
+
* Configure AIEngine for prompt execution
|
|
36
|
+
* Ensures engine is ready before running prompts
|
|
37
|
+
*/
|
|
38
|
+
private configureAIEngine;
|
|
39
|
+
/**
|
|
40
|
+
* Test current query using QueryTester
|
|
41
|
+
* Throws if query testing fails
|
|
42
|
+
*/
|
|
43
|
+
private testCurrentQuery;
|
|
44
|
+
/**
|
|
45
|
+
* Determine if refinement should stop based on evaluation
|
|
46
|
+
* Stops if query answers question and doesn't need refinement
|
|
47
|
+
*/
|
|
48
|
+
private shouldStopRefining;
|
|
49
|
+
/**
|
|
50
|
+
* Build success result when refinement loop completes successfully
|
|
51
|
+
*/
|
|
52
|
+
private buildSuccessResult;
|
|
53
|
+
/**
|
|
54
|
+
* Build final result when max refinements reached
|
|
55
|
+
* Re-tests and re-evaluates final query
|
|
56
|
+
*/
|
|
57
|
+
private buildFinalResult;
|
|
58
|
+
/**
|
|
59
|
+
* Evaluate if query answers the business question correctly
|
|
60
|
+
* Uses Query Result Evaluator AI prompt
|
|
61
|
+
*
|
|
62
|
+
* @param query - Query to evaluate
|
|
63
|
+
* @param businessQuestion - Original business question
|
|
64
|
+
* @param testResult - Test execution results with sample data
|
|
65
|
+
* @returns Evaluation with confidence and suggestions
|
|
66
|
+
*/
|
|
67
|
+
private evaluateQuery;
|
|
68
|
+
/**
|
|
69
|
+
* Refine query based on evaluation feedback
|
|
70
|
+
* Uses Query Refiner AI prompt
|
|
71
|
+
*
|
|
72
|
+
* @param query - Current query to refine
|
|
73
|
+
* @param businessQuestion - Original business question
|
|
74
|
+
* @param evaluation - Evaluation feedback
|
|
75
|
+
* @param entityMetadata - Entity metadata for refinement
|
|
76
|
+
* @returns Refined query with improvements
|
|
77
|
+
*/
|
|
78
|
+
private performRefinement;
|
|
79
|
+
/**
|
|
80
|
+
* Find prompt by name in AIEngine cache
|
|
81
|
+
* Throws if prompt not found
|
|
82
|
+
*/
|
|
83
|
+
private findPromptByName;
|
|
84
|
+
/**
|
|
85
|
+
* Execute AI prompt and parse result
|
|
86
|
+
* Generic method for any prompt type
|
|
87
|
+
*/
|
|
88
|
+
private executePrompt;
|
|
89
|
+
/**
|
|
90
|
+
* Log evaluation results for debugging
|
|
91
|
+
*/
|
|
92
|
+
private logEvaluation;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=QueryRefiner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryRefiner.d.ts","sourceRoot":"","sources":["../../src/core/QueryRefiner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,QAAQ,EAAa,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,YAAY,EAGb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C;;;GAGG;AACH,qBAAa,YAAY;IAIrB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;IALhB,OAAO,CAAC,cAAc,CAAiC;gBAG7C,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,QAAQ,EACrB,MAAM,EAAE,cAAc;IAGhC;;;;;;;;;;;OAWG;IACG,WAAW,CACf,KAAK,EAAE,cAAc,EACrB,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,uBAAuB,EAAE,EACzC,cAAc,GAAE,MAAU,GACzB,OAAO,CAAC,YAAY,CAAC;IA+FxB;;;OAGG;YACW,iBAAiB;IAS/B;;;OAGG;YACW,gBAAgB;IAY9B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;;OAGG;YACW,gBAAgB;IAqB9B;;;;;;;;OAQG;YACW,aAAa;IAkC3B;;;;;;;;;OASG;YACW,iBAAiB;IAqC/B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;OAGG;YACW,aAAa;IAwB3B;;OAEG;IACH,OAAO,CAAC,aAAa;CAiBtB"}
|