agentlang 0.0.37 → 0.0.50
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.d.ts +1 -1
- package/out/api/http.d.ts.map +1 -1
- package/out/api/http.js +9 -3
- package/out/api/http.js.map +1 -1
- package/out/cli/main.js +2 -2
- package/out/cli/main.js.map +1 -1
- package/out/language/generated/ast.d.ts +57 -21
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +80 -26
- 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 +337 -115
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +398 -135
- package/out/language/main.cjs.map +2 -2
- 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 +49 -1
- package/out/runtime/agents/common.js.map +1 -1
- package/out/runtime/agents/registry.js +3 -1
- package/out/runtime/agents/registry.js.map +1 -1
- package/out/runtime/auth/cognito.d.ts.map +1 -1
- package/out/runtime/auth/cognito.js +28 -8
- package/out/runtime/auth/cognito.js.map +1 -1
- package/out/runtime/auth/interface.d.ts +2 -0
- package/out/runtime/auth/interface.d.ts.map +1 -1
- package/out/runtime/defs.d.ts +1 -0
- package/out/runtime/defs.d.ts.map +1 -1
- package/out/runtime/defs.js +1 -0
- package/out/runtime/defs.js.map +1 -1
- package/out/runtime/interpreter.d.ts +5 -0
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +77 -8
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +89 -37
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/module.d.ts +1 -1
- package/out/runtime/module.d.ts.map +1 -1
- package/out/runtime/module.js +10 -3
- package/out/runtime/module.js.map +1 -1
- package/out/runtime/modules/ai.d.ts +13 -0
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +80 -9
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/modules/auth.d.ts +1 -0
- package/out/runtime/modules/auth.d.ts.map +1 -1
- package/out/runtime/modules/auth.js +18 -0
- package/out/runtime/modules/auth.js.map +1 -1
- package/out/runtime/modules/core.d.ts +1 -0
- package/out/runtime/modules/core.d.ts.map +1 -1
- package/out/runtime/modules/core.js +15 -5
- package/out/runtime/modules/core.js.map +1 -1
- package/out/runtime/state.d.ts +5 -0
- package/out/runtime/state.d.ts.map +1 -1
- package/out/runtime/state.js +2 -0
- package/out/runtime/state.js.map +1 -1
- package/out/syntaxes/agentlang.monarch.js +3 -3
- package/out/syntaxes/agentlang.monarch.js.map +1 -1
- package/package.json +2 -2
- package/src/api/http.ts +8 -3
- package/src/cli/main.ts +1 -1
- package/src/language/agentlang.langium +12 -4
- package/src/language/generated/ast.ts +144 -49
- package/src/language/generated/grammar.ts +337 -115
- package/src/runtime/agents/common.ts +50 -1
- package/src/runtime/agents/registry.ts +3 -3
- package/src/runtime/auth/cognito.ts +30 -8
- package/src/runtime/auth/interface.ts +2 -0
- package/src/runtime/defs.ts +1 -0
- package/src/runtime/interpreter.ts +122 -8
- package/src/runtime/loader.ts +98 -37
- package/src/runtime/module.ts +13 -3
- package/src/runtime/modules/ai.ts +102 -11
- package/src/runtime/modules/auth.ts +28 -0
- package/src/runtime/modules/core.ts +16 -4
- package/src/runtime/state.ts +2 -0
- package/src/syntaxes/agentlang.monarch.ts +3 -3
|
@@ -5,7 +5,14 @@ import {
|
|
|
5
5
|
makeEventEvaluator,
|
|
6
6
|
parseAndEvaluateStatement,
|
|
7
7
|
} from '../interpreter.js';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
fetchModule,
|
|
10
|
+
Instance,
|
|
11
|
+
instanceToObject,
|
|
12
|
+
isModule,
|
|
13
|
+
makeInstance,
|
|
14
|
+
newInstanceAttributes,
|
|
15
|
+
} from '../module.js';
|
|
9
16
|
import { provider } from '../agents/registry.js';
|
|
10
17
|
import {
|
|
11
18
|
AgentServiceProvider,
|
|
@@ -15,7 +22,7 @@ import {
|
|
|
15
22
|
systemMessage,
|
|
16
23
|
} from '../agents/provider.js';
|
|
17
24
|
import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
18
|
-
import { PlannerInstructions } from '../agents/common.js';
|
|
25
|
+
import { FlowExecInstructions, PlannerInstructions } from '../agents/common.js';
|
|
19
26
|
import { PathAttributeNameQuery } from '../defs.js';
|
|
20
27
|
import { logger } from '../logger.js';
|
|
21
28
|
|
|
@@ -33,7 +40,8 @@ entity ${LlmEntityName} {
|
|
|
33
40
|
|
|
34
41
|
entity ${AgentEntityName} {
|
|
35
42
|
name String @id,
|
|
36
|
-
|
|
43
|
+
moduleName String @default("${CoreAIModuleName}"),
|
|
44
|
+
type @enum("chat", "planner", "flow-exec") @default("chat"),
|
|
37
45
|
runWorkflows Boolean @default(true),
|
|
38
46
|
instruction String @optional,
|
|
39
47
|
tools String @optional, // comma-separated list of tool names
|
|
@@ -77,6 +85,7 @@ const ProviderDb = new Map<string, AgentServiceProvider>();
|
|
|
77
85
|
export class AgentInstance {
|
|
78
86
|
llm: string = '';
|
|
79
87
|
name: string = '';
|
|
88
|
+
moduleName: string = CoreAIModuleName;
|
|
80
89
|
chatId: string | undefined;
|
|
81
90
|
instruction: string = '';
|
|
82
91
|
type: string = 'chat';
|
|
@@ -88,6 +97,7 @@ export class AgentInstance {
|
|
|
88
97
|
role: string | undefined;
|
|
89
98
|
private toolsArray: string[] | undefined = undefined;
|
|
90
99
|
private hasModuleTools = false;
|
|
100
|
+
private withSession = true;
|
|
91
101
|
|
|
92
102
|
private constructor() {}
|
|
93
103
|
|
|
@@ -123,29 +133,71 @@ export class AgentInstance {
|
|
|
123
133
|
return agent;
|
|
124
134
|
}
|
|
125
135
|
|
|
136
|
+
static FromFlowStep(step: FlowStep, flowAgent: AgentInstance): AgentInstance {
|
|
137
|
+
const fqs = isFqName(step) ? step : `${flowAgent.moduleName}/${step}`;
|
|
138
|
+
const instruction = `Analyse the context and generate the pattern required to invoke ${fqs}.
|
|
139
|
+
Never include references in the pattern. All attribute values must be literals derived from the context.`;
|
|
140
|
+
const inst = makeInstance(
|
|
141
|
+
CoreAIModuleName,
|
|
142
|
+
AgentEntityName,
|
|
143
|
+
newInstanceAttributes()
|
|
144
|
+
.set('llm', flowAgent.llm)
|
|
145
|
+
.set('name', `${step}_agent`)
|
|
146
|
+
.set('moduleName', flowAgent.moduleName)
|
|
147
|
+
.set('instruction', instruction)
|
|
148
|
+
.set('tools', fqs)
|
|
149
|
+
.set('type', 'planner')
|
|
150
|
+
);
|
|
151
|
+
return AgentInstance.FromInstance(inst);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
disableSession(): AgentInstance {
|
|
155
|
+
this.withSession = false;
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
enableSession(): AgentInstance {
|
|
160
|
+
this.withSession = true;
|
|
161
|
+
return this;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
hasSession(): boolean {
|
|
165
|
+
return this.withSession;
|
|
166
|
+
}
|
|
167
|
+
|
|
126
168
|
isPlanner(): boolean {
|
|
127
169
|
return this.hasModuleTools || this.type == 'planner';
|
|
128
170
|
}
|
|
129
171
|
|
|
172
|
+
isFlowExecutor(): boolean {
|
|
173
|
+
return this.type == 'flow-exec';
|
|
174
|
+
}
|
|
175
|
+
|
|
130
176
|
async invoke(message: string, env: Environment) {
|
|
131
177
|
const p = await findProviderForLLM(this.llm, env);
|
|
132
178
|
const agentName = this.name;
|
|
133
179
|
const chatId = this.chatId || agentName;
|
|
134
|
-
const sess: Instance | null = await findAgentChatSession(chatId, env);
|
|
135
|
-
let msgs: BaseMessage[] | undefined;
|
|
136
180
|
const isplnr = this.isPlanner();
|
|
181
|
+
const isflow = !isplnr && this.isFlowExecutor();
|
|
182
|
+
if (isplnr && this.withSession) {
|
|
183
|
+
this.withSession = false;
|
|
184
|
+
}
|
|
185
|
+
if (isflow) {
|
|
186
|
+
this.withSession = false;
|
|
187
|
+
}
|
|
188
|
+
const sess: Instance | null = this.withSession ? await findAgentChatSession(chatId, env) : null;
|
|
189
|
+
let msgs: BaseMessage[] | undefined;
|
|
137
190
|
if (sess) {
|
|
138
191
|
msgs = sess.lookup('messages');
|
|
139
192
|
} else {
|
|
140
|
-
msgs = [systemMessage(this.instruction)];
|
|
193
|
+
msgs = [systemMessage(this.instruction || '')];
|
|
141
194
|
}
|
|
142
195
|
if (msgs) {
|
|
143
196
|
try {
|
|
144
197
|
const sysMsg = msgs[0];
|
|
145
|
-
if (isplnr) {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
);
|
|
198
|
+
if (isplnr || isflow) {
|
|
199
|
+
const s = isplnr ? PlannerInstructions : FlowExecInstructions;
|
|
200
|
+
const newSysMsg = systemMessage(`${s}\n${this.toolsAsString()}\n${this.instruction}`);
|
|
149
201
|
msgs[0] = newSysMsg;
|
|
150
202
|
}
|
|
151
203
|
msgs.push(humanMessage(await this.maybeAddRelevantDocuments(message, env)));
|
|
@@ -155,7 +207,9 @@ export class AgentInstance {
|
|
|
155
207
|
if (isplnr) {
|
|
156
208
|
msgs[0] = sysMsg;
|
|
157
209
|
}
|
|
158
|
-
|
|
210
|
+
if (this.withSession) {
|
|
211
|
+
await saveAgentChatSession(chatId, msgs, env);
|
|
212
|
+
}
|
|
159
213
|
env.setLastResult(response.content);
|
|
160
214
|
} catch (err: any) {
|
|
161
215
|
logger.error(`Error while invoking ${agentName} - ${err}`);
|
|
@@ -362,3 +416,40 @@ export async function saveAgentChatSession(chatId: string, messages: any[], env:
|
|
|
362
416
|
export function agentName(agentInstance: Instance): string {
|
|
363
417
|
return agentInstance.lookup('name');
|
|
364
418
|
}
|
|
419
|
+
|
|
420
|
+
export type FlowSpec = string;
|
|
421
|
+
export type FlowStep = string;
|
|
422
|
+
|
|
423
|
+
const AgentFlows = new Map<string, string[]>();
|
|
424
|
+
const FlowRegistry = new Map<string, FlowSpec>();
|
|
425
|
+
|
|
426
|
+
export function registerFlow(name: string, flow: FlowSpec): string {
|
|
427
|
+
FlowRegistry.set(name, flow);
|
|
428
|
+
return name;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
export function getFlow(name: string): FlowSpec | undefined {
|
|
432
|
+
return FlowRegistry.get(name);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
export function registerAgentFlow(agentName: string, flowSpecName: string): string {
|
|
436
|
+
let currentFlows = AgentFlows.get(agentName);
|
|
437
|
+
if (currentFlows) {
|
|
438
|
+
currentFlows.push(flowSpecName);
|
|
439
|
+
} else {
|
|
440
|
+
currentFlows = new Array<string>();
|
|
441
|
+
currentFlows.push(flowSpecName);
|
|
442
|
+
}
|
|
443
|
+
AgentFlows.set(agentName, currentFlows);
|
|
444
|
+
return agentName;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Return the first flow registered with the agent.
|
|
448
|
+
export function getAgentFlow(agentName: string): FlowSpec | undefined {
|
|
449
|
+
const currentFlows = AgentFlows.get(agentName);
|
|
450
|
+
if (currentFlows) {
|
|
451
|
+
return getFlow(currentFlows[0]);
|
|
452
|
+
} else {
|
|
453
|
+
return undefined;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
@@ -51,6 +51,12 @@ workflow CreateUser {
|
|
|
51
51
|
lastName CreateUser.lastName}}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
workflow UpdateUser {
|
|
55
|
+
{User {id UpdateUser.id,
|
|
56
|
+
firstName UpdateUser.firstName,
|
|
57
|
+
lastName UpdateUser.lastName}, @upsert}
|
|
58
|
+
}
|
|
59
|
+
|
|
54
60
|
workflow FindUser {
|
|
55
61
|
{User {id? FindUser.id}} @as [user];
|
|
56
62
|
user
|
|
@@ -318,6 +324,23 @@ export async function findUserByEmail(email: string, env: Environment): Promise<
|
|
|
318
324
|
);
|
|
319
325
|
}
|
|
320
326
|
|
|
327
|
+
export async function updateUser(
|
|
328
|
+
userId: string,
|
|
329
|
+
firstName: string,
|
|
330
|
+
lastName: string,
|
|
331
|
+
env: Environment
|
|
332
|
+
): Promise<Result> {
|
|
333
|
+
return await evalEvent(
|
|
334
|
+
'UpdateUser',
|
|
335
|
+
{
|
|
336
|
+
id: userId,
|
|
337
|
+
firstName: firstName,
|
|
338
|
+
lastName: lastName,
|
|
339
|
+
},
|
|
340
|
+
env
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
321
344
|
export async function ensureUser(
|
|
322
345
|
email: string,
|
|
323
346
|
firstName: string,
|
|
@@ -326,6 +349,11 @@ export async function ensureUser(
|
|
|
326
349
|
) {
|
|
327
350
|
const user = await findUserByEmail(email, env);
|
|
328
351
|
if (user) {
|
|
352
|
+
// Update existing user with latest name information from ID token
|
|
353
|
+
const userId = user.lookup('id');
|
|
354
|
+
await updateUser(userId, firstName, lastName, env).catch((reason: any) => {
|
|
355
|
+
logger.error(`Failed to update user ${userId} with latest name information: ${reason}`);
|
|
356
|
+
});
|
|
329
357
|
return user;
|
|
330
358
|
}
|
|
331
359
|
return await createUser(crypto.randomUUID(), email, firstName, lastName, env);
|
|
@@ -7,12 +7,13 @@ import {
|
|
|
7
7
|
evaluate,
|
|
8
8
|
evaluateStatements,
|
|
9
9
|
parseAndEvaluateStatement,
|
|
10
|
+
restartFlow,
|
|
10
11
|
} from '../interpreter.js';
|
|
11
12
|
import { logger } from '../logger.js';
|
|
12
13
|
import { Statement } from '../../language/generated/ast.js';
|
|
13
14
|
import { parseStatements } from '../../language/parser.js';
|
|
14
15
|
import { Resolver } from '../resolvers/interface.js';
|
|
15
|
-
import { ForceReadPermFlag, PathAttributeName } from '../defs.js';
|
|
16
|
+
import { FlowSuspensionTag, ForceReadPermFlag, PathAttributeName } from '../defs.js';
|
|
16
17
|
|
|
17
18
|
const CoreModuleDefinition = `module ${DefaultModuleName}
|
|
18
19
|
|
|
@@ -165,9 +166,14 @@ export async function createSuspension(
|
|
|
165
166
|
|
|
166
167
|
export type Suspension = {
|
|
167
168
|
continuation: Statement[];
|
|
169
|
+
flowContext?: string[];
|
|
168
170
|
env: Environment;
|
|
169
171
|
};
|
|
170
172
|
|
|
173
|
+
function isFlowSuspension(cont: string[]): boolean {
|
|
174
|
+
return cont.length > 0 && cont[0] == FlowSuspensionTag;
|
|
175
|
+
}
|
|
176
|
+
|
|
171
177
|
async function loadSuspension(suspId: string, env?: Environment): Promise<Suspension | undefined> {
|
|
172
178
|
const newEnv = new Environment('auditlog', env).setInKernelMode(true);
|
|
173
179
|
const r: any = await parseAndEvaluateStatement(
|
|
@@ -178,12 +184,14 @@ async function loadSuspension(suspId: string, env?: Environment): Promise<Suspen
|
|
|
178
184
|
if (r instanceof Array && r.length > 0) {
|
|
179
185
|
const inst: Instance = r[0];
|
|
180
186
|
const cont = inst.lookup('continuation');
|
|
181
|
-
const
|
|
187
|
+
const ifs = isFlowSuspension(cont);
|
|
188
|
+
const stmts: Statement[] = ifs ? new Array<Statement>() : await parseStatements(cont);
|
|
182
189
|
const envStr = inst.lookup('env');
|
|
183
190
|
const suspEnv: Environment = Environment.FromSerializableObject(JSON.parse(envStr));
|
|
184
191
|
return {
|
|
185
192
|
continuation: stmts,
|
|
186
193
|
env: suspEnv,
|
|
194
|
+
flowContext: ifs ? cont : undefined,
|
|
187
195
|
};
|
|
188
196
|
}
|
|
189
197
|
return undefined;
|
|
@@ -210,8 +218,12 @@ export async function restartSuspension(
|
|
|
210
218
|
): Promise<any> {
|
|
211
219
|
const susp = await loadSuspension(suspId, env);
|
|
212
220
|
if (susp) {
|
|
213
|
-
susp.
|
|
214
|
-
|
|
221
|
+
if (susp.flowContext) {
|
|
222
|
+
await restartFlow(susp.flowContext, userData, susp.env);
|
|
223
|
+
} else {
|
|
224
|
+
susp.env.bindSuspensionUserData(userData);
|
|
225
|
+
await evaluateStatements(susp.continuation, susp.env);
|
|
226
|
+
}
|
|
215
227
|
await deleteSuspension(suspId, env);
|
|
216
228
|
return susp.env.getLastResult();
|
|
217
229
|
} else {
|
package/src/runtime/state.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Monarch syntax highlighting for the agentlang language.
|
|
2
2
|
export default {
|
|
3
3
|
keywords: [
|
|
4
|
-
'@actions','@after','@as','@async','@before','@catch','@distinct','@enum','@expr','@from','@into','@meta','@oneof','@rbac','@ref','@then','@upsert','@with_unique','agent','allow','and','await','between','contains','create','delete','else','entity','error','event','extends','false','for','if','import','in','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','subscribe','true','update','upsert','where','workflow'
|
|
4
|
+
'@actions','@after','@as','@async','@before','@catch','@distinct','@enum','@expr','@from','@into','@meta','@oneof','@rbac','@ref','@then','@upsert','@with_unique','agent','allow','and','await','between','contains','create','delete','else','entity','error','event','extends','false','flow','for','if','import','in','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
|
+
'!=','*','+',',','-','-->','.','/',':',';','<','<=','<>','=','>','>=','?','@'
|
|
8
8
|
],
|
|
9
|
-
symbols: /!=|\(|\)
|
|
9
|
+
symbols: /!=|\(|\)|\*|\+|,|-|-->|\.|\/|:|;|<|<=|<>|=|>|>=|\?|@|\[|\]|\{|\}/,
|
|
10
10
|
|
|
11
11
|
tokenizer: {
|
|
12
12
|
initial: [
|