@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,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* QueryWriter - Generates SQL query templates using AI with few-shot learning
|
|
4
|
+
*
|
|
5
|
+
* Uses the SQL Query Writer AI prompt to generate Nunjucks SQL templates
|
|
6
|
+
* based on business questions and similar golden query examples.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.QueryWriter = 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 prompt_helpers_1 = require("../utils/prompt-helpers");
|
|
14
|
+
const PromptNames_1 = require("../prompts/PromptNames");
|
|
15
|
+
/**
|
|
16
|
+
* QueryWriter class
|
|
17
|
+
* Generates Nunjucks SQL query templates using AI with few-shot learning
|
|
18
|
+
*/
|
|
19
|
+
class QueryWriter {
|
|
20
|
+
contextUser;
|
|
21
|
+
config;
|
|
22
|
+
constructor(contextUser, config) {
|
|
23
|
+
this.contextUser = contextUser;
|
|
24
|
+
this.config = config;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generate SQL query template for a business question
|
|
28
|
+
* Uses few-shot learning with similar golden query examples
|
|
29
|
+
*
|
|
30
|
+
* @param businessQuestion - Business question to answer with SQL
|
|
31
|
+
* @param entityMetadata - Available entity metadata for query
|
|
32
|
+
* @param fewShotExamples - Similar golden queries for few-shot learning
|
|
33
|
+
* @returns Generated SQL query with parameters and output schema
|
|
34
|
+
*/
|
|
35
|
+
async generateQuery(businessQuestion, entityMetadata, fewShotExamples) {
|
|
36
|
+
try {
|
|
37
|
+
// Ensure AIEngine is configured
|
|
38
|
+
const aiEngine = aiengine_1.AIEngine.Instance;
|
|
39
|
+
await aiEngine.Config(false, this.contextUser);
|
|
40
|
+
// Find the SQL Query Writer prompt
|
|
41
|
+
const prompt = this.findPromptByName(aiEngine, PromptNames_1.PROMPT_SQL_QUERY_WRITER);
|
|
42
|
+
// Prepare prompt data
|
|
43
|
+
const promptData = {
|
|
44
|
+
userQuestion: businessQuestion.userQuestion,
|
|
45
|
+
description: businessQuestion.description,
|
|
46
|
+
technicalDescription: businessQuestion.technicalDescription,
|
|
47
|
+
entityMetadata,
|
|
48
|
+
fewShotExamples,
|
|
49
|
+
};
|
|
50
|
+
// Execute AI prompt
|
|
51
|
+
const generatedQuery = await this.executePrompt(prompt, promptData);
|
|
52
|
+
// Validate the generated query structure
|
|
53
|
+
this.validateGeneratedQuery(generatedQuery);
|
|
54
|
+
return generatedQuery;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new Error((0, error_handlers_1.extractErrorMessage)(error, 'QueryWriter.generateQuery'));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Find prompt by name in AIEngine cache
|
|
62
|
+
* Throws if prompt not found
|
|
63
|
+
*/
|
|
64
|
+
findPromptByName(aiEngine, promptName) {
|
|
65
|
+
const prompt = aiEngine.Prompts.find((p) => p.Name === promptName);
|
|
66
|
+
if (!prompt) {
|
|
67
|
+
throw new Error(`Prompt '${promptName}' not found in AIEngine cache`);
|
|
68
|
+
}
|
|
69
|
+
return prompt;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Execute the SQL Query Writer AI prompt with retry logic for validation failures
|
|
73
|
+
* Parses JSON response and validates structure, retrying with feedback if validation fails
|
|
74
|
+
*/
|
|
75
|
+
async executePrompt(prompt, promptData) {
|
|
76
|
+
const maxRetries = 3;
|
|
77
|
+
let lastError = null;
|
|
78
|
+
let lastResult = null;
|
|
79
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
80
|
+
try {
|
|
81
|
+
// Execute AI prompt
|
|
82
|
+
const result = await (0, prompt_helpers_1.executePromptWithOverrides)(prompt, promptData, this.contextUser, this.config);
|
|
83
|
+
if (!result || !result.success) {
|
|
84
|
+
throw new Error(`AI prompt execution failed: ${result?.errorMessage || 'Unknown error'}`);
|
|
85
|
+
}
|
|
86
|
+
if (!result.result) {
|
|
87
|
+
throw new Error('AI prompt returned no result');
|
|
88
|
+
}
|
|
89
|
+
lastResult = result.result;
|
|
90
|
+
// Validate the generated query structure
|
|
91
|
+
// This will throw if validation fails
|
|
92
|
+
this.validateGeneratedQuery(lastResult);
|
|
93
|
+
// Validation passed, return the query
|
|
94
|
+
return lastResult;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
98
|
+
// If this is the last attempt, throw the error
|
|
99
|
+
if (attempt === maxRetries) {
|
|
100
|
+
throw new Error(`Query generation failed after ${maxRetries + 1} attempts: ${lastError.message}`);
|
|
101
|
+
}
|
|
102
|
+
// Log retry attempt
|
|
103
|
+
if (this.config.verbose) {
|
|
104
|
+
(0, core_1.LogStatus)(`⚠️ Query validation failed on attempt ${attempt + 1}/${maxRetries + 1}: ${lastError.message}`);
|
|
105
|
+
(0, core_1.LogStatus)(` Retrying with validation feedback...`);
|
|
106
|
+
}
|
|
107
|
+
// Add validation feedback to the prompt data for next attempt
|
|
108
|
+
// This helps the LLM correct its mistakes
|
|
109
|
+
promptData = {
|
|
110
|
+
...promptData,
|
|
111
|
+
// Add feedback about what went wrong
|
|
112
|
+
validationFeedback: `Previous attempt failed validation: ${lastError.message}. Please correct this issue.`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Should never reach here due to throw in loop, but TypeScript needs this
|
|
117
|
+
throw lastError || new Error('Query generation failed');
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Validate generated query structure
|
|
121
|
+
* Ensures query has proper SQL template syntax and valid metadata
|
|
122
|
+
*
|
|
123
|
+
* @param query - Generated query to validate
|
|
124
|
+
* @throws Error if query structure is invalid
|
|
125
|
+
*/
|
|
126
|
+
validateGeneratedQuery(query) {
|
|
127
|
+
// Validate SQL is present
|
|
128
|
+
if (!query.sql || query.sql.trim().length === 0) {
|
|
129
|
+
throw new Error('Generated query has empty SQL');
|
|
130
|
+
}
|
|
131
|
+
// Validate SQL contains base view references (not raw tables)
|
|
132
|
+
if (!this.usesBaseViews(query.sql)) {
|
|
133
|
+
throw new Error('Generated SQL must use base views (vw*), not raw tables');
|
|
134
|
+
}
|
|
135
|
+
// Validate parameters array
|
|
136
|
+
if (!Array.isArray(query.parameters)) {
|
|
137
|
+
throw new Error('Generated query parameters must be an array');
|
|
138
|
+
}
|
|
139
|
+
// Validate each parameter
|
|
140
|
+
for (const param of query.parameters) {
|
|
141
|
+
this.validateParameter(param);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Check if SQL uses base views (vw* pattern)
|
|
146
|
+
* Basic heuristic: looks for view names in FROM and JOIN clauses
|
|
147
|
+
*/
|
|
148
|
+
usesBaseViews(sql) {
|
|
149
|
+
// Look for view patterns like [schema].[vw...] or FROM vw...
|
|
150
|
+
const viewPattern = /\b(FROM|JOIN)\s+(\[\w+\]\.)?\[?vw\w+\]?/i;
|
|
151
|
+
return viewPattern.test(sql);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Validate a single query parameter
|
|
155
|
+
* Ensures all required fields are present and valid
|
|
156
|
+
*/
|
|
157
|
+
validateParameter(param) {
|
|
158
|
+
if (!param || typeof param !== 'object') {
|
|
159
|
+
throw new Error('Query parameter must be an object');
|
|
160
|
+
}
|
|
161
|
+
const p = param;
|
|
162
|
+
if (!p.name || typeof p.name !== 'string') {
|
|
163
|
+
throw new Error('Query parameter must have a valid name');
|
|
164
|
+
}
|
|
165
|
+
if (!p.type || typeof p.type !== 'string') {
|
|
166
|
+
throw new Error(`Query parameter '${p.name}' must have a valid type`);
|
|
167
|
+
}
|
|
168
|
+
if (typeof p.isRequired !== 'boolean') {
|
|
169
|
+
throw new Error(`Query parameter '${p.name}' must have isRequired boolean`);
|
|
170
|
+
}
|
|
171
|
+
if (!p.description || typeof p.description !== 'string') {
|
|
172
|
+
throw new Error(`Query parameter '${p.name}' must have a description`);
|
|
173
|
+
}
|
|
174
|
+
if (!Array.isArray(p.usage)) {
|
|
175
|
+
throw new Error(`Query parameter '${p.name}' must have usage array`);
|
|
176
|
+
}
|
|
177
|
+
// sampleValue is required and can be string, number, boolean, or array depending on parameter type
|
|
178
|
+
if (p.sampleValue === undefined || p.sampleValue === null || p.sampleValue === '') {
|
|
179
|
+
throw new Error(`Query parameter '${p.name}' must have a sampleValue`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.QueryWriter = QueryWriter;
|
|
184
|
+
//# sourceMappingURL=QueryWriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryWriter.js","sourceRoot":"","sources":["../../src/core/QueryWriter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QuestionGenerator - Generates business questions for entity groups using AI
|
|
3
|
+
*
|
|
4
|
+
* Uses the Business Question Generator AI prompt to create 1-2 meaningful
|
|
5
|
+
* business questions per entity group that can be answered with SQL.
|
|
6
|
+
*/
|
|
7
|
+
import { UserInfo } from '@memberjunction/core';
|
|
8
|
+
import { QueryGenConfig } from '../cli/config';
|
|
9
|
+
import { EntityGroup, BusinessQuestion } from '../data/schema';
|
|
10
|
+
/**
|
|
11
|
+
* QuestionGenerator class
|
|
12
|
+
* Generates domain-specific business questions using AI
|
|
13
|
+
*/
|
|
14
|
+
export declare class QuestionGenerator {
|
|
15
|
+
private contextUser;
|
|
16
|
+
private config;
|
|
17
|
+
constructor(contextUser: UserInfo, config: QueryGenConfig);
|
|
18
|
+
/**
|
|
19
|
+
* Generate business questions for an entity group
|
|
20
|
+
* Uses AI to create 1-2 meaningful questions per entity group
|
|
21
|
+
*
|
|
22
|
+
* @param entityGroup - Entity group to generate questions for
|
|
23
|
+
* @returns Array of validated business questions
|
|
24
|
+
*/
|
|
25
|
+
generateQuestions(entityGroup: EntityGroup): Promise<BusinessQuestion[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Find prompt by name in AIEngine cache
|
|
28
|
+
* Throws if prompt not found
|
|
29
|
+
*/
|
|
30
|
+
private findPromptByName;
|
|
31
|
+
/**
|
|
32
|
+
* Execute the AI prompt with model/vendor overrides
|
|
33
|
+
* Parses JSON response and validates structure
|
|
34
|
+
*/
|
|
35
|
+
private executePrompt;
|
|
36
|
+
/**
|
|
37
|
+
* Validate and filter business questions
|
|
38
|
+
* Removes low-quality or unanswerable questions
|
|
39
|
+
*
|
|
40
|
+
* @param questions - Raw questions from AI
|
|
41
|
+
* @param entityGroup - Entity group for validation context
|
|
42
|
+
* @returns Filtered array of valid questions
|
|
43
|
+
*/
|
|
44
|
+
private validateQuestions;
|
|
45
|
+
/**
|
|
46
|
+
* Check if question has all required fields
|
|
47
|
+
*/
|
|
48
|
+
private hasRequiredFields;
|
|
49
|
+
/**
|
|
50
|
+
* Check if question references entities in the group
|
|
51
|
+
*/
|
|
52
|
+
private referencesGroupEntities;
|
|
53
|
+
/**
|
|
54
|
+
* Check if question is too generic to be useful
|
|
55
|
+
*/
|
|
56
|
+
private isTooGeneric;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=QuestionGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuestionGenerator.d.ts","sourceRoot":"","sources":["../../src/core/QuestionGenerator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,QAAQ,EAAa,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAU/D;;;GAGG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;gBADN,WAAW,EAAE,QAAQ,EACrB,MAAM,EAAE,cAAc;IAGhC;;;;;;OAMG;IACG,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAyC9E;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;OAGG;YACW,aAAa;IAuB3B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAO/B;;OAEG;IACH,OAAO,CAAC,YAAY;CAarB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* QuestionGenerator - Generates business questions for entity groups using AI
|
|
4
|
+
*
|
|
5
|
+
* Uses the Business Question Generator AI prompt to create 1-2 meaningful
|
|
6
|
+
* business questions per entity group that can be answered with SQL.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.QuestionGenerator = 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 entity_helpers_1 = require("../utils/entity-helpers");
|
|
14
|
+
const prompt_helpers_1 = require("../utils/prompt-helpers");
|
|
15
|
+
const PromptNames_1 = require("../prompts/PromptNames");
|
|
16
|
+
/**
|
|
17
|
+
* QuestionGenerator class
|
|
18
|
+
* Generates domain-specific business questions using AI
|
|
19
|
+
*/
|
|
20
|
+
class QuestionGenerator {
|
|
21
|
+
contextUser;
|
|
22
|
+
config;
|
|
23
|
+
constructor(contextUser, config) {
|
|
24
|
+
this.contextUser = contextUser;
|
|
25
|
+
this.config = config;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generate business questions for an entity group
|
|
29
|
+
* Uses AI to create 1-2 meaningful questions per entity group
|
|
30
|
+
*
|
|
31
|
+
* @param entityGroup - Entity group to generate questions for
|
|
32
|
+
* @returns Array of validated business questions
|
|
33
|
+
*/
|
|
34
|
+
async generateQuestions(entityGroup) {
|
|
35
|
+
try {
|
|
36
|
+
// Ensure AIEngine is configured
|
|
37
|
+
const aiEngine = aiengine_1.AIEngine.Instance;
|
|
38
|
+
await aiEngine.Config(false, this.contextUser);
|
|
39
|
+
// Find the Business Question Generator prompt
|
|
40
|
+
const prompt = this.findPromptByName(aiEngine, PromptNames_1.PROMPT_BUSINESS_QUESTION_GENERATOR);
|
|
41
|
+
// Format entity group for prompt
|
|
42
|
+
const entityMetadata = (0, entity_helpers_1.formatEntityGroupForPrompt)(entityGroup);
|
|
43
|
+
// Execute AI prompt
|
|
44
|
+
const result = await this.executePrompt(prompt, entityMetadata);
|
|
45
|
+
// Validate and filter questions
|
|
46
|
+
const totalGenerated = result.questions.length;
|
|
47
|
+
const validQuestions = this.validateQuestions(result.questions, entityGroup);
|
|
48
|
+
// Log if questions were filtered out
|
|
49
|
+
if (this.config.verbose && totalGenerated > validQuestions.length) {
|
|
50
|
+
(0, core_1.LogStatus)(`QuestionGenerator: Filtered out ${totalGenerated - validQuestions.length} of ${totalGenerated} questions for ${entityGroup.primaryEntity.Name}`);
|
|
51
|
+
}
|
|
52
|
+
// Warn if no valid questions generated
|
|
53
|
+
if (validQuestions.length === 0 && totalGenerated > 0) {
|
|
54
|
+
(0, core_1.LogStatus)(`⚠️ QuestionGenerator: All ${totalGenerated} generated questions were filtered out for ${entityGroup.primaryEntity.Name}`);
|
|
55
|
+
}
|
|
56
|
+
return validQuestions;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new Error((0, error_handlers_1.extractErrorMessage)(error, 'QuestionGenerator.generateQuestions'));
|
|
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 AI prompt with model/vendor overrides
|
|
75
|
+
* Parses JSON response and validates structure
|
|
76
|
+
*/
|
|
77
|
+
async executePrompt(prompt, entityMetadata) {
|
|
78
|
+
const result = await (0, prompt_helpers_1.executePromptWithOverrides)(prompt, { entityGroupMetadata: entityMetadata }, this.contextUser, this.config);
|
|
79
|
+
if (!result || !result.success) {
|
|
80
|
+
throw new Error(`AI prompt execution failed: ${result?.errorMessage || 'Unknown error'}`);
|
|
81
|
+
}
|
|
82
|
+
if (!result.result) {
|
|
83
|
+
throw new Error('AI prompt returned no result');
|
|
84
|
+
}
|
|
85
|
+
return result.result;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Validate and filter business questions
|
|
89
|
+
* Removes low-quality or unanswerable questions
|
|
90
|
+
*
|
|
91
|
+
* @param questions - Raw questions from AI
|
|
92
|
+
* @param entityGroup - Entity group for validation context
|
|
93
|
+
* @returns Filtered array of valid questions
|
|
94
|
+
*/
|
|
95
|
+
validateQuestions(questions, entityGroup) {
|
|
96
|
+
const entityNames = new Set(entityGroup.entities.map((e) => e.Name));
|
|
97
|
+
return questions.filter((q) => {
|
|
98
|
+
// Must have required fields
|
|
99
|
+
if (!this.hasRequiredFields(q)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
// Must reference entities in the group
|
|
103
|
+
if (!this.referencesGroupEntities(q, entityNames)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
// Must not be overly generic
|
|
107
|
+
if (this.isTooGeneric(q)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if question has all required fields
|
|
115
|
+
*/
|
|
116
|
+
hasRequiredFields(question) {
|
|
117
|
+
return !!(question.userQuestion &&
|
|
118
|
+
question.description &&
|
|
119
|
+
question.technicalDescription &&
|
|
120
|
+
question.complexity &&
|
|
121
|
+
Array.isArray(question.entities) &&
|
|
122
|
+
question.entities.length > 0);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if question references entities in the group
|
|
126
|
+
*/
|
|
127
|
+
referencesGroupEntities(question, entityNames) {
|
|
128
|
+
return question.entities.some((entityName) => entityNames.has(entityName));
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if question is too generic to be useful
|
|
132
|
+
*/
|
|
133
|
+
isTooGeneric(question) {
|
|
134
|
+
const genericPatterns = [
|
|
135
|
+
/show\s+me\s+all/i,
|
|
136
|
+
/list\s+all/i,
|
|
137
|
+
/get\s+all/i,
|
|
138
|
+
/display\s+all/i,
|
|
139
|
+
/^what\s+is/i,
|
|
140
|
+
];
|
|
141
|
+
return genericPatterns.some((pattern) => pattern.test(question.userQuestion));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.QuestionGenerator = QuestionGenerator;
|
|
145
|
+
//# sourceMappingURL=QuestionGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuestionGenerator.js","sourceRoot":"","sources":["../../src/core/QuestionGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for QueryGen package
|
|
3
|
+
*/
|
|
4
|
+
import { EntityInfo, EntityRelationshipInfo } from '@memberjunction/core';
|
|
5
|
+
/**
|
|
6
|
+
* Represents a group of related entities for query generation
|
|
7
|
+
*/
|
|
8
|
+
export interface EntityGroup {
|
|
9
|
+
entities: EntityInfo[];
|
|
10
|
+
relationships: EntityRelationshipInfo[];
|
|
11
|
+
primaryEntity: EntityInfo;
|
|
12
|
+
relationshipType: 'single' | 'parent-child' | 'many-to-many';
|
|
13
|
+
businessDomain: string;
|
|
14
|
+
businessRationale: string;
|
|
15
|
+
expectedQuestionTypes: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Entity metadata formatted for AI prompts
|
|
19
|
+
*/
|
|
20
|
+
export interface EntityMetadataForPrompt {
|
|
21
|
+
entityName: string;
|
|
22
|
+
description: string;
|
|
23
|
+
schemaName: string;
|
|
24
|
+
baseTable: string;
|
|
25
|
+
baseView: string;
|
|
26
|
+
fields: EntityFieldMetadata[];
|
|
27
|
+
relationships: EntityRelationshipMetadata[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Entity field metadata for prompts
|
|
31
|
+
*/
|
|
32
|
+
export interface EntityFieldMetadata {
|
|
33
|
+
name: string;
|
|
34
|
+
displayName: string;
|
|
35
|
+
type: string;
|
|
36
|
+
sqlFullType: string;
|
|
37
|
+
description: string;
|
|
38
|
+
isPrimaryKey: boolean;
|
|
39
|
+
isForeignKey: boolean;
|
|
40
|
+
isVirtual: boolean;
|
|
41
|
+
allowsNull: boolean;
|
|
42
|
+
relatedEntity?: string;
|
|
43
|
+
isRequired: boolean;
|
|
44
|
+
defaultValue?: string;
|
|
45
|
+
possibleValues?: string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Entity relationship metadata for prompts
|
|
49
|
+
*/
|
|
50
|
+
export interface EntityRelationshipMetadata {
|
|
51
|
+
type: 'one-to-many' | 'many-to-one' | 'many-to-many';
|
|
52
|
+
relatedEntity: string;
|
|
53
|
+
relatedEntityView: string;
|
|
54
|
+
relatedEntitySchema: string;
|
|
55
|
+
foreignKeyField: string;
|
|
56
|
+
description: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Business question generated by AI
|
|
60
|
+
*/
|
|
61
|
+
export interface BusinessQuestion {
|
|
62
|
+
userQuestion: string;
|
|
63
|
+
description: string;
|
|
64
|
+
technicalDescription: string;
|
|
65
|
+
complexity: 'simple' | 'medium' | 'complex';
|
|
66
|
+
requiresAggregation: boolean;
|
|
67
|
+
requiresJoins: boolean;
|
|
68
|
+
entities: string[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* SQL query generated by AI
|
|
72
|
+
* Note: selectClause removed - QueryEntity automatically creates QueryFieldEntity records from SQL
|
|
73
|
+
*/
|
|
74
|
+
export interface GeneratedQuery {
|
|
75
|
+
sql: string;
|
|
76
|
+
parameters: QueryParameter[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Query output field definition
|
|
80
|
+
*/
|
|
81
|
+
export interface QueryOutputField {
|
|
82
|
+
name: string;
|
|
83
|
+
description: string;
|
|
84
|
+
type: string;
|
|
85
|
+
optional: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Query parameter definition
|
|
89
|
+
*/
|
|
90
|
+
export interface QueryParameter {
|
|
91
|
+
name: string;
|
|
92
|
+
type: string;
|
|
93
|
+
isRequired: boolean;
|
|
94
|
+
description: string;
|
|
95
|
+
usage: string[];
|
|
96
|
+
defaultValue: string | null;
|
|
97
|
+
sampleValue: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Golden query for few-shot learning
|
|
101
|
+
*/
|
|
102
|
+
export interface GoldenQuery {
|
|
103
|
+
name: string;
|
|
104
|
+
userQuestion: string;
|
|
105
|
+
description: string;
|
|
106
|
+
technicalDescription: string;
|
|
107
|
+
sql: string;
|
|
108
|
+
parameters: QueryParameter[];
|
|
109
|
+
selectClause: QueryOutputField[];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Similarity search result
|
|
113
|
+
* Note: nameSim excluded since queries don't have names until after generation
|
|
114
|
+
*/
|
|
115
|
+
export interface SimilarQuery {
|
|
116
|
+
query: GoldenQuery;
|
|
117
|
+
similarity: number;
|
|
118
|
+
fieldScores: {
|
|
119
|
+
userQuestionSim: number;
|
|
120
|
+
descSim: number;
|
|
121
|
+
techDescSim: number;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Query test result
|
|
126
|
+
*/
|
|
127
|
+
export interface QueryTestResult {
|
|
128
|
+
success: boolean;
|
|
129
|
+
renderedSQL?: string;
|
|
130
|
+
rowCount?: number;
|
|
131
|
+
sampleRows?: unknown[];
|
|
132
|
+
attempts?: number;
|
|
133
|
+
error?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Query evaluation result
|
|
137
|
+
*/
|
|
138
|
+
export interface QueryEvaluation {
|
|
139
|
+
answersQuestion: boolean;
|
|
140
|
+
confidence: number;
|
|
141
|
+
reasoning: string;
|
|
142
|
+
suggestions: string[];
|
|
143
|
+
needsRefinement: boolean;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Refined query result
|
|
147
|
+
*/
|
|
148
|
+
export interface RefinedQuery {
|
|
149
|
+
query: GeneratedQuery;
|
|
150
|
+
testResult: QueryTestResult;
|
|
151
|
+
evaluation: QueryEvaluation;
|
|
152
|
+
refinementCount: number;
|
|
153
|
+
reachedMaxRefinements?: boolean;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Query category information for metadata export and database write
|
|
157
|
+
*/
|
|
158
|
+
export interface QueryCategoryInfo {
|
|
159
|
+
/** Name of the category */
|
|
160
|
+
name: string;
|
|
161
|
+
/** Parent category name (null for root categories) */
|
|
162
|
+
parentName: string | null;
|
|
163
|
+
/** Category description */
|
|
164
|
+
description: string;
|
|
165
|
+
/** Full category path (e.g., "Golden-Queries/Members") */
|
|
166
|
+
path: string;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Validated query ready for export
|
|
170
|
+
*/
|
|
171
|
+
export interface ValidatedQuery {
|
|
172
|
+
businessQuestion: BusinessQuestion;
|
|
173
|
+
query: GeneratedQuery;
|
|
174
|
+
testResult: QueryTestResult;
|
|
175
|
+
evaluation: QueryEvaluation;
|
|
176
|
+
entityGroup: EntityGroup;
|
|
177
|
+
category: QueryCategoryInfo;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Metadata export result
|
|
181
|
+
*/
|
|
182
|
+
export interface ExportResult {
|
|
183
|
+
success: boolean;
|
|
184
|
+
outputPath: string;
|
|
185
|
+
queryCount: number;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Database write result
|
|
189
|
+
*/
|
|
190
|
+
export interface WriteResult {
|
|
191
|
+
success: boolean;
|
|
192
|
+
results: string[];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Query metadata record for MJ metadata format
|
|
196
|
+
*
|
|
197
|
+
* Note: QueryFields and QueryParameters are not included here.
|
|
198
|
+
* They are automatically extracted by QueryEntity.server.ts using
|
|
199
|
+
* AI analysis of the SQL template during the Save() operation.
|
|
200
|
+
*/
|
|
201
|
+
export interface QueryMetadataRecord {
|
|
202
|
+
fields: {
|
|
203
|
+
Name: string;
|
|
204
|
+
CategoryID: string;
|
|
205
|
+
UserQuestion: string;
|
|
206
|
+
Description: string;
|
|
207
|
+
TechnicalDescription: string;
|
|
208
|
+
SQL: string;
|
|
209
|
+
OriginalSQL: string;
|
|
210
|
+
UsesTemplate: boolean;
|
|
211
|
+
Status: string;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Embeddings for a query or golden query
|
|
216
|
+
* Note: name is excluded since queries don't have names until after generation
|
|
217
|
+
*/
|
|
218
|
+
export interface QueryEmbeddings {
|
|
219
|
+
userQuestion: number[];
|
|
220
|
+
description: number[];
|
|
221
|
+
technicalDescription: number[];
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Golden query with embeddings
|
|
225
|
+
*/
|
|
226
|
+
export interface EmbeddedGoldenQuery {
|
|
227
|
+
query: GoldenQuery;
|
|
228
|
+
embeddings: QueryEmbeddings;
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/data/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/data/schema.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|