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.
- package/out/api/http.js +3 -3
- package/out/api/http.js.map +1 -1
- package/out/language/agentlang-validator.d.ts.map +1 -1
- package/out/language/agentlang-validator.js +3 -1
- package/out/language/agentlang-validator.js.map +1 -1
- package/out/language/generated/ast.d.ts +35 -9
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +40 -1
- package/out/language/generated/ast.js.map +1 -1
- package/out/language/generated/grammar.d.ts.map +1 -1
- package/out/language/generated/grammar.js +289 -120
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +323 -122
- package/out/language/main.cjs.map +2 -2
- package/out/language/parser.d.ts +1 -0
- package/out/language/parser.d.ts.map +1 -1
- package/out/language/parser.js +14 -13
- package/out/language/parser.js.map +1 -1
- package/out/runtime/agents/common.d.ts +2 -1
- package/out/runtime/agents/common.d.ts.map +1 -1
- package/out/runtime/agents/common.js +42 -3
- package/out/runtime/agents/common.js.map +1 -1
- package/out/runtime/exec-graph.d.ts.map +1 -1
- package/out/runtime/exec-graph.js +15 -7
- package/out/runtime/exec-graph.js.map +1 -1
- package/out/runtime/interpreter.d.ts +1 -0
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +76 -32
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +16 -9
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/module.d.ts +15 -0
- package/out/runtime/module.d.ts.map +1 -1
- package/out/runtime/module.js +96 -24
- package/out/runtime/module.js.map +1 -1
- package/out/runtime/modules/ai.d.ts +7 -3
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +85 -22
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/resolvers/interface.js +2 -2
- package/out/runtime/resolvers/interface.js.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.js +2 -2
- package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
- package/out/runtime/util.d.ts +2 -1
- package/out/runtime/util.d.ts.map +1 -1
- package/out/runtime/util.js +4 -1
- package/out/runtime/util.js.map +1 -1
- package/out/syntaxes/agentlang.monarch.js +3 -3
- package/out/syntaxes/agentlang.monarch.js.map +1 -1
- package/package.json +8 -6
- package/src/api/http.ts +3 -3
- package/src/language/agentlang-validator.ts +3 -1
- package/src/language/agentlang.langium +8 -2
- package/src/language/generated/ast.ts +80 -9
- package/src/language/generated/grammar.ts +289 -120
- package/src/language/parser.ts +15 -14
- package/src/runtime/agents/common.ts +43 -3
- package/src/runtime/exec-graph.ts +14 -7
- package/src/runtime/interpreter.ts +82 -32
- package/src/runtime/loader.ts +23 -8
- package/src/runtime/module.ts +111 -22
- package/src/runtime/modules/ai.ts +97 -23
- package/src/runtime/resolvers/interface.ts +2 -2
- package/src/runtime/resolvers/sqldb/impl.ts +2 -2
- package/src/runtime/util.ts +5 -1
- package/src/syntaxes/agentlang.monarch.ts +3 -3
package/src/language/parser.ts
CHANGED
|
@@ -132,34 +132,35 @@ export function maybeGetValidationErrors(document: LangiumDocument): string[] |
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
function maybeRaiseParserErrors(document: LangiumDocument) {
|
|
136
|
-
|
|
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: ${
|
|
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 (
|
|
145
|
+
if (document.parseResult.parserErrors.length > 0) {
|
|
155
146
|
throw new Error(
|
|
156
|
-
`Parser errors: ${
|
|
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
|
|
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
|
|
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,
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
385
|
-
if (!
|
|
386
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 ?
|
|
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(
|
|
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
|
|
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 =
|
|
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.
|
|
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}\
|
|
1748
|
-
|
|
1749
|
-
|
|
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 =
|
|
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
|
-
|
|
2067
|
-
evaluate(eventInst, callback, bindAliasesForPrePost(newEnv, inst)).catch(catchHandler);
|
|
2114
|
+
evaluate(eventInst, callback, bindAliasesForPrePost(env, inst, prefix)).catch(catchHandler);
|
|
2068
2115
|
} else {
|
|
2069
|
-
|
|
2070
|
-
|
|
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
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
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) {
|
package/src/runtime/loader.ts
CHANGED
|
@@ -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 {
|
|
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.
|
|
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
|
-
|
|
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
|
|