agentlang 0.1.9 → 0.2.1

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 (67) hide show
  1. package/out/api/http.js +3 -3
  2. package/out/api/http.js.map +1 -1
  3. package/out/language/agentlang-validator.d.ts.map +1 -1
  4. package/out/language/agentlang-validator.js +3 -1
  5. package/out/language/agentlang-validator.js.map +1 -1
  6. package/out/language/generated/ast.d.ts +35 -9
  7. package/out/language/generated/ast.d.ts.map +1 -1
  8. package/out/language/generated/ast.js +40 -1
  9. package/out/language/generated/ast.js.map +1 -1
  10. package/out/language/generated/grammar.d.ts.map +1 -1
  11. package/out/language/generated/grammar.js +289 -120
  12. package/out/language/generated/grammar.js.map +1 -1
  13. package/out/language/main.cjs +323 -122
  14. package/out/language/main.cjs.map +2 -2
  15. package/out/language/parser.d.ts +1 -0
  16. package/out/language/parser.d.ts.map +1 -1
  17. package/out/language/parser.js +14 -13
  18. package/out/language/parser.js.map +1 -1
  19. package/out/runtime/agents/common.d.ts +2 -1
  20. package/out/runtime/agents/common.d.ts.map +1 -1
  21. package/out/runtime/agents/common.js +42 -3
  22. package/out/runtime/agents/common.js.map +1 -1
  23. package/out/runtime/exec-graph.d.ts.map +1 -1
  24. package/out/runtime/exec-graph.js +15 -7
  25. package/out/runtime/exec-graph.js.map +1 -1
  26. package/out/runtime/interpreter.d.ts +1 -0
  27. package/out/runtime/interpreter.d.ts.map +1 -1
  28. package/out/runtime/interpreter.js +76 -32
  29. package/out/runtime/interpreter.js.map +1 -1
  30. package/out/runtime/loader.d.ts.map +1 -1
  31. package/out/runtime/loader.js +16 -9
  32. package/out/runtime/loader.js.map +1 -1
  33. package/out/runtime/module.d.ts +15 -0
  34. package/out/runtime/module.d.ts.map +1 -1
  35. package/out/runtime/module.js +96 -24
  36. package/out/runtime/module.js.map +1 -1
  37. package/out/runtime/modules/ai.d.ts +7 -3
  38. package/out/runtime/modules/ai.d.ts.map +1 -1
  39. package/out/runtime/modules/ai.js +85 -22
  40. package/out/runtime/modules/ai.js.map +1 -1
  41. package/out/runtime/resolvers/interface.js +2 -2
  42. package/out/runtime/resolvers/interface.js.map +1 -1
  43. package/out/runtime/resolvers/sqldb/impl.js +2 -2
  44. package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
  45. package/out/runtime/util.d.ts +2 -1
  46. package/out/runtime/util.d.ts.map +1 -1
  47. package/out/runtime/util.js +4 -1
  48. package/out/runtime/util.js.map +1 -1
  49. package/out/syntaxes/agentlang.monarch.js +3 -3
  50. package/out/syntaxes/agentlang.monarch.js.map +1 -1
  51. package/package.json +8 -6
  52. package/src/api/http.ts +3 -3
  53. package/src/language/agentlang-validator.ts +3 -1
  54. package/src/language/agentlang.langium +8 -2
  55. package/src/language/generated/ast.ts +80 -9
  56. package/src/language/generated/grammar.ts +289 -120
  57. package/src/language/parser.ts +15 -14
  58. package/src/runtime/agents/common.ts +43 -3
  59. package/src/runtime/exec-graph.ts +14 -7
  60. package/src/runtime/interpreter.ts +82 -32
  61. package/src/runtime/loader.ts +23 -8
  62. package/src/runtime/module.ts +111 -22
  63. package/src/runtime/modules/ai.ts +97 -23
  64. package/src/runtime/resolvers/interface.ts +2 -2
  65. package/src/runtime/resolvers/sqldb/impl.ts +2 -2
  66. package/src/runtime/util.ts +5 -1
  67. package/src/syntaxes/agentlang.monarch.ts +3 -3
@@ -132,34 +132,35 @@ export function maybeGetValidationErrors(document: LangiumDocument): string[] |
132
132
  }
133
133
  }
134
134
 
135
- function maybeRaiseParserErrors(document: LangiumDocument) {
136
- const errs = maybeGetValidationErrors(document);
137
- if (errs) {
138
- throw new Error(errs.join('\n'));
139
- }
140
- }
141
-
142
- export async function introspect(s: string): Promise<BasePattern[]> {
143
- let result: BasePattern[] = [];
144
- const v: LangiumDocument<ModuleDefinition> = await parse(`module Temp workflow Test {${s}}`);
145
- if (v.parseResult.lexerErrors.length > 0) {
135
+ export function maybeRaiseParserErrors(document: LangiumDocument) {
136
+ if (document.parseResult.lexerErrors.length > 0) {
146
137
  throw new Error(
147
- `Lexer errors: ${v.parseResult.lexerErrors
138
+ `Lexer errors: ${document.parseResult.lexerErrors
148
139
  .map((err: any) => {
149
140
  return err.message;
150
141
  })
151
142
  .join('\n')}`
152
143
  );
153
144
  }
154
- if (v.parseResult.parserErrors.length > 0) {
145
+ if (document.parseResult.parserErrors.length > 0) {
155
146
  throw new Error(
156
- `Parser errors: ${v.parseResult.parserErrors
147
+ `Parser errors: ${document.parseResult.parserErrors
157
148
  .map((err: any) => {
158
149
  return err.message;
159
150
  })
160
151
  .join('\n')}`
161
152
  );
162
153
  }
154
+ const errs = maybeGetValidationErrors(document);
155
+ if (errs) {
156
+ throw new Error(errs.join('\n'));
157
+ }
158
+ }
159
+
160
+ export async function introspect(s: string): Promise<BasePattern[]> {
161
+ let result: BasePattern[] = [];
162
+ const v: LangiumDocument<ModuleDefinition> = await parse(`module Temp workflow Test {${s}}`);
163
+ maybeRaiseParserErrors(v);
163
164
  if (isWorkflowDefinition(v.parseResult.value.defs[0])) {
164
165
  result = introspectHelper(v.parseResult.value.defs[0].statements);
165
166
  } else {
@@ -62,11 +62,10 @@ Other than the create-pattern for entities and events, some of the most useful p
62
62
  instance, if the instance does not already exist.
63
63
  4. Delete - e.g: 'delete {Erp/Employee {employeeId? "56392e13-0d9a-42f7-b556-0d7cd9468a24"}}'
64
64
 
65
- The default query operator is '=' (equals). So an expression like 'employeeId? "56392e13-0d9a-42f7-b556-0d7cd9468a24"' means,
65
+ The default query operator is equals. So an expression like 'employeeId? "56392e13-0d9a-42f7-b556-0d7cd9468a24"' means,
66
66
  'where employeeId equals "56392e13-0d9a-42f7-b556-0d7cd9468a24"'. Other comparison operators has to be specified explicitly, as in
67
67
  '{age?< 50}' - which means 'where age less-than 50'. The comparison operators supported by a query pattern are:
68
68
 
69
- = - equals
70
69
  != - not-equals
71
70
  < - less-than
72
71
  <= - less-than or equals
@@ -95,7 +94,7 @@ Another example of the 'if' pattern:
95
94
 
96
95
  workflow validateLicense {
97
96
  {checkLicenseNumber {number validateLicense.number}} @as response;
98
- if (response = "ok") {
97
+ if (response == "ok") {
99
98
  {license {number? validateLicense.number, status "active"}}
100
99
  } else {
101
100
  {license {number? validateLicense.number, status "canceled"}}
@@ -313,6 +312,47 @@ If you detect that you have reached the end of the chart, return 'DONE'. Otherwi
313
312
  any additional description, direction or comments.
314
313
  `;
315
314
 
315
+ export const DecisionAgentInstructions = `Analyse a decision table with multiple cases along with the context to return one or more values.
316
+ A decision table will be a sequence of case-conditions as in,
317
+
318
+ case (condition1) {
319
+ value1
320
+ }
321
+
322
+ case (condition2) {
323
+ value2
324
+ }
325
+
326
+ The context will be some additional instructions and JSON-like data based on which you can evaluate the conditions and decide which values to return.
327
+ Let's consider an example:
328
+
329
+
330
+ analyseSalesReport --> {"Acme/salesReport": {"employeeId": 101, "employeeGrade": "A", "totalSalesAmount": 14000}}
331
+
332
+ case (totalSalesAmount > 10000) {
333
+ giveIncrementToEmployee
334
+ }
335
+
336
+ case (totalSalesAmount > 15000) {
337
+ promoteEmployee
338
+ }
339
+
340
+ case (totalSalesAmount < 10000 and employeeGrade == "A") {
341
+ demoteEmployee
342
+ }
343
+
344
+
345
+ Given the above context and cases, you must return giveIncrementToEmployee - because the data in the context satisfies only the first case.
346
+ If the context is,
347
+
348
+ analyseSalesReport --> {"Acme/salesReport": {"employeeId": 101, "employeeGrade": "A", "totalSalesAmount": 16000}}
349
+
350
+ you must return giveIncrementToEmployee,promoteEmployee because the data satisfies the first two cases. You must return only the value of the
351
+ case or cases you selected and no additional text or comments. If you decide to select more than one case, return the values separated by commas.
352
+ Also select the case that is the best match for the given context, no need to look for a perfect match for all values specified in the context.
353
+ Now apply the same analysis to the following context and cases provided by the user.
354
+ `;
355
+
316
356
  export type AgentCondition = {
317
357
  cond: string;
318
358
  then: string;
@@ -39,7 +39,7 @@ import {
39
39
  RecordType,
40
40
  } from './module.js';
41
41
  import { isOpenApiEventInstance, isOpenApiModule } from './openapi.js';
42
- import { escapeQueryName, makeFqName, splitFqName } from './util.js';
42
+ import { escapeQueryName, makeFqName, nameToPath } from './util.js';
43
43
 
44
44
  const GraphCache = new Map<string, ExecGraph>();
45
45
 
@@ -47,7 +47,7 @@ export async function generateExecutionGraph(eventName: string): Promise<ExecGra
47
47
  const cg = GraphCache.get(eventName);
48
48
  if (cg) return cg;
49
49
  const wf = getWorkflowForEvent(eventName);
50
- const parts = splitFqName(eventName);
50
+ const parts = nameToPath(eventName);
51
51
  const moduleName = parts.hasModule() ? parts.getModuleName() : undefined;
52
52
  if (!isEmptyWorkflow(wf)) {
53
53
  const g = await graphFromStatements(wf.statements, moduleName);
@@ -69,7 +69,7 @@ class GraphGenerator extends PatternHandler {
69
69
  }
70
70
 
71
71
  override async handleCrudMap(crudMap: CrudMap, env: Environment) {
72
- const parts = splitFqName(crudMap.name);
72
+ const parts = nameToPath(crudMap.name);
73
73
  const moduleName = parts.hasModule() ? parts.getModuleName() : env.getActiveModuleName();
74
74
  const crudName = makeFqName(moduleName, parts.getEntryName());
75
75
  if (crudName == DocEventName) {
@@ -381,14 +381,21 @@ export async function executeEventHelper(eventInstance: Instance, env?: Environm
381
381
  env = new Environment(`${fqn}-env`);
382
382
  isLocalEnv = true;
383
383
  }
384
- const g = await generateExecutionGraph(fqn);
385
- if (!g) {
386
- throw new Error(`Failed to generate graph for event ${fqn}`);
384
+ let g: ExecGraph | undefined;
385
+ if (!isAgentEventInstance(eventInstance)) {
386
+ g = await generateExecutionGraph(fqn);
387
+ if (!g) {
388
+ throw new Error(`Failed to generate graph for event ${fqn}`);
389
+ }
387
390
  }
388
391
  const oldModuleName = env.switchActiveModuleName(eventInstance.moduleName);
389
392
  env.bind(eventInstance.name, eventInstance);
390
393
  try {
391
- await executeGraph(g, env);
394
+ if (g) {
395
+ await executeGraph(g, env);
396
+ } else {
397
+ await handleAgentInvocation(eventInstance, env);
398
+ }
392
399
  if (isLocalEnv) {
393
400
  await env.commitAllTransactions();
394
401
  }
@@ -65,7 +65,7 @@ import {
65
65
  Path,
66
66
  QuerySuffix,
67
67
  restoreSpecialChars,
68
- splitFqName,
68
+ nameToPath,
69
69
  splitRefs,
70
70
  } from './util.js';
71
71
  import { getResolver, getResolverNameForPath } from './resolvers/registry.js';
@@ -275,7 +275,26 @@ export class Environment extends Instance {
275
275
  if (this.scratchPad == undefined) {
276
276
  this.scratchPad = {};
277
277
  }
278
+ if (isFqName(k)) {
279
+ const parts = nameToPath(k);
280
+ this.scratchPad[parts.getEntryName()] = data;
281
+ }
278
282
  this.scratchPad[k] = data;
283
+ return this.addAttributesToScratchPad(data);
284
+ }
285
+
286
+ private addAttributesToScratchPad(data: any): Environment {
287
+ if (data instanceof Map) {
288
+ data.forEach((v: any, k: any) => {
289
+ this.addToScratchPad(k as string, v);
290
+ });
291
+ } else if (data instanceof Array) {
292
+ return this;
293
+ } else if (data instanceof Object) {
294
+ Object.keys(data).forEach((k: string) => {
295
+ this.addToScratchPad(k, data[k]);
296
+ });
297
+ }
279
298
  return this;
280
299
  }
281
300
 
@@ -1045,7 +1064,7 @@ async function evaluateFullTextSearch(fts: FullTextSearch, env: Environment): Pr
1045
1064
  throw new Error(`Fully qualified name required for full-text-search in ${n}`);
1046
1065
  }
1047
1066
  }
1048
- const path = splitFqName(n);
1067
+ const path = nameToPath(n);
1049
1068
  const entryName = path.getEntryName();
1050
1069
  const moduleName = path.getModuleName();
1051
1070
  const resolver = await getResolverForPath(entryName, moduleName, env);
@@ -1152,7 +1171,7 @@ async function patternToInstance(
1152
1171
  }
1153
1172
  let moduleName = env.getActiveModuleName();
1154
1173
  if (isFqName(entryName)) {
1155
- const p: Path = splitFqName(entryName);
1174
+ const p: Path = nameToPath(entryName);
1156
1175
  if (p.hasModule()) moduleName = p.getModuleName();
1157
1176
  if (p.hasEntry()) entryName = p.getEntryName();
1158
1177
  }
@@ -1165,7 +1184,7 @@ async function instanceFromSource(crud: CrudMap, env: Environment): Promise<Inst
1165
1184
  const attrsSrc = env.getLastResult();
1166
1185
  if (attrsSrc && attrsSrc instanceof Object) {
1167
1186
  const attrs: InstanceAttributes = new Map(Object.entries(attrsSrc));
1168
- const nparts = splitFqName(crud.name);
1187
+ const nparts = nameToPath(crud.name);
1169
1188
  const n = nparts.getEntryName();
1170
1189
  const m = nparts.hasModule() ? nparts.getModuleName() : env.getActiveModuleName();
1171
1190
  return makeInstance(m, n, attrs);
@@ -1443,7 +1462,7 @@ function triggerTimer(timerInst: Instance): Instance {
1443
1462
  break;
1444
1463
  }
1445
1464
  }
1446
- const eventName = splitFqName(timerInst.lookup('trigger'));
1465
+ const eventName = nameToPath(timerInst.lookup('trigger'));
1447
1466
  const m = eventName.hasModule() ? eventName.getModuleName() : timerInst.moduleName;
1448
1467
  const n = eventName.getEntryName();
1449
1468
  const inst = makeInstance(m, n, newInstanceAttributes());
@@ -1505,7 +1524,31 @@ async function evaluateJoinQuery(
1505
1524
  }
1506
1525
  const resolver = await getResolverForPath(inst.name, moduleName, env);
1507
1526
  const result: Result = await resolver.queryByJoin(inst, joinsSpec, normIntoSpec, distinct);
1508
- env.setLastResult(result);
1527
+
1528
+ const transformedResult = transformDateFieldsInJoinResult(result);
1529
+
1530
+ env.setLastResult(transformedResult);
1531
+ }
1532
+
1533
+ function transformDateFieldsInJoinResult(result: any): any {
1534
+ if (!result || !Array.isArray(result)) {
1535
+ return result;
1536
+ }
1537
+ return result.map((row: any) => {
1538
+ if (typeof row !== 'object' || row === null) {
1539
+ return row;
1540
+ }
1541
+
1542
+ for (const [key, value] of Object.entries(row)) {
1543
+ if (value && value instanceof Date) {
1544
+ if (value instanceof Date) {
1545
+ row[key] = value.toLocaleDateString('en-CA');
1546
+ }
1547
+ }
1548
+ }
1549
+
1550
+ return row;
1551
+ });
1509
1552
  }
1510
1553
 
1511
1554
  async function walkJoinQueryPattern(
@@ -1538,13 +1581,8 @@ const MAX_PLANNER_RETRIES = 3;
1538
1581
 
1539
1582
  async function agentInvoke(agent: AgentInstance, msg: string, env: Environment): Promise<void> {
1540
1583
  const flowContext = env.getFlowContext();
1541
- msg = flowContext ? `context: ${flowContext}\n${msg}` : msg;
1584
+ msg = flowContext ? `${msg}\nContext:\n${flowContext}` : msg;
1542
1585
 
1543
- const scratchPad = env.getScratchPad();
1544
- if (scratchPad) {
1545
- const spad = JSON.stringify(scratchPad);
1546
- msg = `${msg}\nScratchpad:\n${spad}`;
1547
- }
1548
1586
  // log invocation details
1549
1587
  let invokeDebugMsg = `\nInvoking agent ${agent.name}:`;
1550
1588
  if (agent.role) {
@@ -1599,7 +1637,10 @@ async function agentInvoke(agent: AgentInstance, msg: string, env: Environment):
1599
1637
  break;
1600
1638
  } catch (err: any) {
1601
1639
  if (retries < MAX_PLANNER_RETRIES) {
1602
- await agent.invoke(`Please fix these errors:\n ${err}`, env);
1640
+ await agent.invoke(
1641
+ `For my previouns request <${msg}>, you generated this pattern: ${result}. It had these errors: ${err}. Please fix these errors.`,
1642
+ env
1643
+ );
1603
1644
  const r: string | undefined = env.getLastResult();
1604
1645
  result = r;
1605
1646
  ++retries;
@@ -1708,12 +1749,14 @@ async function iterateOnFlow(
1708
1749
  env: Environment
1709
1750
  ): Promise<void> {
1710
1751
  rootAgent.disableSession();
1711
- const s = `Now consider the following flowchart and context:\n${flow}\n\nInitial context: ${msg}\n\n
1752
+ const initContext = msg;
1753
+ const s = `Now consider the following flowchart:\n${flow}\n
1712
1754
  If you understand from the context that a step with no further possible steps has been evaluated,
1713
1755
  terminate the flowchart by returning DONE. Never return to the top or root step of the flowchart, instead return DONE.\n`;
1756
+ env.setFlowContext(initContext);
1714
1757
  await agentInvoke(rootAgent, s, env);
1715
1758
  let step = env.getLastResult().trim();
1716
- let context = msg;
1759
+ let context = initContext;
1717
1760
  let stepc = 0;
1718
1761
  const iterId = crypto.randomUUID();
1719
1762
  console.debug(`Starting iteration ${iterId} on flow: ${flow}`);
@@ -1724,15 +1767,15 @@ async function iterateOnFlow(
1724
1767
  }
1725
1768
  executedSteps.add(step);
1726
1769
  ++stepc;
1727
- const agent = AgentInstance.FromFlowStep(step, rootAgent);
1770
+ const agent = AgentInstance.FromFlowStep(step, rootAgent, context);
1728
1771
  console.debug(`\n---------------------------------------------------\n`);
1729
1772
  console.debug(
1730
1773
  `Starting to execute flow step ${step} with agent ${agent.name} with iteration ID ${iterId} and context: \n${context}`
1731
1774
  );
1732
- agent.disableSession();
1733
- env.setFlowContext(context);
1775
+ const isfxc = agent.isFlowExecutor();
1776
+ if (isfxc || agent.isDecisionExecutor()) env.setFlowContext(context);
1777
+ else env.setFlowContext(initContext);
1734
1778
  await agentInvoke(agent, '', env);
1735
- env.resetFlowContext();
1736
1779
  if (env.isSuspended()) {
1737
1780
  console.debug(`${iterId} suspending iteration on step ${step}`);
1738
1781
  await saveFlowSuspension(rootAgent, context, step, env);
@@ -1744,9 +1787,14 @@ async function iterateOnFlow(
1744
1787
  console.debug(
1745
1788
  `\n----> Completed execution of step ${step}, iteration id ${iterId} with result:\n${rs}`
1746
1789
  );
1747
- context = `${context}\nExecuted steps: ${[...executedSteps].join(', ')}`;
1748
- await agentInvoke(rootAgent, `${s}\n${context}`, env);
1749
- step = env.getLastResult().trim();
1790
+ context = `${context}\n${step} --> ${rs}\n`;
1791
+ if (isfxc) {
1792
+ step = rs.trim();
1793
+ } else {
1794
+ env.setFlowContext(context);
1795
+ await agentInvoke(rootAgent, `${s}\n${context}`, env);
1796
+ step = env.getLastResult().trim();
1797
+ }
1750
1798
  }
1751
1799
  console.debug(`No more flow steps, completed iteration ${iterId} on flow:\n${flow}`);
1752
1800
  }
@@ -1894,7 +1942,7 @@ export async function evaluateExpression(expr: Expr, env: Environment): Promise<
1894
1942
  result = v1 / v2;
1895
1943
  break;
1896
1944
  // comparison operators
1897
- case '=':
1945
+ case '==':
1898
1946
  result = v1 == v2;
1899
1947
  break;
1900
1948
  case '<':
@@ -2042,7 +2090,7 @@ async function runPrePostEvents(
2042
2090
  ? inst.record.getPreTriggerInfo(crudType)
2043
2091
  : inst.record.getPostTriggerInfo(crudType);
2044
2092
  if (trigInfo) {
2045
- const p = splitFqName(trigInfo.eventName);
2093
+ const p = nameToPath(trigInfo.eventName);
2046
2094
  const moduleName = p.hasModule() ? p.getModuleName() : inst.record.moduleName;
2047
2095
  const eventInst: Instance = makeInstance(
2048
2096
  moduleName,
@@ -2063,20 +2111,22 @@ async function runPrePostEvents(
2063
2111
  }
2064
2112
  };
2065
2113
  if (trigInfo.async) {
2066
- const newEnv = new Environment('async.prepost.env');
2067
- evaluate(eventInst, callback, bindAliasesForPrePost(newEnv, inst)).catch(catchHandler);
2114
+ evaluate(eventInst, callback, bindAliasesForPrePost(env, inst, prefix)).catch(catchHandler);
2068
2115
  } else {
2069
- env.bind('this', inst);
2070
- await evaluate(eventInst, callback, bindAliasesForPrePost(env, inst)).catch(catchHandler);
2116
+ await evaluate(eventInst, callback, bindAliasesForPrePost(env, inst, prefix)).catch(
2117
+ catchHandler
2118
+ );
2071
2119
  }
2072
2120
  }
2073
2121
  }
2074
2122
 
2075
- function bindAliasesForPrePost(env: Environment, inst: Instance): Environment {
2123
+ function bindAliasesForPrePost(env: Environment, inst: Instance, prefix: string): Environment {
2124
+ const newEnv = new Environment(`${prefix}.env`, env);
2076
2125
  const fullAlias = inst.getFqName();
2077
- env.bind('this', inst);
2078
- env.bind(fullAlias, inst);
2079
- return env;
2126
+ newEnv.bind('this', inst);
2127
+ newEnv.bind(fullAlias, inst);
2128
+ newEnv.bind(inst.name, inst);
2129
+ return newEnv;
2080
2130
  }
2081
2131
 
2082
2132
  async function runPreCreateEvents(inst: Instance, env: Environment) {
@@ -30,6 +30,9 @@ import {
30
30
  FlowDefinition,
31
31
  isFlowDefinition,
32
32
  Literal,
33
+ isDecisionDefinition,
34
+ DecisionDefinition,
35
+ CaseEntry,
33
36
  } from '../language/generated/ast.js';
34
37
  import {
35
38
  addEntity,
@@ -65,7 +68,13 @@ import { URI } from 'vscode-uri';
65
68
  import { AstNode, LangiumCoreServices, LangiumDocument } from 'langium';
66
69
  import { isNodeEnv, path } from '../utils/runtime.js';
67
70
  import { CoreModules, registerCoreModules } from './modules/core.js';
68
- import { maybeGetValidationErrors, parse, parseModule, parseWorkflow } from '../language/parser.js';
71
+ import {
72
+ maybeGetValidationErrors,
73
+ maybeRaiseParserErrors,
74
+ parse,
75
+ parseModule,
76
+ parseWorkflow,
77
+ } from '../language/parser.js';
69
78
  import { logger } from './logger.js';
70
79
  import { Environment, evaluateStatements, GlobalEnvironment } from './interpreter.js';
71
80
  import { createPermission, createRole } from './modules/auth.js';
@@ -621,7 +630,7 @@ async function addAgentDefinition(def: AgentDefinition, moduleName: string) {
621
630
  } else if (apdef.name == 'glossary') {
622
631
  glossary = processAgentGlossary(name, apdef.value);
623
632
  } else if (apdef.name == 'responseSchema') {
624
- const s = apdef.value.id || apdef.value.str || apdef.value.id;
633
+ const s = apdef.value.id || apdef.value.ref || apdef.value.str;
625
634
  if (s) {
626
635
  if (isFqName(s)) {
627
636
  responseSchema = s;
@@ -755,6 +764,16 @@ function addFlowDefinition(def: FlowDefinition, moduleName: string) {
755
764
  }
756
765
  }
757
766
 
767
+ function addDecisionDefinition(def: DecisionDefinition, moduleName: string) {
768
+ if (def.body) {
769
+ const m = fetchModule(moduleName);
770
+ const cases = def.body.cases.map((ce: CaseEntry) => {
771
+ return ce.$cstNode?.text;
772
+ });
773
+ m.addDecision(def.name, cases as string[]);
774
+ }
775
+ }
776
+
758
777
  function addResolverDefinition(def: ResolverDefinition, moduleName: string) {
759
778
  const resolverName = `${moduleName}/${def.name}`;
760
779
  const paths = def.paths;
@@ -814,6 +833,7 @@ export async function addFromDef(def: Definition, moduleName: string) {
814
833
  else if (isStandaloneStatement(def)) addStandaloneStatement(def.stmt, moduleName);
815
834
  else if (isResolverDefinition(def)) addResolverDefinition(def, moduleName);
816
835
  else if (isFlowDefinition(def)) addFlowDefinition(def, moduleName);
836
+ else if (isDecisionDefinition(def)) addDecisionDefinition(def, moduleName);
817
837
  }
818
838
 
819
839
  export async function parseAndIntern(code: string, moduleName?: string) {
@@ -821,12 +841,7 @@ export async function parseAndIntern(code: string, moduleName?: string) {
821
841
  throw new Error(`Module not found - ${moduleName}`);
822
842
  }
823
843
  const r = await parse(moduleName ? `module ${moduleName} ${code}` : code);
824
- if (r.parseResult.lexerErrors.length > 0) {
825
- throw new Error(`Lexer errors: ${r.parseResult.lexerErrors.join('\n')}`);
826
- }
827
- if (r.parseResult.parserErrors.length > 0) {
828
- throw new Error(`Parser errors: ${r.parseResult.parserErrors.join('\n')}`);
829
- }
844
+ maybeRaiseParserErrors(r);
830
845
  await internModule(r.parseResult.value);
831
846
  }
832
847