agentlang 0.0.66 → 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 (59) hide show
  1. package/README.md +9 -9
  2. package/out/api/http.d.ts.map +1 -1
  3. package/out/api/http.js +2 -1
  4. package/out/api/http.js.map +1 -1
  5. package/out/cli/main.d.ts.map +1 -1
  6. package/out/cli/main.js +7 -1
  7. package/out/cli/main.js.map +1 -1
  8. package/out/language/generated/ast.d.ts +1 -1
  9. package/out/language/generated/ast.d.ts.map +1 -1
  10. package/out/language/generated/ast.js +2 -1
  11. package/out/language/generated/ast.js.map +1 -1
  12. package/out/language/generated/grammar.js +1 -1
  13. package/out/language/main.cjs +2 -2
  14. package/out/language/main.cjs.map +2 -2
  15. package/out/runtime/defs.d.ts +58 -0
  16. package/out/runtime/defs.d.ts.map +1 -1
  17. package/out/runtime/defs.js +172 -0
  18. package/out/runtime/defs.js.map +1 -1
  19. package/out/runtime/exec-graph.d.ts +17 -0
  20. package/out/runtime/exec-graph.d.ts.map +1 -0
  21. package/out/runtime/exec-graph.js +434 -0
  22. package/out/runtime/exec-graph.js.map +1 -0
  23. package/out/runtime/interpreter.d.ts +38 -3
  24. package/out/runtime/interpreter.d.ts.map +1 -1
  25. package/out/runtime/interpreter.js +165 -73
  26. package/out/runtime/interpreter.js.map +1 -1
  27. package/out/runtime/module.d.ts +1 -0
  28. package/out/runtime/module.d.ts.map +1 -1
  29. package/out/runtime/module.js +14 -6
  30. package/out/runtime/module.js.map +1 -1
  31. package/out/runtime/modules/ai.d.ts +0 -1
  32. package/out/runtime/modules/ai.d.ts.map +1 -1
  33. package/out/runtime/modules/ai.js +0 -1
  34. package/out/runtime/modules/ai.js.map +1 -1
  35. package/out/runtime/modules/auth.d.ts.map +1 -1
  36. package/out/runtime/modules/auth.js +13 -13
  37. package/out/runtime/modules/auth.js.map +1 -1
  38. package/out/runtime/resolvers/interface.d.ts +1 -0
  39. package/out/runtime/resolvers/interface.d.ts.map +1 -1
  40. package/out/runtime/resolvers/interface.js +5 -0
  41. package/out/runtime/resolvers/interface.js.map +1 -1
  42. package/out/utils/runtime.d.ts +1 -0
  43. package/out/utils/runtime.d.ts.map +1 -1
  44. package/out/utils/runtime.js +4 -0
  45. package/out/utils/runtime.js.map +1 -1
  46. package/package.json +180 -156
  47. package/src/api/http.ts +2 -1
  48. package/src/cli/main.ts +8 -1
  49. package/src/language/agentlang.langium +3 -2
  50. package/src/language/generated/ast.ts +3 -3
  51. package/src/language/generated/grammar.ts +1 -1
  52. package/src/runtime/defs.ts +210 -0
  53. package/src/runtime/exec-graph.ts +518 -0
  54. package/src/runtime/interpreter.ts +202 -81
  55. package/src/runtime/module.ts +15 -6
  56. package/src/runtime/modules/ai.ts +0 -2
  57. package/src/runtime/modules/auth.ts +25 -18
  58. package/src/runtime/resolvers/interface.ts +5 -0
  59. package/src/utils/runtime.ts +6 -0
@@ -20,6 +20,7 @@ import {
20
20
  Pattern,
21
21
  Purge,
22
22
  RelationshipPattern,
23
+ Return,
23
24
  RuntimeHint,
24
25
  SelectIntoEntry,
25
26
  SelectIntoSpec,
@@ -55,7 +56,6 @@ import {
55
56
  DefaultModuleName,
56
57
  escapeFqName,
57
58
  escapeQueryName,
58
- escapeSpecialChars,
59
59
  fqNameFromPath,
60
60
  isFqName,
61
61
  isPath,
@@ -136,7 +136,12 @@ export class Environment extends Instance {
136
136
  private inDeleteMode: boolean = false;
137
137
  private inKernelMode: boolean = false;
138
138
  private suspensionId: string | undefined;
139
+ private preGeneratedSuspensionId: string;
139
140
  private activeCatchHandlers: Array<CatchHandlers>;
141
+ private eventExecutor: Function | undefined = undefined;
142
+ private statementsExecutor: Function | undefined = undefined;
143
+
144
+ private activeUserData: any = undefined;
140
145
 
141
146
  constructor(name?: string, parent?: Environment) {
142
147
  super(
@@ -158,6 +163,7 @@ export class Environment extends Instance {
158
163
  this.inKernelMode = parent.inKernelMode;
159
164
  this.activeCatchHandlers = parent.activeCatchHandlers;
160
165
  this.suspensionId = parent.suspensionId;
166
+ this.eventExecutor = parent.eventExecutor;
161
167
  } else {
162
168
  this.activeModule = DefaultModuleName;
163
169
  this.activeResolvers = new Map<string, Resolver>();
@@ -165,6 +171,7 @@ export class Environment extends Instance {
165
171
  this.activeCatchHandlers = new Array<CatchHandlers>();
166
172
  this.attributes.set('process', process);
167
173
  }
174
+ this.preGeneratedSuspensionId = crypto.randomUUID();
168
175
  }
169
176
 
170
177
  static from(
@@ -177,6 +184,7 @@ export class Environment extends Instance {
177
184
  env.activeResolvers = new Map<string, Resolver>();
178
185
  env.activeTransactions = new Map<string, string>();
179
186
  env.activeCatchHandlers = new Array<CatchHandlers>();
187
+ env.preGeneratedSuspensionId = parent.preGeneratedSuspensionId;
180
188
  }
181
189
  return env;
182
190
  }
@@ -306,7 +314,7 @@ export class Environment extends Instance {
306
314
 
307
315
  suspend(): string {
308
316
  if (this.suspensionId == undefined) {
309
- const id = crypto.randomUUID();
317
+ const id = this.preGeneratedSuspensionId;
310
318
  this.propagateSuspension(id);
311
319
  return id;
312
320
  } else {
@@ -314,6 +322,16 @@ export class Environment extends Instance {
314
322
  }
315
323
  }
316
324
 
325
+ releaseSuspension(): Environment {
326
+ this.suspensionId = undefined;
327
+ this.preGeneratedSuspensionId = crypto.randomUUID();
328
+ return this;
329
+ }
330
+
331
+ fetchSuspensionId(): string {
332
+ return this.preGeneratedSuspensionId;
333
+ }
334
+
317
335
  markForReturn(): Environment {
318
336
  if (this.parent) {
319
337
  this.parent.markForReturn();
@@ -326,6 +344,14 @@ export class Environment extends Instance {
326
344
  return this.returnFlag;
327
345
  }
328
346
 
347
+ propagateLastResult(): Environment {
348
+ if (this.parent) {
349
+ this.parent.lastResult = this.lastResult;
350
+ this.parent.propagateLastResult();
351
+ }
352
+ return this;
353
+ }
354
+
329
355
  resetReturnFlag(): Environment {
330
356
  if (this.returnFlag) {
331
357
  this.returnFlag = false;
@@ -570,11 +596,53 @@ export class Environment extends Instance {
570
596
  }
571
597
  return r;
572
598
  }
599
+
600
+ setEventExecutor(exec: Function): Environment {
601
+ this.eventExecutor = exec;
602
+ return this;
603
+ }
604
+
605
+ getEventExecutor(): Function | undefined {
606
+ return this.eventExecutor;
607
+ }
608
+
609
+ unsetEventExecutor(): Environment {
610
+ this.eventExecutor = undefined;
611
+ return this;
612
+ }
613
+
614
+ setStatementsExecutor(f: Function): Environment {
615
+ this.statementsExecutor = f;
616
+ return this;
617
+ }
618
+
619
+ getStatementsExecutor(): Function | undefined {
620
+ return this.statementsExecutor;
621
+ }
622
+
623
+ async callWithStatementsExecutor(exec: Function, f: Function): Promise<any> {
624
+ const oldExec = this.statementsExecutor;
625
+ this.statementsExecutor = exec;
626
+ try {
627
+ return await f();
628
+ } finally {
629
+ this.statementsExecutor = oldExec;
630
+ }
631
+ }
632
+
633
+ setActiveUserData(data: any): Environment {
634
+ this.activeUserData = data;
635
+ return this;
636
+ }
637
+
638
+ getActiveUserData(): any {
639
+ return this.activeUserData;
640
+ }
573
641
  }
574
642
 
575
643
  export const GlobalEnvironment = new Environment();
576
644
 
577
- export async function evaluate(
645
+ export let evaluate = async function (
578
646
  eventInstance: Instance,
579
647
  continuation?: Function,
580
648
  activeEnv?: Environment,
@@ -626,6 +694,12 @@ export async function evaluate(
626
694
  await env.commitAllTransactions();
627
695
  }
628
696
  }
697
+ };
698
+
699
+ export function setEvaluateFn(f: any): Function {
700
+ const oldf = evaluate;
701
+ evaluate = f;
702
+ return oldf;
629
703
  }
630
704
 
631
705
  export async function evaluateAsEvent(
@@ -661,27 +735,6 @@ export function makeEventEvaluator(moduleName: string): Function {
661
735
  };
662
736
  }
663
737
 
664
- function statemtentString(stmt: Statement): string {
665
- if (stmt.$cstNode) {
666
- return stmt.$cstNode.text;
667
- } else {
668
- throw new Error(`Failed to fetch text for statement - ${stmt}`);
669
- }
670
- }
671
-
672
- async function saveSuspension(cont: Statement[], env: Environment) {
673
- if (cont.length > 0) {
674
- const suspId = await createSuspension(
675
- env.getSuspensionId(),
676
- cont.map((stmt: Statement) => {
677
- return statemtentString(stmt);
678
- }),
679
- env
680
- );
681
- env.setLastResult({ suspension: suspId || 'null' });
682
- }
683
- }
684
-
685
738
  export async function evaluateStatements(
686
739
  stmts: Statement[],
687
740
  env: Environment,
@@ -710,7 +763,17 @@ async function evaluateAsyncPattern(
710
763
  await evaluatePattern(pat, env);
711
764
  maybeBindStatementResultToAlias(hints, env);
712
765
  if (env.isSuspended()) {
713
- await saveSuspension(thenStmts, env);
766
+ await createSuspension(
767
+ env.fetchSuspensionId(),
768
+ thenStmts.map((s: Statement) => {
769
+ if (s.$cstNode) {
770
+ return s.$cstNode.text;
771
+ } else {
772
+ throw new Error('failed to extract code for suspension statement');
773
+ }
774
+ }),
775
+ env
776
+ );
714
777
  } else {
715
778
  await evaluateStatements(thenStmts, env);
716
779
  }
@@ -722,7 +785,7 @@ async function evaluateAsyncPattern(
722
785
  }
723
786
  }
724
787
 
725
- async function evaluateStatement(stmt: Statement, env: Environment): Promise<void> {
788
+ export async function evaluateStatement(stmt: Statement, env: Environment): Promise<void> {
726
789
  const hints = stmt.hints;
727
790
  const hasHints = hints && hints.length > 0;
728
791
  const thenStmts: Statement[] | undefined = hasHints ? maybeFindThenStatements(hints) : undefined;
@@ -735,9 +798,13 @@ async function evaluateStatement(stmt: Statement, env: Environment): Promise<voi
735
798
  hints,
736
799
  Environment.from(env, env.name + 'async', true)
737
800
  );
801
+ env.setLastResult(env.fetchSuspensionId());
738
802
  if (isReturn(stmt.pattern)) {
739
803
  env.markForReturn();
740
804
  }
805
+ if (hasHints) {
806
+ maybeBindStatementResultToAlias(hints, env);
807
+ }
741
808
  return;
742
809
  }
743
810
  let handlersPushed = false;
@@ -768,7 +835,9 @@ async function maybeHandleNotFound(handlers: CatchHandlers | undefined, env: Env
768
835
  ) {
769
836
  const onNotFound = handlers ? handlers.get('not_found') : undefined;
770
837
  if (onNotFound) {
771
- await evaluateStatement(onNotFound, env);
838
+ const newEnv = new Environment('not-found-env', env).unsetEventExecutor();
839
+ await evaluateStatement(onNotFound, newEnv);
840
+ env.setLastResult(newEnv.getLastResult());
772
841
  }
773
842
  }
774
843
  }
@@ -780,13 +849,15 @@ async function maybeHandleError(
780
849
  ) {
781
850
  const handler = handlers ? handlers.get('error') : undefined;
782
851
  if (handler) {
783
- await evaluateStatement(handler, env);
852
+ const newEnv = new Environment('handler-env', env).unsetEventExecutor();
853
+ await evaluateStatement(handler, newEnv);
854
+ env.setLastResult(newEnv.getLastResult());
784
855
  } else {
785
856
  throw reason;
786
857
  }
787
858
  }
788
859
 
789
- function maybeBindStatementResultToAlias(hints: RuntimeHint[], env: Environment) {
860
+ export function maybeBindStatementResultToAlias(hints: RuntimeHint[], env: Environment) {
790
861
  for (let i = 0; i < hints.length; ++i) {
791
862
  const rh = hints[i];
792
863
  if (rh.aliasSpec) {
@@ -842,7 +913,7 @@ function maybeFindThenStatements(hints: RuntimeHint[]): Statement[] | undefined
842
913
  return undefined;
843
914
  }
844
915
 
845
- export async function parseAndEvaluateStatement(
916
+ export let parseAndEvaluateStatement = async function (
846
917
  stmtString: string,
847
918
  activeUserId?: string,
848
919
  actievEnv?: Environment
@@ -872,25 +943,71 @@ export async function parseAndEvaluateStatement(
872
943
  }
873
944
  }
874
945
  }
946
+ };
947
+
948
+ export function setParseAndEvaluateStatementFn(f: any): Function {
949
+ const oldf = parseAndEvaluateStatement;
950
+ parseAndEvaluateStatement = f;
951
+ return oldf;
952
+ }
953
+
954
+ export class PatternHandler {
955
+ async handleExpression(expr: Expr, env: Environment) {
956
+ await evaluateExpression(expr, env);
957
+ }
958
+
959
+ async handleCrudMap(crudMap: CrudMap, env: Environment) {
960
+ await evaluateCrudMap(crudMap, env);
961
+ }
962
+
963
+ async handleForEach(forEach: ForEach, env: Environment) {
964
+ await evaluateForEach(forEach, env);
965
+ }
966
+
967
+ async handleIf(_if: If, env: Environment) {
968
+ await evaluateIf(_if, env);
969
+ }
970
+
971
+ async handleDelete(del: Delete, env: Environment) {
972
+ await evaluateDelete(del, env);
973
+ }
974
+
975
+ async handlePurge(purge: Purge, env: Environment) {
976
+ await evaluatePurge(purge, env);
977
+ }
978
+
979
+ async handleFullTextSearch(fullTextSearch: FullTextSearch, env: Environment) {
980
+ await evaluateFullTextSearch(fullTextSearch, env);
981
+ }
982
+
983
+ async handleReturn(ret: Return, env: Environment) {
984
+ await evaluatePattern(ret.pattern, env);
985
+ }
875
986
  }
876
987
 
877
- async function evaluatePattern(pat: Pattern, env: Environment): Promise<void> {
988
+ const DefaultPatternHandler = new PatternHandler();
989
+
990
+ export async function evaluatePattern(
991
+ pat: Pattern,
992
+ env: Environment,
993
+ handler: PatternHandler = DefaultPatternHandler
994
+ ): Promise<void> {
878
995
  if (pat.expr) {
879
- await evaluateExpression(pat.expr, env);
996
+ await handler.handleExpression(pat.expr, env);
880
997
  } else if (pat.crudMap) {
881
- await evaluateCrudMap(pat.crudMap, env);
998
+ await handler.handleCrudMap(pat.crudMap, env);
882
999
  } else if (pat.forEach) {
883
- await evaluateForEach(pat.forEach, env);
1000
+ await handler.handleForEach(pat.forEach, env);
884
1001
  } else if (pat.if) {
885
- await evaluateIf(pat.if, env);
1002
+ await handler.handleIf(pat.if, env);
886
1003
  } else if (pat.delete) {
887
- await evaluateDelete(pat.delete, env);
1004
+ await handler.handleDelete(pat.delete, env);
888
1005
  } else if (pat.purge) {
889
- await evaluatePurge(pat.purge, env);
1006
+ await handler.handlePurge(pat.purge, env);
890
1007
  } else if (pat.fullTextSearch) {
891
- await evaluateFullTextSearch(pat.fullTextSearch, env);
1008
+ await handler.handleFullTextSearch(pat.fullTextSearch, env);
892
1009
  } else if (pat.return) {
893
- await evaluatePattern(pat.return.pat, env);
1010
+ await handler.handleReturn(pat.return, env);
894
1011
  env.markForReturn();
895
1012
  }
896
1013
  }
@@ -902,7 +1019,7 @@ async function evaluateFullTextSearch(fts: FullTextSearch, env: Environment): Pr
902
1019
  if (inst) {
903
1020
  n = makeFqName(inst.moduleName, n);
904
1021
  } else {
905
- console.log(`Fully qualified name required for full-text-search in ${n}`);
1022
+ throw new Error(`Fully qualified name required for full-text-search in ${n}`);
906
1023
  }
907
1024
  }
908
1025
  const path = splitFqName(n);
@@ -912,7 +1029,7 @@ async function evaluateFullTextSearch(fts: FullTextSearch, env: Environment): Pr
912
1029
  await evaluateLiteral(fts.query, env);
913
1030
  const q = env.getLastResult();
914
1031
  if (!isString(q)) {
915
- console.log(`Full text search query must be a string - ${q}`);
1032
+ throw new Error(`Full text search query must be a string - ${q}`);
916
1033
  }
917
1034
  let options: Map<string, any> | undefined;
918
1035
  if (fts.options) {
@@ -982,7 +1099,7 @@ async function patternToInstance(
982
1099
  entryName: string,
983
1100
  attributes: SetAttribute[] | undefined,
984
1101
  env: Environment
985
- ): Promise<Instance | undefined> {
1102
+ ): Promise<Instance> {
986
1103
  const attrs: InstanceAttributes = newInstanceAttributes();
987
1104
  let qattrs: InstanceAttributes | undefined;
988
1105
  let qattrVals: InstanceAttributes | undefined;
@@ -1016,13 +1133,7 @@ async function patternToInstance(
1016
1133
  if (p.hasModule()) moduleName = p.getModuleName();
1017
1134
  if (p.hasEntry()) entryName = p.getEntryName();
1018
1135
  }
1019
-
1020
- try {
1021
- return makeInstance(moduleName, entryName, attrs, qattrs, qattrVals, isQueryAll);
1022
- } catch (error) {
1023
- console.error(`patternToInstance: Failed to create instance of ${entryName} - ${error}`);
1024
- return undefined;
1025
- }
1136
+ return makeInstance(moduleName, entryName, attrs, qattrs, qattrVals, isQueryAll);
1026
1137
  }
1027
1138
 
1028
1139
  async function instanceFromSource(crud: CrudMap, env: Environment): Promise<Instance> {
@@ -1078,13 +1189,9 @@ async function evaluateCrudMap(crud: CrudMap, env: Environment): Promise<void> {
1078
1189
  if (!env.isInUpsertMode() && crud.upsert.length > 0) {
1079
1190
  return await evaluateUpsert(crud, env);
1080
1191
  }
1081
- const inst: Instance | undefined = crud.source
1192
+ const inst: Instance = crud.source
1082
1193
  ? await instanceFromSource(crud, env)
1083
1194
  : await patternToInstance(crud.name, crud.body?.attributes, env);
1084
- if (!inst) {
1085
- console.error(`evaluateCrudMap: Failed to create instance of ${crud.name}`);
1086
- return;
1087
- }
1088
1195
  const entryName = inst.name;
1089
1196
  const moduleName = inst.moduleName;
1090
1197
  const attrs = inst.attributes;
@@ -1257,7 +1364,12 @@ async function evaluateCrudMap(crud: CrudMap, env: Environment): Promise<void> {
1257
1364
  else if (isOpenApiEventInstance(inst)) await handleOpenApiEvent(inst, env);
1258
1365
  else if (isDocEventInstance(inst)) await handleDocEvent(inst, env);
1259
1366
  else {
1260
- await evaluate(inst, (result: Result) => env.setLastResult(result), env);
1367
+ const eventExec = env.getEventExecutor();
1368
+ if (eventExec) {
1369
+ await eventExec(inst, env);
1370
+ } else {
1371
+ await evaluate(inst, (result: Result) => env.setLastResult(result), env);
1372
+ }
1261
1373
  env.resetReturnFlag();
1262
1374
  }
1263
1375
  } else {
@@ -1266,7 +1378,7 @@ async function evaluateCrudMap(crud: CrudMap, env: Environment): Promise<void> {
1266
1378
  }
1267
1379
 
1268
1380
  const CoreAIModuleName = makeCoreModuleName('ai');
1269
- const DocEventName = `${CoreAIModuleName}/doc`;
1381
+ export const DocEventName = `${CoreAIModuleName}/doc`;
1270
1382
 
1271
1383
  function isDocEventInstance(inst: Instance): boolean {
1272
1384
  return isInstanceOfType(inst, DocEventName);
@@ -1386,10 +1498,6 @@ async function walkJoinQueryPattern(
1386
1498
  }
1387
1499
  }
1388
1500
  const qInst = await patternToInstance(crudMap.name, crudMap.body?.attributes, env);
1389
- if (!qInst) {
1390
- console.error(`walkJoinQueryPattern: Failed to create instance of ${crudMap.name}`);
1391
- return [];
1392
- }
1393
1501
  joinsSpec.push({
1394
1502
  relationship: getRelationship(rp.name, qInst.moduleName),
1395
1503
  queryInstance: qInst,
@@ -1420,6 +1528,7 @@ async function agentInvoke(agent: AgentInstance, msg: string, env: Environment):
1420
1528
  let result: string | undefined = env.getLastResult();
1421
1529
  logger.debug(`Agent ${agent.name} result: ${result}`);
1422
1530
  const isPlanner = agent.isPlanner();
1531
+ const stmtsExec = env.getStatementsExecutor();
1423
1532
  if (result) {
1424
1533
  if (isPlanner) {
1425
1534
  let retries = 0;
@@ -1442,9 +1551,18 @@ async function agentInvoke(agent: AgentInstance, msg: string, env: Environment):
1442
1551
  }
1443
1552
  if (isWf) {
1444
1553
  const wf = await parseWorkflow(rs);
1445
- await evaluateStatements(wf.statements, env);
1554
+ if (stmtsExec) {
1555
+ await stmtsExec(wf.statements, env);
1556
+ } else {
1557
+ await evaluateStatements(wf.statements, env);
1558
+ }
1446
1559
  } else {
1447
- env.setLastResult(await parseAndEvaluateStatement(rs, undefined, env));
1560
+ if (stmtsExec) {
1561
+ const stmt = await parseStatement(rs);
1562
+ env.setLastResult(await stmtsExec([stmt], env));
1563
+ } else {
1564
+ env.setLastResult(await parseAndEvaluateStatement(rs, undefined, env));
1565
+ }
1448
1566
  }
1449
1567
  break;
1450
1568
  } catch (err: any) {
@@ -1462,15 +1580,15 @@ async function agentInvoke(agent: AgentInstance, msg: string, env: Environment):
1462
1580
  }
1463
1581
  }
1464
1582
  }
1465
- if (agent.output) {
1466
- await pushToAgent(agent.output, env.getLastResult(), env);
1467
- }
1468
1583
  } else {
1469
1584
  throw new Error(`Agent ${agent.name} failed to generate a response`);
1470
1585
  }
1471
1586
  }
1472
1587
 
1473
- async function handleAgentInvocation(agentEventInst: Instance, env: Environment): Promise<void> {
1588
+ export async function handleAgentInvocation(
1589
+ agentEventInst: Instance,
1590
+ env: Environment
1591
+ ): Promise<void> {
1474
1592
  const agent: AgentInstance = await findAgentByName(agentEventInst.name, env);
1475
1593
  const origMsg: any = agentEventInst.lookup('message');
1476
1594
  const msg: string = isString(origMsg) ? origMsg : agentInputAsString(origMsg);
@@ -1555,6 +1673,7 @@ async function iterateOnFlow(
1555
1673
  if (env.isSuspended()) {
1556
1674
  console.debug(`${iterId} suspending iteration on step ${step}`);
1557
1675
  await saveFlowSuspension(rootAgent, context, step, env);
1676
+ env.releaseSuspension();
1558
1677
  return;
1559
1678
  }
1560
1679
  const r = env.getLastResult();
@@ -1584,13 +1703,7 @@ function agentInputAsString(result: any): string {
1584
1703
  return result;
1585
1704
  }
1586
1705
 
1587
- async function pushToAgent(agentName: string, result: any, env: Environment) {
1588
- const r = escapeSpecialChars(agentInputAsString(result));
1589
- const pat = `{${agentName} {message "\n${r}"}}`;
1590
- env.setLastResult(await parseAndEvaluateStatement(pat, undefined, env));
1591
- }
1592
-
1593
- async function handleOpenApiEvent(eventInst: Instance, env: Environment): Promise<void> {
1706
+ export async function handleOpenApiEvent(eventInst: Instance, env: Environment): Promise<void> {
1594
1707
  const r = await invokeOpenApiEvent(
1595
1708
  eventInst.moduleName,
1596
1709
  eventInst.name,
@@ -1642,11 +1755,19 @@ async function evaluateDeleteHelper(
1642
1755
  ): Promise<void> {
1643
1756
  const newEnv = Environment.from(env).setInDeleteMode(true);
1644
1757
  await evaluatePattern(pattern, newEnv);
1645
- const inst: Instance[] | Instance = newEnv.getLastResult();
1758
+ await maybeDeleteQueriedInstances(newEnv, env, purge);
1759
+ }
1760
+
1761
+ export async function maybeDeleteQueriedInstances(
1762
+ queryEnv: Environment,
1763
+ env: Environment,
1764
+ purge: boolean = false
1765
+ ): Promise<void> {
1766
+ const inst: Instance[] | Instance = queryEnv.getLastResult();
1646
1767
  let resolver: Resolver = Resolver.Default;
1647
1768
  if (inst instanceof Array) {
1648
1769
  if (inst.length > 0) {
1649
- resolver = await getResolverForPath(inst[0].name, inst[0].moduleName, newEnv);
1770
+ resolver = await getResolverForPath(inst[0].name, inst[0].moduleName, queryEnv);
1650
1771
  const finalResult: Array<any> = new Array<any>();
1651
1772
  for (let i = 0; i < inst.length; ++i) {
1652
1773
  await runPreDeleteEvents(inst[i], env);
@@ -1654,18 +1775,18 @@ async function evaluateDeleteHelper(
1654
1775
  await runPostDeleteEvents(inst[i], env);
1655
1776
  finalResult.push(r);
1656
1777
  }
1657
- newEnv.setLastResult(finalResult);
1778
+ queryEnv.setLastResult(finalResult);
1658
1779
  } else {
1659
- newEnv.setLastResult(inst);
1780
+ queryEnv.setLastResult(inst);
1660
1781
  }
1661
1782
  } else {
1662
- resolver = await getResolverForPath(inst.name, inst.moduleName, newEnv);
1783
+ resolver = await getResolverForPath(inst.name, inst.moduleName, queryEnv);
1663
1784
  await runPreDeleteEvents(inst, env);
1664
1785
  const r: Instance | null = await resolver.deleteInstance(inst, purge);
1665
1786
  await runPostDeleteEvents(inst, env);
1666
- newEnv.setLastResult(r);
1787
+ queryEnv.setLastResult(r);
1667
1788
  }
1668
- env.setLastResult(newEnv.getLastResult());
1789
+ env.setLastResult(queryEnv.getLastResult());
1669
1790
  }
1670
1791
 
1671
1792
  async function evaluateDelete(delStmt: Delete, env: Environment): Promise<void> {
@@ -1676,7 +1797,7 @@ async function evaluatePurge(purgeStmt: Purge, env: Environment): Promise<void>
1676
1797
  await evaluateDeleteHelper(purgeStmt.pattern, true, env);
1677
1798
  }
1678
1799
 
1679
- async function evaluateExpression(expr: Expr, env: Environment): Promise<void> {
1800
+ export async function evaluateExpression(expr: Expr, env: Environment): Promise<void> {
1680
1801
  let result: Result = EmptyResult;
1681
1802
  if (isBinExpr(expr)) {
1682
1803
  await evaluateExpression(expr.e1, env);
@@ -2231,12 +2231,21 @@ function getEntityDef(entityName: string, moduleName: string): Entity | undefine
2231
2231
  }
2232
2232
 
2233
2233
  export function getWorkflow(eventInstance: Instance): Workflow {
2234
- const eventName: string = eventInstance.name;
2235
- const moduleName: string = eventInstance.moduleName;
2236
- const wfName: string = asWorkflowName(eventName);
2237
- const module: Module = fetchModule(moduleName);
2238
- if (module.hasEntry(wfName)) {
2239
- return module.getEntry(wfName) as Workflow;
2234
+ return getWorkflowForEvent(eventInstance.name, eventInstance.moduleName);
2235
+ }
2236
+
2237
+ export function getWorkflowForEvent(eventName: string, moduleName?: string): Workflow {
2238
+ if (isFqName(eventName)) {
2239
+ const parts = splitFqName(eventName);
2240
+ eventName = parts.getEntryName();
2241
+ moduleName = parts.getModuleName();
2242
+ }
2243
+ if (moduleName) {
2244
+ const wfName: string = asWorkflowName(eventName);
2245
+ const module: Module = fetchModule(moduleName);
2246
+ if (module.hasEntry(wfName)) {
2247
+ return module.getEntry(wfName) as Workflow;
2248
+ }
2240
2249
  }
2241
2250
  return EmptyWorkflow;
2242
2251
  }
@@ -47,7 +47,6 @@ entity ${AgentEntityName} {
47
47
  tools String @optional, // comma-separated list of tool names
48
48
  documents String @optional, // comma-separated list of document names
49
49
  channels String @optional, // comma-separated list of channel names
50
- output String @optional, // fq-name of another agent to which the result will be pushed
51
50
  role String @optional,
52
51
  flows String @optional,
53
52
  llm String
@@ -94,7 +93,6 @@ export class AgentInstance {
94
93
  documents: string | undefined;
95
94
  channels: string | undefined;
96
95
  runWorkflows: boolean = true;
97
- output: string | undefined;
98
96
  role: string | undefined;
99
97
  flows: string | undefined;
100
98
  private toolsArray: string[] | undefined = undefined;