agentlang 0.10.1 → 0.10.3

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 (178) hide show
  1. package/README.md +7 -14
  2. package/out/api/http.d.ts +4 -0
  3. package/out/api/http.d.ts.map +1 -1
  4. package/out/api/http.js +307 -26
  5. package/out/api/http.js.map +1 -1
  6. package/out/cli/main.d.ts.map +1 -1
  7. package/out/cli/main.js +3 -0
  8. package/out/cli/main.js.map +1 -1
  9. package/out/extension/main.cjs +250 -250
  10. package/out/extension/main.cjs.map +2 -2
  11. package/out/language/agentlang-validator.d.ts.map +1 -1
  12. package/out/language/agentlang-validator.js +4 -0
  13. package/out/language/agentlang-validator.js.map +1 -1
  14. package/out/language/error-reporter.d.ts +53 -0
  15. package/out/language/error-reporter.d.ts.map +1 -0
  16. package/out/language/error-reporter.js +879 -0
  17. package/out/language/error-reporter.js.map +1 -0
  18. package/out/language/generated/ast.d.ts +77 -2
  19. package/out/language/generated/ast.d.ts.map +1 -1
  20. package/out/language/generated/ast.js +60 -0
  21. package/out/language/generated/ast.js.map +1 -1
  22. package/out/language/generated/grammar.d.ts.map +1 -1
  23. package/out/language/generated/grammar.js +342 -206
  24. package/out/language/generated/grammar.js.map +1 -1
  25. package/out/language/main.cjs +901 -710
  26. package/out/language/main.cjs.map +3 -3
  27. package/out/language/parser.d.ts +4 -2
  28. package/out/language/parser.d.ts.map +1 -1
  29. package/out/language/parser.js +58 -99
  30. package/out/language/parser.js.map +1 -1
  31. package/out/language/syntax.d.ts +16 -0
  32. package/out/language/syntax.d.ts.map +1 -1
  33. package/out/language/syntax.js +66 -27
  34. package/out/language/syntax.js.map +1 -1
  35. package/out/runtime/api.d.ts +2 -0
  36. package/out/runtime/api.d.ts.map +1 -1
  37. package/out/runtime/api.js +25 -0
  38. package/out/runtime/api.js.map +1 -1
  39. package/out/runtime/datefns.d.ts +34 -0
  40. package/out/runtime/datefns.d.ts.map +1 -0
  41. package/out/runtime/datefns.js +82 -0
  42. package/out/runtime/datefns.js.map +1 -0
  43. package/out/runtime/defs.d.ts +1 -0
  44. package/out/runtime/defs.d.ts.map +1 -1
  45. package/out/runtime/defs.js +2 -1
  46. package/out/runtime/defs.js.map +1 -1
  47. package/out/runtime/document-retriever.d.ts +24 -0
  48. package/out/runtime/document-retriever.d.ts.map +1 -0
  49. package/out/runtime/document-retriever.js +258 -0
  50. package/out/runtime/document-retriever.js.map +1 -0
  51. package/out/runtime/embeddings/chunker.d.ts +18 -0
  52. package/out/runtime/embeddings/chunker.d.ts.map +1 -1
  53. package/out/runtime/embeddings/chunker.js +47 -15
  54. package/out/runtime/embeddings/chunker.js.map +1 -1
  55. package/out/runtime/embeddings/openai.d.ts.map +1 -1
  56. package/out/runtime/embeddings/openai.js +22 -9
  57. package/out/runtime/embeddings/openai.js.map +1 -1
  58. package/out/runtime/embeddings/provider.d.ts +1 -0
  59. package/out/runtime/embeddings/provider.d.ts.map +1 -1
  60. package/out/runtime/embeddings/provider.js +20 -1
  61. package/out/runtime/embeddings/provider.js.map +1 -1
  62. package/out/runtime/exec-graph.d.ts.map +1 -1
  63. package/out/runtime/exec-graph.js +22 -3
  64. package/out/runtime/exec-graph.js.map +1 -1
  65. package/out/runtime/integration-client.d.ts +21 -0
  66. package/out/runtime/integration-client.d.ts.map +1 -0
  67. package/out/runtime/integration-client.js +112 -0
  68. package/out/runtime/integration-client.js.map +1 -0
  69. package/out/runtime/integrations.d.ts.map +1 -1
  70. package/out/runtime/integrations.js +20 -9
  71. package/out/runtime/integrations.js.map +1 -1
  72. package/out/runtime/interpreter.d.ts +10 -0
  73. package/out/runtime/interpreter.d.ts.map +1 -1
  74. package/out/runtime/interpreter.js +221 -22
  75. package/out/runtime/interpreter.js.map +1 -1
  76. package/out/runtime/loader.d.ts.map +1 -1
  77. package/out/runtime/loader.js +70 -7
  78. package/out/runtime/loader.js.map +1 -1
  79. package/out/runtime/logger.d.ts.map +1 -1
  80. package/out/runtime/logger.js +8 -1
  81. package/out/runtime/logger.js.map +1 -1
  82. package/out/runtime/module.d.ts +18 -0
  83. package/out/runtime/module.d.ts.map +1 -1
  84. package/out/runtime/module.js +91 -3
  85. package/out/runtime/module.js.map +1 -1
  86. package/out/runtime/modules/ai.d.ts +16 -5
  87. package/out/runtime/modules/ai.d.ts.map +1 -1
  88. package/out/runtime/modules/ai.js +286 -88
  89. package/out/runtime/modules/ai.js.map +1 -1
  90. package/out/runtime/modules/core.d.ts.map +1 -1
  91. package/out/runtime/modules/core.js +5 -1
  92. package/out/runtime/modules/core.js.map +1 -1
  93. package/out/runtime/monitor.d.ts +6 -0
  94. package/out/runtime/monitor.d.ts.map +1 -1
  95. package/out/runtime/monitor.js +21 -1
  96. package/out/runtime/monitor.js.map +1 -1
  97. package/out/runtime/relgraph.d.ts.map +1 -1
  98. package/out/runtime/relgraph.js +7 -3
  99. package/out/runtime/relgraph.js.map +1 -1
  100. package/out/runtime/resolvers/interface.d.ts +7 -2
  101. package/out/runtime/resolvers/interface.d.ts.map +1 -1
  102. package/out/runtime/resolvers/interface.js +17 -3
  103. package/out/runtime/resolvers/interface.js.map +1 -1
  104. package/out/runtime/resolvers/sqldb/database.d.ts +2 -0
  105. package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -1
  106. package/out/runtime/resolvers/sqldb/database.js +142 -126
  107. package/out/runtime/resolvers/sqldb/database.js.map +1 -1
  108. package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -1
  109. package/out/runtime/resolvers/sqldb/dbutil.js +25 -4
  110. package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -1
  111. package/out/runtime/resolvers/sqldb/impl.d.ts +2 -1
  112. package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
  113. package/out/runtime/resolvers/sqldb/impl.js +24 -7
  114. package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
  115. package/out/runtime/resolvers/vector/lancedb-store.d.ts +16 -0
  116. package/out/runtime/resolvers/vector/lancedb-store.d.ts.map +1 -0
  117. package/out/runtime/resolvers/vector/lancedb-store.js +159 -0
  118. package/out/runtime/resolvers/vector/lancedb-store.js.map +1 -0
  119. package/out/runtime/resolvers/vector/types.d.ts +32 -0
  120. package/out/runtime/resolvers/vector/types.d.ts.map +1 -0
  121. package/out/runtime/resolvers/vector/types.js +2 -0
  122. package/out/runtime/resolvers/vector/types.js.map +1 -0
  123. package/out/runtime/services/documentFetcher.d.ts.map +1 -1
  124. package/out/runtime/services/documentFetcher.js +21 -6
  125. package/out/runtime/services/documentFetcher.js.map +1 -1
  126. package/out/runtime/state.d.ts +19 -1
  127. package/out/runtime/state.d.ts.map +1 -1
  128. package/out/runtime/state.js +36 -1
  129. package/out/runtime/state.js.map +1 -1
  130. package/out/runtime/util.d.ts +3 -2
  131. package/out/runtime/util.d.ts.map +1 -1
  132. package/out/runtime/util.js +13 -2
  133. package/out/runtime/util.js.map +1 -1
  134. package/out/syntaxes/agentlang.monarch.js +1 -1
  135. package/out/syntaxes/agentlang.monarch.js.map +1 -1
  136. package/out/test-harness.d.ts +36 -0
  137. package/out/test-harness.d.ts.map +1 -0
  138. package/out/test-harness.js +341 -0
  139. package/out/test-harness.js.map +1 -0
  140. package/package.json +22 -19
  141. package/src/api/http.ts +336 -38
  142. package/src/cli/main.ts +3 -0
  143. package/src/language/agentlang-validator.ts +3 -0
  144. package/src/language/agentlang.langium +6 -2
  145. package/src/language/error-reporter.ts +1028 -0
  146. package/src/language/generated/ast.ts +94 -1
  147. package/src/language/generated/grammar.ts +342 -206
  148. package/src/language/parser.ts +64 -101
  149. package/src/language/syntax.ts +79 -24
  150. package/src/runtime/api.ts +36 -0
  151. package/src/runtime/datefns.ts +112 -0
  152. package/src/runtime/defs.ts +2 -1
  153. package/src/runtime/document-retriever.ts +311 -0
  154. package/src/runtime/embeddings/chunker.ts +52 -14
  155. package/src/runtime/embeddings/openai.ts +27 -9
  156. package/src/runtime/embeddings/provider.ts +22 -1
  157. package/src/runtime/exec-graph.ts +23 -2
  158. package/src/runtime/integration-client.ts +158 -0
  159. package/src/runtime/integrations.ts +20 -11
  160. package/src/runtime/interpreter.ts +221 -15
  161. package/src/runtime/loader.ts +83 -5
  162. package/src/runtime/logger.ts +12 -1
  163. package/src/runtime/module.ts +104 -3
  164. package/src/runtime/modules/ai.ts +341 -107
  165. package/src/runtime/modules/core.ts +5 -1
  166. package/src/runtime/monitor.ts +27 -1
  167. package/src/runtime/relgraph.ts +7 -3
  168. package/src/runtime/resolvers/interface.ts +23 -3
  169. package/src/runtime/resolvers/sqldb/database.ts +158 -130
  170. package/src/runtime/resolvers/sqldb/dbutil.ts +28 -6
  171. package/src/runtime/resolvers/sqldb/impl.ts +25 -7
  172. package/src/runtime/resolvers/vector/lancedb-store.ts +187 -0
  173. package/src/runtime/resolvers/vector/types.ts +39 -0
  174. package/src/runtime/services/documentFetcher.ts +21 -6
  175. package/src/runtime/state.ts +40 -1
  176. package/src/runtime/util.ts +19 -2
  177. package/src/syntaxes/agentlang.monarch.ts +1 -1
  178. package/src/test-harness.ts +423 -0
@@ -1,13 +1,13 @@
1
1
  import { isBinExpr, isGroup, isLiteral, isNegExpr, isNotExpr, isReturn, } from '../language/generated/ast.js';
2
- import { Agent, defineAgentEvent, getOneOfRef, getRelationship, getWorkflow, Instance, isAgentEventInstance, isBetweenRelationship, isContainsRelationship, isEmptyWorkflow, isEntityInstance, isEventInstance, isInstanceOfType, isOneToOneBetweenRelationship, isTimer, makeInstance, maybeInstanceAsString, newInstanceAttributes, PlaceholderRecordEntry, setMetaAttributes, } from './module.js';
2
+ import { Agent, defineAgentEvent, getOneOfRef, getRelationship, getWorkflow, Instance, isAgentEventInstance, isBetweenRelationship, isContainsRelationship, isEmptyWorkflow, isEntityInstance, isEventInstance, isInstanceOfType, getAllBetweenRelationshipsForEntity, isOneToOneBetweenRelationship, isTimer, makeInstance, maybeInstanceAsString, newInstanceAttributes, PlaceholderRecordEntry, setMetaAttributes, } from './module.js';
3
3
  import { Resolver } from './resolvers/interface.js';
4
4
  import { ResolverAuthInfo } from './resolvers/authinfo.js';
5
5
  import { SqlDbResolver } from './resolvers/sqldb/impl.js';
6
- import { CrudType, DefaultModuleName, escapeFqName, escapeQueryName, fqNameFromPath, isCoreModule, isFqName, isPath, isString, makeCoreModuleName, makeFqName, nameToPath, preprocessRawConfig, QuerySuffix, restoreSpecialChars, splitRefs, } from './util.js';
6
+ import { CrudType, DefaultModuleName, escapeFqName, escapeQueryName, firstAliasSpec, fqNameFromPath, isCoreModule, isFqName, isPath, isString, makeCoreModuleName, makeFqName, nameToPath, preprocessRawConfig, QuerySuffix, restoreSpecialChars, splitFqName, splitRefs, } from './util.js';
7
7
  import { getResolver, getResolverNameForPath } from './resolvers/registry.js';
8
8
  import { extractQueryOptions, parseStatement, parseWorkflow, } from '../language/parser.js';
9
9
  import { AdminSession, AdminUserId } from './auth/defs.js';
10
- import { AgentEntityName, AgentFqName, AgentInstance, findAgentByName, normalizeGeneratedCode, saveFlowStepResult, } from './modules/ai.js';
10
+ import { AgentCancelledException, AgentEntityName, AgentFqName, AgentInstance, checkCancelled, clearCancellation, findAgentByName, normalizeGeneratedCode, saveFlowStepResult, } from './modules/ai.js';
11
11
  import { logger } from './logger.js';
12
12
  import { FlowSuspensionTag, ParentAttributeName, PathAttributeName, PathAttributeNameQuery, } from './defs.js';
13
13
  import { addCreateAudit, addDeleteAudit, addUpdateAudit, createSuspension, flushMonitoringData, triggerTimer, } from './modules/core.js';
@@ -20,6 +20,7 @@ import { Monitor, MonitorEntry } from './monitor.js';
20
20
  import { detailedDiff } from 'deep-object-diff';
21
21
  import { callMcpTool, mcpClientNameFromToolEvent } from './mcpclient.js';
22
22
  import { isNodeEnv } from '../utils/runtime.js';
23
+ import Handlebars from 'handlebars';
23
24
  const EmptyResult = null;
24
25
  export function isEmptyResult(r) {
25
26
  return r == EmptyResult;
@@ -70,6 +71,7 @@ export class Environment extends Instance {
70
71
  this.agentChatId = parent.agentChatId;
71
72
  this.monitor = parent.monitor;
72
73
  this.escalatedRole = parent.escalatedRole;
74
+ this.activeChatId = parent.activeChatId;
73
75
  }
74
76
  else {
75
77
  this.activeModule = DefaultModuleName;
@@ -180,6 +182,13 @@ export class Environment extends Instance {
180
182
  getFlowContext() {
181
183
  return this.attributes.get(Environment.FlowContextTag);
182
184
  }
185
+ setActiveChatId(chatId) {
186
+ this.activeChatId = chatId;
187
+ return this;
188
+ }
189
+ getActiveChatId() {
190
+ return this.activeChatId;
191
+ }
183
192
  addToScratchPad(k, data) {
184
193
  if (this.scratchPad === undefined) {
185
194
  this.scratchPad = {};
@@ -244,6 +253,10 @@ export class Environment extends Instance {
244
253
  (_a = this.templateMappings) === null || _a === void 0 ? void 0 : _a.clear();
245
254
  return this;
246
255
  }
256
+ maybeRewriteTemplatePatterns(instruction, scratchPad) {
257
+ const templ = Handlebars.compile(this.rewriteTemplateMappings(instruction));
258
+ return templ(scratchPad);
259
+ }
247
260
  bindSuspensionUserData(userData) {
248
261
  this.bind(Environment.SuspensionUserData, userData);
249
262
  return this;
@@ -380,6 +393,13 @@ export class Environment extends Instance {
380
393
  getLastResult() {
381
394
  return this.lastResult;
382
395
  }
396
+ setLastPattern(pattern) {
397
+ this.lastPattern = pattern;
398
+ return this;
399
+ }
400
+ getLastPattern() {
401
+ return this.lastPattern;
402
+ }
383
403
  getActiveModuleName() {
384
404
  return this.activeModule;
385
405
  }
@@ -666,6 +686,12 @@ export class Environment extends Instance {
666
686
  }
667
687
  return this;
668
688
  }
689
+ setMonitorEntryLlmTokenUsage(input, output, total) {
690
+ if (this.monitor !== undefined) {
691
+ this.monitor.setEntryLlmTokenUsage(input, output, total);
692
+ }
693
+ return this;
694
+ }
669
695
  incrementMonitor() {
670
696
  if (this.monitor !== undefined) {
671
697
  this.monitor = this.monitor.increment();
@@ -709,8 +735,14 @@ export let evaluate = async function (eventInstance, continuation, activeEnv, ke
709
735
  else if (isAgentEventInstance(eventInstance)) {
710
736
  env = new Environment(eventInstance.name + '.env', activeEnv);
711
737
  await handleAgentInvocation(eventInstance, env);
712
- if (continuation)
713
- continuation(env.getLastResult());
738
+ if (continuation) {
739
+ if (env.getLastPattern()) {
740
+ continuation({ result: env.getLastResult(), pattern: env.getLastPattern() });
741
+ }
742
+ else {
743
+ continuation(env.getLastResult());
744
+ }
745
+ }
714
746
  }
715
747
  else if (isOpenApiEventInstance(eventInstance)) {
716
748
  env = new Environment(eventInstance.name + '.env', activeEnv);
@@ -833,7 +865,11 @@ export async function evaluateStatement(stmt, env) {
833
865
  handlersPushed = env.pushHandlers(handlers);
834
866
  }
835
867
  await evaluatePattern(stmt.pattern, env);
868
+ let skipOuterAlias = false;
836
869
  if (hasHints) {
870
+ skipOuterAlias = await maybeHandleEmpty(hints, env);
871
+ }
872
+ if (hasHints && !skipOuterAlias) {
837
873
  maybeBindStatementResultToAlias(hints, env);
838
874
  }
839
875
  await maybeHandleNotFound(handlers, env);
@@ -860,6 +896,28 @@ async function maybeHandleNotFound(handlers, env) {
860
896
  }
861
897
  }
862
898
  }
899
+ async function maybeHandleEmpty(hints, env) {
900
+ const lastResult = env.getLastResult();
901
+ if (lastResult === null ||
902
+ lastResult === undefined ||
903
+ (lastResult instanceof Array && lastResult.length == 0)) {
904
+ for (const rh of hints) {
905
+ if (rh.emptySpec) {
906
+ const newEnv = new Environment('empty-env', env).unsetEventExecutor();
907
+ await evaluateStatement(rh.emptySpec.stmt, newEnv);
908
+ env.setLastResult(newEnv.getLastResult());
909
+ // If inner statement has its own @as, propagate binding to parent env
910
+ const innerAlias = firstAliasSpec(rh.emptySpec.stmt);
911
+ if (innerAlias) {
912
+ maybeBindStatementResultToAlias(rh.emptySpec.stmt.hints, env);
913
+ return true; // signal: skip outer @as
914
+ }
915
+ break;
916
+ }
917
+ }
918
+ }
919
+ return false;
920
+ }
863
921
  async function maybeHandleError(handlers, reason, env) {
864
922
  const handler = handlers ? handlers.get('error') : undefined;
865
923
  if (handler) {
@@ -1226,9 +1284,15 @@ function maybeSetQueryClauses(inst, qopts) {
1226
1284
  if (qopts.orderByClause) {
1227
1285
  inst.setOrderBy(qopts.orderByClause.colNames, qopts.orderByClause.order === '@desc');
1228
1286
  }
1287
+ if (qopts.limitClause) {
1288
+ inst.setLimit(qopts.limitClause.value);
1289
+ }
1290
+ if (qopts.offsetClause) {
1291
+ inst.setOffset(qopts.offsetClause.value);
1292
+ }
1229
1293
  }
1230
1294
  async function evaluateCrudMap(crud, env) {
1231
- var _a, _b, _c;
1295
+ var _a, _b, _c, _d;
1232
1296
  const qopts = extractQueryOptions(crud);
1233
1297
  if (!env.isInUpsertMode() && qopts.upsert !== undefined) {
1234
1298
  return await evaluateUpsert(crud, env);
@@ -1272,7 +1336,7 @@ async function evaluateCrudMap(crud, env) {
1272
1336
  }
1273
1337
  const res = await getResolverForPath(entryName, moduleName, env);
1274
1338
  let r;
1275
- await computeExprAttributes(inst, undefined, undefined, env);
1339
+ await computeExprAttributes(inst, (_b = crud.body) === null || _b === void 0 ? void 0 : _b.attributes, inst.attributes, env);
1276
1340
  await setMetaAttributes(inst.attributes, env);
1277
1341
  if (env.isInUpsertMode()) {
1278
1342
  await runPreUpdateEvents(inst, env);
@@ -1337,7 +1401,7 @@ async function evaluateCrudMap(crud, env) {
1337
1401
  }
1338
1402
  else if (betRelInfo !== undefined) {
1339
1403
  res = await getResolverForPath(betRelInfo.relationship.name, betRelInfo.relationship.moduleName, env);
1340
- const insts = await res.queryConnectedInstances(betRelInfo.relationship, betRelInfo.connectedInstance, inst);
1404
+ const insts = await res.queryConnectedInstances(betRelInfo.relationship, betRelInfo.connectedInstance, inst, betRelInfo.connectedAlias);
1341
1405
  env.setLastResult(insts);
1342
1406
  }
1343
1407
  else {
@@ -1350,7 +1414,7 @@ async function evaluateCrudMap(crud, env) {
1350
1414
  }
1351
1415
  if (oneToOne && rel !== undefined) {
1352
1416
  await res.handleInstancesLink(inst.lookupQueryVal(rel.node1.alias), inst.lookupQueryVal(rel.node2.alias), rel, false, true);
1353
- env.setLastResult(inst);
1417
+ env.setLastResult([inst]);
1354
1418
  }
1355
1419
  else {
1356
1420
  const insts = await res.queryInstances(inst, isQueryAll, distinct);
@@ -1380,7 +1444,12 @@ async function evaluateCrudMap(crud, env) {
1380
1444
  lastRes[j].attachRelatedInstances(rel.name, newEnv.getLastResult());
1381
1445
  }
1382
1446
  else if (isBetweenRelationship(rel.name, moduleName)) {
1383
- newEnv.setBetweenRelInfo({ relationship: relEntry, connectedInstance: lastRes[j] });
1447
+ const connAlias = relEntry.isSelfReferencing() ? relEntry.node1.alias : undefined;
1448
+ newEnv.setBetweenRelInfo({
1449
+ relationship: relEntry,
1450
+ connectedInstance: lastRes[j],
1451
+ connectedAlias: connAlias,
1452
+ });
1384
1453
  await evaluatePattern(rel.pattern, newEnv);
1385
1454
  lastRes[j].attachRelatedInstances(rel.name, newEnv.getLastResult());
1386
1455
  }
@@ -1394,7 +1463,7 @@ async function evaluateCrudMap(crud, env) {
1394
1463
  const resolver = await getResolverForPath(lastRes[0].name, lastRes[0].moduleName, env);
1395
1464
  const res = new Array();
1396
1465
  for (let i = 0; i < lastRes.length; ++i) {
1397
- await computeExprAttributes(lastRes[i], (_b = crud.body) === null || _b === void 0 ? void 0 : _b.attributes, attrs, env);
1466
+ await computeExprAttributes(lastRes[i], (_c = crud.body) === null || _c === void 0 ? void 0 : _c.attributes, attrs, env);
1398
1467
  env.attributes.set('__patch', attrs);
1399
1468
  await runPreUpdateEvents(lastRes[i], env);
1400
1469
  await setMetaAttributes(attrs, env, true);
@@ -1410,11 +1479,11 @@ async function evaluateCrudMap(crud, env) {
1410
1479
  }
1411
1480
  else {
1412
1481
  const res = await getResolverForPath(lastRes.name, lastRes.moduleName, env);
1413
- await computeExprAttributes(lastRes, (_c = crud.body) === null || _c === void 0 ? void 0 : _c.attributes, attrs, env);
1482
+ await computeExprAttributes(lastRes, (_d = crud.body) === null || _d === void 0 ? void 0 : _d.attributes, attrs, env);
1414
1483
  await runPreUpdateEvents(lastRes, env);
1415
1484
  const finalInst = await res.updateInstance(lastRes, attrs);
1416
1485
  await runPostUpdateEvents(finalInst, lastRes, env);
1417
- env.setLastResult(finalInst);
1486
+ env.setLastResult([finalInst]);
1418
1487
  }
1419
1488
  }
1420
1489
  }
@@ -1513,24 +1582,103 @@ async function computeExprAttributes(inst, origAttrs, updatedAttrs, env) {
1513
1582
  if (v !== undefined)
1514
1583
  newEnv.bind(k, v);
1515
1584
  });
1585
+ // Bind related instances from between-relationships so that @expr references
1586
+ // like DeptEmployee.Department.BudgetMultiplier can be resolved via followReference.
1587
+ const entityFqName = inst.getFqName();
1588
+ const fqParts = splitFqName(entityFqName);
1589
+ const rels = getAllBetweenRelationshipsForEntity(fqParts[0], fqParts[1]);
1590
+ for (const rel of rels) {
1591
+ const isFirst = rel.isFirstNodeName(entityFqName);
1592
+ // Only bind if this entity is on a valid side for single-entity resolution
1593
+ if (rel.isManyToMany())
1594
+ continue;
1595
+ if (rel.isOneToMany() && isFirst)
1596
+ continue;
1597
+ // Determine the target entity on the other side
1598
+ const targetNode = isFirst ? rel.node2 : rel.node1;
1599
+ const targetAlias = targetNode.alias;
1600
+ let connectedInst;
1601
+ // Fast path: check if the environment carries between-rel info for this relationship
1602
+ const betRelInfo = env.getBetweenRelInfo();
1603
+ if (betRelInfo && betRelInfo.relationship.name === rel.name) {
1604
+ connectedInst = betRelInfo.connectedInstance;
1605
+ }
1606
+ else if (inst.lookup(PathAttributeName)) {
1607
+ // Slow path: query the connected instance through the resolver.
1608
+ // Only possible if the current instance has been persisted (has a __path__).
1609
+ try {
1610
+ const targetFqName = targetNode.path.asFqName();
1611
+ const targetParts = splitFqName(targetFqName);
1612
+ const res = await getResolverForPath(targetParts[1], targetParts[0], env);
1613
+ const queryInst = Instance.EmptyInstance(targetParts[1], targetParts[0]);
1614
+ const connected = await res.queryConnectedInstances(rel, inst, queryInst);
1615
+ if (connected && connected.length > 0) {
1616
+ connectedInst = connected[0];
1617
+ }
1618
+ }
1619
+ catch (reason) {
1620
+ logger.debug(`Relationship query failed (e.g. not yet linked) - skip binding - ${reason}`);
1621
+ }
1622
+ }
1623
+ if (connectedInst) {
1624
+ const relMap = new Map();
1625
+ relMap.set(targetAlias, connectedInst);
1626
+ newEnv.bind(rel.name, relMap);
1627
+ }
1628
+ }
1629
+ // Build a map of user-provided values for @expr attributes so that
1630
+ // overrides are applied inline during expression evaluation, allowing
1631
+ // dependent expressions to see the user's value immediately.
1632
+ let userExprOverrides;
1633
+ if (exprAttrs && origAttrs) {
1634
+ for (let i = 0; i < origAttrs.length; ++i) {
1635
+ const a = origAttrs[i];
1636
+ const n = a.name;
1637
+ if (exprAttrs.has(n) && !n.endsWith(QuerySuffix) && a.value !== undefined) {
1638
+ if (userExprOverrides === undefined) {
1639
+ userExprOverrides = new Map();
1640
+ }
1641
+ userExprOverrides.set(n, a.value);
1642
+ }
1643
+ }
1644
+ }
1516
1645
  if (exprAttrs) {
1517
1646
  const ks = [...exprAttrs.keys()];
1518
1647
  for (let i = 0; i < ks.length; ++i) {
1519
1648
  const n = ks[i];
1520
- const expr = exprAttrs.get(n);
1521
- if (expr) {
1522
- await evaluateExpression(expr, newEnv);
1523
- const v = newEnv.getLastResult();
1524
- newEnv.bind(n, v);
1525
- inst.attributes.set(n, v);
1526
- updatedAttrs === null || updatedAttrs === void 0 ? void 0 : updatedAttrs.set(n, v);
1649
+ const userValue = userExprOverrides === null || userExprOverrides === void 0 ? void 0 : userExprOverrides.get(n);
1650
+ if (userValue !== undefined) {
1651
+ // User explicitly provided a value for this @expr attribute - use it
1652
+ await evaluateExpression(userValue, newEnv);
1653
+ }
1654
+ else {
1655
+ // No user override - evaluate the @expr expression
1656
+ const expr = exprAttrs.get(n);
1657
+ if (expr) {
1658
+ await evaluateExpression(expr, newEnv);
1659
+ }
1660
+ else {
1661
+ continue;
1662
+ }
1527
1663
  }
1664
+ const v = newEnv.getLastResult();
1665
+ newEnv.bind(n, v);
1666
+ inst.attributes.set(n, v);
1667
+ updatedAttrs === null || updatedAttrs === void 0 ? void 0 : updatedAttrs.set(n, v);
1528
1668
  }
1529
1669
  }
1530
- if (origAttrs && updatedAttrs) {
1670
+ // Re-evaluate non-@expr attribute expressions from origAttrs in the context
1671
+ // of the queried instance. This handles workflow update expressions like
1672
+ // `balance balance + (balance * interestRate) + makeDeposit.amount` where
1673
+ // the local attribute references must resolve from the existing instance.
1674
+ // Only runs on the update path (where updatedAttrs is a separate map from
1675
+ // inst.attributes) to avoid double-evaluating expressions on create.
1676
+ if (origAttrs && updatedAttrs && updatedAttrs !== inst.attributes) {
1531
1677
  for (let i = 0; i < origAttrs.length; ++i) {
1532
1678
  const a = origAttrs[i];
1533
1679
  const n = a.name;
1680
+ if (exprAttrs === null || exprAttrs === void 0 ? void 0 : exprAttrs.has(n))
1681
+ continue;
1534
1682
  if (!n.endsWith(QuerySuffix) && updatedAttrs.has(n) && a.value !== undefined) {
1535
1683
  await evaluateExpression(a.value, newEnv);
1536
1684
  const v = newEnv.getLastResult();
@@ -1655,6 +1803,8 @@ async function agentInvoke(agent, msg, env) {
1655
1803
  invokeDebugMsg = `\nMessage=${msg}`;
1656
1804
  console.debug(invokeDebugMsg);
1657
1805
  //
1806
+ const agentChatId = env.getAgentChatId() || env.getActiveChatId() || '';
1807
+ await clearCancellation(agentChatId);
1658
1808
  const monitoringEnabled = isMonitoringEnabled();
1659
1809
  await agent.invoke(msg, env);
1660
1810
  let result = env.getLastResult();
@@ -1669,8 +1819,15 @@ async function agentInvoke(agent, msg, env) {
1669
1819
  }
1670
1820
  let retries = 0;
1671
1821
  while (true) {
1822
+ await checkCancelled(agentChatId);
1672
1823
  try {
1673
1824
  let rs = result ? normalizeGeneratedCode(result) : '';
1825
+ if (agent.tools) {
1826
+ env.setLastPattern(rs);
1827
+ }
1828
+ else {
1829
+ env.setLastPattern(undefined);
1830
+ }
1674
1831
  let isWf = rs.startsWith('workflow');
1675
1832
  if (isWf && !agent.runWorkflows) {
1676
1833
  await parseWorkflow(rs);
@@ -1729,6 +1886,7 @@ async function agentInvoke(agent, msg, env) {
1729
1886
  else {
1730
1887
  let retries = 0;
1731
1888
  while (true) {
1889
+ await checkCancelled(agentChatId);
1732
1890
  try {
1733
1891
  result = normalizeGeneratedCode(result);
1734
1892
  const obj = agent.maybeValidateJsonResponse(result);
@@ -1765,6 +1923,10 @@ async function agentInvoke(agent, msg, env) {
1765
1923
  }
1766
1924
  export async function handleAgentInvocation(agentEventInst, env) {
1767
1925
  const agent = await findAgentByName(agentEventInst.name, env);
1926
+ const chatId = agentEventInst.lookup('chatId');
1927
+ if (chatId) {
1928
+ env.setActiveChatId(chatId);
1929
+ }
1768
1930
  const origMsg = agentEventInst.lookup('message') || JSON.stringify(agentEventInst.asObject());
1769
1931
  const msg = isString(origMsg) ? origMsg : maybeInstanceAsString(origMsg);
1770
1932
  const flow = getAgentFlow(agent.name, agent.moduleName);
@@ -1774,7 +1936,6 @@ export async function handleAgentInvocation(agentEventInst, env) {
1774
1936
  else {
1775
1937
  const mode = agentEventInst.lookup('mode');
1776
1938
  let activeEnv = env;
1777
- const chatId = agentEventInst.lookup('chatId');
1778
1939
  if (chatId !== undefined) {
1779
1940
  activeEnv.setAgentChatId(chatId);
1780
1941
  }
@@ -1822,9 +1983,11 @@ async function iterateOnFlow(flow, rootAgent, msg, env) {
1822
1983
  rootAgent.disableSession();
1823
1984
  const chatId = (_a = env.getActiveEventInstance()) === null || _a === void 0 ? void 0 : _a.lookup('chatId');
1824
1985
  const iterId = chatId || crypto.randomUUID();
1986
+ await clearCancellation(iterId);
1825
1987
  let step = '';
1826
1988
  let fullFlowRetries = 0;
1827
1989
  while (true) {
1990
+ await checkCancelled(iterId);
1828
1991
  try {
1829
1992
  const initContext = msg;
1830
1993
  const s = `Now consider the following flowchart and return the next step:\n${flow}\n
@@ -1847,6 +2010,7 @@ async function iterateOnFlow(flow, rootAgent, msg, env) {
1847
2010
  env.flagMonitorEntryAsFlow().incrementMonitor();
1848
2011
  }
1849
2012
  while (step != 'DONE' && !executedSteps.has(step)) {
2013
+ await checkCancelled(iterId);
1850
2014
  if (stepc > MaxFlowSteps) {
1851
2015
  throw new Error(`Flow execution exceeded maximum steps limit`);
1852
2016
  }
@@ -1903,6 +2067,9 @@ async function iterateOnFlow(flow, rootAgent, msg, env) {
1903
2067
  }
1904
2068
  }
1905
2069
  catch (reason) {
2070
+ if (reason instanceof AgentCancelledException) {
2071
+ throw reason;
2072
+ }
1906
2073
  if (fullFlowRetries < MaxFlowRetries) {
1907
2074
  msg = `The previous attempt failed at step ${step} with the error ${reason}. Restart the flow the appropriate step
1908
2075
  (maybe even from the first step) and try to fix the issue.`;
@@ -2114,6 +2281,38 @@ export async function evaluateExpression(expr, env) {
2114
2281
  }
2115
2282
  env.setLastResult(result);
2116
2283
  }
2284
+ export function extractRefsFromExpr(expr) {
2285
+ const refs = [];
2286
+ function walk(e) {
2287
+ if (isBinExpr(e)) {
2288
+ walk(e.e1);
2289
+ walk(e.e2);
2290
+ }
2291
+ else if (isLiteral(e)) {
2292
+ if (e.ref)
2293
+ refs.push(e.ref);
2294
+ if (e.fnCall) {
2295
+ for (const arg of e.fnCall.args)
2296
+ walk(arg);
2297
+ }
2298
+ if (e.asyncFnCall) {
2299
+ for (const arg of e.asyncFnCall.fnCall.args)
2300
+ walk(arg);
2301
+ }
2302
+ }
2303
+ else if (isGroup(e)) {
2304
+ walk(e.ge);
2305
+ }
2306
+ else if (isNegExpr(e)) {
2307
+ walk(e.ne);
2308
+ }
2309
+ else if (isNotExpr(e)) {
2310
+ walk(e.ne);
2311
+ }
2312
+ }
2313
+ walk(expr);
2314
+ return refs;
2315
+ }
2117
2316
  async function getRef(r, src, env) {
2118
2317
  if (Instance.IsInstance(src))
2119
2318
  return src.lookup(r);