agentlang 0.0.67 → 0.1.0

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 (68) hide show
  1. package/out/api/http.d.ts.map +1 -1
  2. package/out/api/http.js +2 -1
  3. package/out/api/http.js.map +1 -1
  4. package/out/cli/main.d.ts.map +1 -1
  5. package/out/cli/main.js +7 -1
  6. package/out/cli/main.js.map +1 -1
  7. package/out/language/generated/ast.d.ts +1 -1
  8. package/out/language/generated/ast.d.ts.map +1 -1
  9. package/out/language/generated/ast.js +1 -1
  10. package/out/language/generated/ast.js.map +1 -1
  11. package/out/language/generated/grammar.js +1 -1
  12. package/out/language/main.cjs +2 -2
  13. package/out/language/main.cjs.map +2 -2
  14. package/out/runtime/agents/common.d.ts +0 -7
  15. package/out/runtime/agents/common.d.ts.map +1 -1
  16. package/out/runtime/agents/common.js +0 -34
  17. package/out/runtime/agents/common.js.map +1 -1
  18. package/out/runtime/agents/flows.d.ts +7 -0
  19. package/out/runtime/agents/flows.d.ts.map +1 -0
  20. package/out/runtime/agents/flows.js +33 -0
  21. package/out/runtime/agents/flows.js.map +1 -0
  22. package/out/runtime/defs.d.ts +58 -0
  23. package/out/runtime/defs.d.ts.map +1 -1
  24. package/out/runtime/defs.js +172 -0
  25. package/out/runtime/defs.js.map +1 -1
  26. package/out/runtime/exec-graph.d.ts +17 -0
  27. package/out/runtime/exec-graph.d.ts.map +1 -0
  28. package/out/runtime/exec-graph.js +434 -0
  29. package/out/runtime/exec-graph.js.map +1 -0
  30. package/out/runtime/interpreter.d.ts +38 -3
  31. package/out/runtime/interpreter.d.ts.map +1 -1
  32. package/out/runtime/interpreter.js +167 -60
  33. package/out/runtime/interpreter.js.map +1 -1
  34. package/out/runtime/loader.d.ts.map +1 -1
  35. package/out/runtime/loader.js +120 -2
  36. package/out/runtime/loader.js.map +1 -1
  37. package/out/runtime/module.d.ts +3 -0
  38. package/out/runtime/module.d.ts.map +1 -1
  39. package/out/runtime/module.js +35 -12
  40. package/out/runtime/module.js.map +1 -1
  41. package/out/runtime/modules/ai.d.ts +21 -2
  42. package/out/runtime/modules/ai.d.ts.map +1 -1
  43. package/out/runtime/modules/ai.js +56 -3
  44. package/out/runtime/modules/ai.js.map +1 -1
  45. package/out/runtime/resolvers/interface.d.ts +1 -0
  46. package/out/runtime/resolvers/interface.d.ts.map +1 -1
  47. package/out/runtime/resolvers/interface.js +5 -0
  48. package/out/runtime/resolvers/interface.js.map +1 -1
  49. package/out/utils/runtime.d.ts +1 -0
  50. package/out/utils/runtime.d.ts.map +1 -1
  51. package/out/utils/runtime.js +9 -0
  52. package/out/utils/runtime.js.map +1 -1
  53. package/package.json +34 -52
  54. package/src/api/http.ts +2 -1
  55. package/src/cli/main.ts +8 -1
  56. package/src/language/agentlang.langium +3 -2
  57. package/src/language/generated/ast.ts +2 -2
  58. package/src/language/generated/grammar.ts +1 -1
  59. package/src/runtime/agents/common.ts +0 -41
  60. package/src/runtime/agents/flows.ts +38 -0
  61. package/src/runtime/defs.ts +210 -0
  62. package/src/runtime/exec-graph.ts +518 -0
  63. package/src/runtime/interpreter.ts +202 -66
  64. package/src/runtime/loader.ts +124 -2
  65. package/src/runtime/module.ts +36 -12
  66. package/src/runtime/modules/ai.ts +102 -5
  67. package/src/runtime/resolvers/interface.ts +5 -0
  68. package/src/utils/runtime.ts +10 -0
@@ -1393,8 +1393,21 @@ export class Flow extends ModuleEntry {
1393
1393
  return result;
1394
1394
  }
1395
1395
 
1396
+ static asFlowName(n: string): string {
1397
+ return `${n}.flow`;
1398
+ }
1399
+
1400
+ static normaliseFlowName(n: string): string {
1401
+ const i = n.lastIndexOf('.flow');
1402
+ if (i > 0) {
1403
+ return n.substring(0, i);
1404
+ } else {
1405
+ return n;
1406
+ }
1407
+ }
1408
+
1396
1409
  override toString(): string {
1397
- return `flow ${this.name} {
1410
+ return `flow ${Flow.normaliseFlowName(this.name)} {
1398
1411
  ${this.getFlow()}
1399
1412
  }`;
1400
1413
  }
@@ -1491,16 +1504,18 @@ export class Module {
1491
1504
  }
1492
1505
 
1493
1506
  addFlow(name: string, flowString?: string): Flow {
1494
- const flow: Flow = new Flow(name, this.name, flowString);
1507
+ const flow: Flow = new Flow(Flow.asFlowName(name), this.name, flowString);
1495
1508
  this.addEntry(flow);
1496
1509
  return flow;
1497
1510
  }
1498
1511
 
1499
1512
  getFlow(name: string): Flow | undefined {
1500
- if (this.hasEntry(name)) {
1501
- return this.getEntry(name) as Flow;
1513
+ const n = Flow.asFlowName(name);
1514
+ if (this.hasEntry(n)) {
1515
+ return this.getEntry(n) as Flow;
1516
+ } else {
1517
+ return undefined;
1502
1518
  }
1503
- return undefined;
1504
1519
  }
1505
1520
 
1506
1521
  getAllFlows(): Flow[] {
@@ -1511,7 +1526,7 @@ export class Module {
1511
1526
 
1512
1527
  removeFlow(name: string): boolean {
1513
1528
  if (this.getFlow(name)) {
1514
- return this.removeEntry(name);
1529
+ return this.removeEntry(Flow.asFlowName(name));
1515
1530
  }
1516
1531
  return false;
1517
1532
  }
@@ -2231,12 +2246,21 @@ function getEntityDef(entityName: string, moduleName: string): Entity | undefine
2231
2246
  }
2232
2247
 
2233
2248
  export function getWorkflow(eventInstance: Instance): Workflow {
2234
- const eventName: string = eventInstance.name;
2235
- const moduleName: string = eventInstance.moduleName;
2236
- const wfName: string = asWorkflowName(eventName);
2237
- const module: Module = fetchModule(moduleName);
2238
- if (module.hasEntry(wfName)) {
2239
- return module.getEntry(wfName) as Workflow;
2249
+ return getWorkflowForEvent(eventInstance.name, eventInstance.moduleName);
2250
+ }
2251
+
2252
+ export function getWorkflowForEvent(eventName: string, moduleName?: string): Workflow {
2253
+ if (isFqName(eventName)) {
2254
+ const parts = splitFqName(eventName);
2255
+ eventName = parts.getEntryName();
2256
+ moduleName = parts.getModuleName();
2257
+ }
2258
+ if (moduleName) {
2259
+ const wfName: string = asWorkflowName(eventName);
2260
+ const module: Module = fetchModule(moduleName);
2261
+ if (module.hasEntry(wfName)) {
2262
+ return module.getEntry(wfName) as Workflow;
2263
+ }
2240
2264
  }
2241
2265
  return EmptyWorkflow;
2242
2266
  }
@@ -22,9 +22,10 @@ import {
22
22
  systemMessage,
23
23
  } from '../agents/provider.js';
24
24
  import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
25
- import { FlowExecInstructions, FlowStep, PlannerInstructions } from '../agents/common.js';
25
+ import { FlowExecInstructions, PlannerInstructions } from '../agents/common.js';
26
26
  import { PathAttributeNameQuery } from '../defs.js';
27
27
  import { logger } from '../logger.js';
28
+ import { FlowStep } from '../agents/flows.js';
28
29
 
29
30
  export const CoreAIModuleName = makeCoreModuleName('ai');
30
31
  export const AgentEntityName = 'Agent';
@@ -47,7 +48,6 @@ entity ${AgentEntityName} {
47
48
  tools String @optional, // comma-separated list of tool names
48
49
  documents String @optional, // comma-separated list of document names
49
50
  channels String @optional, // comma-separated list of channel names
50
- output String @optional, // fq-name of another agent to which the result will be pushed
51
51
  role String @optional,
52
52
  flows String @optional,
53
53
  llm String
@@ -83,6 +83,52 @@ export const AgentFqName = makeFqName(CoreAIModuleName, AgentEntityName);
83
83
 
84
84
  const ProviderDb = new Map<string, AgentServiceProvider>();
85
85
 
86
+ export type AgentCondition = {
87
+ cond: string;
88
+ then: string;
89
+ };
90
+
91
+ const AgentDirectives = new Map<string, AgentCondition[]>();
92
+
93
+ export function registerAgentDirectives(
94
+ moduleName: string,
95
+ agentName: string,
96
+ conds: AgentCondition[]
97
+ ) {
98
+ AgentDirectives.set(makeFqName(moduleName, agentName), conds);
99
+ }
100
+
101
+ export type AgentScenario = {
102
+ user: string;
103
+ ai: string;
104
+ };
105
+
106
+ const AgentScenarios = new Map<string, AgentScenario[]>();
107
+
108
+ export function registerAgentScenarios(
109
+ moduleName: string,
110
+ agentName: string,
111
+ scenarios: AgentScenario[]
112
+ ) {
113
+ AgentScenarios.set(makeFqName(moduleName, agentName), scenarios);
114
+ }
115
+
116
+ export type AgentGlossaryEntry = {
117
+ name: string;
118
+ meaning: string;
119
+ synonyms: string | undefined;
120
+ };
121
+
122
+ const AgentGlossary = new Map<string, AgentGlossaryEntry[]>();
123
+
124
+ export function registerAgentGlossary(
125
+ moduleName: string,
126
+ agentName: string,
127
+ glossary: AgentGlossaryEntry[]
128
+ ) {
129
+ AgentGlossary.set(makeFqName(moduleName, agentName), glossary);
130
+ }
131
+
86
132
  export class AgentInstance {
87
133
  llm: string = '';
88
134
  name: string = '';
@@ -94,7 +140,6 @@ export class AgentInstance {
94
140
  documents: string | undefined;
95
141
  channels: string | undefined;
96
142
  runWorkflows: boolean = true;
97
- output: string | undefined;
98
143
  role: string | undefined;
99
144
  flows: string | undefined;
100
145
  private toolsArray: string[] | undefined = undefined;
@@ -175,6 +220,56 @@ export class AgentInstance {
175
220
  return this.type == 'flow-exec';
176
221
  }
177
222
 
223
+ private directivesAsString(fqName: string): string {
224
+ const conds = AgentDirectives.get(fqName);
225
+ if (conds) {
226
+ const ss = new Array<string>();
227
+ ss.push(
228
+ '\nUse the following guidelines to take more accurate decisions in relevant scenarios.\n'
229
+ );
230
+ conds.forEach((ac: AgentCondition) => {
231
+ ss.push(`if ${ac.cond}, then ${ac.then}`);
232
+ });
233
+ return `${ss.join('\n')}\n`;
234
+ }
235
+ return '';
236
+ }
237
+
238
+ private cachedInstruction: string | undefined = undefined;
239
+
240
+ private getFullInstructions(): string {
241
+ if (this.cachedInstruction) {
242
+ return this.cachedInstruction;
243
+ }
244
+ const fqName = makeFqName(this.moduleName, this.name);
245
+ this.cachedInstruction = `${this.instruction || ''} ${this.directivesAsString(fqName)}`;
246
+ const gls = AgentGlossary.get(fqName);
247
+ if (gls) {
248
+ const glss = new Array<string>();
249
+ gls.forEach((age: AgentGlossaryEntry) => {
250
+ glss.push(
251
+ `${age.name}: ${age.meaning}. ${age.synonyms ? `These words are synonyms for ${age.name}: ${age.synonyms}` : ''}`
252
+ );
253
+ });
254
+ this.cachedInstruction = `${this.cachedInstruction}\nThe following glossary will be helpful for understanding user requests.
255
+ ${glss.join('\n')}\n`;
256
+ }
257
+ const scenarios = AgentScenarios.get(fqName);
258
+ if (scenarios) {
259
+ const scs = new Array<string>();
260
+ scenarios.forEach((sc: AgentScenario) => {
261
+ scs.push(`User: ${sc.user}\nAI: ${sc.ai}\n`);
262
+ });
263
+ this.cachedInstruction = `${this.cachedInstruction}\nHere are some example user requests and the corresponding responses you are supposed to produce:\n${scs.join('\n')}`;
264
+ }
265
+ return this.cachedInstruction;
266
+ }
267
+
268
+ markAsFlowExecutor(): AgentInstance {
269
+ this.type = 'flow-exec';
270
+ return this;
271
+ }
272
+
178
273
  async invoke(message: string, env: Environment) {
179
274
  const p = await findProviderForLLM(this.llm, env);
180
275
  const agentName = this.name;
@@ -192,14 +287,16 @@ export class AgentInstance {
192
287
  if (sess) {
193
288
  msgs = sess.lookup('messages');
194
289
  } else {
195
- msgs = [systemMessage(this.instruction || '')];
290
+ msgs = [systemMessage(this.getFullInstructions() || '')];
196
291
  }
197
292
  if (msgs) {
198
293
  try {
199
294
  const sysMsg = msgs[0];
200
295
  if (isplnr || isflow) {
201
296
  const s = isplnr ? PlannerInstructions : FlowExecInstructions;
202
- const newSysMsg = systemMessage(`${s}\n${this.toolsAsString()}\n${this.instruction}`);
297
+ const newSysMsg = systemMessage(
298
+ `${s}\n${this.toolsAsString()}\n${this.getFullInstructions()}`
299
+ );
203
300
  msgs[0] = newSysMsg;
204
301
  }
205
302
  msgs.push(humanMessage(await this.maybeAddRelevantDocuments(message, env)));
@@ -57,6 +57,11 @@ export class Resolver {
57
57
  return this.env;
58
58
  }
59
59
 
60
+ public suspend(): Resolver {
61
+ this.env?.suspend();
62
+ return this;
63
+ }
64
+
60
65
  public getName(): string {
61
66
  return this.name;
62
67
  }
@@ -12,6 +12,16 @@ if (isNodeEnv) {
12
12
  });
13
13
  }
14
14
 
15
+ export function isExecGraphEnabled(): boolean {
16
+ if (isNodeEnv) {
17
+ const flag = process.env['AL_EXEC_GRAPH_ENABLED'];
18
+ if (flag != undefined && flag == 'false') {
19
+ return false;
20
+ }
21
+ }
22
+ return true;
23
+ }
24
+
15
25
  // Browser-compatible path utilities
16
26
  export const browserPath = {
17
27
  extname: (path: string): string => {