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.
Files changed (78) hide show
  1. package/out/api/http.d.ts +1 -1
  2. package/out/api/http.d.ts.map +1 -1
  3. package/out/api/http.js +9 -3
  4. package/out/api/http.js.map +1 -1
  5. package/out/cli/main.js +2 -2
  6. package/out/cli/main.js.map +1 -1
  7. package/out/language/generated/ast.d.ts +57 -21
  8. package/out/language/generated/ast.d.ts.map +1 -1
  9. package/out/language/generated/ast.js +80 -26
  10. package/out/language/generated/ast.js.map +1 -1
  11. package/out/language/generated/grammar.d.ts.map +1 -1
  12. package/out/language/generated/grammar.js +337 -115
  13. package/out/language/generated/grammar.js.map +1 -1
  14. package/out/language/main.cjs +398 -135
  15. package/out/language/main.cjs.map +2 -2
  16. package/out/runtime/agents/common.d.ts +2 -1
  17. package/out/runtime/agents/common.d.ts.map +1 -1
  18. package/out/runtime/agents/common.js +49 -1
  19. package/out/runtime/agents/common.js.map +1 -1
  20. package/out/runtime/agents/registry.js +3 -1
  21. package/out/runtime/agents/registry.js.map +1 -1
  22. package/out/runtime/auth/cognito.d.ts.map +1 -1
  23. package/out/runtime/auth/cognito.js +28 -8
  24. package/out/runtime/auth/cognito.js.map +1 -1
  25. package/out/runtime/auth/interface.d.ts +2 -0
  26. package/out/runtime/auth/interface.d.ts.map +1 -1
  27. package/out/runtime/defs.d.ts +1 -0
  28. package/out/runtime/defs.d.ts.map +1 -1
  29. package/out/runtime/defs.js +1 -0
  30. package/out/runtime/defs.js.map +1 -1
  31. package/out/runtime/interpreter.d.ts +5 -0
  32. package/out/runtime/interpreter.d.ts.map +1 -1
  33. package/out/runtime/interpreter.js +77 -8
  34. package/out/runtime/interpreter.js.map +1 -1
  35. package/out/runtime/loader.d.ts.map +1 -1
  36. package/out/runtime/loader.js +89 -37
  37. package/out/runtime/loader.js.map +1 -1
  38. package/out/runtime/module.d.ts +1 -1
  39. package/out/runtime/module.d.ts.map +1 -1
  40. package/out/runtime/module.js +10 -3
  41. package/out/runtime/module.js.map +1 -1
  42. package/out/runtime/modules/ai.d.ts +13 -0
  43. package/out/runtime/modules/ai.d.ts.map +1 -1
  44. package/out/runtime/modules/ai.js +80 -9
  45. package/out/runtime/modules/ai.js.map +1 -1
  46. package/out/runtime/modules/auth.d.ts +1 -0
  47. package/out/runtime/modules/auth.d.ts.map +1 -1
  48. package/out/runtime/modules/auth.js +18 -0
  49. package/out/runtime/modules/auth.js.map +1 -1
  50. package/out/runtime/modules/core.d.ts +1 -0
  51. package/out/runtime/modules/core.d.ts.map +1 -1
  52. package/out/runtime/modules/core.js +15 -5
  53. package/out/runtime/modules/core.js.map +1 -1
  54. package/out/runtime/state.d.ts +5 -0
  55. package/out/runtime/state.d.ts.map +1 -1
  56. package/out/runtime/state.js +2 -0
  57. package/out/runtime/state.js.map +1 -1
  58. package/out/syntaxes/agentlang.monarch.js +3 -3
  59. package/out/syntaxes/agentlang.monarch.js.map +1 -1
  60. package/package.json +2 -2
  61. package/src/api/http.ts +8 -3
  62. package/src/cli/main.ts +1 -1
  63. package/src/language/agentlang.langium +12 -4
  64. package/src/language/generated/ast.ts +144 -49
  65. package/src/language/generated/grammar.ts +337 -115
  66. package/src/runtime/agents/common.ts +50 -1
  67. package/src/runtime/agents/registry.ts +3 -3
  68. package/src/runtime/auth/cognito.ts +30 -8
  69. package/src/runtime/auth/interface.ts +2 -0
  70. package/src/runtime/defs.ts +1 -0
  71. package/src/runtime/interpreter.ts +122 -8
  72. package/src/runtime/loader.ts +98 -37
  73. package/src/runtime/module.ts +13 -3
  74. package/src/runtime/modules/ai.ts +102 -11
  75. package/src/runtime/modules/auth.ts +28 -0
  76. package/src/runtime/modules/core.ts +16 -4
  77. package/src/runtime/state.ts +2 -0
  78. 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 { fetchModule, Instance, instanceToObject, isModule } from '../module.js';
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
- type @enum("chat", "planner") @default("chat"),
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 newSysMsg = systemMessage(
147
- `${PlannerInstructions}\n${this.toolsAsString()}\n${this.instruction}`
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
- await saveAgentChatSession(chatId, msgs, env);
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 stmts: Statement[] = await parseStatements(cont);
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.env.bindSuspensionUserData(userData);
214
- await evaluateStatements(susp.continuation, susp.env);
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 {
@@ -5,9 +5,11 @@ export const ConfigSchema = z.object({
5
5
  service: z
6
6
  .object({
7
7
  port: z.number(),
8
+ host: z.string().optional(),
8
9
  })
9
10
  .default({
10
11
  port: 8080,
12
+ host: 'localhost',
11
13
  }),
12
14
  store: z
13
15
  .discriminatedUnion('type', [
@@ -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: [