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,563 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Function,
|
|
3
|
+
AggregateFunction,
|
|
4
|
+
AsyncFunction,
|
|
5
|
+
PredicateFunction,
|
|
6
|
+
ReducerElement,
|
|
7
|
+
FunctionDef,
|
|
8
|
+
FunctionMetadata,
|
|
9
|
+
FunctionDefOptions,
|
|
10
|
+
ParameterSchema,
|
|
11
|
+
OutputSchema,
|
|
12
|
+
FunctionCategory
|
|
13
|
+
} from "../src/extensibility";
|
|
14
|
+
import {
|
|
15
|
+
getRegisteredAsyncProvider,
|
|
16
|
+
getFunctionMetadata
|
|
17
|
+
} from "../src/parsing/functions/function_metadata";
|
|
18
|
+
|
|
19
|
+
describe("Extensibility API Exports", () => {
|
|
20
|
+
test("Function class is exported and can be extended", () => {
|
|
21
|
+
class CustomFunction extends Function {
|
|
22
|
+
constructor() {
|
|
23
|
+
super("customFunc");
|
|
24
|
+
this._expectedParameterCount = 1;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public value(): string {
|
|
28
|
+
return "custom value";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const func = new CustomFunction();
|
|
33
|
+
expect(func.name).toBe("customFunc");
|
|
34
|
+
expect(func.toString()).toBe("Function (customFunc)");
|
|
35
|
+
expect(func.value()).toBe("custom value");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("Function validates parameter count when set", () => {
|
|
39
|
+
class TwoParamFunction extends Function {
|
|
40
|
+
constructor() {
|
|
41
|
+
super("twoParam");
|
|
42
|
+
this._expectedParameterCount = 2;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const func = new TwoParamFunction();
|
|
47
|
+
|
|
48
|
+
// Should throw when wrong number of parameters
|
|
49
|
+
expect(() => {
|
|
50
|
+
func.parameters = [];
|
|
51
|
+
}).toThrow("Function twoParam expected 2 parameters, but got 0");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("Function without expected parameter count accepts any number", () => {
|
|
55
|
+
class FlexibleFunction extends Function {
|
|
56
|
+
constructor() {
|
|
57
|
+
super("flexible");
|
|
58
|
+
// _expectedParameterCount is null by default
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const func = new FlexibleFunction();
|
|
63
|
+
// Should not throw
|
|
64
|
+
func.parameters = [];
|
|
65
|
+
expect(func.getChildren().length).toBe(0);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("AggregateFunction class is exported and can be extended", () => {
|
|
69
|
+
class SumElement extends ReducerElement {
|
|
70
|
+
private _value: number = 0;
|
|
71
|
+
public get value(): number {
|
|
72
|
+
return this._value;
|
|
73
|
+
}
|
|
74
|
+
public set value(v: number) {
|
|
75
|
+
this._value = v;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class CustomSum extends AggregateFunction {
|
|
80
|
+
private _total: number = 0;
|
|
81
|
+
|
|
82
|
+
constructor() {
|
|
83
|
+
super("customSum");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public reduce(element: ReducerElement): void {
|
|
87
|
+
this._total += element.value;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public element(): ReducerElement {
|
|
91
|
+
const el = new SumElement();
|
|
92
|
+
el.value = this._total;
|
|
93
|
+
return el;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public value(): number {
|
|
97
|
+
return this._total;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const agg = new CustomSum();
|
|
102
|
+
expect(agg.name).toBe("customSum");
|
|
103
|
+
|
|
104
|
+
const elem = new SumElement();
|
|
105
|
+
elem.value = 5;
|
|
106
|
+
agg.reduce(elem);
|
|
107
|
+
expect(agg.value()).toBe(5);
|
|
108
|
+
|
|
109
|
+
const elem2 = new SumElement();
|
|
110
|
+
elem2.value = 3;
|
|
111
|
+
agg.reduce(elem2);
|
|
112
|
+
expect(agg.value()).toBe(8);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("PredicateFunction class is exported and can be extended", () => {
|
|
116
|
+
class CustomPredicate extends PredicateFunction {
|
|
117
|
+
constructor() {
|
|
118
|
+
super("customPredicate");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public value(): boolean {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const pred = new CustomPredicate();
|
|
127
|
+
expect(pred.name).toBe("customPredicate");
|
|
128
|
+
expect(pred.toString()).toBe("PredicateFunction (customPredicate)");
|
|
129
|
+
expect(pred.value()).toBe(true);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("AsyncFunction class is exported and can be instantiated", () => {
|
|
133
|
+
const asyncFunc = new AsyncFunction("testAsync");
|
|
134
|
+
expect(asyncFunc.name).toBe("testAsync");
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("ReducerElement class is exported and can be extended", () => {
|
|
138
|
+
class NumberElement extends ReducerElement {
|
|
139
|
+
private _num: number = 0;
|
|
140
|
+
|
|
141
|
+
public get value(): number {
|
|
142
|
+
return this._num;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public set value(v: number) {
|
|
146
|
+
this._num = v;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const elem = new NumberElement();
|
|
151
|
+
elem.value = 42;
|
|
152
|
+
expect(elem.value).toBe(42);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe("FunctionDef Decorator", () => {
|
|
157
|
+
test("FunctionDef decorator can be applied to a scalar function", () => {
|
|
158
|
+
@FunctionDef({
|
|
159
|
+
description: "Test function for extensibility",
|
|
160
|
+
category: "scalar",
|
|
161
|
+
parameters: [
|
|
162
|
+
{ name: "input", description: "Input value", type: "string" }
|
|
163
|
+
],
|
|
164
|
+
output: { description: "Output value", type: "string" },
|
|
165
|
+
examples: ["RETURN testExtFunc('hello')"]
|
|
166
|
+
})
|
|
167
|
+
class TestExtFunc extends Function {
|
|
168
|
+
constructor() {
|
|
169
|
+
super("testExtFunc");
|
|
170
|
+
this._expectedParameterCount = 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public value(): string {
|
|
174
|
+
return "test result";
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Verify the decorated class still works correctly
|
|
179
|
+
const instance = new TestExtFunc();
|
|
180
|
+
expect(instance.name).toBe("testExtFunc");
|
|
181
|
+
expect(instance.value()).toBe("test result");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("FunctionDef decorator can be applied to an aggregate function", () => {
|
|
185
|
+
@FunctionDef({
|
|
186
|
+
description: "Test aggregate function",
|
|
187
|
+
category: "aggregate",
|
|
188
|
+
parameters: [
|
|
189
|
+
{ name: "value", description: "Numeric value", type: "number" }
|
|
190
|
+
],
|
|
191
|
+
output: { description: "Aggregated result", type: "number" }
|
|
192
|
+
})
|
|
193
|
+
class TestAggExt extends AggregateFunction {
|
|
194
|
+
private _sum: number = 0;
|
|
195
|
+
|
|
196
|
+
constructor() {
|
|
197
|
+
super("testAggExt");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public value(): number {
|
|
201
|
+
return this._sum;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const instance = new TestAggExt();
|
|
206
|
+
expect(instance.name).toBe("testAggExt");
|
|
207
|
+
expect(instance.value()).toBe(0);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("FunctionDef decorator can be applied to an async provider", async () => {
|
|
211
|
+
@FunctionDef({
|
|
212
|
+
description: "Test async provider for extensibility",
|
|
213
|
+
category: "async",
|
|
214
|
+
parameters: [
|
|
215
|
+
{ name: "count", description: "Number of items", type: "number", required: false, default: 1 }
|
|
216
|
+
],
|
|
217
|
+
output: { description: "Data object", type: "object" }
|
|
218
|
+
})
|
|
219
|
+
class SimpleLoader {
|
|
220
|
+
async *fetch(count: number = 1): AsyncGenerator<any> {
|
|
221
|
+
for (let i = 0; i < count; i++) {
|
|
222
|
+
yield { id: i, data: `item${i}` };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Verify the decorated class still works correctly
|
|
228
|
+
const loader = new SimpleLoader();
|
|
229
|
+
const results: any[] = [];
|
|
230
|
+
for await (const item of loader.fetch(2)) {
|
|
231
|
+
results.push(item);
|
|
232
|
+
}
|
|
233
|
+
expect(results.length).toBe(2);
|
|
234
|
+
expect(results[0]).toEqual({ id: 0, data: "item0" });
|
|
235
|
+
expect(results[1]).toEqual({ id: 1, data: "item1" });
|
|
236
|
+
|
|
237
|
+
// Verify the async provider was registered
|
|
238
|
+
const provider = getRegisteredAsyncProvider("simple");
|
|
239
|
+
expect(provider).toBeDefined();
|
|
240
|
+
expect(typeof provider).toBe("function");
|
|
241
|
+
|
|
242
|
+
// Verify the metadata was registered
|
|
243
|
+
const metadata = getFunctionMetadata("simple");
|
|
244
|
+
expect(metadata).toBeDefined();
|
|
245
|
+
expect(metadata?.name).toBe("simple");
|
|
246
|
+
expect(metadata?.category).toBe("async");
|
|
247
|
+
expect(metadata?.description).toBe("Test async provider for extensibility");
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
test("FunctionDef decorator can be applied to a predicate function", () => {
|
|
251
|
+
@FunctionDef({
|
|
252
|
+
description: "Test predicate function",
|
|
253
|
+
category: "predicate",
|
|
254
|
+
parameters: [
|
|
255
|
+
{ name: "list", description: "List to check", type: "array" }
|
|
256
|
+
],
|
|
257
|
+
output: { description: "Boolean result", type: "boolean" }
|
|
258
|
+
})
|
|
259
|
+
class TestPredExt extends PredicateFunction {
|
|
260
|
+
constructor() {
|
|
261
|
+
super("testPredExt");
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
public value(): boolean {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const instance = new TestPredExt();
|
|
270
|
+
expect(instance.name).toBe("testPredExt");
|
|
271
|
+
expect(instance.value()).toBe(true);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
describe("Type Exports", () => {
|
|
276
|
+
test("FunctionMetadata type can be used", () => {
|
|
277
|
+
const meta: FunctionMetadata = {
|
|
278
|
+
name: "typeTest",
|
|
279
|
+
description: "Testing type exports",
|
|
280
|
+
category: "scalar",
|
|
281
|
+
parameters: [],
|
|
282
|
+
output: { description: "Output", type: "string" }
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
expect(meta.name).toBe("typeTest");
|
|
286
|
+
expect(meta.description).toBe("Testing type exports");
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
test("ParameterSchema type can be used", () => {
|
|
290
|
+
const param: ParameterSchema = {
|
|
291
|
+
name: "testParam",
|
|
292
|
+
description: "A test parameter",
|
|
293
|
+
type: "string",
|
|
294
|
+
required: true,
|
|
295
|
+
default: "default value",
|
|
296
|
+
example: "example value"
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
expect(param.name).toBe("testParam");
|
|
300
|
+
expect(param.required).toBe(true);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test("ParameterSchema with nested types", () => {
|
|
304
|
+
const arrayParam: ParameterSchema = {
|
|
305
|
+
name: "items",
|
|
306
|
+
description: "Array of items",
|
|
307
|
+
type: "array",
|
|
308
|
+
items: {
|
|
309
|
+
description: "Item in array",
|
|
310
|
+
type: "string"
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const objectParam: ParameterSchema = {
|
|
315
|
+
name: "config",
|
|
316
|
+
description: "Configuration object",
|
|
317
|
+
type: "object",
|
|
318
|
+
properties: {
|
|
319
|
+
enabled: { description: "Is enabled", type: "boolean" },
|
|
320
|
+
value: { description: "Value", type: "number" }
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
expect(arrayParam.items?.type).toBe("string");
|
|
325
|
+
expect(objectParam.properties?.enabled.type).toBe("boolean");
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test("OutputSchema type can be used", () => {
|
|
329
|
+
const output: OutputSchema = {
|
|
330
|
+
description: "Result output",
|
|
331
|
+
type: "object",
|
|
332
|
+
properties: {
|
|
333
|
+
success: { description: "Success flag", type: "boolean" },
|
|
334
|
+
data: { description: "Result data", type: "array" }
|
|
335
|
+
},
|
|
336
|
+
example: { success: true, data: [] }
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
expect(output.type).toBe("object");
|
|
340
|
+
expect(output.properties?.success.type).toBe("boolean");
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test("FunctionCategory type accepts standard and custom categories", () => {
|
|
344
|
+
const scalar: FunctionCategory = "scalar";
|
|
345
|
+
const aggregate: FunctionCategory = "aggregate";
|
|
346
|
+
const predicate: FunctionCategory = "predicate";
|
|
347
|
+
const async: FunctionCategory = "async";
|
|
348
|
+
const custom: FunctionCategory = "myCustomCategory";
|
|
349
|
+
|
|
350
|
+
expect(scalar).toBe("scalar");
|
|
351
|
+
expect(aggregate).toBe("aggregate");
|
|
352
|
+
expect(predicate).toBe("predicate");
|
|
353
|
+
expect(async).toBe("async");
|
|
354
|
+
expect(custom).toBe("myCustomCategory");
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test("FunctionDefOptions type can be used", () => {
|
|
358
|
+
const options: FunctionDefOptions = {
|
|
359
|
+
description: "Function options test",
|
|
360
|
+
category: "scalar",
|
|
361
|
+
parameters: [],
|
|
362
|
+
output: { description: "Output", type: "string" },
|
|
363
|
+
notes: "Some additional notes"
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
expect(options.description).toBe("Function options test");
|
|
367
|
+
expect(options.notes).toBe("Some additional notes");
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
describe("Plugin Functions Integration with FlowQuery", () => {
|
|
372
|
+
// Import Runner for executing FlowQuery statements
|
|
373
|
+
const Runner = require("../src/compute/runner").default;
|
|
374
|
+
|
|
375
|
+
test("Custom scalar function can be used in a FlowQuery statement", async () => {
|
|
376
|
+
// Define and register a custom function via @FunctionDef decorator
|
|
377
|
+
@FunctionDef({
|
|
378
|
+
description: "Doubles a number",
|
|
379
|
+
category: "scalar",
|
|
380
|
+
parameters: [{ name: "value", description: "Number to double", type: "number" }],
|
|
381
|
+
output: { description: "Doubled value", type: "number" }
|
|
382
|
+
})
|
|
383
|
+
class Double extends Function {
|
|
384
|
+
constructor() {
|
|
385
|
+
super("double");
|
|
386
|
+
this._expectedParameterCount = 1;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
public value(): number {
|
|
390
|
+
return this.getChildren()[0].value() * 2;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Execute a FlowQuery statement that uses the custom function
|
|
395
|
+
const runner = new Runner("WITH 5 AS num RETURN double(num) AS result");
|
|
396
|
+
await runner.run();
|
|
397
|
+
|
|
398
|
+
expect(runner.results.length).toBe(1);
|
|
399
|
+
expect(runner.results[0]).toEqual({ result: 10 });
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
test("Custom string function can be used in a FlowQuery statement", async () => {
|
|
403
|
+
@FunctionDef({
|
|
404
|
+
description: "Reverses a string",
|
|
405
|
+
category: "scalar",
|
|
406
|
+
parameters: [{ name: "text", description: "String to reverse", type: "string" }],
|
|
407
|
+
output: { description: "Reversed string", type: "string" }
|
|
408
|
+
})
|
|
409
|
+
class StrReverse extends Function {
|
|
410
|
+
constructor() {
|
|
411
|
+
super("strreverse");
|
|
412
|
+
this._expectedParameterCount = 1;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
public value(): string {
|
|
416
|
+
const input = String(this.getChildren()[0].value());
|
|
417
|
+
return input.split('').reverse().join('');
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const runner = new Runner("WITH 'hello' AS s RETURN strreverse(s) AS reversed");
|
|
422
|
+
await runner.run();
|
|
423
|
+
|
|
424
|
+
expect(runner.results.length).toBe(1);
|
|
425
|
+
expect(runner.results[0]).toEqual({ reversed: 'olleh' });
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
test("Custom aggregate function can be used in a FlowQuery statement", async () => {
|
|
429
|
+
// Create a custom reducer element for the aggregate
|
|
430
|
+
class ProductElement extends ReducerElement {
|
|
431
|
+
private _value: number = 1;
|
|
432
|
+
public get value(): number {
|
|
433
|
+
return this._value;
|
|
434
|
+
}
|
|
435
|
+
public set value(v: number) {
|
|
436
|
+
this._value *= v;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
@FunctionDef({
|
|
441
|
+
description: "Calculates the product of values",
|
|
442
|
+
category: "aggregate",
|
|
443
|
+
parameters: [{ name: "value", description: "Number to multiply", type: "number" }],
|
|
444
|
+
output: { description: "Product of all values", type: "number" }
|
|
445
|
+
})
|
|
446
|
+
class Product extends AggregateFunction {
|
|
447
|
+
constructor() {
|
|
448
|
+
super("product");
|
|
449
|
+
this._expectedParameterCount = 1;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
public reduce(element: ReducerElement): void {
|
|
453
|
+
element.value = this.firstChild().value();
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
public element(): ReducerElement {
|
|
457
|
+
return new ProductElement();
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const runner = new Runner("UNWIND [2, 3, 4] AS num RETURN product(num) AS result");
|
|
462
|
+
await runner.run();
|
|
463
|
+
|
|
464
|
+
expect(runner.results.length).toBe(1);
|
|
465
|
+
expect(runner.results[0]).toEqual({ result: 24 });
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
test("Custom function works with expressions and other functions", async () => {
|
|
469
|
+
@FunctionDef({
|
|
470
|
+
description: "Adds 100 to a number",
|
|
471
|
+
category: "scalar",
|
|
472
|
+
parameters: [{ name: "value", description: "Number", type: "number" }],
|
|
473
|
+
output: { description: "Number plus 100", type: "number" }
|
|
474
|
+
})
|
|
475
|
+
class AddHundred extends Function {
|
|
476
|
+
constructor() {
|
|
477
|
+
super("addhundred");
|
|
478
|
+
this._expectedParameterCount = 1;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
public value(): number {
|
|
482
|
+
return this.getChildren()[0].value() + 100;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Use the custom function with expressions
|
|
487
|
+
const runner = new Runner("WITH 5 * 3 AS num RETURN addhundred(num) + 1 AS result");
|
|
488
|
+
await runner.run();
|
|
489
|
+
|
|
490
|
+
expect(runner.results.length).toBe(1);
|
|
491
|
+
expect(runner.results[0]).toEqual({ result: 116 }); // (5*3) + 100 + 1 = 116
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
test("Multiple custom functions can be used together", async () => {
|
|
495
|
+
@FunctionDef({
|
|
496
|
+
description: "Triples a number",
|
|
497
|
+
category: "scalar",
|
|
498
|
+
parameters: [{ name: "value", description: "Number to triple", type: "number" }],
|
|
499
|
+
output: { description: "Tripled value", type: "number" }
|
|
500
|
+
})
|
|
501
|
+
class Triple extends Function {
|
|
502
|
+
constructor() {
|
|
503
|
+
super("triple");
|
|
504
|
+
this._expectedParameterCount = 1;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
public value(): number {
|
|
508
|
+
return this.getChildren()[0].value() * 3;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
@FunctionDef({
|
|
513
|
+
description: "Squares a number",
|
|
514
|
+
category: "scalar",
|
|
515
|
+
parameters: [{ name: "value", description: "Number to square", type: "number" }],
|
|
516
|
+
output: { description: "Squared value", type: "number" }
|
|
517
|
+
})
|
|
518
|
+
class Square extends Function {
|
|
519
|
+
constructor() {
|
|
520
|
+
super("square");
|
|
521
|
+
this._expectedParameterCount = 1;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
public value(): number {
|
|
525
|
+
const v = this.getChildren()[0].value();
|
|
526
|
+
return v * v;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Use both custom functions in a query
|
|
531
|
+
const runner = new Runner("WITH 2 AS num RETURN triple(num) AS tripled, square(num) AS squared");
|
|
532
|
+
await runner.run();
|
|
533
|
+
|
|
534
|
+
expect(runner.results.length).toBe(1);
|
|
535
|
+
expect(runner.results[0]).toEqual({ tripled: 6, squared: 4 });
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
test("Custom async provider can be used in LOAD JSON FROM statement", async () => {
|
|
539
|
+
@FunctionDef({
|
|
540
|
+
description: "Provides example data for testing",
|
|
541
|
+
category: "async",
|
|
542
|
+
parameters: [],
|
|
543
|
+
output: { description: "Example data object", type: "object" }
|
|
544
|
+
})
|
|
545
|
+
class GetExampleDataLoader {
|
|
546
|
+
async *fetch(): AsyncGenerator<any> {
|
|
547
|
+
yield { id: 1, name: "Alice" };
|
|
548
|
+
yield { id: 2, name: "Bob" };
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Verify registration worked
|
|
553
|
+
expect(getRegisteredAsyncProvider("getExampleData")).toBeDefined();
|
|
554
|
+
|
|
555
|
+
// Use the async provider in a FlowQuery statement
|
|
556
|
+
const runner = new Runner("LOAD JSON FROM getExampleData() AS data RETURN data.id AS id, data.name AS name");
|
|
557
|
+
await runner.run();
|
|
558
|
+
|
|
559
|
+
expect(runner.results.length).toBe(2);
|
|
560
|
+
expect(runner.results[0]).toEqual({ id: 1, name: "Alice" });
|
|
561
|
+
expect(runner.results[1]).toEqual({ id: 2, name: "Bob" });
|
|
562
|
+
});
|
|
563
|
+
});
|
package/tsconfig.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"outDir": "./dist",
|
|
5
5
|
"rootDir": "./src", // Optional, but recommended to specify the root directory
|
|
6
6
|
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ /* Modules */
|
|
7
|
+
"experimentalDecorators": true, /* Enable experimental support for decorators. */
|
|
7
8
|
"module": "commonjs", /* Specify what module code is generated. */
|
|
8
9
|
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
|
9
10
|
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"predicate_function_factory.d.ts","sourceRoot":"","sources":["../../../src/parsing/functions/predicate_function_factory.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;AAGrD,cAAM,wBAAwB;WACZ,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB;CAQxD;AAED,eAAe,wBAAwB,CAAC"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const predicate_function_1 = __importDefault(require("./predicate_function"));
|
|
7
|
-
const predicate_sum_1 = __importDefault(require("./predicate_sum"));
|
|
8
|
-
class PredicateFunctionFactory {
|
|
9
|
-
static create(name) {
|
|
10
|
-
switch (name.toLowerCase()) {
|
|
11
|
-
case "sum":
|
|
12
|
-
return new predicate_sum_1.default();
|
|
13
|
-
default:
|
|
14
|
-
return new predicate_function_1.default(name);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
exports.default = PredicateFunctionFactory;
|
|
19
|
-
//# sourceMappingURL=predicate_function_factory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"predicate_function_factory.js","sourceRoot":"","sources":["../../../src/parsing/functions/predicate_function_factory.ts"],"names":[],"mappings":";;;;;AAAA,8EAAqD;AACrD,oEAA2C;AAE3C,MAAM,wBAAwB;IACnB,MAAM,CAAC,MAAM,CAAC,IAAY;QAC7B,QAAQ,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,KAAK,KAAK;gBACN,OAAO,IAAI,uBAAY,EAAE,CAAC;YAC9B;gBACI,OAAO,IAAI,4BAAiB,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC;CACJ;AAED,kBAAe,wBAAwB,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { FlowQuery } from 'flowquery';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* RAG (Retrieval Augmented Generation) loop using FlowQuery.
|
|
5
|
-
*
|
|
6
|
-
* This is a starter template - customize it for your RAG implementation.
|
|
7
|
-
*/
|
|
8
|
-
async function main() {
|
|
9
|
-
// Example: Run a simple FlowQuery query
|
|
10
|
-
const query = new FlowQuery('WITH 1 AS x RETURN x + 1');
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
await query.run();
|
|
14
|
-
console.log('Result:', query.results); // [ { expr0: 2 } ]
|
|
15
|
-
} catch (error) {
|
|
16
|
-
console.error('Error running query:', error);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
main();
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import PredicateFunction from "./predicate_function";
|
|
2
|
-
import PredicateSum from "./predicate_sum";
|
|
3
|
-
|
|
4
|
-
class PredicateFunctionFactory {
|
|
5
|
-
public static create(name: string): PredicateFunction {
|
|
6
|
-
switch (name.toLowerCase()) {
|
|
7
|
-
case "sum":
|
|
8
|
-
return new PredicateSum();
|
|
9
|
-
default:
|
|
10
|
-
return new PredicateFunction(name);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export default PredicateFunctionFactory;
|