flowquery 1.0.5 → 1.0.7
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 +74 -0
- package/dist/compute/runner.d.ts +1 -22
- package/dist/compute/runner.d.ts.map +1 -1
- package/dist/compute/runner.js.map +1 -1
- package/dist/extensibility.d.ts +35 -0
- package/dist/extensibility.d.ts.map +1 -0
- package/dist/extensibility.js +49 -0
- package/dist/extensibility.js.map +1 -0
- package/dist/flowquery.min.js +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +0 -80
- package/dist/index.browser.js.map +1 -1
- package/dist/index.node.d.ts +3 -3
- package/dist/index.node.d.ts.map +1 -1
- package/dist/index.node.js +0 -80
- package/dist/index.node.js.map +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/function_factory.d.ts +26 -80
- package/dist/parsing/functions/function_factory.d.ts.map +1 -1
- package/dist/parsing/functions/function_factory.js +46 -168
- package/dist/parsing/functions/function_factory.js.map +1 -1
- package/dist/parsing/functions/function_metadata.d.ts +81 -20
- package/dist/parsing/functions/function_metadata.d.ts.map +1 -1
- package/dist/parsing/functions/function_metadata.js +154 -152
- 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/README.md +139 -0
- package/misc/apps/RAG/src/plugins/index.ts +68 -0
- package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +75 -0
- package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +67 -0
- package/misc/apps/RAG/src/plugins/loaders/Llm.ts +437 -0
- package/misc/apps/RAG/src/plugins/loaders/MockData.ts +151 -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/compute/runner.ts +1 -26
- package/src/extensibility.ts +45 -0
- package/src/index.browser.ts +2 -88
- package/src/index.node.ts +3 -92
- package/src/parsing/functions/avg.ts +10 -0
- package/src/parsing/functions/collect.ts +10 -0
- package/src/parsing/functions/function_factory.ts +56 -194
- package/src/parsing/functions/function_metadata.ts +187 -168
- 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/extensibility.test.ts +563 -0
- 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
- package/tests/parsing/function_plugins.test.ts +0 -369
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowQuery Extraction Utility
|
|
3
|
+
*
|
|
4
|
+
* Extracts FlowQuery statements from LLM responses.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extraction result containing the query and any explanation text.
|
|
9
|
+
*/
|
|
10
|
+
export interface FlowQueryExtraction {
|
|
11
|
+
/** The extracted FlowQuery statement, if found */
|
|
12
|
+
query: string | null;
|
|
13
|
+
/** Whether a query was successfully extracted */
|
|
14
|
+
found: boolean;
|
|
15
|
+
/** Any explanation text before the code block */
|
|
16
|
+
explanation?: string;
|
|
17
|
+
/** Whether the LLM indicated no query is needed */
|
|
18
|
+
noQueryNeeded?: boolean;
|
|
19
|
+
/** Message from the LLM if no query is needed */
|
|
20
|
+
directResponse?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* FlowQuery Extractor class for extracting FlowQuery statements from LLM responses.
|
|
25
|
+
*
|
|
26
|
+
* Looks for code blocks with flowquery, cypher, or sql language tags,
|
|
27
|
+
* or generic code blocks that appear to contain FlowQuery syntax.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const extractor = new FlowQueryExtractor();
|
|
32
|
+
* const response = `Here's the query:
|
|
33
|
+
* \`\`\`flowquery
|
|
34
|
+
* LOAD JSON FROM somePlugin(5) AS item
|
|
35
|
+
* RETURN item.text
|
|
36
|
+
* \`\`\``;
|
|
37
|
+
*
|
|
38
|
+
* const extraction = extractor.extract(response);
|
|
39
|
+
* console.log(extraction.query); // "LOAD JSON FROM somePlugin(5) AS item\nRETURN item.text"
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class FlowQueryExtractor {
|
|
43
|
+
/** Regex patterns for matching code blocks with language tags */
|
|
44
|
+
private readonly codeBlockPatterns: RegExp[] = [
|
|
45
|
+
/```(?:flowquery|cypher|fql)\s*\n([\s\S]*?)```/i,
|
|
46
|
+
/```(?:sql)\s*\n([\s\S]*?)```/i,
|
|
47
|
+
/```\s*\n([\s\S]*?)```/, // Generic code block
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
/** Keywords that indicate a FlowQuery statement */
|
|
51
|
+
private readonly flowQueryKeywords: RegExp[] = [
|
|
52
|
+
/\bWITH\b/i,
|
|
53
|
+
/\bLOAD\s+JSON\s+FROM\b/i,
|
|
54
|
+
/\bUNWIND\b/i,
|
|
55
|
+
/\bRETURN\b/i,
|
|
56
|
+
/\bWHERE\b/i,
|
|
57
|
+
/\bORDER\s+BY\b/i,
|
|
58
|
+
/\bLIMIT\b/i,
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
/** Keywords that can start a FlowQuery statement */
|
|
62
|
+
private readonly startKeywords = /^(WITH|LOAD\s+JSON\s+FROM|UNWIND)\b/i;
|
|
63
|
+
|
|
64
|
+
/** Keywords that can continue a FlowQuery statement */
|
|
65
|
+
private readonly continueKeywords = /^(WITH|LOAD|UNWIND|WHERE|RETURN|ORDER|LIMIT|SKIP|HEADERS|POST|AS)\b/i;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Extract a FlowQuery statement from an LLM response.
|
|
69
|
+
*
|
|
70
|
+
* @param llmResponse - The full text response from the LLM
|
|
71
|
+
* @returns The extraction result
|
|
72
|
+
*/
|
|
73
|
+
public extract(llmResponse: string): FlowQueryExtraction {
|
|
74
|
+
if (!llmResponse || llmResponse.trim() === '') {
|
|
75
|
+
return { query: null, found: false };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check for explicit "NO_QUERY_NEEDED" marker
|
|
79
|
+
if (llmResponse.includes('[NO_QUERY_NEEDED]') ||
|
|
80
|
+
llmResponse.includes('NO_QUERY_NEEDED')) {
|
|
81
|
+
// Extract the direct response after the marker
|
|
82
|
+
const directMatch = llmResponse.match(/\[NO_QUERY_NEEDED\]\s*([\s\S]*)/i);
|
|
83
|
+
return {
|
|
84
|
+
query: null,
|
|
85
|
+
found: false,
|
|
86
|
+
noQueryNeeded: true,
|
|
87
|
+
directResponse: directMatch ? directMatch[1].trim() : llmResponse
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Try to match code blocks with specific language tags
|
|
92
|
+
for (const pattern of this.codeBlockPatterns) {
|
|
93
|
+
const match = llmResponse.match(pattern);
|
|
94
|
+
if (match && match[1]) {
|
|
95
|
+
const query = match[1].trim();
|
|
96
|
+
|
|
97
|
+
// Verify it looks like a FlowQuery statement
|
|
98
|
+
if (this.isLikelyFlowQuery(query)) {
|
|
99
|
+
// Extract explanation text before the code block
|
|
100
|
+
const beforeMatch = llmResponse.substring(0, llmResponse.indexOf(match[0])).trim();
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
query,
|
|
104
|
+
found: true,
|
|
105
|
+
explanation: beforeMatch || undefined
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Try to extract inline FlowQuery if no code block found
|
|
112
|
+
// Look for lines starting with FlowQuery keywords
|
|
113
|
+
const inlineQuery = this.extractInlineQuery(llmResponse);
|
|
114
|
+
if (inlineQuery) {
|
|
115
|
+
return {
|
|
116
|
+
query: inlineQuery,
|
|
117
|
+
found: true
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return { query: null, found: false };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Extract multiple FlowQuery statements from an LLM response.
|
|
126
|
+
* Useful when the LLM provides alternative queries.
|
|
127
|
+
*
|
|
128
|
+
* @param llmResponse - The full text response from the LLM
|
|
129
|
+
* @returns Array of extracted queries
|
|
130
|
+
*/
|
|
131
|
+
public extractAll(llmResponse: string): string[] {
|
|
132
|
+
if (!llmResponse) return [];
|
|
133
|
+
|
|
134
|
+
const queries: string[] = [];
|
|
135
|
+
const codeBlockPattern = /```(?:flowquery|cypher|fql|sql)?\s*\n([\s\S]*?)```/gi;
|
|
136
|
+
|
|
137
|
+
let match;
|
|
138
|
+
while ((match = codeBlockPattern.exec(llmResponse)) !== null) {
|
|
139
|
+
if (match[1]) {
|
|
140
|
+
const query = match[1].trim();
|
|
141
|
+
if (this.isLikelyFlowQuery(query)) {
|
|
142
|
+
queries.push(query);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return queries;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Check if a string looks like a FlowQuery statement.
|
|
152
|
+
*/
|
|
153
|
+
private isLikelyFlowQuery(text: string): boolean {
|
|
154
|
+
// Must contain at least one FlowQuery keyword
|
|
155
|
+
return this.flowQueryKeywords.some(pattern => pattern.test(text));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Try to extract a FlowQuery statement that's not in a code block.
|
|
160
|
+
*/
|
|
161
|
+
private extractInlineQuery(text: string): string | null {
|
|
162
|
+
const lines = text.split('\n');
|
|
163
|
+
const queryLines: string[] = [];
|
|
164
|
+
let inQuery = false;
|
|
165
|
+
|
|
166
|
+
for (const line of lines) {
|
|
167
|
+
const trimmedLine = line.trim();
|
|
168
|
+
|
|
169
|
+
if (!inQuery && this.startKeywords.test(trimmedLine)) {
|
|
170
|
+
inQuery = true;
|
|
171
|
+
queryLines.push(trimmedLine);
|
|
172
|
+
} else if (inQuery) {
|
|
173
|
+
// Check if this line continues the query
|
|
174
|
+
if (this.continueKeywords.test(trimmedLine) ||
|
|
175
|
+
trimmedLine.startsWith('{') ||
|
|
176
|
+
trimmedLine.startsWith('}') ||
|
|
177
|
+
trimmedLine === '' ||
|
|
178
|
+
/^[A-Za-z_][A-Za-z0-9_]*\./.test(trimmedLine) ||
|
|
179
|
+
/^\s+/.test(line)) { // Indented line
|
|
180
|
+
queryLines.push(trimmedLine);
|
|
181
|
+
} else {
|
|
182
|
+
// End of query
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const query = queryLines.join('\n').trim();
|
|
189
|
+
return query && this.isLikelyFlowQuery(query) ? query : null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Convenience function for backward compatibility
|
|
194
|
+
export function extractFlowQuery(llmResponse: string): FlowQueryExtraction {
|
|
195
|
+
return new FlowQueryExtractor().extract(llmResponse);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Convenience function for backward compatibility
|
|
199
|
+
export function extractAllFlowQueries(llmResponse: string): string[] {
|
|
200
|
+
return new FlowQueryExtractor().extractAll(llmResponse);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export default FlowQueryExtractor;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils module exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { FlowQueryExecutor } from './FlowQueryExecutor';
|
|
6
|
+
export type { FlowQueryExecutionResult } from './FlowQueryExecutor';
|
|
7
|
+
|
|
8
|
+
export { FlowQueryExtractor, extractFlowQuery, extractAllFlowQueries } from './FlowQueryExtractor';
|
|
9
|
+
export type { FlowQueryExtraction } from './FlowQueryExtractor';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
"outDir": "./dist",
|
|
4
4
|
"rootDir": "./src",
|
|
5
5
|
"target": "ES2020",
|
|
6
|
-
"module": "
|
|
7
|
-
"moduleResolution": "
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
8
|
"esModuleInterop": true,
|
|
9
9
|
"forceConsistentCasingInFileNames": true,
|
|
10
10
|
"strict": true,
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
"declaration": true,
|
|
13
13
|
"sourceMap": true,
|
|
14
14
|
"resolveJsonModule": true,
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
15
17
|
"types": ["node"]
|
|
16
18
|
},
|
|
17
19
|
"include": ["src/**/*"],
|
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
|
-
mode: '
|
|
5
|
-
entry: './src/index.
|
|
6
|
-
target: '
|
|
5
|
+
mode: 'development',
|
|
6
|
+
entry: './src/index.tsx',
|
|
7
|
+
target: 'web',
|
|
7
8
|
output: {
|
|
8
|
-
filename: '
|
|
9
|
+
filename: 'bundle.js',
|
|
9
10
|
path: path.resolve(__dirname, 'dist'),
|
|
10
|
-
|
|
11
|
+
clean: true
|
|
11
12
|
},
|
|
12
13
|
resolve: {
|
|
13
|
-
extensions: ['.ts', '.js']
|
|
14
|
+
extensions: ['.tsx', '.ts', '.js', '.jsx']
|
|
14
15
|
},
|
|
15
16
|
module: {
|
|
16
17
|
rules: [
|
|
17
18
|
{
|
|
18
|
-
test: /\.
|
|
19
|
+
test: /\.tsx?$/,
|
|
19
20
|
use: 'ts-loader',
|
|
20
21
|
exclude: /node_modules/
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
test: /\.css$/,
|
|
25
|
+
use: ['style-loader', 'css-loader']
|
|
21
26
|
}
|
|
22
27
|
]
|
|
23
28
|
},
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
plugins: [
|
|
30
|
+
new HtmlWebpackPlugin({
|
|
31
|
+
template: './public/index.html'
|
|
32
|
+
}),
|
|
33
|
+
],
|
|
34
|
+
devServer: {
|
|
35
|
+
static: './dist',
|
|
36
|
+
port: 3000,
|
|
37
|
+
open: true,
|
|
38
|
+
hot: true
|
|
28
39
|
},
|
|
29
40
|
optimization: {
|
|
30
|
-
minimize:
|
|
41
|
+
minimize: false
|
|
31
42
|
}
|
|
32
43
|
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowquery",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "A declarative query language for data processing pipelines.",
|
|
5
5
|
"main": "dist/index.node.js",
|
|
6
6
|
"types": "dist/index.node.d.ts",
|
|
7
|
+
"sideEffects": true,
|
|
7
8
|
"exports": {
|
|
8
9
|
".": {
|
|
9
10
|
"import": "./dist/index.node.js",
|
|
@@ -13,6 +14,11 @@
|
|
|
13
14
|
"./browser": {
|
|
14
15
|
"import": "./dist/flowquery.min.js",
|
|
15
16
|
"require": "./dist/flowquery.min.js"
|
|
17
|
+
},
|
|
18
|
+
"./extensibility": {
|
|
19
|
+
"import": "./dist/extensibility.js",
|
|
20
|
+
"require": "./dist/extensibility.js",
|
|
21
|
+
"types": "./dist/extensibility.d.ts"
|
|
16
22
|
}
|
|
17
23
|
},
|
|
18
24
|
"bin": {
|
package/src/compute/runner.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Operation from "../parsing/operations/operation";
|
|
2
2
|
import Parser from "../parsing/parser";
|
|
3
|
-
import {
|
|
4
|
-
import { FunctionMetadata, RegisterFunctionOptions, RegisterAsyncProviderOptions } from "../parsing/functions/function_metadata";
|
|
3
|
+
import { FunctionMetadata } from "../parsing/functions/function_metadata";
|
|
5
4
|
import Function from "../parsing/functions/function";
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -21,30 +20,6 @@ class Runner {
|
|
|
21
20
|
private first: Operation;
|
|
22
21
|
private last: Operation;
|
|
23
22
|
|
|
24
|
-
/**
|
|
25
|
-
* Register a synchronous plugin function.
|
|
26
|
-
* Added dynamically in index.browser.ts / index.node.ts
|
|
27
|
-
*/
|
|
28
|
-
static registerFunction: (name: string, factoryOrOptions: FunctionCreator | RegisterFunctionOptions) => void;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Unregister a synchronous plugin function.
|
|
32
|
-
* Added dynamically in index.browser.ts / index.node.ts
|
|
33
|
-
*/
|
|
34
|
-
static unregisterFunction: (name: string) => void;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Register an async data provider function for use in LOAD operations.
|
|
38
|
-
* Added dynamically in index.browser.ts / index.node.ts
|
|
39
|
-
*/
|
|
40
|
-
static registerAsyncProvider: (name: string, providerOrOptions: AsyncDataProvider | RegisterAsyncProviderOptions) => void;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Unregister an async data provider function.
|
|
44
|
-
* Added dynamically in index.browser.ts / index.node.ts
|
|
45
|
-
*/
|
|
46
|
-
static unregisterAsyncProvider: (name: string) => void;
|
|
47
|
-
|
|
48
23
|
/**
|
|
49
24
|
* List all registered functions with their metadata.
|
|
50
25
|
* Added dynamically in index.browser.ts / index.node.ts
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowQuery Extensibility API
|
|
3
|
+
*
|
|
4
|
+
* This module provides all the exports needed to create custom FlowQuery functions.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { Function, FunctionDef } from 'flowquery/extensibility';
|
|
11
|
+
*
|
|
12
|
+
* @FunctionDef({
|
|
13
|
+
* description: "Converts a string to uppercase",
|
|
14
|
+
* category: "string",
|
|
15
|
+
* parameters: [{ name: "text", description: "String to convert", type: "string" }],
|
|
16
|
+
* output: { description: "Uppercase string", type: "string" }
|
|
17
|
+
* })
|
|
18
|
+
* class UpperCase extends Function {
|
|
19
|
+
* constructor() {
|
|
20
|
+
* super("uppercase");
|
|
21
|
+
* this._expectedParameterCount = 1;
|
|
22
|
+
* }
|
|
23
|
+
* public value(): string {
|
|
24
|
+
* return String(this.getChildren()[0].value()).toUpperCase();
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
// Base function classes for creating custom functions
|
|
31
|
+
export { default as Function } from "./parsing/functions/function";
|
|
32
|
+
export { default as AggregateFunction } from "./parsing/functions/aggregate_function";
|
|
33
|
+
export { default as AsyncFunction } from "./parsing/functions/async_function";
|
|
34
|
+
export { default as PredicateFunction } from "./parsing/functions/predicate_function";
|
|
35
|
+
export { default as ReducerElement } from "./parsing/functions/reducer_element";
|
|
36
|
+
|
|
37
|
+
// Decorator and metadata types for function registration
|
|
38
|
+
export {
|
|
39
|
+
FunctionDef,
|
|
40
|
+
FunctionMetadata,
|
|
41
|
+
FunctionDefOptions,
|
|
42
|
+
ParameterSchema,
|
|
43
|
+
OutputSchema,
|
|
44
|
+
FunctionCategory
|
|
45
|
+
} from "./parsing/functions/function_metadata";
|
package/src/index.browser.ts
CHANGED
|
@@ -7,100 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import {default as FlowQuery} from "./compute/runner";
|
|
10
|
-
import FunctionFactory
|
|
10
|
+
import FunctionFactory from "./parsing/functions/function_factory";
|
|
11
11
|
import {
|
|
12
12
|
FunctionMetadata,
|
|
13
13
|
ParameterSchema,
|
|
14
|
-
OutputSchema
|
|
15
|
-
RegisterFunctionOptions,
|
|
16
|
-
RegisterAsyncProviderOptions
|
|
14
|
+
OutputSchema
|
|
17
15
|
} from "./parsing/functions/function_metadata";
|
|
18
16
|
import Function from "./parsing/functions/function";
|
|
19
17
|
|
|
20
|
-
/**
|
|
21
|
-
* Register a synchronous plugin function.
|
|
22
|
-
*
|
|
23
|
-
* @param name - The function name
|
|
24
|
-
* @param factoryOrOptions - Factory function or options object with metadata
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```javascript
|
|
28
|
-
* // Simple registration
|
|
29
|
-
* FlowQuery.registerFunction("uppercase", () => new MyUpperCaseFunction());
|
|
30
|
-
*
|
|
31
|
-
* // Registration with metadata for LLM consumption
|
|
32
|
-
* FlowQuery.registerFunction("uppercase", {
|
|
33
|
-
* factory: () => new MyUpperCaseFunction(),
|
|
34
|
-
* metadata: {
|
|
35
|
-
* name: "uppercase",
|
|
36
|
-
* description: "Converts a string to uppercase",
|
|
37
|
-
* category: "string",
|
|
38
|
-
* parameters: [{ name: "text", description: "String to convert", type: "string" }],
|
|
39
|
-
* output: { description: "Uppercase string", type: "string" },
|
|
40
|
-
* examples: ["WITH 'hello' AS s RETURN uppercase(s)"]
|
|
41
|
-
* }
|
|
42
|
-
* });
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
FlowQuery.registerFunction = function(name: string, factoryOrOptions: FunctionCreator | RegisterFunctionOptions): void {
|
|
46
|
-
FunctionFactory.register(name, factoryOrOptions);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Unregister a synchronous plugin function.
|
|
51
|
-
*
|
|
52
|
-
* @param name - The function name
|
|
53
|
-
*/
|
|
54
|
-
FlowQuery.unregisterFunction = function(name: string): void {
|
|
55
|
-
FunctionFactory.unregister(name);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Register an async data provider function for use in LOAD operations.
|
|
60
|
-
*
|
|
61
|
-
* @param name - The function name
|
|
62
|
-
* @param providerOrOptions - Async provider or options object with metadata
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```javascript
|
|
66
|
-
* // Registration with metadata for LLM consumption
|
|
67
|
-
* FlowQuery.registerAsyncProvider("fetchUsers", {
|
|
68
|
-
* provider: async function* (endpoint) {
|
|
69
|
-
* const response = await fetch(endpoint);
|
|
70
|
-
* const data = await response.json();
|
|
71
|
-
* for (const item of data) yield item;
|
|
72
|
-
* },
|
|
73
|
-
* metadata: {
|
|
74
|
-
* name: "fetchUsers",
|
|
75
|
-
* description: "Fetches user data from an API",
|
|
76
|
-
* category: "data",
|
|
77
|
-
* parameters: [{ name: "endpoint", description: "API URL", type: "string" }],
|
|
78
|
-
* output: {
|
|
79
|
-
* description: "User object",
|
|
80
|
-
* type: "object",
|
|
81
|
-
* properties: {
|
|
82
|
-
* id: { description: "User ID", type: "number" },
|
|
83
|
-
* name: { description: "User name", type: "string" }
|
|
84
|
-
* }
|
|
85
|
-
* },
|
|
86
|
-
* examples: ["LOAD JSON FROM fetchUsers('https://api.example.com/users') AS user"]
|
|
87
|
-
* }
|
|
88
|
-
* });
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
FlowQuery.registerAsyncProvider = function(name: string, providerOrOptions: AsyncDataProvider | RegisterAsyncProviderOptions): void {
|
|
92
|
-
FunctionFactory.registerAsyncProvider(name, providerOrOptions);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Unregister an async data provider function.
|
|
97
|
-
*
|
|
98
|
-
* @param name - The function name
|
|
99
|
-
*/
|
|
100
|
-
FlowQuery.unregisterAsyncProvider = function(name: string): void {
|
|
101
|
-
FunctionFactory.unregisterAsyncProvider(name);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
18
|
/**
|
|
105
19
|
* List all registered functions with their metadata.
|
|
106
20
|
*
|
package/src/index.node.ts
CHANGED
|
@@ -7,100 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import {default as FlowQuery} from "./compute/runner";
|
|
10
|
-
import FunctionFactory, {
|
|
10
|
+
import FunctionFactory, { AsyncDataProvider } from "./parsing/functions/function_factory";
|
|
11
11
|
import {
|
|
12
12
|
FunctionMetadata,
|
|
13
13
|
ParameterSchema,
|
|
14
|
-
OutputSchema
|
|
15
|
-
RegisterFunctionOptions,
|
|
16
|
-
RegisterAsyncProviderOptions
|
|
14
|
+
OutputSchema
|
|
17
15
|
} from "./parsing/functions/function_metadata";
|
|
18
16
|
import Function from "./parsing/functions/function";
|
|
19
17
|
|
|
20
|
-
/**
|
|
21
|
-
* Register a synchronous plugin function.
|
|
22
|
-
*
|
|
23
|
-
* @param name - The function name
|
|
24
|
-
* @param factoryOrOptions - Factory function or options object with metadata
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```javascript
|
|
28
|
-
* // Simple registration
|
|
29
|
-
* FlowQuery.registerFunction("uppercase", () => new MyUpperCaseFunction());
|
|
30
|
-
*
|
|
31
|
-
* // Registration with metadata for LLM consumption
|
|
32
|
-
* FlowQuery.registerFunction("uppercase", {
|
|
33
|
-
* factory: () => new MyUpperCaseFunction(),
|
|
34
|
-
* metadata: {
|
|
35
|
-
* name: "uppercase",
|
|
36
|
-
* description: "Converts a string to uppercase",
|
|
37
|
-
* category: "string",
|
|
38
|
-
* parameters: [{ name: "text", description: "String to convert", type: "string" }],
|
|
39
|
-
* output: { description: "Uppercase string", type: "string" },
|
|
40
|
-
* examples: ["WITH 'hello' AS s RETURN uppercase(s)"]
|
|
41
|
-
* }
|
|
42
|
-
* });
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
FlowQuery.registerFunction = function(name: string, factoryOrOptions: FunctionCreator | RegisterFunctionOptions): void {
|
|
46
|
-
FunctionFactory.register(name, factoryOrOptions);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Unregister a synchronous plugin function.
|
|
51
|
-
*
|
|
52
|
-
* @param name - The function name
|
|
53
|
-
*/
|
|
54
|
-
FlowQuery.unregisterFunction = function(name: string): void {
|
|
55
|
-
FunctionFactory.unregister(name);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Register an async data provider function for use in LOAD operations.
|
|
60
|
-
*
|
|
61
|
-
* @param name - The function name
|
|
62
|
-
* @param providerOrOptions - Async provider or options object with metadata
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```javascript
|
|
66
|
-
* // Registration with metadata for LLM consumption
|
|
67
|
-
* FlowQuery.registerAsyncProvider("fetchUsers", {
|
|
68
|
-
* provider: async function* (endpoint) {
|
|
69
|
-
* const response = await fetch(endpoint);
|
|
70
|
-
* const data = await response.json();
|
|
71
|
-
* for (const item of data) yield item;
|
|
72
|
-
* },
|
|
73
|
-
* metadata: {
|
|
74
|
-
* name: "fetchUsers",
|
|
75
|
-
* description: "Fetches user data from an API",
|
|
76
|
-
* category: "data",
|
|
77
|
-
* parameters: [{ name: "endpoint", description: "API URL", type: "string" }],
|
|
78
|
-
* output: {
|
|
79
|
-
* description: "User object",
|
|
80
|
-
* type: "object",
|
|
81
|
-
* properties: {
|
|
82
|
-
* id: { description: "User ID", type: "number" },
|
|
83
|
-
* name: { description: "User name", type: "string" }
|
|
84
|
-
* }
|
|
85
|
-
* },
|
|
86
|
-
* examples: ["LOAD JSON FROM fetchUsers('https://api.example.com/users') AS user"]
|
|
87
|
-
* }
|
|
88
|
-
* });
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
FlowQuery.registerAsyncProvider = function(name: string, providerOrOptions: AsyncDataProvider | RegisterAsyncProviderOptions): void {
|
|
92
|
-
FunctionFactory.registerAsyncProvider(name, providerOrOptions);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Unregister an async data provider function.
|
|
97
|
-
*
|
|
98
|
-
* @param name - The function name
|
|
99
|
-
*/
|
|
100
|
-
FlowQuery.unregisterAsyncProvider = function(name: string): void {
|
|
101
|
-
FunctionFactory.unregisterAsyncProvider(name);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
18
|
/**
|
|
105
19
|
* List all registered functions with their metadata.
|
|
106
20
|
*
|
|
@@ -131,11 +45,8 @@ export {
|
|
|
131
45
|
FlowQuery,
|
|
132
46
|
Function,
|
|
133
47
|
FunctionFactory,
|
|
134
|
-
FunctionCreator,
|
|
135
48
|
AsyncDataProvider,
|
|
136
49
|
FunctionMetadata,
|
|
137
50
|
ParameterSchema,
|
|
138
|
-
OutputSchema
|
|
139
|
-
RegisterFunctionOptions,
|
|
140
|
-
RegisterAsyncProviderOptions
|
|
51
|
+
OutputSchema
|
|
141
52
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import AggregateFunction from "./aggregate_function";
|
|
2
2
|
import ASTNode from "../ast_node";
|
|
3
3
|
import ReducerElement from "./reducer_element";
|
|
4
|
+
import { FunctionDef } from "./function_metadata";
|
|
4
5
|
|
|
5
6
|
class AvgReducerElement extends ReducerElement {
|
|
6
7
|
private _count: number = 0;
|
|
@@ -21,6 +22,15 @@ class AvgReducerElement extends ReducerElement {
|
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
@FunctionDef({
|
|
26
|
+
description: "Calculates the average of numeric values across grouped rows",
|
|
27
|
+
category: "aggregate",
|
|
28
|
+
parameters: [
|
|
29
|
+
{ name: "value", description: "Numeric value to average", type: "number" }
|
|
30
|
+
],
|
|
31
|
+
output: { description: "Average of all values", type: "number", example: 50 },
|
|
32
|
+
examples: ["WITH [10, 20, 30] AS nums UNWIND nums AS n RETURN avg(n)"]
|
|
33
|
+
})
|
|
24
34
|
class Avg extends AggregateFunction {
|
|
25
35
|
constructor() {
|
|
26
36
|
super("avg");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import AggregateFunction from "./aggregate_function";
|
|
2
2
|
import ReducerElement from "./reducer_element";
|
|
3
|
+
import { FunctionDef } from "./function_metadata";
|
|
3
4
|
|
|
4
5
|
class CollectReducerElement extends ReducerElement {
|
|
5
6
|
private _value: any[] = [];
|
|
@@ -24,6 +25,15 @@ class DistinctCollectReducerElement extends ReducerElement {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
@FunctionDef({
|
|
29
|
+
description: "Collects values into an array across grouped rows",
|
|
30
|
+
category: "aggregate",
|
|
31
|
+
parameters: [
|
|
32
|
+
{ name: "value", description: "Value to collect", type: "any" }
|
|
33
|
+
],
|
|
34
|
+
output: { description: "Array of collected values", type: "array", example: [1, 2, 3] },
|
|
35
|
+
examples: ["WITH [1, 2, 3] AS nums UNWIND nums AS n RETURN collect(n)"]
|
|
36
|
+
})
|
|
27
37
|
class Collect extends AggregateFunction {
|
|
28
38
|
private _distinct: boolean = false;
|
|
29
39
|
constructor() {
|