flowquery 1.0.5 → 1.0.6
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/README.md +182 -0
- package/dist/extensibility.d.ts +9 -0
- package/dist/extensibility.d.ts.map +1 -0
- package/dist/extensibility.js +25 -0
- package/dist/extensibility.js.map +1 -0
- package/dist/flowquery.min.js +1 -1
- package/dist/parsing/functions/avg.d.ts.map +1 -1
- package/dist/parsing/functions/avg.js +20 -2
- package/dist/parsing/functions/avg.js.map +1 -1
- package/dist/parsing/functions/collect.d.ts.map +1 -1
- package/dist/parsing/functions/collect.js +20 -2
- package/dist/parsing/functions/collect.js.map +1 -1
- package/dist/parsing/functions/extensibility/index.d.ts +37 -0
- package/dist/parsing/functions/extensibility/index.d.ts.map +1 -0
- package/dist/parsing/functions/extensibility/index.js +50 -0
- package/dist/parsing/functions/extensibility/index.js.map +1 -0
- package/dist/parsing/functions/function_factory.d.ts +23 -0
- package/dist/parsing/functions/function_factory.d.ts.map +1 -1
- package/dist/parsing/functions/function_factory.js +44 -47
- package/dist/parsing/functions/function_factory.js.map +1 -1
- package/dist/parsing/functions/function_metadata.d.ts +57 -6
- package/dist/parsing/functions/function_metadata.d.ts.map +1 -1
- package/dist/parsing/functions/function_metadata.js +103 -153
- package/dist/parsing/functions/function_metadata.js.map +1 -1
- package/dist/parsing/functions/functions.d.ts.map +1 -1
- package/dist/parsing/functions/functions.js +37 -2
- package/dist/parsing/functions/functions.js.map +1 -1
- package/dist/parsing/functions/join.d.ts.map +1 -1
- package/dist/parsing/functions/join.js +21 -2
- package/dist/parsing/functions/join.js.map +1 -1
- package/dist/parsing/functions/predicate_function.d.ts +1 -0
- package/dist/parsing/functions/predicate_function.d.ts.map +1 -1
- package/dist/parsing/functions/predicate_function.js +3 -0
- package/dist/parsing/functions/predicate_function.js.map +1 -1
- package/dist/parsing/functions/predicate_sum.d.ts.map +1 -1
- package/dist/parsing/functions/predicate_sum.js +23 -2
- package/dist/parsing/functions/predicate_sum.js.map +1 -1
- package/dist/parsing/functions/rand.d.ts.map +1 -1
- package/dist/parsing/functions/rand.js +18 -2
- package/dist/parsing/functions/rand.js.map +1 -1
- package/dist/parsing/functions/range.d.ts.map +1 -1
- package/dist/parsing/functions/range.js +21 -2
- package/dist/parsing/functions/range.js.map +1 -1
- package/dist/parsing/functions/replace.d.ts.map +1 -1
- package/dist/parsing/functions/replace.js +22 -2
- package/dist/parsing/functions/replace.js.map +1 -1
- package/dist/parsing/functions/round.d.ts.map +1 -1
- package/dist/parsing/functions/round.js +20 -2
- package/dist/parsing/functions/round.js.map +1 -1
- package/dist/parsing/functions/size.d.ts.map +1 -1
- package/dist/parsing/functions/size.js +20 -2
- package/dist/parsing/functions/size.js.map +1 -1
- package/dist/parsing/functions/split.d.ts.map +1 -1
- package/dist/parsing/functions/split.js +21 -2
- package/dist/parsing/functions/split.js.map +1 -1
- package/dist/parsing/functions/stringify.d.ts.map +1 -1
- package/dist/parsing/functions/stringify.js +20 -2
- package/dist/parsing/functions/stringify.js.map +1 -1
- package/dist/parsing/functions/sum.d.ts.map +1 -1
- package/dist/parsing/functions/sum.js +20 -2
- package/dist/parsing/functions/sum.js.map +1 -1
- package/dist/parsing/functions/to_json.d.ts.map +1 -1
- package/dist/parsing/functions/to_json.js +20 -2
- package/dist/parsing/functions/to_json.js.map +1 -1
- package/dist/parsing/parser.d.ts.map +1 -1
- package/dist/parsing/parser.js +1 -2
- package/dist/parsing/parser.js.map +1 -1
- package/docs/flowquery.min.js +1 -1
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/misc/apps/RAG/.env.example +14 -0
- package/misc/apps/RAG/README.md +0 -7
- package/misc/apps/RAG/package.json +16 -7
- package/misc/apps/RAG/public/index.html +18 -0
- package/misc/apps/RAG/src/App.css +42 -0
- package/misc/apps/RAG/src/App.tsx +50 -0
- package/misc/apps/RAG/src/components/ApiKeySettings.tsx +245 -0
- package/misc/apps/RAG/src/components/ChatContainer.css +67 -0
- package/misc/apps/RAG/src/components/ChatContainer.tsx +239 -0
- package/misc/apps/RAG/src/components/ChatInput.css +23 -0
- package/misc/apps/RAG/src/components/ChatInput.tsx +62 -0
- package/misc/apps/RAG/src/components/ChatMessage.css +136 -0
- package/misc/apps/RAG/src/components/ChatMessage.tsx +152 -0
- package/misc/apps/RAG/src/components/FlowQueryAgent.ts +390 -0
- package/misc/apps/RAG/src/components/FlowQueryRunner.css +104 -0
- package/misc/apps/RAG/src/components/FlowQueryRunner.tsx +332 -0
- package/misc/apps/RAG/src/components/index.ts +15 -0
- package/misc/apps/RAG/src/index.tsx +17 -0
- package/misc/apps/RAG/src/plugins/PluginRegistry.ts +136 -0
- package/misc/apps/RAG/src/plugins/README.md +139 -0
- package/misc/apps/RAG/src/plugins/index.ts +72 -0
- package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +79 -0
- package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +71 -0
- package/misc/apps/RAG/src/plugins/loaders/Llm.ts +441 -0
- package/misc/apps/RAG/src/plugins/loaders/MockData.ts +161 -0
- package/misc/apps/RAG/src/plugins/types.ts +52 -0
- package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +385 -0
- package/misc/apps/RAG/src/prompts/index.ts +10 -0
- package/misc/apps/RAG/src/utils/FlowQueryExecutor.ts +131 -0
- package/misc/apps/RAG/src/utils/FlowQueryExtractor.ts +203 -0
- package/misc/apps/RAG/src/utils/index.ts +9 -0
- package/misc/apps/RAG/tsconfig.json +4 -2
- package/misc/apps/RAG/webpack.config.js +23 -12
- package/package.json +7 -1
- package/src/extensibility.ts +9 -0
- package/src/parsing/functions/avg.ts +10 -0
- package/src/parsing/functions/collect.ts +10 -0
- package/src/parsing/functions/extensibility/index.ts +54 -0
- package/src/parsing/functions/function_factory.ts +51 -48
- package/src/parsing/functions/function_metadata.ts +132 -156
- package/src/parsing/functions/functions.ts +27 -0
- package/src/parsing/functions/join.ts +11 -0
- package/src/parsing/functions/predicate_function.ts +4 -0
- package/src/parsing/functions/predicate_sum.ts +13 -0
- package/src/parsing/functions/rand.ts +8 -0
- package/src/parsing/functions/range.ts +11 -0
- package/src/parsing/functions/replace.ts +12 -0
- package/src/parsing/functions/round.ts +10 -0
- package/src/parsing/functions/size.ts +10 -0
- package/src/parsing/functions/split.ts +11 -0
- package/src/parsing/functions/stringify.ts +10 -0
- package/src/parsing/functions/sum.ts +10 -0
- package/src/parsing/functions/to_json.ts +10 -0
- package/src/parsing/parser.ts +1 -2
- package/tests/parsing/function_plugins.test.ts +11 -11
- package/tsconfig.json +1 -0
- package/dist/parsing/functions/predicate_function_factory.d.ts +0 -6
- package/dist/parsing/functions/predicate_function_factory.d.ts.map +0 -1
- package/dist/parsing/functions/predicate_function_factory.js +0 -19
- package/dist/parsing/functions/predicate_function_factory.js.map +0 -1
- package/misc/apps/RAG/src/index.ts +0 -20
- package/src/parsing/functions/predicate_function_factory.ts +0 -15
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowQuery System Prompt Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates a system prompt that instructs the LLM to create FlowQuery statements
|
|
5
|
+
* based on natural language queries, with awareness of available loader plugins.
|
|
6
|
+
*
|
|
7
|
+
* Uses FlowQuery's built-in functions() introspection to dynamically discover
|
|
8
|
+
* available async data loaders and their metadata.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { PluginMetadata, ParameterSchema, OutputSchema } from '../plugins/types';
|
|
12
|
+
import { pluginRegistry } from '../plugins/PluginRegistry';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* FlowQuery language reference documentation.
|
|
16
|
+
*/
|
|
17
|
+
const FLOWQUERY_LANGUAGE_REFERENCE = `
|
|
18
|
+
## FlowQuery Language Reference
|
|
19
|
+
|
|
20
|
+
FlowQuery is a declarative query language for data processing pipelines. It uses SQL-like syntax with additional constructs for working with APIs and data transformations.
|
|
21
|
+
|
|
22
|
+
### Core Clauses
|
|
23
|
+
|
|
24
|
+
1. **WITH** - Define variables and expressions
|
|
25
|
+
\`\`\`
|
|
26
|
+
WITH 'value' AS myVariable
|
|
27
|
+
WITH 1 + 2 AS result
|
|
28
|
+
WITH expression1 AS var1, expression2 AS var2
|
|
29
|
+
\`\`\`
|
|
30
|
+
|
|
31
|
+
2. **LOAD JSON FROM** - Load data from a URL or async data provider
|
|
32
|
+
\`\`\`
|
|
33
|
+
LOAD JSON FROM 'https://api.example.com/data' AS item
|
|
34
|
+
LOAD JSON FROM myFunction(arg1, arg2) AS item
|
|
35
|
+
\`\`\`
|
|
36
|
+
|
|
37
|
+
3. **LOAD JSON FROM ... HEADERS ... POST** - Make HTTP requests with headers and body
|
|
38
|
+
\`\`\`
|
|
39
|
+
LOAD JSON FROM 'https://api.example.com/data'
|
|
40
|
+
HEADERS {
|
|
41
|
+
\`Content-Type\`: 'application/json',
|
|
42
|
+
Authorization: f'Bearer {apiKey}'
|
|
43
|
+
}
|
|
44
|
+
POST {
|
|
45
|
+
field1: 'value1',
|
|
46
|
+
field2: variable
|
|
47
|
+
} AS response
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
4. **UNWIND** - Expand arrays into individual rows
|
|
51
|
+
\`\`\`
|
|
52
|
+
UNWIND [1, 2, 3] AS number
|
|
53
|
+
UNWIND myArray AS item
|
|
54
|
+
UNWIND range(0, 10) AS index
|
|
55
|
+
\`\`\`
|
|
56
|
+
|
|
57
|
+
5. **WHERE** - Filter results
|
|
58
|
+
\`\`\`
|
|
59
|
+
WHERE item.active = true
|
|
60
|
+
WHERE user.age > 18 AND user.name CONTAINS 'John'
|
|
61
|
+
\`\`\`
|
|
62
|
+
|
|
63
|
+
6. **RETURN** - Specify output columns
|
|
64
|
+
\`\`\`
|
|
65
|
+
RETURN item.name, item.value
|
|
66
|
+
RETURN item.name AS Name, item.price AS Price
|
|
67
|
+
RETURN * -- Return all fields
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
7. **ORDER BY** - Sort results
|
|
71
|
+
\`\`\`
|
|
72
|
+
ORDER BY item.name ASC
|
|
73
|
+
ORDER BY item.price DESC, item.name ASC
|
|
74
|
+
\`\`\`
|
|
75
|
+
|
|
76
|
+
8. **LIMIT** - Limit number of results
|
|
77
|
+
\`\`\`
|
|
78
|
+
LIMIT 10
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
9. **SKIP** - Skip a number of results
|
|
82
|
+
\`\`\`
|
|
83
|
+
SKIP 5
|
|
84
|
+
\`\`\`
|
|
85
|
+
|
|
86
|
+
### Built-in Functions
|
|
87
|
+
|
|
88
|
+
- **String Functions**: \`size()\`, \`substring()\`, \`trim()\`, \`toLower()\`, \`toUpper()\`, \`split()\`, \`join()\`, \`replace()\`, \`startsWith()\`, \`endsWith()\`, \`contains()\`
|
|
89
|
+
- **Math Functions**: \`abs()\`, \`ceil()\`, \`floor()\`, \`round()\`, \`sqrt()\`, \`pow()\`, \`min()\`, \`max()\`
|
|
90
|
+
- **Aggregate Functions**: \`sum()\`, \`avg()\`, \`count()\`, \`collect()\`, \`min()\`, \`max()\`
|
|
91
|
+
- **List Functions**: \`range()\`, \`head()\`, \`tail()\`, \`last()\`, \`size()\`, \`reverse()\`
|
|
92
|
+
- **Type Functions**: \`type()\`, \`toInteger()\`, \`toFloat()\`, \`toString()\`, \`toBoolean()\`
|
|
93
|
+
- **Utility Functions**: \`coalesce()\`, \`keys()\`, \`properties()\`, \`stringify()\`
|
|
94
|
+
|
|
95
|
+
### F-Strings (Template Literals)
|
|
96
|
+
|
|
97
|
+
Use \`f"..."\` for string interpolation:
|
|
98
|
+
\`\`\`
|
|
99
|
+
WITH f"Hello, {name}!" AS greeting
|
|
100
|
+
WITH f"The result is {value * 2}" AS message
|
|
101
|
+
\`\`\`
|
|
102
|
+
|
|
103
|
+
### Object and Array Literals
|
|
104
|
+
|
|
105
|
+
\`\`\`
|
|
106
|
+
WITH { name: 'John', age: 30 } AS person
|
|
107
|
+
WITH [1, 2, 3] AS numbers
|
|
108
|
+
WITH { items: [{ id: 1 }, { id: 2 }] } AS data
|
|
109
|
+
\`\`\`
|
|
110
|
+
|
|
111
|
+
### Property Access
|
|
112
|
+
|
|
113
|
+
\`\`\`
|
|
114
|
+
item.propertyName
|
|
115
|
+
item['property-with-dashes']
|
|
116
|
+
item.nested.property
|
|
117
|
+
array[0]
|
|
118
|
+
\`\`\`
|
|
119
|
+
|
|
120
|
+
### Comparison Operators
|
|
121
|
+
|
|
122
|
+
- \`=\`, \`<>\` (not equal), \`<\`, \`>\`, \`<=\`, \`>=\`
|
|
123
|
+
- \`AND\`, \`OR\`, \`NOT\`
|
|
124
|
+
- \`IN\`, \`CONTAINS\`, \`STARTS WITH\`, \`ENDS WITH\`
|
|
125
|
+
- \`IS NULL\`, \`IS NOT NULL\`
|
|
126
|
+
|
|
127
|
+
### Comments
|
|
128
|
+
|
|
129
|
+
\`\`\`
|
|
130
|
+
// Single line comment
|
|
131
|
+
/* Multi-line
|
|
132
|
+
comment */
|
|
133
|
+
\`\`\`
|
|
134
|
+
`;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* FlowQuery System Prompt Generator class.
|
|
138
|
+
* Provides methods to generate various system prompts for LLM interactions.
|
|
139
|
+
*/
|
|
140
|
+
export class FlowQuerySystemPrompt {
|
|
141
|
+
/**
|
|
142
|
+
* Format a parameter schema into a readable string.
|
|
143
|
+
*/
|
|
144
|
+
private static formatParameter(param: ParameterSchema): string {
|
|
145
|
+
const required = param.required ? ' (required)' : ' (optional)';
|
|
146
|
+
const defaultVal = param.default !== undefined ? `, default: ${JSON.stringify(param.default)}` : '';
|
|
147
|
+
const enumVals = param.enum ? `, values: [${param.enum.map(v => JSON.stringify(v)).join(', ')}]` : '';
|
|
148
|
+
return ` - \`${param.name}\`: ${param.type}${required}${defaultVal}${enumVals} - ${param.description}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Format output schema into a readable string.
|
|
153
|
+
*/
|
|
154
|
+
private static formatOutput(output: OutputSchema): string {
|
|
155
|
+
let result = ` Returns: ${output.type} - ${output.description}`;
|
|
156
|
+
|
|
157
|
+
if (output.properties) {
|
|
158
|
+
result += '\n Output properties:';
|
|
159
|
+
for (const [key, prop] of Object.entries(output.properties)) {
|
|
160
|
+
result += `\n - \`${key}\`: ${prop.type} - ${prop.description}`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (output.example) {
|
|
165
|
+
result += `\n Example output: ${JSON.stringify(output.example, null, 2)}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Format a plugin metadata into a readable documentation block.
|
|
173
|
+
*/
|
|
174
|
+
private static formatPluginDocumentation(plugin: PluginMetadata): string {
|
|
175
|
+
const lines: string[] = [];
|
|
176
|
+
|
|
177
|
+
lines.push(`### \`${plugin.name}\``);
|
|
178
|
+
lines.push(`**Description**: ${plugin.description}`);
|
|
179
|
+
|
|
180
|
+
if (plugin.category) {
|
|
181
|
+
lines.push(`**Category**: ${plugin.category}`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (plugin.parameters.length > 0) {
|
|
185
|
+
lines.push('\n**Parameters**:');
|
|
186
|
+
for (const param of plugin.parameters) {
|
|
187
|
+
lines.push(this.formatParameter(param));
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
lines.push('\n**Parameters**: None');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
lines.push('\n**Output**:');
|
|
194
|
+
lines.push(this.formatOutput(plugin.output));
|
|
195
|
+
|
|
196
|
+
if (plugin.examples && plugin.examples.length > 0) {
|
|
197
|
+
lines.push('\n**Usage Examples**:');
|
|
198
|
+
for (const example of plugin.examples) {
|
|
199
|
+
lines.push(`\`\`\`\n${example}\n\`\`\``);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (plugin.notes) {
|
|
204
|
+
lines.push(`\n**Notes**: ${plugin.notes}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return lines.join('\n');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Generate documentation for all available plugins.
|
|
212
|
+
*/
|
|
213
|
+
private static generatePluginDocumentation(plugins: PluginMetadata[]): string {
|
|
214
|
+
if (plugins.length === 0) {
|
|
215
|
+
return 'No data loader plugins are currently available.';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const sections: string[] = [];
|
|
219
|
+
|
|
220
|
+
// Group plugins by category
|
|
221
|
+
const byCategory = new Map<string, PluginMetadata[]>();
|
|
222
|
+
for (const plugin of plugins) {
|
|
223
|
+
const category = plugin.category || 'general';
|
|
224
|
+
if (!byCategory.has(category)) {
|
|
225
|
+
byCategory.set(category, []);
|
|
226
|
+
}
|
|
227
|
+
byCategory.get(category)!.push(plugin);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
sections.push('## Available Data Loader Plugins\n');
|
|
231
|
+
sections.push('The following async data loader functions are available for use with `LOAD JSON FROM`:\n');
|
|
232
|
+
|
|
233
|
+
for (const [category, categoryPlugins] of byCategory) {
|
|
234
|
+
sections.push(`\n### Category: ${category.charAt(0).toUpperCase() + category.slice(1)}\n`);
|
|
235
|
+
for (const plugin of categoryPlugins) {
|
|
236
|
+
sections.push(this.formatPluginDocumentation(plugin));
|
|
237
|
+
sections.push('---');
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return sections.join('\n');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Internal helper to build the system prompt from plugin documentation.
|
|
246
|
+
*/
|
|
247
|
+
private static buildSystemPrompt(pluginDocs: string, additionalContext?: string): string {
|
|
248
|
+
return `You are a FlowQuery assistant. Your primary role is to help users by creating and executing FlowQuery statements based on their natural language requests.
|
|
249
|
+
|
|
250
|
+
## How You Work
|
|
251
|
+
|
|
252
|
+
You operate in a multi-step process:
|
|
253
|
+
1. **Analyze** the user's natural language request
|
|
254
|
+
2. **Generate** a FlowQuery statement that fulfills the request using available plugins
|
|
255
|
+
3. The system will **execute** your FlowQuery and provide you with the results
|
|
256
|
+
4. You will then **interpret** the results and present them to the user in a helpful way
|
|
257
|
+
|
|
258
|
+
## Response Format for Query Generation
|
|
259
|
+
|
|
260
|
+
When the user makes a request that requires fetching or processing data:
|
|
261
|
+
1. Generate a FlowQuery statement wrapped in a code block with \`\`\`flowquery language tag
|
|
262
|
+
2. Keep any explanation brief - the main focus should be the query
|
|
263
|
+
3. The query will be automatically executed and you'll receive the results
|
|
264
|
+
|
|
265
|
+
When the user asks a question that doesn't require data fetching (e.g., asking about FlowQuery syntax or general questions):
|
|
266
|
+
1. Start your response with [NO_QUERY_NEEDED]
|
|
267
|
+
2. Then provide your direct answer
|
|
268
|
+
|
|
269
|
+
## Important Guidelines
|
|
270
|
+
|
|
271
|
+
- Only use the available data loader plugins documented below
|
|
272
|
+
- Use proper FlowQuery syntax as documented in the language reference
|
|
273
|
+
- For API calls, prefer using the registered loader plugins over raw HTTP calls when possible
|
|
274
|
+
- Always alias loaded items with \`AS\` for clarity
|
|
275
|
+
- Use meaningful aliases in RETURN statements for better readability
|
|
276
|
+
- Generate the simplest query that fulfills the user's request
|
|
277
|
+
- If you cannot determine what the user needs, ask clarifying questions (with [NO_QUERY_NEEDED])
|
|
278
|
+
|
|
279
|
+
${FLOWQUERY_LANGUAGE_REFERENCE}
|
|
280
|
+
|
|
281
|
+
${pluginDocs}
|
|
282
|
+
|
|
283
|
+
${additionalContext ? `## Additional Context\n\n${additionalContext}` : ''}
|
|
284
|
+
|
|
285
|
+
## Example Response Format
|
|
286
|
+
|
|
287
|
+
**When a query is needed**:
|
|
288
|
+
\`\`\`flowquery
|
|
289
|
+
LOAD JSON FROM pluginName(args) AS item
|
|
290
|
+
WHERE item.field = 'value'
|
|
291
|
+
RETURN item.name AS Name, item.value AS Value
|
|
292
|
+
\`\`\`
|
|
293
|
+
|
|
294
|
+
**When no query is needed** (e.g., general questions about FlowQuery):
|
|
295
|
+
[NO_QUERY_NEEDED]
|
|
296
|
+
Your direct answer here...
|
|
297
|
+
|
|
298
|
+
Now help the user with their request.`;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Generate the complete FlowQuery system prompt.
|
|
303
|
+
* Uses FlowQuery's introspection via functions() as the single source of truth.
|
|
304
|
+
*
|
|
305
|
+
* @param additionalContext - Optional additional context to include in the prompt
|
|
306
|
+
* @returns The complete system prompt string
|
|
307
|
+
*/
|
|
308
|
+
public static generate(additionalContext?: string): string {
|
|
309
|
+
// Uses FlowQuery's introspection to get available async providers
|
|
310
|
+
const plugins = pluginRegistry.getAllPluginMetadata();
|
|
311
|
+
const pluginDocs = this.generatePluginDocumentation(plugins);
|
|
312
|
+
|
|
313
|
+
return this.buildSystemPrompt(pluginDocs, additionalContext);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Generate a system prompt for the interpretation phase.
|
|
318
|
+
* Used after FlowQuery execution to interpret results.
|
|
319
|
+
*
|
|
320
|
+
* @returns The interpretation system prompt string
|
|
321
|
+
*/
|
|
322
|
+
public static generateInterpretationPrompt(): string {
|
|
323
|
+
return `You are a helpful assistant interpreting FlowQuery execution results.
|
|
324
|
+
|
|
325
|
+
## Your Role
|
|
326
|
+
|
|
327
|
+
The user made a natural language request, which was converted to a FlowQuery statement and executed.
|
|
328
|
+
You are now receiving the execution results. Your job is to:
|
|
329
|
+
|
|
330
|
+
1. **Summarize** the results in a clear, user-friendly way
|
|
331
|
+
2. **Highlight** key insights or patterns in the data
|
|
332
|
+
3. **Format** the data appropriately (tables, lists, or prose depending on the data)
|
|
333
|
+
4. **Answer** the user's original question using the data
|
|
334
|
+
|
|
335
|
+
## Guidelines
|
|
336
|
+
|
|
337
|
+
- Be concise but thorough
|
|
338
|
+
- If the results contain many items, summarize rather than listing all
|
|
339
|
+
- If there's an error, explain what went wrong in user-friendly terms
|
|
340
|
+
- Use markdown formatting for better readability
|
|
341
|
+
- If the data doesn't fully answer the user's question, note what's missing`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Get a minimal system prompt without full documentation.
|
|
346
|
+
* Useful for contexts where token count is a concern.
|
|
347
|
+
*/
|
|
348
|
+
public static getMinimalPrompt(): string {
|
|
349
|
+
const plugins = pluginRegistry.getAllPluginMetadata();
|
|
350
|
+
const pluginList = plugins.map(p => `- \`${p.name}\`: ${p.description}`).join('\n');
|
|
351
|
+
|
|
352
|
+
return `You are a FlowQuery assistant. Generate FlowQuery statements based on user requests.
|
|
353
|
+
|
|
354
|
+
Available data loader plugins:
|
|
355
|
+
${pluginList}
|
|
356
|
+
|
|
357
|
+
FlowQuery uses SQL-like syntax: WITH, LOAD JSON FROM, UNWIND, WHERE, RETURN, ORDER BY, LIMIT, SKIP.
|
|
358
|
+
Use f"..." for string interpolation. Access properties with dot notation or brackets.
|
|
359
|
+
|
|
360
|
+
Always wrap FlowQuery code in \`\`\`flowquery code blocks.`;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Generate the FlowQuery system prompt asynchronously using functions() introspection.
|
|
365
|
+
* This is the preferred method that uses FlowQuery's built-in introspection.
|
|
366
|
+
*
|
|
367
|
+
* @param additionalContext - Optional additional context to include in the prompt
|
|
368
|
+
* @returns Promise resolving to the complete system prompt string
|
|
369
|
+
*/
|
|
370
|
+
public static async generateAsync(additionalContext?: string): Promise<string> {
|
|
371
|
+
// Use FlowQuery's functions() introspection to discover available loaders
|
|
372
|
+
const plugins = await pluginRegistry.getAvailableLoadersAsync();
|
|
373
|
+
const pluginDocs = this.generatePluginDocumentation(plugins);
|
|
374
|
+
|
|
375
|
+
return this.buildSystemPrompt(pluginDocs, additionalContext);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Export functions for backward compatibility
|
|
380
|
+
export const generateFlowQuerySystemPrompt = FlowQuerySystemPrompt.generate.bind(FlowQuerySystemPrompt);
|
|
381
|
+
export const generateInterpretationPrompt = FlowQuerySystemPrompt.generateInterpretationPrompt.bind(FlowQuerySystemPrompt);
|
|
382
|
+
export const getMinimalFlowQueryPrompt = FlowQuerySystemPrompt.getMinimalPrompt.bind(FlowQuerySystemPrompt);
|
|
383
|
+
export const generateFlowQuerySystemPromptAsync = FlowQuerySystemPrompt.generateAsync.bind(FlowQuerySystemPrompt);
|
|
384
|
+
|
|
385
|
+
export default FlowQuerySystemPrompt;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowQuery Executor Utility
|
|
3
|
+
*
|
|
4
|
+
* Executes FlowQuery statements and handles errors gracefully.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { FlowQuery } from 'flowquery';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Result of executing a FlowQuery statement.
|
|
11
|
+
*/
|
|
12
|
+
export interface FlowQueryExecutionResult {
|
|
13
|
+
/** Whether the execution was successful */
|
|
14
|
+
success: boolean;
|
|
15
|
+
/** The query that was executed */
|
|
16
|
+
query: string;
|
|
17
|
+
/** The results from the query, if successful */
|
|
18
|
+
results?: any[];
|
|
19
|
+
/** Error message, if execution failed */
|
|
20
|
+
error?: string;
|
|
21
|
+
/** Execution time in milliseconds */
|
|
22
|
+
executionTime: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* FlowQuery Executor class for executing FlowQuery statements.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const executor = new FlowQueryExecutor();
|
|
31
|
+
* const result = await executor.execute("LOAD JSON FROM somePlugin(5) AS item RETURN item.text");
|
|
32
|
+
* if (result.success) {
|
|
33
|
+
* console.log(result.results);
|
|
34
|
+
* } else {
|
|
35
|
+
* console.error(result.error);
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class FlowQueryExecutor {
|
|
40
|
+
private defaultMaxItems: number;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new FlowQueryExecutor instance.
|
|
44
|
+
* @param defaultMaxItems - Default maximum items to display when formatting results (default: 20)
|
|
45
|
+
*/
|
|
46
|
+
constructor(defaultMaxItems: number = 20) {
|
|
47
|
+
this.defaultMaxItems = defaultMaxItems;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Execute a FlowQuery statement and return the results.
|
|
52
|
+
*
|
|
53
|
+
* @param query - The FlowQuery statement to execute
|
|
54
|
+
* @returns The execution result including success status, results or error
|
|
55
|
+
*/
|
|
56
|
+
async execute(query: string): Promise<FlowQueryExecutionResult> {
|
|
57
|
+
const startTime = performance.now();
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
// Validate the query is not empty
|
|
61
|
+
if (!query || query.trim() === '') {
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
query,
|
|
65
|
+
error: 'Query cannot be empty',
|
|
66
|
+
executionTime: performance.now() - startTime
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Create a runner and execute the query
|
|
71
|
+
const runner = new FlowQuery(query);
|
|
72
|
+
await runner.run();
|
|
73
|
+
|
|
74
|
+
// Get the results
|
|
75
|
+
const results = runner.results;
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
success: true,
|
|
79
|
+
query,
|
|
80
|
+
results: Array.isArray(results) ? results : [results],
|
|
81
|
+
executionTime: performance.now() - startTime
|
|
82
|
+
};
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
success: false,
|
|
88
|
+
query,
|
|
89
|
+
error: errorMessage,
|
|
90
|
+
executionTime: performance.now() - startTime
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Format execution results for display or LLM consumption.
|
|
97
|
+
*
|
|
98
|
+
* @param result - The execution result to format
|
|
99
|
+
* @param maxItems - Maximum number of items to include (uses default if not specified)
|
|
100
|
+
* @returns A formatted string representation of the results
|
|
101
|
+
*/
|
|
102
|
+
formatResult(result: FlowQueryExecutionResult, maxItems?: number): string {
|
|
103
|
+
const limit = maxItems ?? this.defaultMaxItems;
|
|
104
|
+
|
|
105
|
+
if (!result.success) {
|
|
106
|
+
return `Execution Error: ${result.error}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const results = result.results || [];
|
|
110
|
+
const totalCount = results.length;
|
|
111
|
+
const displayResults = results.slice(0, limit);
|
|
112
|
+
|
|
113
|
+
let output = `Execution successful (${result.executionTime.toFixed(2)}ms)\n`;
|
|
114
|
+
output += `Total results: ${totalCount}\n\n`;
|
|
115
|
+
|
|
116
|
+
if (totalCount === 0) {
|
|
117
|
+
output += 'No results returned.';
|
|
118
|
+
} else {
|
|
119
|
+
output += 'Results:\n';
|
|
120
|
+
output += JSON.stringify(displayResults, null, 2);
|
|
121
|
+
|
|
122
|
+
if (totalCount > limit) {
|
|
123
|
+
output += `\n\n... and ${totalCount - limit} more results`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return output;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export default FlowQueryExecutor;
|