agentlang 0.0.10 → 0.0.11
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/language/generated/ast.d.ts +11 -2
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +15 -2
- 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 +162 -119
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +174 -121
- package/out/language/main.cjs.map +2 -2
- package/out/language/syntax.js +2 -2
- package/out/language/syntax.js.map +1 -1
- package/out/runtime/agents/common.d.ts +1 -1
- package/out/runtime/agents/common.d.ts.map +1 -1
- package/out/runtime/agents/common.js +10 -10
- package/out/runtime/interpreter.d.ts +6 -0
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +26 -0
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/jsmodules.js +1 -1
- package/out/runtime/jsmodules.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +5 -2
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/modules/ai.js +1 -1
- package/out/runtime/modules/auth.d.ts.map +1 -1
- package/out/runtime/modules/auth.js +21 -16
- package/out/runtime/modules/auth.js.map +1 -1
- package/out/runtime/modules/core.d.ts +3 -1
- package/out/runtime/modules/core.d.ts.map +1 -1
- package/out/runtime/modules/core.js +30 -3
- package/out/runtime/modules/core.js.map +1 -1
- package/out/syntaxes/agentlang.monarch.js +1 -1
- package/out/syntaxes/agentlang.monarch.js.map +1 -1
- package/package.json +1 -1
- package/src/language/agentlang.langium +7 -5
- package/src/language/generated/ast.ts +29 -5
- package/src/language/generated/grammar.ts +162 -119
- package/src/language/syntax.ts +2 -2
- package/src/runtime/agents/common.ts +10 -10
- package/src/runtime/interpreter.ts +29 -0
- package/src/runtime/jsmodules.ts +1 -1
- package/src/runtime/loader.ts +4 -1
- package/src/runtime/modules/ai.ts +1 -1
- package/src/runtime/modules/auth.ts +21 -17
- package/src/runtime/modules/core.ts +38 -3
- package/src/syntaxes/agentlang.monarch.ts +1 -1
package/src/language/syntax.ts
CHANGED
|
@@ -39,9 +39,9 @@ export class BasePattern {
|
|
|
39
39
|
|
|
40
40
|
private aliasesAsString(): string | undefined {
|
|
41
41
|
if (this.alias) {
|
|
42
|
-
return ` as ${this.alias}`;
|
|
42
|
+
return ` @as ${this.alias}`;
|
|
43
43
|
} else if (this.aliases) {
|
|
44
|
-
return ` as [${this.aliases.join(',')}]`;
|
|
44
|
+
return ` @as [${this.aliases.join(',')}]`;
|
|
45
45
|
} else {
|
|
46
46
|
return undefined;
|
|
47
47
|
}
|
|
@@ -92,24 +92,24 @@ Note the value passed to the 'salary' attribute - it's an arithmetic expression.
|
|
|
92
92
|
A successful query pattern will return an array of instances. The 'for' pattern can be used to iterate over an array. An example follows:
|
|
93
93
|
|
|
94
94
|
workflow NotifyEmployees {
|
|
95
|
-
{Erp/Employee {salary?> 1000}} as employees;
|
|
95
|
+
{Erp/Employee {salary?> 1000}} @as employees;
|
|
96
96
|
for emp in employees {
|
|
97
97
|
{Erp/SendMail {email emp.email, body "You are selected for an increment!"}}
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
Also note the use of the 'as' keyword - this binds the result of a pattern to an 'alias'. Here the result of the query is bound to the
|
|
101
|
+
Also note the use of the '@as' keyword - this binds the result of a pattern to an 'alias'. Here the result of the query is bound to the
|
|
102
102
|
alias named 'employees'. Any pattern can have an alias, including 'if' and 'for'. An alias can be used to refer to the attributes of the instance,
|
|
103
103
|
via the dot(.) notation. Aliases can also be used to destructure a query result - here's an example:
|
|
104
104
|
|
|
105
105
|
workflow FindFirstTwoEmployees {
|
|
106
|
-
{Erp/Employee {salary?> 1000}} as [emp1, emp2];
|
|
106
|
+
{Erp/Employee {salary?> 1000}} @as [emp1, emp2];
|
|
107
107
|
[emp1, emp2]
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
This alias will bind the first two instances to 'a' and 'b' and the rest of the instances to an array named 'xs':
|
|
111
111
|
|
|
112
|
-
{SomeEntity {id?> 1}} as [a, b, _, xs]
|
|
112
|
+
{SomeEntity {id?> 1}} @as [a, b, _, xs]
|
|
113
113
|
|
|
114
114
|
Examples of binding aliases to 'if' and 'for':
|
|
115
115
|
|
|
@@ -117,11 +117,11 @@ if (IncrementSalary.percentage > 10) {
|
|
|
117
117
|
{Erp/Employee {employeeId IncrementSalary.employeeId, salary salary + salary * IncrementSalary.percentage}}
|
|
118
118
|
} else {
|
|
119
119
|
{Erp/Employee {employeeId IncrementSalary.employeeId, salary salary + 1500}}
|
|
120
|
-
} as emp
|
|
120
|
+
} @as emp
|
|
121
121
|
|
|
122
122
|
for emp in employees {
|
|
123
123
|
{Erp/SendMail {email emp.email, body "You are selected for an increment!"}}
|
|
124
|
-
} as emails
|
|
124
|
+
} @as emails
|
|
125
125
|
|
|
126
126
|
Make sure all references based on a preceding pattern is based either on an actual alias or the name of the workflow. For example, the following sequence of patterns
|
|
127
127
|
are invalid, because the alias 'employee' is not defined:
|
|
@@ -131,7 +131,7 @@ are invalid, because the alias 'employee' is not defined:
|
|
|
131
131
|
|
|
132
132
|
A fix for the reference-error is shown below:
|
|
133
133
|
|
|
134
|
-
{Employee {id? 101}} as employee;
|
|
134
|
+
{Employee {id? 101}} @as employee;
|
|
135
135
|
{SendEmail {to employee.email, body "hello"}}
|
|
136
136
|
|
|
137
137
|
Entities in a module can be connected together in relationships. There are two types of relationships - 'contains' and 'between'.
|
|
@@ -198,7 +198,7 @@ fill-in values from the available context. For example, if your instruction is "
|
|
|
198
198
|
'please call me as soon as possible'", the best workflow to return is:
|
|
199
199
|
|
|
200
200
|
workflow sendEmail {
|
|
201
|
-
{employee {id? 101}} as emp;
|
|
201
|
+
{employee {id? 101}} @as emp;
|
|
202
202
|
{email {to emp.email body "please call me as soon as possible"}}
|
|
203
203
|
}
|
|
204
204
|
|
|
@@ -206,7 +206,7 @@ because all the information needed is available in the context. If the instructi
|
|
|
206
206
|
'please call me as soon as possible'", then you can return:
|
|
207
207
|
|
|
208
208
|
workflow sendEmail {
|
|
209
|
-
{employee {id? sendEmail.employeeId}} as emp;
|
|
209
|
+
{employee {id? sendEmail.employeeId}} @as emp;
|
|
210
210
|
{email {to emp.email body "please call me as soon as possible"}}
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -215,7 +215,7 @@ The point is use the immediate context to fill-in values in generated patterns,
|
|
|
215
215
|
Also generate a workflow only if required explicitly by the user or the contextual information is incomplete. Otherwise, just return an array of patterns.
|
|
216
216
|
As an example, if the user request is "send an email to employee 101 with this message - 'please call me as soon as possible'", you must return:
|
|
217
217
|
|
|
218
|
-
[{employee {id? 101}} as emp;
|
|
218
|
+
[{employee {id? 101}} @as emp;
|
|
219
219
|
{email {to emp.email, body "please call me as soon as possible"}}]
|
|
220
220
|
|
|
221
221
|
Note that each pattern in the array is separated by a ; and not a comma(,).
|
|
@@ -114,6 +114,7 @@ export class Environment extends Instance {
|
|
|
114
114
|
private activeUser: string = AdminUserId;
|
|
115
115
|
private activeUserSet: boolean = false;
|
|
116
116
|
private lastResult: Result;
|
|
117
|
+
private returnFlag: boolean = false;
|
|
117
118
|
private parentPath: string | undefined;
|
|
118
119
|
private normalizedParentPath: string | undefined;
|
|
119
120
|
private betweenRelInfo: BetweenRelInfo | undefined;
|
|
@@ -222,6 +223,17 @@ export class Environment extends Instance {
|
|
|
222
223
|
return this;
|
|
223
224
|
}
|
|
224
225
|
|
|
226
|
+
static SuspensionUserData = '^';
|
|
227
|
+
|
|
228
|
+
bindSuspensionUserData(userData: string): Environment {
|
|
229
|
+
this.bind(Environment.SuspensionUserData, userData);
|
|
230
|
+
return this;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
lookupSuspensionUserData(): string | undefined {
|
|
234
|
+
return this.lookup(Environment.SuspensionUserData);
|
|
235
|
+
}
|
|
236
|
+
|
|
225
237
|
maybeLookupAgentInstance(entryName: string): Instance | undefined {
|
|
226
238
|
const v = this.lookup(entryName);
|
|
227
239
|
if (v && isInstanceOfType(v, AgentFqName)) {
|
|
@@ -263,6 +275,18 @@ export class Environment extends Instance {
|
|
|
263
275
|
}
|
|
264
276
|
}
|
|
265
277
|
|
|
278
|
+
markForReturn(): Environment {
|
|
279
|
+
if (this.parent) {
|
|
280
|
+
this.parent.markForReturn();
|
|
281
|
+
}
|
|
282
|
+
this.returnFlag = true;
|
|
283
|
+
return this;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
isMarkedForReturn(): boolean {
|
|
287
|
+
return this.returnFlag;
|
|
288
|
+
}
|
|
289
|
+
|
|
266
290
|
protected propagateSuspension(suspId: string) {
|
|
267
291
|
this.suspensionId = suspId;
|
|
268
292
|
if (this.parent) {
|
|
@@ -597,6 +621,8 @@ export async function evaluateStatements(
|
|
|
597
621
|
env.setLastResult({ suspension: suspId || 'null' });
|
|
598
622
|
break;
|
|
599
623
|
}
|
|
624
|
+
} else if (env.isMarkedForReturn()) {
|
|
625
|
+
break;
|
|
600
626
|
}
|
|
601
627
|
}
|
|
602
628
|
if (continuation != undefined) {
|
|
@@ -735,6 +761,9 @@ async function evaluatePattern(pat: Pattern, env: Environment): Promise<void> {
|
|
|
735
761
|
await evaluatePurge(pat.purge, env);
|
|
736
762
|
} else if (pat.fullTextSearch) {
|
|
737
763
|
await evaluateFullTextSearch(pat.fullTextSearch, env);
|
|
764
|
+
} else if (pat.return) {
|
|
765
|
+
await evaluatePattern(pat.return.pat, env);
|
|
766
|
+
env.markForReturn();
|
|
738
767
|
}
|
|
739
768
|
}
|
|
740
769
|
|
package/src/runtime/jsmodules.ts
CHANGED
|
@@ -17,7 +17,7 @@ export async function importModule(path: string, name: string, moduleFileName?:
|
|
|
17
17
|
}
|
|
18
18
|
path = `${s}${sep}${path}`;
|
|
19
19
|
}
|
|
20
|
-
if (
|
|
20
|
+
if ((path.startsWith(sep) || path.startsWith('.')) && moduleFileName) {
|
|
21
21
|
path = process.cwd() + sep + path;
|
|
22
22
|
}
|
|
23
23
|
const m = await import(/* @vite-ignore */ path);
|
package/src/runtime/loader.ts
CHANGED
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
addAgent,
|
|
46
46
|
} from './module.js';
|
|
47
47
|
import {
|
|
48
|
+
escapeSpecialChars,
|
|
48
49
|
findRbacSchema,
|
|
49
50
|
isString,
|
|
50
51
|
makeFqName,
|
|
@@ -446,8 +447,10 @@ async function addAgentDefinition(def: AgentDefinition, moduleName: string) {
|
|
|
446
447
|
hasUserLlm = true;
|
|
447
448
|
}
|
|
448
449
|
const ov = v;
|
|
449
|
-
if (apdef.value.
|
|
450
|
+
if (apdef.value.id || apdef.value.array) {
|
|
450
451
|
v = `"${v}"`;
|
|
452
|
+
} else if (apdef.value.str) {
|
|
453
|
+
v = `"${escapeSpecialChars(v)}"`;
|
|
451
454
|
}
|
|
452
455
|
attrsStrs.push(`${apdef.name} ${v}`);
|
|
453
456
|
attrs.set(apdef.name, ov);
|
|
@@ -29,7 +29,7 @@ export const CoreAuthModuleName = makeCoreModuleName('auth');
|
|
|
29
29
|
|
|
30
30
|
export default `module ${CoreAuthModuleName}
|
|
31
31
|
|
|
32
|
-
import "./modules/auth.js" as Auth
|
|
32
|
+
import "./modules/auth.js" @as Auth
|
|
33
33
|
|
|
34
34
|
entity User {
|
|
35
35
|
id UUID @id @default(uuid()),
|
|
@@ -52,12 +52,12 @@ workflow CreateUser {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
workflow FindUser {
|
|
55
|
-
{User {id? FindUser.id}} as [user];
|
|
55
|
+
{User {id? FindUser.id}} @as [user];
|
|
56
56
|
user
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
workflow FindUserByEmail {
|
|
60
|
-
{User {email? FindUserByEmail.email}} as [user];
|
|
60
|
+
{User {email? FindUserByEmail.email}} @as [user];
|
|
61
61
|
user
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -83,19 +83,19 @@ workflow CreateRole {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
workflow FindRole {
|
|
86
|
-
{Role {name? FindRole.name}} as [role];
|
|
86
|
+
{Role {name? FindRole.name}} @as [role];
|
|
87
87
|
role
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
workflow AssignUserToRole {
|
|
91
|
-
{User {id? AssignUserToRole.userId}} as [user];
|
|
92
|
-
{Role {name? AssignUserToRole.roleName}} as [role];
|
|
91
|
+
{User {id? AssignUserToRole.userId}} @as [user];
|
|
92
|
+
{Role {name? AssignUserToRole.roleName}} @as [role];
|
|
93
93
|
{UserRole {User user, Role role}, @upsert}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
workflow AssignUserToRoleByEmail {
|
|
97
|
-
{User {email? AssignUserToRoleByEmail.email}} as [user];
|
|
98
|
-
{Role {name? AssignUserToRoleByEmail.roleName}} as [role];
|
|
97
|
+
{User {email? AssignUserToRoleByEmail.email}} @as [user];
|
|
98
|
+
{Role {name? AssignUserToRoleByEmail.roleName}} @as [role];
|
|
99
99
|
{UserRole {User user, Role role}, @upsert}
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -116,8 +116,8 @@ workflow CreatePermission {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
workflow AddPermissionToRole {
|
|
119
|
-
{Role {name? AddPermissionToRole.roleName}} as role;
|
|
120
|
-
{Permission {id? AddPermissionToRole.permissionId}} as perm;
|
|
119
|
+
{Role {name? AddPermissionToRole.roleName}} @as role;
|
|
120
|
+
{Permission {id? AddPermissionToRole.permissionId}} @as perm;
|
|
121
121
|
{RolePermission {Role role, Permission perm}, @upsert}
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -154,12 +154,12 @@ workflow UpdateSession {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
workflow FindSession {
|
|
157
|
-
{Session {id? FindSession.id}} as [session];
|
|
157
|
+
{Session {id? FindSession.id}} @as [session];
|
|
158
158
|
session
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
workflow FindUserSession {
|
|
162
|
-
{Session {userId? FindUserSession.userId}} as [session];
|
|
162
|
+
{Session {userId? FindUserSession.userId}} @as [session];
|
|
163
163
|
session
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -168,7 +168,7 @@ workflow RemoveSession {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
workflow RemoveUserSession {
|
|
171
|
-
{Session {userId? RemoveUserSession.id}} as [session];
|
|
171
|
+
{Session {userId? RemoveUserSession.id}} @as [session];
|
|
172
172
|
purge {Session {id? session.id}}
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -837,10 +837,14 @@ export async function refreshUserToken(refreshToken: string, env: Environment):
|
|
|
837
837
|
}
|
|
838
838
|
|
|
839
839
|
export function requireAuth(moduleName: string, eventName: string): boolean {
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
840
|
+
if (isAuthEnabled()) {
|
|
841
|
+
const f =
|
|
842
|
+
moduleName == CoreAuthModuleName &&
|
|
843
|
+
(eventName == 'login' || eventName == 'signup' || eventName == 'refreshToken');
|
|
844
|
+
return !f;
|
|
845
|
+
} else {
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
844
848
|
}
|
|
845
849
|
|
|
846
850
|
// Export getHttpStatusForError for use in HTTP handlers
|
|
@@ -11,10 +11,12 @@ import {
|
|
|
11
11
|
import { logger } from '../logger.js';
|
|
12
12
|
import { Statement } from '../../language/generated/ast.js';
|
|
13
13
|
import { parseStatements } from '../../language/parser.js';
|
|
14
|
+
import { Resolver } from '../resolvers/interface.js';
|
|
15
|
+
import { PathAttributeName } from '../defs.js';
|
|
14
16
|
|
|
15
17
|
const CoreModuleDefinition = `module ${DefaultModuleName}
|
|
16
18
|
|
|
17
|
-
import "./modules/core.js" as Core
|
|
19
|
+
import "./modules/core.js" @as Core
|
|
18
20
|
|
|
19
21
|
entity timer {
|
|
20
22
|
name String @id,
|
|
@@ -42,6 +44,14 @@ entity suspension {
|
|
|
42
44
|
createdBy String
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
entity activeSuspension {
|
|
48
|
+
id UUID @id
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
resolver servicenow ["${DefaultModuleName}/activeSuspension"] {
|
|
52
|
+
query Core.lookupActiveSuspension
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
workflow createSuspension {
|
|
46
56
|
{suspension
|
|
47
57
|
{id createSuspension.id
|
|
@@ -51,7 +61,7 @@ workflow createSuspension {
|
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
workflow restartSuspension {
|
|
54
|
-
await Core.restartSuspension(restartSuspension.id)
|
|
64
|
+
await Core.restartSuspension(restartSuspension.id, restartSuspension.data)
|
|
55
65
|
}
|
|
56
66
|
`;
|
|
57
67
|
export const CoreModules: string[] = [];
|
|
@@ -191,9 +201,14 @@ async function deleteSuspension(suspId: string, env?: Environment): Promise<any>
|
|
|
191
201
|
}
|
|
192
202
|
}
|
|
193
203
|
|
|
194
|
-
export async function restartSuspension(
|
|
204
|
+
export async function restartSuspension(
|
|
205
|
+
suspId: string,
|
|
206
|
+
userData: string,
|
|
207
|
+
env?: Environment
|
|
208
|
+
): Promise<any> {
|
|
195
209
|
const susp = await loadSuspension(suspId, env);
|
|
196
210
|
if (susp) {
|
|
211
|
+
susp.env.bindSuspensionUserData(userData);
|
|
197
212
|
await evaluateStatements(susp.continuation, susp.env);
|
|
198
213
|
await deleteSuspension(suspId, env);
|
|
199
214
|
return susp.env.getLastResult();
|
|
@@ -202,3 +217,23 @@ export async function restartSuspension(suspId: string, env?: Environment): Prom
|
|
|
202
217
|
return undefined;
|
|
203
218
|
}
|
|
204
219
|
}
|
|
220
|
+
|
|
221
|
+
export async function lookupActiveSuspension(
|
|
222
|
+
resolver: Resolver,
|
|
223
|
+
inst: Instance,
|
|
224
|
+
queryAll: boolean
|
|
225
|
+
) {
|
|
226
|
+
if (!queryAll) {
|
|
227
|
+
const data = inst.lookupQueryVal(PathAttributeName).split('/')[1];
|
|
228
|
+
if (data) {
|
|
229
|
+
const parts = data.split(':');
|
|
230
|
+
const id = parts[0];
|
|
231
|
+
const userData = parts[1];
|
|
232
|
+
return await restartSuspension(id, userData, resolver.getEnvironment());
|
|
233
|
+
} else {
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Monarch syntax highlighting for the agentlang language.
|
|
2
2
|
export default {
|
|
3
3
|
keywords: [
|
|
4
|
-
'@actions','@after','@async','@before','@enum','@expr','@from','@meta','@oneof','@rbac','@ref','@upsert','@with_unique','agent','allow','and','
|
|
4
|
+
'@actions','@after','@as','@async','@before','@catch','@enum','@expr','@from','@meta','@oneof','@rbac','@ref','@upsert','@with_unique','agent','allow','and','await','between','contains','create','delete','else','entity','error','event','extends','false','for','if','import','in','into','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','subscribe','true','update','upsert','where','workflow'
|
|
5
5
|
],
|
|
6
6
|
operators: [
|
|
7
7
|
'*','+',',','-','.','/',':',';','<','<=','<>','=','>','>=','?','@'
|