flowquery 1.0.12 → 1.0.13

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 (58) hide show
  1. package/README.md +3 -3
  2. package/dist/flowquery.min.js +1 -1
  3. package/dist/parsing/functions/aggregate_function.d.ts +1 -1
  4. package/dist/parsing/functions/aggregate_function.d.ts.map +1 -1
  5. package/dist/parsing/functions/aggregate_function.js.map +1 -1
  6. package/dist/parsing/functions/async_function.d.ts +4 -15
  7. package/dist/parsing/functions/async_function.d.ts.map +1 -1
  8. package/dist/parsing/functions/async_function.js +6 -59
  9. package/dist/parsing/functions/async_function.js.map +1 -1
  10. package/dist/parsing/functions/function.d.ts +1 -1
  11. package/dist/parsing/functions/function.d.ts.map +1 -1
  12. package/dist/parsing/functions/function.js +1 -1
  13. package/dist/parsing/functions/function.js.map +1 -1
  14. package/dist/parsing/functions/function_factory.d.ts +2 -0
  15. package/dist/parsing/functions/function_factory.d.ts.map +1 -1
  16. package/dist/parsing/functions/function_factory.js +12 -11
  17. package/dist/parsing/functions/function_factory.js.map +1 -1
  18. package/dist/parsing/functions/function_metadata.d.ts +53 -24
  19. package/dist/parsing/functions/function_metadata.d.ts.map +1 -1
  20. package/dist/parsing/functions/function_metadata.js +55 -45
  21. package/dist/parsing/functions/function_metadata.js.map +1 -1
  22. package/dist/parsing/functions/predicate_function.d.ts +1 -1
  23. package/dist/parsing/functions/predicate_function.d.ts.map +1 -1
  24. package/dist/parsing/functions/predicate_function.js +1 -1
  25. package/dist/parsing/functions/predicate_function.js.map +1 -1
  26. package/dist/parsing/operations/load.js +1 -1
  27. package/dist/parsing/operations/load.js.map +1 -1
  28. package/dist/parsing/parser.d.ts.map +1 -1
  29. package/dist/parsing/parser.js +1 -2
  30. package/dist/parsing/parser.js.map +1 -1
  31. package/docs/flowquery.min.js +1 -1
  32. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  33. package/misc/apps/RAG/package.json +1 -2
  34. package/misc/apps/RAG/src/components/ChatContainer.tsx +33 -6
  35. package/misc/apps/RAG/src/components/ChatMessage.css +24 -0
  36. package/misc/apps/RAG/src/components/ChatMessage.tsx +51 -2
  37. package/misc/apps/RAG/src/components/FlowQueryAgent.ts +566 -286
  38. package/misc/apps/RAG/src/plugins/index.ts +3 -1
  39. package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +6 -5
  40. package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +3 -3
  41. package/misc/apps/RAG/src/plugins/loaders/Form.ts +5 -5
  42. package/misc/apps/RAG/src/plugins/loaders/Llm.ts +14 -14
  43. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +5 -5
  44. package/misc/apps/RAG/src/plugins/loaders/Table.ts +4 -4
  45. package/misc/apps/RAG/src/plugins/loaders/Weather.ts +126 -0
  46. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +4 -0
  47. package/package.json +1 -1
  48. package/src/parsing/functions/aggregate_function.ts +1 -1
  49. package/src/parsing/functions/async_function.ts +5 -50
  50. package/src/parsing/functions/function.ts +2 -2
  51. package/src/parsing/functions/function_factory.ts +18 -9
  52. package/src/parsing/functions/function_metadata.ts +55 -47
  53. package/src/parsing/functions/predicate_function.ts +2 -2
  54. package/src/parsing/operations/load.ts +1 -1
  55. package/src/parsing/parser.ts +2 -1
  56. package/tests/extensibility.test.ts +22 -22
  57. package/tests/parsing/parser.test.ts +2 -2
  58. package/misc/apps/RAG/.env.example +0 -14
@@ -78,19 +78,9 @@ export type AsyncDataProvider = (...args: any[]) => AsyncGenerator<any, void, un
78
78
  class FunctionRegistry {
79
79
  private static metadata: Map<string, FunctionMetadata> = new Map<string, FunctionMetadata>();
80
80
  private static factories: Map<string, () => any> = new Map<string, () => any>();
81
- private static asyncProviders: Map<string, AsyncDataProvider> = new Map<string, AsyncDataProvider>();
82
-
83
- /** Registers an async data provider class. */
84
- static registerAsync<T extends new (...args: any[]) => any>(constructor: T, options: FunctionDefOptions): void {
85
- const displayName: string = constructor.name;
86
- const registryKey: string = displayName.toLowerCase();
87
-
88
- this.metadata.set(registryKey, { name: displayName, ...options });
89
- this.asyncProviders.set(registryKey, (...args: any[]) => new constructor().fetch(...args));
90
- }
91
81
 
92
82
  /** Registers a regular function class. */
93
- static registerFunction<T extends new (...args: any[]) => any>(constructor: T, options: FunctionDefOptions): void {
83
+ static register<T extends new (...args: any[]) => any>(constructor: T, options: FunctionDefOptions): void {
94
84
  const instance: any = new constructor();
95
85
  const displayName: string = (instance.name?.toLowerCase() || constructor.name.toLowerCase());
96
86
  const registryKey: string = options.category ? `${displayName}:${options.category}` : displayName;
@@ -121,10 +111,6 @@ class FunctionRegistry {
121
111
  if (category) return this.factories.get(`${lowerName}:${category}`);
122
112
  return this.factories.get(lowerName);
123
113
  }
124
-
125
- static getAsyncProvider(name: string): AsyncDataProvider | undefined {
126
- return this.asyncProviders.get(name.toLowerCase());
127
- }
128
114
  }
129
115
 
130
116
  /**
@@ -137,45 +123,74 @@ export type FunctionDefOptions = Omit<FunctionMetadata, 'name'>;
137
123
  * The function name is derived from the class's constructor call to super() for regular functions,
138
124
  * or from the class name for async providers.
139
125
  *
140
- * For async providers (category: "async"), the class must have a `fetch` method that returns
141
- * an AsyncGenerator. The function name is derived from the class name, converted to camelCase
142
- * (first letter lowercased).
126
+ * For async providers (category: "async"), the class must have a `generate` method that returns
127
+ * an AsyncGenerator. This allows the function to be used as a data source in LOAD operations.
143
128
  *
144
129
  * @param options - Function metadata (excluding name)
145
130
  * @returns Class decorator
146
131
  *
147
132
  * @example
148
133
  * ```typescript
149
- * // Regular function
134
+ * // Scalar function example
150
135
  * @FunctionDef({
151
- * description: "Calculates the sum of numeric values",
152
- * category: "aggregate",
153
- * parameters: [{ name: "value", description: "Numeric value to sum", type: "number" }],
154
- * output: { description: "Sum of all values", type: "number", example: 150 },
155
- * examples: ["WITH [1, 2, 3] AS nums UNWIND nums AS n RETURN sum(n)"]
136
+ * description: "Adds two numbers",
137
+ * category: "scalar",
138
+ * parameters: [
139
+ * { name: "a", description: "First number", type: "number" },
140
+ * { name: "b", description: "Second number", type: "number" }
141
+ * ],
142
+ * output: { description: "Sum of a and b", type: "number" },
143
+ * examples: ["ADD(2, 3) // returns 5"]
156
144
  * })
157
- * class Sum extends AggregateFunction { ... }
158
- *
159
- * // Async data provider
145
+ * class AddFunction extends Function {
146
+ * constructor() {
147
+ * super("add");
148
+ * }
149
+ * public execute(a: number, b: number): number {
150
+ * return a + b;
151
+ * }
152
+ * }
153
+ * // Aggregate function example
160
154
  * @FunctionDef({
161
- * description: "Fetches random cat facts from the Cat Facts API",
162
- * category: "async",
163
- * parameters: [{ name: "count", description: "Number of facts", type: "number", required: false, default: 1 }],
164
- * output: { description: "Cat fact object", type: "object" },
165
- * examples: ["LOAD JSON FROM catFacts(5) AS fact RETURN fact.text"]
155
+ * description: "Calculates the average of a list of numbers",
156
+ * category: "aggregate",
157
+ * parameters: [
158
+ * { name: "values", description: "Array of numbers", type: "array", items: { type: "number" } }
159
+ * ],
160
+ * output: { description: "Average value", type: "number" },
161
+ * examples: ["AVERAGE([1, 2, 3, 4, 5]) // returns 3"]
166
162
  * })
167
- * class CatFacts {
168
- * async *fetch(count: number = 1): AsyncGenerator<any> { ... }
163
+ * class AverageFunction extends AggregateFunction {
164
+ * constructor() {
165
+ * super("average");
166
+ * }
167
+ * public execute(values: number[]): number {
168
+ * const sum = values.reduce((acc, val) => acc + val, 0);
169
+ * return sum / values.length;
170
+ * }
171
+ * }
172
+ * // Async data provider example
173
+ * @FunctionDef({
174
+ * description: "Fetches data from an external API",
175
+ * category: "async",
176
+ * parameters: [
177
+ * { name: "endpoint", description: "API endpoint URL", type: "string" }
178
+ * ],
179
+ * output: { description: "Data object", type: "object" },
180
+ * examples: ["MyAsyncDataProvider('https://api.example.com/data')"]
181
+ * })
182
+ * class MyAsyncDataProvider extends AsyncFunction {
183
+ * public async *generate(endpoint: string): AsyncGenerator<any> {
184
+ * const response = await fetch(endpoint);
185
+ * const data = await response.json();
186
+ * for (const item of data) {
187
+ * yield item;
188
+ * }
169
189
  * }
170
- * ```
171
190
  */
172
191
  export function FunctionDef(options: FunctionDefOptions) {
173
192
  return function <T extends new (...args: any[]) => any>(constructor: T): T {
174
- if (options.category === 'async') {
175
- FunctionRegistry.registerAsync(constructor, options);
176
- } else {
177
- FunctionRegistry.registerFunction(constructor, options);
178
- }
193
+ FunctionRegistry.register(constructor, options);
179
194
  return constructor;
180
195
  };
181
196
  }
@@ -200,10 +215,3 @@ export function getRegisteredFunctionFactory(name: string, category?: string): (
200
215
  export function getFunctionMetadata(name: string, category?: string): FunctionMetadata | undefined {
201
216
  return FunctionRegistry.getMetadata(name, category);
202
217
  }
203
-
204
- /**
205
- * Gets a registered async data provider by name.
206
- */
207
- export function getRegisteredAsyncProvider(name: string): AsyncDataProvider | undefined {
208
- return FunctionRegistry.getAsyncProvider(name);
209
- }
@@ -8,9 +8,9 @@ class PredicateFunction extends ASTNode {
8
8
  private _name: string;
9
9
  protected _valueHolder: ValueHolder = new ValueHolder();
10
10
 
11
- constructor(name: string) {
11
+ constructor(name?: string) {
12
12
  super();
13
- this._name = name;
13
+ this._name = name || this.constructor.name;
14
14
  }
15
15
 
16
16
  public get name(): string {
@@ -87,7 +87,7 @@ class Load extends Operation {
87
87
  */
88
88
  private async loadFromFunction(): Promise<void> {
89
89
  const asyncFunc = this.asyncFunction!;
90
- for await (const item of asyncFunc.execute()) {
90
+ for await (const item of asyncFunc.generate()) {
91
91
  this._value = item;
92
92
  await this.next?.run();
93
93
  }
@@ -597,7 +597,7 @@ class Parser extends BaseParser {
597
597
  if(!this.peek()?.isLeftParenthesis()) {
598
598
  return null;
599
599
  }
600
- const asyncFunc = new AsyncFunction(this.token.value);
600
+ const asyncFunc = FunctionFactory.createAsync(this.token.value);
601
601
  this.setNextToken(); // skip function name
602
602
  this.setNextToken(); // skip left parenthesis
603
603
  this.skipWhitespaceAndComments();
@@ -609,6 +609,7 @@ class Parser extends BaseParser {
609
609
  this.setNextToken();
610
610
  return asyncFunc;
611
611
  }
612
+
612
613
  private parsePredicateFunction(): PredicateFunction | null {
613
614
  if(!this.ahead([Token.IDENTIFIER(""), Token.LEFT_PARENTHESIS, Token.IDENTIFIER(""), Token.IN])) {
614
615
  return null;
@@ -12,8 +12,8 @@ import {
12
12
  FunctionCategory
13
13
  } from "../src/extensibility";
14
14
  import {
15
- getRegisteredAsyncProvider,
16
- getFunctionMetadata
15
+ getFunctionMetadata,
16
+ getRegisteredFunctionFactory
17
17
  } from "../src/parsing/functions/function_metadata";
18
18
 
19
19
  describe("Extensibility API Exports", () => {
@@ -216,8 +216,8 @@ describe("FunctionDef Decorator", () => {
216
216
  ],
217
217
  output: { description: "Data object", type: "object" }
218
218
  })
219
- class Simple {
220
- async *fetch(count: number = 1): AsyncGenerator<any> {
219
+ class Simple extends AsyncFunction {
220
+ public async *generate(count: number = 1): AsyncGenerator<any> {
221
221
  for (let i = 0; i < count; i++) {
222
222
  yield { id: i, data: `item${i}` };
223
223
  }
@@ -225,9 +225,9 @@ describe("FunctionDef Decorator", () => {
225
225
  }
226
226
 
227
227
  // Verify the decorated class still works correctly
228
- const loader = new Simple();
228
+ const loader = new Simple("simple");
229
229
  const results: any[] = [];
230
- for await (const item of loader.fetch(2)) {
230
+ for await (const item of loader.generate(2)) {
231
231
  results.push(item);
232
232
  }
233
233
  expect(results.length).toBe(2);
@@ -235,14 +235,14 @@ describe("FunctionDef Decorator", () => {
235
235
  expect(results[1]).toEqual({ id: 1, data: "item1" });
236
236
 
237
237
  // Verify the async provider was registered
238
- const provider = getRegisteredAsyncProvider("simple");
238
+ const provider = getRegisteredFunctionFactory("simple", "async");
239
239
  expect(provider).toBeDefined();
240
240
  expect(typeof provider).toBe("function");
241
241
 
242
242
  // Verify the metadata was registered
243
- const metadata = getFunctionMetadata("simple");
243
+ const metadata = getFunctionMetadata("simple", "async");
244
244
  expect(metadata).toBeDefined();
245
- expect(metadata?.name).toBe("Simple");
245
+ expect(metadata?.name).toBe("simple");
246
246
  expect(metadata?.category).toBe("async");
247
247
  expect(metadata?.description).toBe("Test async provider for extensibility");
248
248
  });
@@ -540,17 +540,17 @@ describe("Plugin Functions Integration with FlowQuery", () => {
540
540
  description: "Provides example data for testing",
541
541
  category: "async",
542
542
  parameters: [],
543
- output: { description: "Example data object", type: "object" }
543
+ output: { description: "Example data o.bject", type: "object" }
544
544
  })
545
- class GetExampleData {
546
- async *fetch(): AsyncGenerator<any> {
545
+ class GetExampleData extends AsyncFunction {
546
+ public async *generate(): AsyncGenerator<any> {
547
547
  yield { id: 1, name: "Alice" };
548
548
  yield { id: 2, name: "Bob" };
549
549
  }
550
550
  }
551
551
 
552
552
  // Verify registration worked
553
- expect(getRegisteredAsyncProvider("getExampleData")).toBeDefined();
553
+ expect(getRegisteredFunctionFactory("getExampleData", "async")).toBeDefined();
554
554
 
555
555
  // Use the async provider in a FlowQuery statement
556
556
  const runner = new Runner("LOAD JSON FROM getExampleData() AS data RETURN data.id AS id, data.name AS name");
@@ -568,22 +568,22 @@ describe("Plugin Functions Integration with FlowQuery", () => {
568
568
  parameters: [],
569
569
  output: { description: "Test data", type: "object" }
570
570
  })
571
- class MixedCaseFunc {
572
- async *fetch(): AsyncGenerator<any> {
571
+ class MixedCaseFunc extends AsyncFunction {
572
+ public async *generate(): AsyncGenerator<any> {
573
573
  yield { value: 42 };
574
574
  }
575
575
  }
576
576
 
577
577
  // Verify registration works with different casings
578
- expect(getRegisteredAsyncProvider("MixedCaseFunc")).toBeDefined();
579
- expect(getRegisteredAsyncProvider("mixedcasefunc")).toBeDefined();
580
- expect(getRegisteredAsyncProvider("MIXEDCASEFUNC")).toBeDefined();
581
- expect(getRegisteredAsyncProvider("mIxEdCaSeFuNc")).toBeDefined();
578
+ expect(getRegisteredFunctionFactory("MixedCaseFunc", "async")).toBeDefined();
579
+ expect(getRegisteredFunctionFactory("mixedcasefunc", "async")).toBeDefined();
580
+ expect(getRegisteredFunctionFactory("MIXEDCASEFUNC", "async")).toBeDefined();
581
+ expect(getRegisteredFunctionFactory("mIxEdCaSeFuNc", "async")).toBeDefined();
582
582
 
583
583
  // Verify metadata lookup is case-insensitive
584
- expect(getFunctionMetadata("MixedCaseFunc")).toBeDefined();
585
- expect(getFunctionMetadata("mixedcasefunc")).toBeDefined();
586
- expect(getFunctionMetadata("MIXEDCASEFUNC")).toBeDefined();
584
+ expect(getFunctionMetadata("MixedCaseFunc", "async")).toBeDefined();
585
+ expect(getFunctionMetadata("mixedcasefunc", "async")).toBeDefined();
586
+ expect(getFunctionMetadata("MIXEDCASEFUNC", "async")).toBeDefined();
587
587
 
588
588
  // Test using different casings in FlowQuery statements
589
589
  const runner1 = new Runner("LOAD JSON FROM mixedcasefunc() AS d RETURN d.value AS v");
@@ -17,12 +17,12 @@ test('Test Parser', () => {
17
17
 
18
18
  test('Test Parser with function', () => {
19
19
  const parser = new Parser();
20
- const ast = parser.parse('RETURN f()');
20
+ const ast = parser.parse('RETURN rand()');
21
21
  expect(ast.print()).toBe(
22
22
  'ASTNode\n' +
23
23
  '- Return\n' +
24
24
  '-- Expression\n' +
25
- '--- Function (f)'
25
+ '--- Function (rand)'
26
26
  );
27
27
  });
28
28
 
@@ -1,14 +0,0 @@
1
- # OpenAI API Configuration
2
- # Copy this file to .env and fill in your values
3
-
4
- # Your OpenAI API key (required)
5
- OPENAI_API_KEY=sk-your-api-key-here
6
-
7
- # Optional: OpenAI Organization ID
8
- OPENAI_ORGANIZATION_ID=org-your-org-id
9
-
10
- # Optional: Default model
11
- OPENAI_MODEL=gpt-4o-mini
12
-
13
- # Note: These values are read at build time and used as defaults
14
- # when localStorage is empty. Changes require rebuilding the app.