agentlang 0.10.2 → 0.10.4

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 (154) hide show
  1. package/README.md +7 -14
  2. package/out/api/http.d.ts +4 -0
  3. package/out/api/http.d.ts.map +1 -1
  4. package/out/api/http.js +171 -26
  5. package/out/api/http.js.map +1 -1
  6. package/out/cli/main.d.ts.map +1 -1
  7. package/out/cli/main.js +3 -0
  8. package/out/cli/main.js.map +1 -1
  9. package/out/extension/main.cjs +250 -250
  10. package/out/extension/main.cjs.map +2 -2
  11. package/out/language/agentlang-validator.d.ts.map +1 -1
  12. package/out/language/agentlang-validator.js +4 -0
  13. package/out/language/agentlang-validator.js.map +1 -1
  14. package/out/language/error-reporter.d.ts +53 -0
  15. package/out/language/error-reporter.d.ts.map +1 -0
  16. package/out/language/error-reporter.js +879 -0
  17. package/out/language/error-reporter.js.map +1 -0
  18. package/out/language/generated/ast.d.ts +66 -6
  19. package/out/language/generated/ast.d.ts.map +1 -1
  20. package/out/language/generated/ast.js +48 -0
  21. package/out/language/generated/ast.js.map +1 -1
  22. package/out/language/generated/grammar.d.ts.map +1 -1
  23. package/out/language/generated/grammar.js +320 -190
  24. package/out/language/generated/grammar.js.map +1 -1
  25. package/out/language/main.cjs +870 -694
  26. package/out/language/main.cjs.map +3 -3
  27. package/out/language/parser.d.ts +4 -2
  28. package/out/language/parser.d.ts.map +1 -1
  29. package/out/language/parser.js +31 -98
  30. package/out/language/parser.js.map +1 -1
  31. package/out/language/syntax.d.ts +2 -0
  32. package/out/language/syntax.d.ts.map +1 -1
  33. package/out/language/syntax.js +6 -0
  34. package/out/language/syntax.js.map +1 -1
  35. package/out/runtime/api.d.ts.map +1 -1
  36. package/out/runtime/api.js +22 -0
  37. package/out/runtime/api.js.map +1 -1
  38. package/out/runtime/defs.d.ts +1 -0
  39. package/out/runtime/defs.d.ts.map +1 -1
  40. package/out/runtime/defs.js +2 -1
  41. package/out/runtime/defs.js.map +1 -1
  42. package/out/runtime/document-retriever.d.ts +24 -0
  43. package/out/runtime/document-retriever.d.ts.map +1 -0
  44. package/out/runtime/document-retriever.js +258 -0
  45. package/out/runtime/document-retriever.js.map +1 -0
  46. package/out/runtime/embeddings/chunker.d.ts +18 -0
  47. package/out/runtime/embeddings/chunker.d.ts.map +1 -1
  48. package/out/runtime/embeddings/chunker.js +47 -15
  49. package/out/runtime/embeddings/chunker.js.map +1 -1
  50. package/out/runtime/embeddings/openai.d.ts.map +1 -1
  51. package/out/runtime/embeddings/openai.js +22 -9
  52. package/out/runtime/embeddings/openai.js.map +1 -1
  53. package/out/runtime/embeddings/provider.d.ts +1 -0
  54. package/out/runtime/embeddings/provider.d.ts.map +1 -1
  55. package/out/runtime/embeddings/provider.js +20 -1
  56. package/out/runtime/embeddings/provider.js.map +1 -1
  57. package/out/runtime/integration-client.d.ts +21 -0
  58. package/out/runtime/integration-client.d.ts.map +1 -0
  59. package/out/runtime/integration-client.js +112 -0
  60. package/out/runtime/integration-client.js.map +1 -0
  61. package/out/runtime/integrations.d.ts.map +1 -1
  62. package/out/runtime/integrations.js +20 -9
  63. package/out/runtime/integrations.js.map +1 -1
  64. package/out/runtime/interpreter.d.ts +1 -0
  65. package/out/runtime/interpreter.d.ts.map +1 -1
  66. package/out/runtime/interpreter.js +172 -19
  67. package/out/runtime/interpreter.js.map +1 -1
  68. package/out/runtime/loader.d.ts.map +1 -1
  69. package/out/runtime/loader.js +70 -7
  70. package/out/runtime/loader.js.map +1 -1
  71. package/out/runtime/logger.d.ts.map +1 -1
  72. package/out/runtime/logger.js +8 -1
  73. package/out/runtime/logger.js.map +1 -1
  74. package/out/runtime/module.d.ts +10 -0
  75. package/out/runtime/module.d.ts.map +1 -1
  76. package/out/runtime/module.js +68 -3
  77. package/out/runtime/module.js.map +1 -1
  78. package/out/runtime/modules/ai.d.ts +9 -2
  79. package/out/runtime/modules/ai.d.ts.map +1 -1
  80. package/out/runtime/modules/ai.js +219 -67
  81. package/out/runtime/modules/ai.js.map +1 -1
  82. package/out/runtime/modules/core.d.ts.map +1 -1
  83. package/out/runtime/modules/core.js +3 -0
  84. package/out/runtime/modules/core.js.map +1 -1
  85. package/out/runtime/modules/messaging.d.ts +10 -0
  86. package/out/runtime/modules/messaging.d.ts.map +1 -0
  87. package/out/runtime/modules/messaging.js +210 -0
  88. package/out/runtime/modules/messaging.js.map +1 -0
  89. package/out/runtime/resolvers/interface.d.ts +4 -0
  90. package/out/runtime/resolvers/interface.d.ts.map +1 -1
  91. package/out/runtime/resolvers/interface.js +14 -1
  92. package/out/runtime/resolvers/interface.js.map +1 -1
  93. package/out/runtime/resolvers/sqldb/database.d.ts +2 -0
  94. package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -1
  95. package/out/runtime/resolvers/sqldb/database.js +142 -126
  96. package/out/runtime/resolvers/sqldb/database.js.map +1 -1
  97. package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -1
  98. package/out/runtime/resolvers/sqldb/dbutil.js +8 -0
  99. package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -1
  100. package/out/runtime/resolvers/sqldb/impl.d.ts +1 -0
  101. package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
  102. package/out/runtime/resolvers/sqldb/impl.js +7 -0
  103. package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
  104. package/out/runtime/resolvers/vector/lancedb-store.d.ts +16 -0
  105. package/out/runtime/resolvers/vector/lancedb-store.d.ts.map +1 -0
  106. package/out/runtime/resolvers/vector/lancedb-store.js +159 -0
  107. package/out/runtime/resolvers/vector/lancedb-store.js.map +1 -0
  108. package/out/runtime/resolvers/vector/types.d.ts +32 -0
  109. package/out/runtime/resolvers/vector/types.d.ts.map +1 -0
  110. package/out/runtime/resolvers/vector/types.js +2 -0
  111. package/out/runtime/resolvers/vector/types.js.map +1 -0
  112. package/out/runtime/services/documentFetcher.d.ts.map +1 -1
  113. package/out/runtime/services/documentFetcher.js +21 -6
  114. package/out/runtime/services/documentFetcher.js.map +1 -1
  115. package/out/runtime/state.d.ts +19 -1
  116. package/out/runtime/state.d.ts.map +1 -1
  117. package/out/runtime/state.js +36 -1
  118. package/out/runtime/state.js.map +1 -1
  119. package/out/syntaxes/agentlang.monarch.js +1 -1
  120. package/out/syntaxes/agentlang.monarch.js.map +1 -1
  121. package/package.json +19 -19
  122. package/src/api/http.ts +197 -37
  123. package/src/cli/main.ts +3 -0
  124. package/src/language/agentlang-validator.ts +3 -0
  125. package/src/language/agentlang.langium +3 -1
  126. package/src/language/error-reporter.ts +1028 -0
  127. package/src/language/generated/ast.ts +77 -5
  128. package/src/language/generated/grammar.ts +320 -190
  129. package/src/language/parser.ts +31 -100
  130. package/src/language/syntax.ts +8 -0
  131. package/src/runtime/api.ts +31 -0
  132. package/src/runtime/defs.ts +2 -1
  133. package/src/runtime/document-retriever.ts +311 -0
  134. package/src/runtime/embeddings/chunker.ts +52 -14
  135. package/src/runtime/embeddings/openai.ts +27 -9
  136. package/src/runtime/embeddings/provider.ts +22 -1
  137. package/src/runtime/integration-client.ts +158 -0
  138. package/src/runtime/integrations.ts +20 -11
  139. package/src/runtime/interpreter.ts +164 -14
  140. package/src/runtime/loader.ts +83 -5
  141. package/src/runtime/logger.ts +12 -1
  142. package/src/runtime/module.ts +78 -3
  143. package/src/runtime/modules/ai.ts +263 -76
  144. package/src/runtime/modules/core.ts +4 -0
  145. package/src/runtime/modules/messaging.ts +228 -0
  146. package/src/runtime/resolvers/interface.ts +19 -1
  147. package/src/runtime/resolvers/sqldb/database.ts +158 -130
  148. package/src/runtime/resolvers/sqldb/dbutil.ts +8 -0
  149. package/src/runtime/resolvers/sqldb/impl.ts +8 -0
  150. package/src/runtime/resolvers/vector/lancedb-store.ts +187 -0
  151. package/src/runtime/resolvers/vector/types.ts +39 -0
  152. package/src/runtime/services/documentFetcher.ts +21 -6
  153. package/src/runtime/state.ts +40 -1
  154. package/src/syntaxes/agentlang.monarch.ts +1 -1
@@ -72,6 +72,9 @@ import {
72
72
  Retry,
73
73
  addGlobalRetry,
74
74
  AgentEvaluator,
75
+ getAllBetweenRelationshipsForEntity,
76
+ getAttributeExpr,
77
+ AttributeSpec,
75
78
  } from './module.js';
76
79
  import {
77
80
  asStringLiteralsMap,
@@ -85,6 +88,7 @@ import {
85
88
  registerInitFunction,
86
89
  rootRef,
87
90
  ScratchModuleName,
91
+ splitRefs,
88
92
  } from './util.js';
89
93
  import { getFileSystem, toFsPath, readFile, readdir, exists } from '../utils/fs-utils.js';
90
94
  import { URI } from 'vscode-uri';
@@ -102,7 +106,12 @@ import {
102
106
  parseWorkflow,
103
107
  } from '../language/parser.js';
104
108
  import { logger } from './logger.js';
105
- import { Environment, evaluateStatements, GlobalEnvironment } from './interpreter.js';
109
+ import {
110
+ Environment,
111
+ evaluateStatements,
112
+ extractRefsFromExpr,
113
+ GlobalEnvironment,
114
+ } from './interpreter.js';
106
115
  import { createPermission, createRole } from './modules/auth.js';
107
116
  import {
108
117
  AgentEntityName,
@@ -114,7 +123,7 @@ import {
114
123
  import { getDefaultLLMService } from './agents/registry.js';
115
124
  import { GenericResolver, GenericResolverMethods } from './resolvers/interface.js';
116
125
  import { registerResolver, setResolver } from './resolvers/registry.js';
117
- import { Config, ConfigSchema, setAppConfig } from './state.js';
126
+ import { AppConfig, Config, ConfigSchema, setAppConfig } from './state.js';
118
127
  import { getModuleFn, importModule } from './jsmodules.js';
119
128
  import { SetSubscription } from './defs.js';
120
129
  import { ExtendedFileSystem } from '../utils/fs/interfaces.js';
@@ -178,12 +187,14 @@ export async function extractDocument(
178
187
  validation: true,
179
188
  });
180
189
 
190
+ // Handle parser/lexer errors (with human-friendly messages)
191
+ maybeRaiseParserErrors(document);
192
+
181
193
  // Handle validation errors
182
194
  const errs = maybeGetValidationErrors(document);
183
195
 
184
196
  if (errs) {
185
- const errorMsg = `${errs.join('\n')}`;
186
- throw new Error(errorMsg);
197
+ throw new Error('\n' + errs);
187
198
  }
188
199
 
189
200
  return document;
@@ -423,7 +434,9 @@ export async function loadAppConfig(configDirOrContent: string): Promise<Config>
423
434
  const envConfig = JSON.parse(envAppConfig);
424
435
  cfg = { ...cfg, ...envConfig };
425
436
  }
426
- return setAppConfig(cfg);
437
+ const result = setAppConfig(cfg);
438
+
439
+ return result;
427
440
  } catch (err: any) {
428
441
  if (err instanceof z.ZodError) {
429
442
  console.log(chalk.red('Config validation failed:'));
@@ -1152,6 +1165,16 @@ function addResolverDefinition(def: ResolverDefinition, moduleName: string) {
1152
1165
  });
1153
1166
  const methodsObj = Object.fromEntries(methods.entries()) as GenericResolverMethods;
1154
1167
  const resolver = new GenericResolver(resolverName, methodsObj);
1168
+ const connections = AppConfig?.integrations?.connections;
1169
+ if (connections) {
1170
+ for (const [integName, conn] of Object.entries(connections)) {
1171
+ const resolvers = typeof conn === 'string' ? [] : conn.resolvers;
1172
+ if (resolvers.includes(resolverName)) {
1173
+ resolver.setIntegrationName(integName);
1174
+ break;
1175
+ }
1176
+ }
1177
+ }
1155
1178
  registerResolver(resolverName, () => {
1156
1179
  return resolver;
1157
1180
  });
@@ -1215,6 +1238,60 @@ export async function refreshModuleDefinition(moduleName: string, moduleDefiniti
1215
1238
  await internModule(r.parseResult.value);
1216
1239
  }
1217
1240
 
1241
+ function validateExprRelationshipRefs(moduleName: string, mod: Module) {
1242
+ const entities = mod.getEntityEntries();
1243
+ for (const entity of entities) {
1244
+ const schema = entity.schema;
1245
+ schema.forEach((attrSpec: AttributeSpec, attrName: string) => {
1246
+ const expr = getAttributeExpr(attrSpec);
1247
+ if (!expr) return;
1248
+ const refs = extractRefsFromExpr(expr);
1249
+ const entityFqName = makeFqName(moduleName, entity.name);
1250
+ const rels = getAllBetweenRelationshipsForEntity(moduleName, entity.name);
1251
+ if (rels.length === 0) return;
1252
+ for (const ref of refs) {
1253
+ const parts = splitRefs(ref);
1254
+ if (parts.length < 3) continue;
1255
+ const relName = parts[0];
1256
+ const targetEntityAlias = parts[1];
1257
+ const rel = rels.find((r: Relationship) => r.name === relName);
1258
+ if (!rel) continue;
1259
+ // Matched a relationship name - validate
1260
+ if (targetEntityAlias !== rel.node1.alias && targetEntityAlias !== rel.node2.alias) {
1261
+ throw new Error(
1262
+ `Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
1263
+ `"${targetEntityAlias}" does not match any entity alias in relationship ${relName} ` +
1264
+ `(expected "${rel.node1.alias}" or "${rel.node2.alias}")`
1265
+ );
1266
+ }
1267
+ // The target entity must be on the OTHER side from the current entity
1268
+ const isFirstNode = rel.isFirstNodeName(entityFqName);
1269
+ const targetIsFirst = targetEntityAlias === rel.node1.alias;
1270
+ if ((isFirstNode && targetIsFirst) || (!isFirstNode && !targetIsFirst)) {
1271
+ throw new Error(
1272
+ `Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
1273
+ `the referenced entity "${targetEntityAlias}" must be on the other side of relationship ${relName}`
1274
+ );
1275
+ }
1276
+ // Cardinality check
1277
+ if (rel.isManyToMany()) {
1278
+ throw new Error(
1279
+ `Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
1280
+ `cannot reference through many-to-many relationship ${relName}`
1281
+ );
1282
+ }
1283
+ if (rel.isOneToMany() && isFirstNode) {
1284
+ throw new Error(
1285
+ `Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
1286
+ `cannot reference from the "one" side of one-to-many relationship ${relName} ` +
1287
+ `(would resolve to multiple entities)`
1288
+ );
1289
+ }
1290
+ }
1291
+ });
1292
+ }
1293
+ }
1294
+
1218
1295
  export async function internModule(
1219
1296
  module: ModuleDefinition,
1220
1297
  moduleFileName?: string
@@ -1230,6 +1307,7 @@ export async function internModule(
1230
1307
  const def = module.defs[i];
1231
1308
  await addFromDef(def, mn);
1232
1309
  }
1310
+ validateExprRelationshipRefs(mn, r);
1233
1311
  return r;
1234
1312
  }
1235
1313
 
@@ -36,6 +36,17 @@ export function initializeLogger() {
36
36
  maxFiles: '7d',
37
37
  });
38
38
 
39
+ // Add console transport for visibility
40
+ const consoleTransport = new winston.transports.Console({
41
+ level: logLevel,
42
+ format: winston.format.combine(
43
+ winston.format.colorize(),
44
+ winston.format.printf(({ level, message }: any) => {
45
+ return `${level}: ${message}`;
46
+ })
47
+ ),
48
+ });
49
+
39
50
  logger = winston.createLogger({
40
51
  level: logLevel,
41
52
  format: winston.format.combine(
@@ -44,7 +55,7 @@ export function initializeLogger() {
44
55
  return `[${timestamp}] ${level}: ${message}`;
45
56
  })
46
57
  ),
47
- transports: [fileTransport],
58
+ transports: [fileTransport, consoleTransport],
48
59
  });
49
60
  } else {
50
61
  function mkLogger(tag: string): Function {
@@ -2030,7 +2030,7 @@ export class Retry extends ModuleEntry {
2030
2030
 
2031
2031
  constructor(name: string, moduleName: string, attempts: number) {
2032
2032
  super(name, moduleName);
2033
- this.attempts = attempts <= 0 ? 0 : attempts;
2033
+ this.attempts = attempts;
2034
2034
  this.backoff = {
2035
2035
  strategy: undefined,
2036
2036
  delay: undefined,
@@ -2122,7 +2122,7 @@ export class Retry extends ModuleEntry {
2122
2122
  }
2123
2123
 
2124
2124
  getNextDelayMs(attempt: number): number {
2125
- if (attempt >= this.attempts) {
2125
+ if (this.attempts >= 0 && attempt >= this.attempts) {
2126
2126
  return 0;
2127
2127
  }
2128
2128
  const delay = this.backoff.delay === undefined ? 2 : this.backoff.delay;
@@ -2859,6 +2859,46 @@ export function resolveDocumentAliases(names: string[]): string[] {
2859
2859
  return names.map((name: string) => DocumentAliasMap.get(name) ?? name);
2860
2860
  }
2861
2861
 
2862
+ // TopicRegistry: maps topic name → list of document titles belonging to that topic
2863
+ const TopicRegistry: Map<string, string[]> = new Map();
2864
+
2865
+ export function registerTopic(name: string, documents?: string): void {
2866
+ if (!name) return;
2867
+ const docs = documents
2868
+ ? documents
2869
+ .split(',')
2870
+ .map(d => d.trim())
2871
+ .filter(Boolean)
2872
+ : [];
2873
+ TopicRegistry.set(name, docs);
2874
+ }
2875
+
2876
+ export function getTopicDocuments(topicName: string): string[] {
2877
+ return TopicRegistry.get(topicName) ?? [];
2878
+ }
2879
+
2880
+ export function resolveTopicNames(topicsCsv: string): string[] {
2881
+ return topicsCsv
2882
+ .split(',')
2883
+ .map(t => t.trim())
2884
+ .filter(Boolean);
2885
+ }
2886
+
2887
+ export function getTopicContainerTags(topicNames: string[]): string[] {
2888
+ return topicNames.filter(name => TopicRegistry.has(name));
2889
+ }
2890
+
2891
+ export function getAllDocumentsForTopics(topicNames: string[]): string[] {
2892
+ const docs: string[] = [];
2893
+ for (const name of topicNames) {
2894
+ const topicDocs = TopicRegistry.get(name);
2895
+ if (topicDocs) {
2896
+ docs.push(...topicDocs);
2897
+ }
2898
+ }
2899
+ return [...new Set(docs)];
2900
+ }
2901
+
2862
2902
  export function addGlobalRetry(r: Retry): Retry {
2863
2903
  if (GlobalRetries === undefined) {
2864
2904
  GlobalRetries = new Array<Retry>();
@@ -2955,6 +2995,19 @@ export function fetchModuleEntry(entryName: string, moduleName: string): ModuleE
2955
2995
  const module: Module = fetchModule(moduleName);
2956
2996
  return module.getEntry(entryName);
2957
2997
  }
2998
+ // UUID regex pattern
2999
+ const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
3000
+
3001
+ // containerTag format: alphanumeric with dashes/underscores, no spaces
3002
+ const CONTAINER_TAG_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
3003
+
3004
+ export function isTopicReference(value: any): boolean {
3005
+ if (!isString(value)) {
3006
+ return false;
3007
+ }
3008
+ // Topic can be a UUID or a containerTag format
3009
+ return UUID_REGEX.test(value) || CONTAINER_TAG_REGEX.test(value);
3010
+ }
2958
3011
 
2959
3012
  const builtInChecks = new Map([
2960
3013
  ['String', isString],
@@ -2983,6 +3036,7 @@ const builtInChecks = new Map([
2983
3036
  return true;
2984
3037
  },
2985
3038
  ],
3039
+ ['Topic', isTopicReference],
2986
3040
  ]);
2987
3041
 
2988
3042
  export const builtInTypes = new Set(Array.from(builtInChecks.keys()));
@@ -3006,7 +3060,16 @@ export const propertyNames = new Set([
3006
3060
  '@comment',
3007
3061
  ]);
3008
3062
 
3009
- const TextualTypes = new Set(['String', 'Email', 'UUID', 'DateTime', 'Date', 'Time', 'Path']);
3063
+ const TextualTypes = new Set([
3064
+ 'String',
3065
+ 'Email',
3066
+ 'UUID',
3067
+ 'DateTime',
3068
+ 'Date',
3069
+ 'Time',
3070
+ 'Path',
3071
+ 'Topic',
3072
+ ]);
3010
3073
 
3011
3074
  function isTextualType(type: string): boolean {
3012
3075
  return TextualTypes.has(type);
@@ -3775,6 +3838,8 @@ export class Instance {
3775
3838
  groupBy: string[] | undefined;
3776
3839
  orderBy: string[] | undefined;
3777
3840
  orderByDesc: boolean = false;
3841
+ limit: number | undefined;
3842
+ offset: number | undefined;
3778
3843
  private contextData: Map<string, any> | undefined;
3779
3844
  private ___id: string;
3780
3845
 
@@ -3887,6 +3952,16 @@ export class Instance {
3887
3952
  return this;
3888
3953
  }
3889
3954
 
3955
+ setLimit(n: number): Instance {
3956
+ this.limit = n;
3957
+ return this;
3958
+ }
3959
+
3960
+ setOffset(n: number): Instance {
3961
+ this.offset = n;
3962
+ return this;
3963
+ }
3964
+
3890
3965
  asSerializableObject(): object {
3891
3966
  const obj: any = {
3892
3967
  AL_INSTANCE: true,