flowquery 1.0.3 → 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.
Files changed (268) hide show
  1. package/README.md +182 -0
  2. package/dist/compute/runner.d.ts +81 -0
  3. package/dist/compute/runner.d.ts.map +1 -0
  4. package/dist/extensibility.d.ts +9 -0
  5. package/dist/extensibility.d.ts.map +1 -0
  6. package/dist/extensibility.js +25 -0
  7. package/dist/extensibility.js.map +1 -0
  8. package/dist/flowquery.min.js +1 -1
  9. package/dist/index.browser.d.ts +10 -0
  10. package/dist/index.browser.d.ts.map +1 -0
  11. package/dist/index.d.ts +9 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.node.d.ts +14 -0
  14. package/dist/index.node.d.ts.map +1 -0
  15. package/dist/io/command_line.d.ts +28 -0
  16. package/dist/io/command_line.d.ts.map +1 -0
  17. package/dist/parsing/alias.d.ts +10 -0
  18. package/dist/parsing/alias.d.ts.map +1 -0
  19. package/dist/parsing/alias_option.d.ts +6 -0
  20. package/dist/parsing/alias_option.d.ts.map +1 -0
  21. package/dist/parsing/ast_node.d.ts +100 -0
  22. package/dist/parsing/ast_node.d.ts.map +1 -0
  23. package/dist/parsing/base_parser.d.ts +49 -0
  24. package/dist/parsing/base_parser.d.ts.map +1 -0
  25. package/dist/parsing/components/csv.d.ts +6 -0
  26. package/dist/parsing/components/csv.d.ts.map +1 -0
  27. package/dist/parsing/components/from.d.ts +7 -0
  28. package/dist/parsing/components/from.d.ts.map +1 -0
  29. package/dist/parsing/components/headers.d.ts +7 -0
  30. package/dist/parsing/components/headers.d.ts.map +1 -0
  31. package/dist/parsing/components/json.d.ts +6 -0
  32. package/dist/parsing/components/json.d.ts.map +1 -0
  33. package/dist/parsing/components/null.d.ts +6 -0
  34. package/dist/parsing/components/null.d.ts.map +1 -0
  35. package/dist/parsing/components/post.d.ts +6 -0
  36. package/dist/parsing/components/post.d.ts.map +1 -0
  37. package/dist/parsing/components/text.d.ts +6 -0
  38. package/dist/parsing/components/text.d.ts.map +1 -0
  39. package/dist/parsing/context.d.ts +38 -0
  40. package/dist/parsing/context.d.ts.map +1 -0
  41. package/dist/parsing/data_structures/associative_array.d.ts +28 -0
  42. package/dist/parsing/data_structures/associative_array.d.ts.map +1 -0
  43. package/dist/parsing/data_structures/json_array.d.ts +26 -0
  44. package/dist/parsing/data_structures/json_array.d.ts.map +1 -0
  45. package/dist/parsing/data_structures/key_value_pair.d.ts +25 -0
  46. package/dist/parsing/data_structures/key_value_pair.d.ts.map +1 -0
  47. package/dist/parsing/data_structures/lookup.d.ts +25 -0
  48. package/dist/parsing/data_structures/lookup.d.ts.map +1 -0
  49. package/dist/parsing/data_structures/range_lookup.d.ts +14 -0
  50. package/dist/parsing/data_structures/range_lookup.d.ts.map +1 -0
  51. package/dist/parsing/expressions/expression.d.ts +53 -0
  52. package/dist/parsing/expressions/expression.d.ts.map +1 -0
  53. package/dist/parsing/expressions/f_string.d.ts +21 -0
  54. package/dist/parsing/expressions/f_string.d.ts.map +1 -0
  55. package/dist/parsing/expressions/identifier.d.ts +17 -0
  56. package/dist/parsing/expressions/identifier.d.ts.map +1 -0
  57. package/dist/parsing/expressions/number.d.ts +25 -0
  58. package/dist/parsing/expressions/number.d.ts.map +1 -0
  59. package/dist/parsing/expressions/operator.d.ts +79 -0
  60. package/dist/parsing/expressions/operator.d.ts.map +1 -0
  61. package/dist/parsing/expressions/reference.d.ts +29 -0
  62. package/dist/parsing/expressions/reference.d.ts.map +1 -0
  63. package/dist/parsing/expressions/string.d.ts +23 -0
  64. package/dist/parsing/expressions/string.d.ts.map +1 -0
  65. package/dist/parsing/functions/aggregate_function.d.ts +42 -0
  66. package/dist/parsing/functions/aggregate_function.d.ts.map +1 -0
  67. package/dist/parsing/functions/async_function.d.ts +52 -0
  68. package/dist/parsing/functions/async_function.d.ts.map +1 -0
  69. package/dist/parsing/functions/avg.d.ts +15 -0
  70. package/dist/parsing/functions/avg.d.ts.map +1 -0
  71. package/dist/parsing/functions/avg.js +20 -2
  72. package/dist/parsing/functions/avg.js.map +1 -1
  73. package/dist/parsing/functions/collect.d.ts +21 -0
  74. package/dist/parsing/functions/collect.d.ts.map +1 -0
  75. package/dist/parsing/functions/collect.js +20 -2
  76. package/dist/parsing/functions/collect.js.map +1 -1
  77. package/dist/parsing/functions/extensibility/index.d.ts +37 -0
  78. package/dist/parsing/functions/extensibility/index.d.ts.map +1 -0
  79. package/dist/parsing/functions/extensibility/index.js +50 -0
  80. package/dist/parsing/functions/extensibility/index.js.map +1 -0
  81. package/dist/parsing/functions/function.d.ts +36 -0
  82. package/dist/parsing/functions/function.d.ts.map +1 -0
  83. package/dist/parsing/functions/function_factory.d.ts +174 -0
  84. package/dist/parsing/functions/function_factory.d.ts.map +1 -0
  85. package/dist/parsing/functions/function_factory.js +44 -47
  86. package/dist/parsing/functions/function_factory.js.map +1 -1
  87. package/dist/parsing/functions/function_metadata.d.ts +134 -0
  88. package/dist/parsing/functions/function_metadata.d.ts.map +1 -0
  89. package/dist/parsing/functions/function_metadata.js +103 -153
  90. package/dist/parsing/functions/function_metadata.js.map +1 -1
  91. package/dist/parsing/functions/functions.d.ts +21 -0
  92. package/dist/parsing/functions/functions.d.ts.map +1 -0
  93. package/dist/parsing/functions/functions.js +37 -2
  94. package/dist/parsing/functions/functions.js.map +1 -1
  95. package/dist/parsing/functions/join.d.ts +9 -0
  96. package/dist/parsing/functions/join.d.ts.map +1 -0
  97. package/dist/parsing/functions/join.js +21 -2
  98. package/dist/parsing/functions/join.js.map +1 -1
  99. package/dist/parsing/functions/predicate_function.d.ts +19 -0
  100. package/dist/parsing/functions/predicate_function.d.ts.map +1 -0
  101. package/dist/parsing/functions/predicate_function.js +3 -0
  102. package/dist/parsing/functions/predicate_function.js.map +1 -1
  103. package/dist/parsing/functions/predicate_sum.d.ts +7 -0
  104. package/dist/parsing/functions/predicate_sum.d.ts.map +1 -0
  105. package/dist/parsing/functions/predicate_sum.js +23 -2
  106. package/dist/parsing/functions/predicate_sum.js.map +1 -1
  107. package/dist/parsing/functions/rand.d.ts +7 -0
  108. package/dist/parsing/functions/rand.d.ts.map +1 -0
  109. package/dist/parsing/functions/rand.js +18 -2
  110. package/dist/parsing/functions/rand.js.map +1 -1
  111. package/dist/parsing/functions/range.d.ts +7 -0
  112. package/dist/parsing/functions/range.d.ts.map +1 -0
  113. package/dist/parsing/functions/range.js +21 -2
  114. package/dist/parsing/functions/range.js.map +1 -1
  115. package/dist/parsing/functions/reducer_element.d.ts +6 -0
  116. package/dist/parsing/functions/reducer_element.d.ts.map +1 -0
  117. package/dist/parsing/functions/replace.d.ts +7 -0
  118. package/dist/parsing/functions/replace.d.ts.map +1 -0
  119. package/dist/parsing/functions/replace.js +22 -2
  120. package/dist/parsing/functions/replace.js.map +1 -1
  121. package/dist/parsing/functions/round.d.ts +7 -0
  122. package/dist/parsing/functions/round.d.ts.map +1 -0
  123. package/dist/parsing/functions/round.js +20 -2
  124. package/dist/parsing/functions/round.js.map +1 -1
  125. package/dist/parsing/functions/size.d.ts +7 -0
  126. package/dist/parsing/functions/size.d.ts.map +1 -0
  127. package/dist/parsing/functions/size.js +20 -2
  128. package/dist/parsing/functions/size.js.map +1 -1
  129. package/dist/parsing/functions/split.d.ts +9 -0
  130. package/dist/parsing/functions/split.d.ts.map +1 -0
  131. package/dist/parsing/functions/split.js +21 -2
  132. package/dist/parsing/functions/split.js.map +1 -1
  133. package/dist/parsing/functions/stringify.d.ts +9 -0
  134. package/dist/parsing/functions/stringify.d.ts.map +1 -0
  135. package/dist/parsing/functions/stringify.js +20 -2
  136. package/dist/parsing/functions/stringify.js.map +1 -1
  137. package/dist/parsing/functions/sum.d.ts +14 -0
  138. package/dist/parsing/functions/sum.d.ts.map +1 -0
  139. package/dist/parsing/functions/sum.js +20 -2
  140. package/dist/parsing/functions/sum.js.map +1 -1
  141. package/dist/parsing/functions/to_json.d.ts +7 -0
  142. package/dist/parsing/functions/to_json.d.ts.map +1 -0
  143. package/dist/parsing/functions/to_json.js +20 -2
  144. package/dist/parsing/functions/to_json.js.map +1 -1
  145. package/dist/parsing/functions/value_holder.d.ts +8 -0
  146. package/dist/parsing/functions/value_holder.d.ts.map +1 -0
  147. package/dist/parsing/logic/case.d.ts +7 -0
  148. package/dist/parsing/logic/case.d.ts.map +1 -0
  149. package/dist/parsing/logic/else.d.ts +7 -0
  150. package/dist/parsing/logic/else.d.ts.map +1 -0
  151. package/dist/parsing/logic/end.d.ts +6 -0
  152. package/dist/parsing/logic/end.d.ts.map +1 -0
  153. package/dist/parsing/logic/then.d.ts +7 -0
  154. package/dist/parsing/logic/then.d.ts.map +1 -0
  155. package/dist/parsing/logic/when.d.ts +7 -0
  156. package/dist/parsing/logic/when.d.ts.map +1 -0
  157. package/dist/parsing/operations/aggregated_return.d.ts +8 -0
  158. package/dist/parsing/operations/aggregated_return.d.ts.map +1 -0
  159. package/dist/parsing/operations/aggregated_with.d.ts +8 -0
  160. package/dist/parsing/operations/aggregated_with.d.ts.map +1 -0
  161. package/dist/parsing/operations/group_by.d.ts +35 -0
  162. package/dist/parsing/operations/group_by.d.ts.map +1 -0
  163. package/dist/parsing/operations/limit.d.ts +10 -0
  164. package/dist/parsing/operations/limit.d.ts.map +1 -0
  165. package/dist/parsing/operations/load.d.ts +48 -0
  166. package/dist/parsing/operations/load.d.ts.map +1 -0
  167. package/dist/parsing/operations/operation.d.ts +39 -0
  168. package/dist/parsing/operations/operation.d.ts.map +1 -0
  169. package/dist/parsing/operations/projection.d.ts +8 -0
  170. package/dist/parsing/operations/projection.d.ts.map +1 -0
  171. package/dist/parsing/operations/return.d.ts +23 -0
  172. package/dist/parsing/operations/return.d.ts.map +1 -0
  173. package/dist/parsing/operations/unwind.d.ts +12 -0
  174. package/dist/parsing/operations/unwind.d.ts.map +1 -0
  175. package/dist/parsing/operations/where.d.ts +26 -0
  176. package/dist/parsing/operations/where.d.ts.map +1 -0
  177. package/dist/parsing/operations/with.d.ts +17 -0
  178. package/dist/parsing/operations/with.d.ts.map +1 -0
  179. package/dist/parsing/parser.d.ts +66 -0
  180. package/dist/parsing/parser.d.ts.map +1 -0
  181. package/dist/parsing/parser.js +2 -3
  182. package/dist/parsing/parser.js.map +1 -1
  183. package/dist/parsing/token_to_node.d.ts +7 -0
  184. package/dist/parsing/token_to_node.d.ts.map +1 -0
  185. package/dist/tokenization/keyword.d.ts +43 -0
  186. package/dist/tokenization/keyword.d.ts.map +1 -0
  187. package/dist/tokenization/operator.d.ts +22 -0
  188. package/dist/tokenization/operator.d.ts.map +1 -0
  189. package/dist/tokenization/string_walker.d.ts +55 -0
  190. package/dist/tokenization/string_walker.d.ts.map +1 -0
  191. package/dist/tokenization/symbol.d.ts +15 -0
  192. package/dist/tokenization/symbol.d.ts.map +1 -0
  193. package/dist/tokenization/token.d.ts +176 -0
  194. package/dist/tokenization/token.d.ts.map +1 -0
  195. package/dist/tokenization/token_mapper.d.ts +40 -0
  196. package/dist/tokenization/token_mapper.d.ts.map +1 -0
  197. package/dist/tokenization/token_type.d.ts +16 -0
  198. package/dist/tokenization/token_type.d.ts.map +1 -0
  199. package/dist/tokenization/tokenizer.d.ts +45 -0
  200. package/dist/tokenization/tokenizer.d.ts.map +1 -0
  201. package/dist/tokenization/trie.d.ts +41 -0
  202. package/dist/tokenization/trie.d.ts.map +1 -0
  203. package/dist/utils/object_utils.d.ts +15 -0
  204. package/dist/utils/object_utils.d.ts.map +1 -0
  205. package/dist/utils/string_utils.d.ts +51 -0
  206. package/dist/utils/string_utils.d.ts.map +1 -0
  207. package/docs/flowquery.min.js +1 -1
  208. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  209. package/misc/apps/RAG/.env.example +14 -0
  210. package/misc/apps/RAG/README.md +0 -7
  211. package/misc/apps/RAG/package.json +16 -7
  212. package/misc/apps/RAG/public/index.html +18 -0
  213. package/misc/apps/RAG/src/App.css +42 -0
  214. package/misc/apps/RAG/src/App.tsx +50 -0
  215. package/misc/apps/RAG/src/components/ApiKeySettings.tsx +245 -0
  216. package/misc/apps/RAG/src/components/ChatContainer.css +67 -0
  217. package/misc/apps/RAG/src/components/ChatContainer.tsx +239 -0
  218. package/misc/apps/RAG/src/components/ChatInput.css +23 -0
  219. package/misc/apps/RAG/src/components/ChatInput.tsx +62 -0
  220. package/misc/apps/RAG/src/components/ChatMessage.css +136 -0
  221. package/misc/apps/RAG/src/components/ChatMessage.tsx +152 -0
  222. package/misc/apps/RAG/src/components/FlowQueryAgent.ts +390 -0
  223. package/misc/apps/RAG/src/components/FlowQueryRunner.css +104 -0
  224. package/misc/apps/RAG/src/components/FlowQueryRunner.tsx +332 -0
  225. package/misc/apps/RAG/src/components/index.ts +15 -0
  226. package/misc/apps/RAG/src/index.tsx +17 -0
  227. package/misc/apps/RAG/src/plugins/PluginRegistry.ts +136 -0
  228. package/misc/apps/RAG/src/plugins/README.md +139 -0
  229. package/misc/apps/RAG/src/plugins/index.ts +72 -0
  230. package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +79 -0
  231. package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +71 -0
  232. package/misc/apps/RAG/src/plugins/loaders/Llm.ts +441 -0
  233. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +161 -0
  234. package/misc/apps/RAG/src/plugins/types.ts +52 -0
  235. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +385 -0
  236. package/misc/apps/RAG/src/prompts/index.ts +10 -0
  237. package/misc/apps/RAG/src/utils/FlowQueryExecutor.ts +131 -0
  238. package/misc/apps/RAG/src/utils/FlowQueryExtractor.ts +203 -0
  239. package/misc/apps/RAG/src/utils/index.ts +9 -0
  240. package/misc/apps/RAG/tsconfig.json +4 -2
  241. package/misc/apps/RAG/webpack.config.js +23 -12
  242. package/package.json +7 -1
  243. package/src/extensibility.ts +9 -0
  244. package/src/parsing/functions/avg.ts +10 -0
  245. package/src/parsing/functions/collect.ts +10 -0
  246. package/src/parsing/functions/extensibility/index.ts +54 -0
  247. package/src/parsing/functions/function_factory.ts +51 -48
  248. package/src/parsing/functions/function_metadata.ts +132 -156
  249. package/src/parsing/functions/functions.ts +27 -0
  250. package/src/parsing/functions/join.ts +11 -0
  251. package/src/parsing/functions/predicate_function.ts +4 -0
  252. package/src/parsing/functions/predicate_sum.ts +13 -0
  253. package/src/parsing/functions/rand.ts +8 -0
  254. package/src/parsing/functions/range.ts +11 -0
  255. package/src/parsing/functions/replace.ts +12 -0
  256. package/src/parsing/functions/round.ts +10 -0
  257. package/src/parsing/functions/size.ts +10 -0
  258. package/src/parsing/functions/split.ts +11 -0
  259. package/src/parsing/functions/stringify.ts +10 -0
  260. package/src/parsing/functions/sum.ts +10 -0
  261. package/src/parsing/functions/to_json.ts +10 -0
  262. package/src/parsing/parser.ts +2 -3
  263. package/tests/parsing/function_plugins.test.ts +11 -11
  264. package/tsconfig.json +4 -1
  265. package/dist/parsing/functions/predicate_function_factory.js +0 -19
  266. package/dist/parsing/functions/predicate_function_factory.js.map +0 -1
  267. package/misc/apps/RAG/src/index.ts +0 -20
  268. package/src/parsing/functions/predicate_function_factory.ts +0 -15
@@ -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": "commonjs",
7
- "moduleResolution": "node",
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: 'production',
5
- entry: './src/index.ts',
6
- target: 'node',
5
+ mode: 'development',
6
+ entry: './src/index.tsx',
7
+ target: 'web',
7
8
  output: {
8
- filename: 'rag.bundle.js',
9
+ filename: 'bundle.js',
9
10
  path: path.resolve(__dirname, 'dist'),
10
- libraryTarget: 'commonjs2'
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: /\.ts$/,
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
- externals: {
25
- // Add any externals here if needed
26
- // For example, if you want to exclude flowquery from the bundle:
27
- // 'flowquery': 'commonjs flowquery'
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: true
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",
3
+ "version": "1.0.6",
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": {
@@ -0,0 +1,9 @@
1
+ /**
2
+ * FlowQuery Extensibility API
3
+ *
4
+ * This module re-exports the extensibility API from the parsing/functions/extensibility module.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+
9
+ export * from "./parsing/functions/extensibility";
@@ -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() {
@@ -0,0 +1,54 @@
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 '../parsing/functions/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 "../function";
32
+ export { default as AggregateFunction } from "../aggregate_function";
33
+ export { default as PredicateFunction } from "../predicate_function";
34
+ export { default as ReducerElement } from "../reducer_element";
35
+
36
+ // Decorator and metadata types for function registration
37
+ export {
38
+ FunctionDef,
39
+ FunctionMetadata,
40
+ FunctionDefOptions,
41
+ ParameterSchema,
42
+ OutputSchema,
43
+ FunctionCategory
44
+ } from "../function_metadata";
45
+
46
+ // Factory for advanced usage
47
+ export { default as FunctionFactory } from "../function_factory";
48
+ export type { FunctionCreator, AsyncDataProvider } from "../function_factory";
49
+
50
+ // Registration option types
51
+ export type {
52
+ RegisterFunctionOptions,
53
+ RegisterAsyncProviderOptions
54
+ } from "../function_metadata";
@@ -1,22 +1,27 @@
1
- import Sum from "./sum";
2
- import Collect from "./collect";
3
- import Avg from "./avg";
4
- import Range from "./range";
5
- import Rand from "./rand";
6
- import Round from "./round";
7
- import Split from "./split";
8
- import Join from "./join";
9
- import ToJson from "./to_json";
10
- import Replace from "./replace";
11
- import Stringify from "./stringify";
12
- import Size from "./size";
13
- import Functions from "./functions";
14
1
  import Function from "./function";
2
+ import PredicateFunction from "./predicate_function";
3
+ // Import built-in functions to ensure their @FunctionDef decorators run
4
+ import "./sum";
5
+ import "./collect";
6
+ import "./avg";
7
+ import "./range";
8
+ import "./rand";
9
+ import "./round";
10
+ import "./split";
11
+ import "./join";
12
+ import "./to_json";
13
+ import "./replace";
14
+ import "./stringify";
15
+ import "./size";
16
+ import "./functions";
17
+ import "./predicate_sum";
15
18
  import {
16
19
  FunctionMetadata,
17
20
  RegisterFunctionOptions,
18
21
  RegisterAsyncProviderOptions,
19
- BUILTIN_FUNCTION_METADATA
22
+ getRegisteredFunctionMetadata,
23
+ getFunctionMetadata,
24
+ getRegisteredFunctionFactory
20
25
  } from "./function_metadata";
21
26
 
22
27
  /**
@@ -182,8 +187,8 @@ class FunctionFactory {
182
187
  if (FunctionFactory.metadata.has(lowerName)) {
183
188
  return FunctionFactory.metadata.get(lowerName);
184
189
  }
185
- // Fall back to built-in metadata
186
- return BUILTIN_FUNCTION_METADATA.find(m => m.name === lowerName);
190
+ // Fall back to decorator-registered metadata
191
+ return getFunctionMetadata(lowerName);
187
192
  }
188
193
 
189
194
  /**
@@ -202,9 +207,9 @@ class FunctionFactory {
202
207
  const result: FunctionMetadata[] = [];
203
208
  const includeBuiltins = options?.includeBuiltins !== false;
204
209
 
205
- // Add built-in functions
210
+ // Add decorator-registered functions (built-ins)
206
211
  if (includeBuiltins) {
207
- for (const meta of BUILTIN_FUNCTION_METADATA) {
212
+ for (const meta of getRegisteredFunctionMetadata()) {
208
213
  if (options?.category && meta.category !== options.category) continue;
209
214
  if (options?.asyncOnly) continue; // Built-ins are sync
210
215
  result.push(meta);
@@ -228,7 +233,7 @@ class FunctionFactory {
228
233
  * @returns Array of function names
229
234
  */
230
235
  public static listFunctionNames(): string[] {
231
- const builtinNames = BUILTIN_FUNCTION_METADATA.map(m => m.name);
236
+ const builtinNames = getRegisteredFunctionMetadata().map(m => m.name);
232
237
  const pluginNames = Array.from(FunctionFactory.plugins.keys());
233
238
  const asyncNames = Array.from(FunctionFactory.asyncProviders.keys());
234
239
  return [...new Set([...builtinNames, ...pluginNames, ...asyncNames])];
@@ -259,36 +264,34 @@ class FunctionFactory {
259
264
  return FunctionFactory.plugins.get(lowerName)!();
260
265
  }
261
266
 
262
- switch (lowerName) {
263
- case "sum":
264
- return new Sum();
265
- case "collect":
266
- return new Collect();
267
- case "avg":
268
- return new Avg();
269
- case "range":
270
- return new Range();
271
- case "rand":
272
- return new Rand();
273
- case "round":
274
- return new Round();
275
- case "split":
276
- return new Split();
277
- case "join":
278
- return new Join();
279
- case "tojson":
280
- return new ToJson();
281
- case "replace":
282
- return new Replace();
283
- case "stringify":
284
- return new Stringify();
285
- case "size":
286
- return new Size();
287
- case "functions":
288
- return new Functions();
289
- default:
290
- return new Function(name);
267
+ // Check decorator-registered functions (built-ins use @FunctionDef)
268
+ const decoratorFactory = getRegisteredFunctionFactory(lowerName);
269
+ if (decoratorFactory) {
270
+ return decoratorFactory();
291
271
  }
272
+
273
+ // Unknown function - return generic Function instance
274
+ return new Function(name);
275
+ }
276
+
277
+ /**
278
+ * Creates a predicate function instance by name.
279
+ * Predicate functions are used in WHERE clauses with quantifiers (e.g., ANY, ALL).
280
+ *
281
+ * @param name - The function name (case-insensitive)
282
+ * @returns A PredicateFunction instance of the appropriate type
283
+ */
284
+ public static createPredicate(name: string): PredicateFunction {
285
+ const lowerName = name.toLowerCase();
286
+
287
+ // Check decorator-registered predicate functions
288
+ const decoratorFactory = getRegisteredFunctionFactory(lowerName, 'predicate');
289
+ if (decoratorFactory) {
290
+ return decoratorFactory();
291
+ }
292
+
293
+ // Unknown predicate function - return generic PredicateFunction instance
294
+ return new PredicateFunction(name);
292
295
  }
293
296
  }
294
297