agentlang 0.0.67 → 0.0.68

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 (54) hide show
  1. package/out/api/http.d.ts.map +1 -1
  2. package/out/api/http.js +2 -1
  3. package/out/api/http.js.map +1 -1
  4. package/out/cli/main.d.ts.map +1 -1
  5. package/out/cli/main.js +7 -1
  6. package/out/cli/main.js.map +1 -1
  7. package/out/language/generated/ast.d.ts +1 -1
  8. package/out/language/generated/ast.d.ts.map +1 -1
  9. package/out/language/generated/ast.js +1 -1
  10. package/out/language/generated/ast.js.map +1 -1
  11. package/out/language/generated/grammar.js +1 -1
  12. package/out/language/main.cjs +2 -2
  13. package/out/language/main.cjs.map +2 -2
  14. package/out/runtime/defs.d.ts +58 -0
  15. package/out/runtime/defs.d.ts.map +1 -1
  16. package/out/runtime/defs.js +172 -0
  17. package/out/runtime/defs.js.map +1 -1
  18. package/out/runtime/exec-graph.d.ts +17 -0
  19. package/out/runtime/exec-graph.d.ts.map +1 -0
  20. package/out/runtime/exec-graph.js +434 -0
  21. package/out/runtime/exec-graph.js.map +1 -0
  22. package/out/runtime/interpreter.d.ts +38 -3
  23. package/out/runtime/interpreter.d.ts.map +1 -1
  24. package/out/runtime/interpreter.js +162 -56
  25. package/out/runtime/interpreter.js.map +1 -1
  26. package/out/runtime/module.d.ts +1 -0
  27. package/out/runtime/module.d.ts.map +1 -1
  28. package/out/runtime/module.js +14 -6
  29. package/out/runtime/module.js.map +1 -1
  30. package/out/runtime/modules/ai.d.ts +0 -1
  31. package/out/runtime/modules/ai.d.ts.map +1 -1
  32. package/out/runtime/modules/ai.js +0 -1
  33. package/out/runtime/modules/ai.js.map +1 -1
  34. package/out/runtime/resolvers/interface.d.ts +1 -0
  35. package/out/runtime/resolvers/interface.d.ts.map +1 -1
  36. package/out/runtime/resolvers/interface.js +5 -0
  37. package/out/runtime/resolvers/interface.js.map +1 -1
  38. package/out/utils/runtime.d.ts +1 -0
  39. package/out/utils/runtime.d.ts.map +1 -1
  40. package/out/utils/runtime.js +4 -0
  41. package/out/utils/runtime.js.map +1 -1
  42. package/package.json +34 -52
  43. package/src/api/http.ts +2 -1
  44. package/src/cli/main.ts +8 -1
  45. package/src/language/agentlang.langium +3 -2
  46. package/src/language/generated/ast.ts +2 -2
  47. package/src/language/generated/grammar.ts +1 -1
  48. package/src/runtime/defs.ts +210 -0
  49. package/src/runtime/exec-graph.ts +518 -0
  50. package/src/runtime/interpreter.ts +197 -62
  51. package/src/runtime/module.ts +15 -6
  52. package/src/runtime/modules/ai.ts +0 -2
  53. package/src/runtime/resolvers/interface.ts +5 -0
  54. package/src/utils/runtime.ts +6 -0
@@ -0,0 +1,518 @@
1
+ import {
2
+ CrudMap,
3
+ Delete,
4
+ Expr,
5
+ ForEach,
6
+ FullTextSearch,
7
+ If,
8
+ isWorkflowDefinition,
9
+ ModuleDefinition,
10
+ Pattern,
11
+ Purge,
12
+ Return,
13
+ Statement,
14
+ } from '../language/generated/ast.js';
15
+ import { parseModule, parseStatement } from '../language/parser.js';
16
+ import { ExecGraph, ExecGraphNode, ExecGraphWalker, SubGraphType } from './defs.js';
17
+ import {
18
+ DocEventName,
19
+ Environment,
20
+ evaluateExpression,
21
+ evaluatePattern,
22
+ evaluateStatement,
23
+ handleAgentInvocation,
24
+ handleOpenApiEvent,
25
+ maybeBindStatementResultToAlias,
26
+ maybeDeleteQueriedInstances,
27
+ PatternHandler,
28
+ setEvaluateFn,
29
+ setParseAndEvaluateStatementFn,
30
+ } from './interpreter.js';
31
+ import {
32
+ fetchModule,
33
+ getWorkflowForEvent,
34
+ Instance,
35
+ isAgentEvent,
36
+ isAgentEventInstance,
37
+ isEmptyWorkflow,
38
+ isEventInstance,
39
+ RecordType,
40
+ } from './module.js';
41
+ import { isOpenApiEventInstance, isOpenApiModule } from './openapi.js';
42
+ import { escapeQueryName, makeFqName, splitFqName } from './util.js';
43
+
44
+ const GraphCache = new Map<string, ExecGraph>();
45
+
46
+ export async function generateExecutionGraph(eventName: string): Promise<ExecGraph | undefined> {
47
+ const cg = GraphCache.get(eventName);
48
+ if (cg) return cg;
49
+ const wf = getWorkflowForEvent(eventName);
50
+ const parts = splitFqName(eventName);
51
+ const moduleName = parts.hasModule() ? parts.getModuleName() : undefined;
52
+ if (!isEmptyWorkflow(wf)) {
53
+ const g = await graphFromStatements(wf.statements, moduleName);
54
+ if (g.canCache()) GraphCache.set(eventName, g);
55
+ return g;
56
+ }
57
+ return undefined;
58
+ }
59
+
60
+ class GraphGenerator extends PatternHandler {
61
+ private graph: ExecGraph = new ExecGraph();
62
+
63
+ private genericHandler(env: Environment) {
64
+ this.graph.pushNode(new ExecGraphNode(env.getActiveUserData()));
65
+ }
66
+
67
+ override async handleExpression(_: Expr, env: Environment) {
68
+ this.genericHandler(env);
69
+ }
70
+
71
+ override async handleCrudMap(crudMap: CrudMap, env: Environment) {
72
+ const parts = splitFqName(crudMap.name);
73
+ const moduleName = parts.hasModule() ? parts.getModuleName() : env.getActiveModuleName();
74
+ const crudName = makeFqName(moduleName, parts.getEntryName());
75
+ if (crudName == DocEventName) {
76
+ return this.genericHandler(env);
77
+ }
78
+ if (isOpenApiModule(moduleName)) {
79
+ return this.genericHandler(env);
80
+ }
81
+ const module = fetchModule(moduleName);
82
+ const record = module.getRecord(escapeQueryName(parts.getEntryName()));
83
+ if (record.type == RecordType.EVENT) {
84
+ if (isAgentEvent(record)) {
85
+ this.graph.pushNode(new ExecGraphNode(env.getActiveUserData(), -2, SubGraphType.AGENT));
86
+ this.graph.setHasAgents(true);
87
+ return;
88
+ } else {
89
+ const g = await generateExecutionGraph(crudName);
90
+ if (g) {
91
+ return this.addSubGraph(SubGraphType.EVENT, g, env);
92
+ }
93
+ }
94
+ }
95
+ this.genericHandler(env);
96
+ }
97
+
98
+ override async handleForEach(forEach: ForEach, env: Environment) {
99
+ const handler = new GraphGenerator();
100
+ const srcEnv = Environment.from(env).setActiveUserData(forEach.src);
101
+ await evaluatePattern(forEach.src, srcEnv, handler);
102
+ const srcg = handler.getGraph();
103
+ const g = await graphFromStatements(forEach.statements, env.getActiveModuleName());
104
+ srcg.pushSubGraph(g);
105
+ this.addSubGraph(SubGraphType.FOR_EACH, srcg, env);
106
+ }
107
+
108
+ override async handleIf(ifStmt: If, env: Environment) {
109
+ const handler = new GraphGenerator();
110
+ await handler.handleExpression(
111
+ ifStmt.cond,
112
+ Environment.from(env).setActiveUserData(ifStmt.cond)
113
+ );
114
+ const cond = handler.getGraph();
115
+ const conseq = await graphFromStatements(ifStmt.statements, env.getActiveModuleName());
116
+ cond.pushSubGraph(conseq);
117
+ if (ifStmt.else != undefined) {
118
+ const alter = await graphFromStatements(ifStmt.else.statements, env.getActiveModuleName());
119
+ cond.pushSubGraph(alter);
120
+ } else {
121
+ cond.pushSubGraph(ExecGraph.Empty);
122
+ }
123
+ this.addSubGraph(SubGraphType.IF, cond, env);
124
+ }
125
+
126
+ private async handleSubPattern(subGraphType: SubGraphType, pat: Pattern, env: Environment) {
127
+ const newEnv = Environment.from(env).setActiveUserData(pat);
128
+ const handler = new GraphGenerator();
129
+ await evaluatePattern(pat, newEnv, handler);
130
+ this.addSubGraph(subGraphType, handler.getGraph(), env);
131
+ }
132
+
133
+ override async handleDelete(del: Delete, env: Environment) {
134
+ this.handleSubPattern(SubGraphType.DELETE, del.pattern, env);
135
+ }
136
+
137
+ override async handlePurge(purge: Purge, env: Environment) {
138
+ this.handleSubPattern(SubGraphType.PURGE, purge.pattern, env);
139
+ }
140
+
141
+ override async handleFullTextSearch(_: FullTextSearch, env: Environment) {
142
+ this.genericHandler(env);
143
+ }
144
+
145
+ override async handleReturn(ret: Return, env: Environment) {
146
+ this.handleSubPattern(SubGraphType.RETURN, ret.pattern, env);
147
+ }
148
+
149
+ getGraph(): ExecGraph {
150
+ return this.graph;
151
+ }
152
+
153
+ private addSubGraph(subGraphType: SubGraphType, g: ExecGraph, env: Environment) {
154
+ this.graph.pushSubGraph(g);
155
+ this.graph.pushNode(
156
+ new ExecGraphNode(env.getActiveUserData(), this.graph.getLastSubGraphIndex(), subGraphType)
157
+ );
158
+ }
159
+ }
160
+
161
+ async function graphFromStatements(
162
+ stmts: Statement[],
163
+ activeModuleName?: string
164
+ ): Promise<ExecGraph> {
165
+ const handler = new GraphGenerator();
166
+ const env = new Environment();
167
+ if (activeModuleName) {
168
+ env.switchActiveModuleName(activeModuleName);
169
+ }
170
+ for (let i = 0; i < stmts.length; ++i) {
171
+ const stmt = stmts[i];
172
+ env.setActiveUserData(stmt);
173
+ await evaluatePattern(stmt.pattern, env, handler);
174
+ }
175
+ return handler.getGraph().setActiveModuleName(activeModuleName);
176
+ }
177
+
178
+ async function eventExecutor(eventInst: Instance, env: Environment) {
179
+ const newEnv = new Environment(`${eventInst.name}-env`, env);
180
+ await executeEventHelper(eventInst, newEnv);
181
+ env.setLastResult(newEnv.getLastResult());
182
+ }
183
+
184
+ function makeStatementsExecutor(execGraph: ExecGraph, triggeringNode: ExecGraphNode): Function {
185
+ return async (stmts: Statement[], env: Environment): Promise<any> => {
186
+ const g = await graphFromStatements(stmts, env.getActiveModuleName());
187
+ if (execGraph && triggeringNode) {
188
+ execGraph.pushSubGraph(g);
189
+ triggeringNode.subGraphIndex = execGraph.getLastSubGraphIndex();
190
+ }
191
+ await executeGraph(g, env);
192
+ return env.getLastResult();
193
+ };
194
+ }
195
+
196
+ export async function executeGraph(execGraph: ExecGraph, env: Environment): Promise<any> {
197
+ const activeModuleName = execGraph.getActiveModuleName();
198
+ env.setEventExecutor(eventExecutor);
199
+ let oldModule: string | undefined = undefined;
200
+ if (activeModuleName) {
201
+ oldModule = env.switchActiveModuleName(activeModuleName);
202
+ }
203
+ try {
204
+ const walker = new ExecGraphWalker(execGraph);
205
+ while (walker.hasNext()) {
206
+ if (env.isMarkedForReturn()) {
207
+ break;
208
+ }
209
+ const node = walker.nextNode();
210
+ if (node.subGraphIndex == -1) {
211
+ await evaluateStatement(node.code as Statement, env);
212
+ } else {
213
+ if (node.subGraphType == SubGraphType.AGENT) {
214
+ await executeAgent(node, execGraph, env);
215
+ } else {
216
+ const subg = execGraph.fetchSubGraphAt(node.subGraphIndex);
217
+ switch (node.subGraphType) {
218
+ case SubGraphType.EVENT:
219
+ await evaluateStatement(node.code as Statement, env);
220
+ break;
221
+ case SubGraphType.IF:
222
+ await executeIfSubGraph(subg, env);
223
+ break;
224
+ case SubGraphType.FOR_EACH:
225
+ await executeForEachSubGraph(subg, node, env);
226
+ break;
227
+ case SubGraphType.DELETE:
228
+ await executeDeleteSubGraph(subg, node, env);
229
+ break;
230
+ case SubGraphType.PURGE:
231
+ await executePurgeSubGraph(subg, node, env);
232
+ break;
233
+ case SubGraphType.RETURN:
234
+ await executeReturnSubGraph(subg, env);
235
+ return;
236
+ default:
237
+ throw new Error(`Invalid sub-graph type: ${node.subGraphType}`);
238
+ }
239
+ }
240
+ maybeSetAlias(node, env);
241
+ }
242
+ }
243
+ } finally {
244
+ if (oldModule) {
245
+ env.switchActiveModuleName(oldModule);
246
+ }
247
+ }
248
+ }
249
+
250
+ async function evaluateFirstPattern(g: ExecGraph, env: Environment) {
251
+ await evaluatePattern(g.getRootNodes()[0].code as Pattern, env);
252
+ }
253
+
254
+ async function executeForEachSubGraph(
255
+ subGraph: ExecGraph,
256
+ triggeringNode: ExecGraphNode,
257
+ env: Environment
258
+ ) {
259
+ await evaluateFirstPattern(subGraph, env);
260
+ const rs: any[] = env.getLastResult();
261
+ if (rs.length > 0) {
262
+ const stmt = triggeringNode.code as Statement;
263
+ const loopVar = stmt.pattern.forEach?.var || 'x';
264
+ const loopEnv: Environment = new Environment('for-each-body-env', env);
265
+ const loopg = subGraph.fetchForEachBodySubGraph();
266
+ const finalResult = new Array<any>();
267
+ for (let i = 0; i < rs.length; ++i) {
268
+ loopEnv.bind(loopVar, rs[i]);
269
+ await executeGraph(loopg, loopEnv);
270
+ finalResult.push(loopEnv.getLastResult());
271
+ }
272
+ env.setLastResult(finalResult);
273
+ } else {
274
+ env.setLastResult([]);
275
+ }
276
+ }
277
+
278
+ async function executeIfSubGraph(subGraph: ExecGraph, env: Environment) {
279
+ await evaluateExpression(subGraph.getRootNodes()[0].code as Expr, env);
280
+ const newEnv = new Environment('cond-env', env);
281
+ if (env.getLastResult()) {
282
+ const conseq = subGraph.fetchIfConsequentSubGraph();
283
+ await executeGraph(conseq, newEnv);
284
+ } else {
285
+ const alter = subGraph.fetchIfAlternativeSubGraph();
286
+ if (alter) {
287
+ if (ExecGraph.isEmpty(alter)) {
288
+ newEnv.setLastResult(false);
289
+ } else {
290
+ await executeGraph(alter, newEnv);
291
+ }
292
+ }
293
+ }
294
+ env.setLastResult(newEnv.getLastResult());
295
+ }
296
+
297
+ async function executeAgent(triggeringNode: ExecGraphNode, execGraph: ExecGraph, env: Environment) {
298
+ await env.callWithStatementsExecutor(
299
+ makeStatementsExecutor(execGraph, triggeringNode),
300
+ async () => {
301
+ await evaluateStatement(triggeringNode.code as Statement, env);
302
+ return env.getLastResult();
303
+ }
304
+ );
305
+ }
306
+
307
+ async function executeReturnSubGraph(subGraph: ExecGraph, env: Environment) {
308
+ await evaluateFirstPattern(subGraph, env);
309
+ env.markForReturn();
310
+ }
311
+
312
+ async function executeDeleteSubGraph(subGraph: ExecGraph, node: ExecGraphNode, env: Environment) {
313
+ const newEnv = new Environment(`delete-env`, env).setInDeleteMode(true);
314
+ await evaluateFirstPattern(subGraph, newEnv);
315
+ await maybeDeleteQueriedInstances(newEnv, env, false);
316
+ maybeSetAlias(node, env);
317
+ }
318
+
319
+ async function executePurgeSubGraph(subGraph: ExecGraph, node: ExecGraphNode, env: Environment) {
320
+ const newEnv = new Environment(`purge-env`, env).setInDeleteMode(true);
321
+ await evaluateFirstPattern(subGraph, newEnv);
322
+ await maybeDeleteQueriedInstances(newEnv, env, true);
323
+ maybeSetAlias(node, env);
324
+ }
325
+
326
+ export async function executeEvent(
327
+ eventInstance: Instance,
328
+ continuation?: Function,
329
+ activeEnv?: Environment,
330
+ kernelCall?: boolean
331
+ ): Promise<any> {
332
+ const env: Environment = new Environment(eventInstance.name + '.env', activeEnv);
333
+ let txnRolledBack: boolean = false;
334
+ try {
335
+ if (isEventInstance(eventInstance)) {
336
+ env.setActiveEvent(eventInstance);
337
+ if (kernelCall) {
338
+ env.setInKernelMode(true);
339
+ }
340
+ await executeEventHelper(eventInstance, env);
341
+ } else if (isAgentEventInstance(eventInstance)) {
342
+ env.setStatementsExecutor(executeStatements);
343
+ await handleAgentInvocation(eventInstance, env);
344
+ }
345
+ const r = env.getLastResult();
346
+ if (continuation) continuation(r);
347
+ return r;
348
+ } catch (err) {
349
+ if (env && env.hasHandlers()) {
350
+ throw err;
351
+ } else {
352
+ if (env != undefined && activeEnv == undefined) {
353
+ await env.rollbackAllTransactions().then(() => {
354
+ txnRolledBack = true;
355
+ });
356
+ }
357
+ throw err;
358
+ }
359
+ } finally {
360
+ if (!txnRolledBack && env != undefined && activeEnv == undefined) {
361
+ await env.commitAllTransactions();
362
+ }
363
+ }
364
+ }
365
+
366
+ export async function executeEventHelper(eventInstance: Instance, env?: Environment): Promise<any> {
367
+ if (isOpenApiEventInstance(eventInstance)) {
368
+ env = env || new Environment();
369
+ await handleOpenApiEvent(eventInstance, env);
370
+ return env.getLastResult();
371
+ }
372
+ const fqn = eventInstance.getFqName();
373
+ let isLocalEnv = false;
374
+ if (env == undefined) {
375
+ env = new Environment(`${fqn}-env`);
376
+ isLocalEnv = true;
377
+ }
378
+ const g = await generateExecutionGraph(fqn);
379
+ if (!g) {
380
+ throw new Error(`Failed to generate graph for event ${fqn}`);
381
+ }
382
+ const oldModuleName = env.switchActiveModuleName(eventInstance.moduleName);
383
+ env.bind(eventInstance.name, eventInstance);
384
+ try {
385
+ await executeGraph(g, env);
386
+ if (isLocalEnv) {
387
+ await env.commitAllTransactions();
388
+ }
389
+ return env.getLastResult();
390
+ } catch (err: any) {
391
+ if (isLocalEnv) {
392
+ await env.rollbackAllTransactions();
393
+ }
394
+ throw err;
395
+ } finally {
396
+ if (!isLocalEnv) env.switchActiveModuleName(oldModuleName);
397
+ }
398
+ }
399
+
400
+ export async function executeStatement(
401
+ stmt: string,
402
+ env?: Environment,
403
+ activeModule?: string
404
+ ): Promise<any> {
405
+ return await executeStatements([stmt], env, activeModule);
406
+ }
407
+
408
+ export async function executeStatements(
409
+ stmts: string[],
410
+ env?: Environment,
411
+ activeModule?: string
412
+ ): Promise<any> {
413
+ const mod: ModuleDefinition = await parseModule(
414
+ `module Temp\nworkflow TempEvent { ${stmts.join(';')} }`
415
+ );
416
+ if (isWorkflowDefinition(mod.defs[0])) {
417
+ return await executeStatementsHelper(mod.defs[0].statements, env, activeModule);
418
+ } else {
419
+ throw new Error('Failed to extract workflow-statement');
420
+ }
421
+ }
422
+
423
+ async function executeStatementsHelper(
424
+ stmts: Statement[],
425
+ env?: Environment,
426
+ activeModule?: string
427
+ ): Promise<any> {
428
+ const g = await graphFromStatements(stmts);
429
+ let isLocalEnv = false;
430
+ if (env == undefined) {
431
+ env = new Environment(`stmt-exec-env`);
432
+ isLocalEnv = true;
433
+ }
434
+ let oldModuleName: string | undefined = undefined;
435
+ if (activeModule) {
436
+ oldModuleName = env.switchActiveModuleName(activeModule);
437
+ }
438
+ try {
439
+ await executeGraph(g, env);
440
+ if (isLocalEnv) {
441
+ await env.commitAllTransactions();
442
+ }
443
+ return env.getLastResult();
444
+ } catch (err: any) {
445
+ if (isLocalEnv) {
446
+ await env.rollbackAllTransactions();
447
+ }
448
+ throw err;
449
+ } finally {
450
+ if (oldModuleName) {
451
+ env.switchActiveModuleName(oldModuleName);
452
+ }
453
+ }
454
+ }
455
+
456
+ async function executeStatementHelper(stmt: Statement, env: Environment): Promise<any> {
457
+ return await executeStatementsHelper([stmt], env);
458
+ }
459
+
460
+ export async function parseAndExecuteStatement(
461
+ stmtString: string,
462
+ activeUserId?: string,
463
+ actievEnv?: Environment
464
+ ): Promise<any> {
465
+ const env = actievEnv ? actievEnv : new Environment();
466
+ if (activeUserId) {
467
+ env.setActiveUser(activeUserId);
468
+ }
469
+ let commit: boolean = true;
470
+ try {
471
+ const stmt: Statement = await parseStatement(stmtString);
472
+ if (stmt) {
473
+ await executeStatementHelper(stmt, env);
474
+ return env.getLastResult();
475
+ } else {
476
+ commit = false;
477
+ }
478
+ } catch (err) {
479
+ commit = false;
480
+ throw err;
481
+ } finally {
482
+ if (!actievEnv) {
483
+ if (commit) {
484
+ await env.commitAllTransactions();
485
+ } else {
486
+ await env.rollbackAllTransactions();
487
+ }
488
+ }
489
+ }
490
+ }
491
+
492
+ function maybeSetAlias(node: ExecGraphNode, env: Environment) {
493
+ const stmt = node.code as Statement;
494
+ const hints = stmt.hints;
495
+ if (hints && hints.length > 0) {
496
+ maybeBindStatementResultToAlias(hints, env);
497
+ }
498
+ }
499
+
500
+ export type EvalFns = {
501
+ evaluate: Function;
502
+ parseAndEvaluateStatement: Function;
503
+ };
504
+
505
+ export function enableExecutionGraph(): EvalFns {
506
+ const e = setEvaluateFn(executeEvent);
507
+ const es = setParseAndEvaluateStatementFn(parseAndExecuteStatement);
508
+ return { evaluate: e, parseAndEvaluateStatement: es };
509
+ }
510
+
511
+ export function disableExecutionGraph(oldFns: EvalFns): boolean {
512
+ if (oldFns.evaluate && oldFns.parseAndEvaluateStatement) {
513
+ setEvaluateFn(oldFns.evaluate);
514
+ setParseAndEvaluateStatementFn(oldFns.parseAndEvaluateStatement);
515
+ return true;
516
+ }
517
+ return false;
518
+ }