agentlang 0.10.4 → 0.10.5

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 (111) hide show
  1. package/README.md +22 -9
  2. package/out/extension/main.cjs +250 -250
  3. package/out/extension/main.cjs.map +2 -2
  4. package/out/language/generated/ast.d.ts +2 -12
  5. package/out/language/generated/ast.d.ts.map +1 -1
  6. package/out/language/generated/ast.js +0 -8
  7. package/out/language/generated/ast.js.map +1 -1
  8. package/out/language/generated/grammar.d.ts.map +1 -1
  9. package/out/language/generated/grammar.js +18 -52
  10. package/out/language/generated/grammar.js.map +1 -1
  11. package/out/language/main.cjs +522 -564
  12. package/out/language/main.cjs.map +3 -3
  13. package/out/language/parser.d.ts.map +1 -1
  14. package/out/language/parser.js +10 -3
  15. package/out/language/parser.js.map +1 -1
  16. package/out/runtime/api.d.ts.map +1 -1
  17. package/out/runtime/api.js +0 -14
  18. package/out/runtime/api.js.map +1 -1
  19. package/out/runtime/defs.d.ts +0 -1
  20. package/out/runtime/defs.d.ts.map +1 -1
  21. package/out/runtime/defs.js +1 -2
  22. package/out/runtime/defs.js.map +1 -1
  23. package/out/runtime/embeddings/chunker.d.ts +0 -18
  24. package/out/runtime/embeddings/chunker.d.ts.map +1 -1
  25. package/out/runtime/embeddings/chunker.js +15 -47
  26. package/out/runtime/embeddings/chunker.js.map +1 -1
  27. package/out/runtime/embeddings/openai.d.ts.map +1 -1
  28. package/out/runtime/embeddings/openai.js +11 -22
  29. package/out/runtime/embeddings/openai.js.map +1 -1
  30. package/out/runtime/embeddings/provider.d.ts +0 -1
  31. package/out/runtime/embeddings/provider.d.ts.map +1 -1
  32. package/out/runtime/embeddings/provider.js +1 -20
  33. package/out/runtime/embeddings/provider.js.map +1 -1
  34. package/out/runtime/exec-graph.js +5 -5
  35. package/out/runtime/exec-graph.js.map +1 -1
  36. package/out/runtime/interpreter.d.ts +4 -4
  37. package/out/runtime/interpreter.d.ts.map +1 -1
  38. package/out/runtime/interpreter.js +23 -30
  39. package/out/runtime/interpreter.js.map +1 -1
  40. package/out/runtime/loader.d.ts.map +1 -1
  41. package/out/runtime/loader.js +6 -2
  42. package/out/runtime/loader.js.map +1 -1
  43. package/out/runtime/logger.d.ts.map +1 -1
  44. package/out/runtime/logger.js +1 -8
  45. package/out/runtime/logger.js.map +1 -1
  46. package/out/runtime/module.d.ts +0 -6
  47. package/out/runtime/module.d.ts.map +1 -1
  48. package/out/runtime/module.js +1 -58
  49. package/out/runtime/module.js.map +1 -1
  50. package/out/runtime/modules/ai.d.ts +4 -4
  51. package/out/runtime/modules/ai.d.ts.map +1 -1
  52. package/out/runtime/modules/ai.js +70 -166
  53. package/out/runtime/modules/ai.js.map +1 -1
  54. package/out/runtime/modules/auth.d.ts.map +1 -1
  55. package/out/runtime/modules/auth.js +6 -4
  56. package/out/runtime/modules/auth.js.map +1 -1
  57. package/out/runtime/monitor.d.ts +2 -1
  58. package/out/runtime/monitor.d.ts.map +1 -1
  59. package/out/runtime/monitor.js +5 -1
  60. package/out/runtime/monitor.js.map +1 -1
  61. package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -1
  62. package/out/runtime/resolvers/sqldb/database.js +126 -128
  63. package/out/runtime/resolvers/sqldb/database.js.map +1 -1
  64. package/out/runtime/resolvers/sqldb/impl.d.ts +0 -1
  65. package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
  66. package/out/runtime/resolvers/sqldb/impl.js +0 -3
  67. package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
  68. package/out/runtime/services/documentFetcher.d.ts.map +1 -1
  69. package/out/runtime/services/documentFetcher.js +6 -21
  70. package/out/runtime/services/documentFetcher.js.map +1 -1
  71. package/out/runtime/state.d.ts +0 -14
  72. package/out/runtime/state.d.ts.map +1 -1
  73. package/out/runtime/state.js +0 -28
  74. package/out/runtime/state.js.map +1 -1
  75. package/package.json +19 -19
  76. package/src/language/agentlang.langium +2 -2
  77. package/src/language/generated/ast.ts +2 -12
  78. package/src/language/generated/grammar.ts +18 -52
  79. package/src/language/parser.ts +9 -2
  80. package/src/runtime/api.ts +0 -15
  81. package/src/runtime/defs.ts +1 -2
  82. package/src/runtime/embeddings/chunker.ts +14 -52
  83. package/src/runtime/embeddings/openai.ts +9 -27
  84. package/src/runtime/embeddings/provider.ts +1 -22
  85. package/src/runtime/exec-graph.ts +4 -4
  86. package/src/runtime/interpreter.ts +24 -29
  87. package/src/runtime/loader.ts +10 -2
  88. package/src/runtime/logger.ts +1 -12
  89. package/src/runtime/module.ts +1 -64
  90. package/src/runtime/modules/ai.ts +81 -206
  91. package/src/runtime/modules/auth.ts +6 -4
  92. package/src/runtime/monitor.ts +10 -1
  93. package/src/runtime/resolvers/sqldb/database.ts +130 -142
  94. package/src/runtime/resolvers/sqldb/impl.ts +0 -4
  95. package/src/runtime/services/documentFetcher.ts +6 -21
  96. package/src/runtime/state.ts +0 -29
  97. package/out/runtime/document-retriever.d.ts +0 -24
  98. package/out/runtime/document-retriever.d.ts.map +0 -1
  99. package/out/runtime/document-retriever.js +0 -258
  100. package/out/runtime/document-retriever.js.map +0 -1
  101. package/out/runtime/resolvers/vector/lancedb-store.d.ts +0 -16
  102. package/out/runtime/resolvers/vector/lancedb-store.d.ts.map +0 -1
  103. package/out/runtime/resolvers/vector/lancedb-store.js +0 -159
  104. package/out/runtime/resolvers/vector/lancedb-store.js.map +0 -1
  105. package/out/runtime/resolvers/vector/types.d.ts +0 -32
  106. package/out/runtime/resolvers/vector/types.d.ts.map +0 -1
  107. package/out/runtime/resolvers/vector/types.js +0 -2
  108. package/out/runtime/resolvers/vector/types.js.map +0 -1
  109. package/src/runtime/document-retriever.ts +0 -311
  110. package/src/runtime/resolvers/vector/lancedb-store.ts +0 -187
  111. package/src/runtime/resolvers/vector/types.ts +0 -39
@@ -4359,33 +4359,16 @@ export const AgentlangGrammar = (): Grammar => loadedAgentlangGrammar ?? (loaded
4359
4359
  "value": "("
4360
4360
  },
4361
4361
  {
4362
- "$type": "Alternatives",
4363
- "elements": [
4364
- {
4365
- "$type": "Assignment",
4366
- "feature": "value",
4367
- "operator": "=",
4368
- "terminal": {
4369
- "$type": "RuleCall",
4370
- "rule": {
4371
- "$ref": "#/rules@135"
4372
- },
4373
- "arguments": []
4374
- }
4362
+ "$type": "Assignment",
4363
+ "feature": "value",
4364
+ "operator": "=",
4365
+ "terminal": {
4366
+ "$type": "RuleCall",
4367
+ "rule": {
4368
+ "$ref": "#/rules@113"
4375
4369
  },
4376
- {
4377
- "$type": "Assignment",
4378
- "feature": "expr",
4379
- "operator": "=",
4380
- "terminal": {
4381
- "$type": "RuleCall",
4382
- "rule": {
4383
- "$ref": "#/rules@113"
4384
- },
4385
- "arguments": []
4386
- }
4387
- }
4388
- ]
4370
+ "arguments": []
4371
+ }
4389
4372
  },
4390
4373
  {
4391
4374
  "$type": "Keyword",
@@ -4412,33 +4395,16 @@ export const AgentlangGrammar = (): Grammar => loadedAgentlangGrammar ?? (loaded
4412
4395
  "value": "("
4413
4396
  },
4414
4397
  {
4415
- "$type": "Alternatives",
4416
- "elements": [
4417
- {
4418
- "$type": "Assignment",
4419
- "feature": "value",
4420
- "operator": "=",
4421
- "terminal": {
4422
- "$type": "RuleCall",
4423
- "rule": {
4424
- "$ref": "#/rules@135"
4425
- },
4426
- "arguments": []
4427
- }
4398
+ "$type": "Assignment",
4399
+ "feature": "value",
4400
+ "operator": "=",
4401
+ "terminal": {
4402
+ "$type": "RuleCall",
4403
+ "rule": {
4404
+ "$ref": "#/rules@113"
4428
4405
  },
4429
- {
4430
- "$type": "Assignment",
4431
- "feature": "expr",
4432
- "operator": "=",
4433
- "terminal": {
4434
- "$type": "RuleCall",
4435
- "rule": {
4436
- "$ref": "#/rules@113"
4437
- },
4438
- "arguments": []
4439
- }
4440
- }
4441
- ]
4406
+ "arguments": []
4407
+ }
4442
4408
  },
4443
4409
  {
4444
4410
  "$type": "Keyword",
@@ -294,6 +294,13 @@ function introspectExpression(expr: Expr | undefined): BasePattern {
294
294
  throw new Error('Failed to introspect expression - ' + expr);
295
295
  }
296
296
 
297
+ function exprToLimitOffset(expr: Expr): number | string | undefined {
298
+ if (isLiteral(expr) && expr.num !== undefined) {
299
+ return expr.num;
300
+ }
301
+ return expr.$cstNode?.text;
302
+ }
303
+
297
304
  function introspectQueryPattern(crudMap: CrudMap): CrudPattern {
298
305
  if (crudMap) {
299
306
  const cp: CrudPattern = new CrudPattern(crudMap.name);
@@ -327,10 +334,10 @@ function introspectQueryPattern(crudMap: CrudMap): CrudPattern {
327
334
  cp.orderBy = opts.orderByClause.colNames;
328
335
  }
329
336
  if (opts.limitClause) {
330
- cp.limit = opts.limitClause.value ?? opts.limitClause.expr?.$cstNode?.text;
337
+ cp.limit = exprToLimitOffset(opts.limitClause.value);
331
338
  }
332
339
  if (opts.offsetClause) {
333
- cp.offset = opts.offsetClause.value ?? opts.offsetClause.expr?.$cstNode?.text;
340
+ cp.offset = exprToLimitOffset(opts.offsetClause.value);
334
341
  }
335
342
  cp.isCreate = false;
336
343
  cp.isQueryUpdate = false;
@@ -1,5 +1,4 @@
1
1
  import { fetchConfig as al_fetchConfig } from './interpreter.js';
2
- import { defaultDataSource } from './resolvers/sqldb/database.js';
3
2
  import {
4
3
  makeInstance as al_makeInstance,
5
4
  isInstanceOfType as al_isInstanceOfType,
@@ -54,20 +53,6 @@ export function initGlobalApi() {
54
53
  globalThis.agentlang.exchangeOAuthCode = al_exchangeOAuthCode;
55
54
  globalThis.agentlang.getAccessToken = al_getAccessToken;
56
55
 
57
- // Expose raw SQL query for resolvers that need direct database access (e.g. pgvector)
58
- globalThis.agentlang.rawQuery = async (sql: string, params?: any[]) => {
59
- if (!defaultDataSource || !defaultDataSource.isInitialized) {
60
- throw new Error('Database not initialized');
61
- }
62
- return defaultDataSource.query(sql, params);
63
- };
64
-
65
- // Expose database type detection for resolvers
66
- globalThis.agentlang.getDbType = () => {
67
- if (!defaultDataSource || !defaultDataSource.isInitialized) return 'unknown';
68
- return defaultDataSource.options.type;
69
- };
70
-
71
56
  ApiInited = true;
72
57
  }
73
58
  }
@@ -4,8 +4,7 @@ export const PathAttributeName: string = '__path__';
4
4
  export const PathAttributeNameQuery: string = '__path__?';
5
5
  export const ParentAttributeName: string = '__parent__';
6
6
  export const DeletedFlagAttributeName: string = '__is_deleted__';
7
- export const AgentIdAttributeName: string = 'agentId';
8
- export const TenantAttributeName: string = 'agentId';
7
+ export const TenantAttributeName: string = '__tenant__';
9
8
 
10
9
  export function isPathAttribute(n: string): boolean {
11
10
  return n.startsWith(PathAttributeName);
@@ -1,79 +1,41 @@
1
- /**
2
- * Streaming text chunker - yields chunks one at a time without storing all in memory.
3
- */
4
1
  export class TextChunker {
5
2
  private chunkSize: number;
6
3
  private chunkOverlap: number;
7
4
  private separators: string[] = ['\n\n', '\n', '. ', ' ', ''];
8
5
 
9
6
  constructor(chunkSize: number = 1000, chunkOverlap: number = 200) {
10
- // Ensure valid values - overlap must be less than chunk size to avoid infinite loop
11
- this.chunkSize = Math.max(100, chunkSize || 1000);
12
- // Cap overlap to at most 20% of chunk size to ensure progress
13
- this.chunkOverlap = Math.max(
14
- 0,
15
- Math.min(chunkOverlap || 200, Math.floor(this.chunkSize * 0.2))
16
- );
7
+ this.chunkSize = chunkSize;
8
+ this.chunkOverlap = chunkOverlap;
17
9
  }
18
10
 
19
- /**
20
- * Calculate total chunks without creating them all in memory.
21
- * Used for logging/progress tracking.
22
- */
23
- estimateChunks(text: string): number {
24
- if (text.length <= this.chunkSize) {
25
- return 1;
26
- }
27
- // Rough estimate: (text length / effective chunk size) + 1
28
- const effectiveChunkSize = this.chunkSize - this.chunkOverlap;
29
- return Math.ceil(text.length / effectiveChunkSize);
30
- }
31
-
32
- /**
33
- * Streaming generator that yields chunks one at a time.
34
- * Memory-efficient: doesn't store all chunks in an array.
35
- */
36
- *streamChunks(text: string): Generator<string, void, unknown> {
11
+ splitText(text: string): string[] {
37
12
  if (text.length <= this.chunkSize) {
38
- yield text;
39
- return;
13
+ return [text];
40
14
  }
41
15
 
16
+ const chunks: string[] = [];
42
17
  let start = 0;
43
- const minAdvance = Math.max(50, this.chunkSize - this.chunkOverlap); // Ensure we always advance
44
18
 
45
19
  while (start < text.length) {
46
20
  let end = Math.min(start + this.chunkSize, text.length);
47
21
 
48
22
  if (end < text.length) {
49
- // Try to find a good split point, but ensure we advance by at least minAdvance
50
- const splitPoint = this.findBestSplitPoint(text, start, end);
51
- // Only use split point if it gives us reasonable progress
52
- if (splitPoint - start >= minAdvance * 0.5) {
53
- end = splitPoint;
54
- }
55
- // Otherwise use the hard end to ensure progress
23
+ end = this.findBestSplitPoint(text, start, end);
56
24
  }
57
25
 
58
- yield text.substring(start, end);
59
-
60
- // Advance by at least minAdvance characters to avoid infinite loops
61
- const nextStart = end - this.chunkOverlap;
62
- start = Math.max(nextStart, start + minAdvance * 0.5);
26
+ chunks.push(text.substring(start, end));
27
+ start = end - this.chunkOverlap;
63
28
 
64
- if (start >= text.length) {
29
+ if (start < 0) start = 0;
30
+ if (start >= text.length - this.chunkOverlap) {
31
+ if (start < text.length) {
32
+ chunks.push(text.substring(start));
33
+ }
65
34
  break;
66
35
  }
67
36
  }
68
- }
69
37
 
70
- /**
71
- * Legacy method for backwards compatibility.
72
- * ⚠️ WARNING: This creates all chunks in memory and can cause OOM on large documents.
73
- * Prefer streamChunks() for large documents.
74
- */
75
- splitText(text: string): string[] {
76
- return Array.from(this.streamChunks(text));
38
+ return chunks;
77
39
  }
78
40
 
79
41
  private findBestSplitPoint(text: string, start: number, end: number): number {
@@ -1,7 +1,6 @@
1
1
  import { OpenAIEmbeddings } from '@langchain/openai';
2
2
  import { EmbeddingProvider, EmbeddingProviderConfig } from './provider.js';
3
3
  import { getLocalEnv } from '../auth/defs.js';
4
- import { logger } from '../logger.js';
5
4
 
6
5
  export interface OpenAIEmbeddingConfig extends EmbeddingProviderConfig {
7
6
  model?: string;
@@ -15,9 +14,6 @@ export class OpenAIEmbeddingProvider extends EmbeddingProvider {
15
14
  constructor(config?: EmbeddingProviderConfig) {
16
15
  super(config || {});
17
16
  this.openaiConfig = (this.config as OpenAIEmbeddingConfig) || {};
18
- logger.debug(
19
- `[OPENAI-EMBEDDING] Provider created with model: ${this.openaiConfig.model || 'default'}`
20
- );
21
17
  }
22
18
 
23
19
  protected createEmbeddings(): OpenAIEmbeddings {
@@ -25,40 +21,26 @@ export class OpenAIEmbeddingProvider extends EmbeddingProvider {
25
21
  apiKey: this.resolveApiKey(),
26
22
  };
27
23
 
28
- // Use this.config directly since this.openaiConfig is not initialized yet
29
- // during parent constructor (super() calls createEmbeddings before child init)
30
- const openaiConfig = (this.config as OpenAIEmbeddingConfig) || {};
31
-
32
- if (openaiConfig?.model) {
33
- config.model = openaiConfig.model;
24
+ if (this.openaiConfig?.model) {
25
+ config.model = this.openaiConfig.model;
34
26
  }
35
27
 
36
- if (openaiConfig?.dimensions) {
37
- config.dimensions = openaiConfig.dimensions;
28
+ if (this.openaiConfig?.dimensions) {
29
+ config.dimensions = this.openaiConfig.dimensions;
38
30
  }
39
31
 
40
- if (openaiConfig?.maxRetries !== undefined) {
41
- config.maxRetries = openaiConfig.maxRetries;
32
+ if (this.openaiConfig?.maxRetries !== undefined) {
33
+ config.maxRetries = this.openaiConfig.maxRetries;
42
34
  }
43
35
 
44
36
  return new OpenAIEmbeddings(config);
45
37
  }
46
38
 
47
39
  protected resolveApiKey(): string {
48
- // Use this.config directly since this.openaiConfig may not be initialized yet
49
- // during constructor (createEmbeddings is called during super())
50
- const config = this.openaiConfig || (this.config as OpenAIEmbeddingConfig) || {};
51
- if (config.apiKey) {
52
- return config.apiKey;
53
- }
54
- const envKey = process.env.AGENTLANG_OPENAI_KEY || getLocalEnv('AGENTLANG_OPENAI_KEY');
55
- if (envKey) {
56
- return envKey;
40
+ if (this.openaiConfig?.apiKey) {
41
+ return this.openaiConfig.apiKey;
57
42
  }
58
- logger.warn(
59
- `[OPENAI-EMBEDDING] No API key found! Set AGENTLANG_OPENAI_KEY environment variable.`
60
- );
61
- return '';
43
+ return process.env.AGENTLANG_OPENAI_KEY || getLocalEnv('AGENTLANG_OPENAI_KEY') || '';
62
44
  }
63
45
 
64
46
  getProviderName(): string {
@@ -1,5 +1,4 @@
1
1
  import { Embeddings } from '@langchain/core/embeddings';
2
- import { logger } from '../logger.js';
3
2
 
4
3
  export interface EmbeddingProviderConfig {
5
4
  chunkSize?: number;
@@ -24,27 +23,7 @@ export abstract class EmbeddingProvider {
24
23
  abstract getProviderName(): string;
25
24
 
26
25
  async embedText(text: string): Promise<number[]> {
27
- logger.debug(`[EMBEDDING-PROVIDER] embedText called (${text.length} chars)`);
28
- const startTime = Date.now();
29
- const result = await this.embeddings.embedQuery(text);
30
- const duration = Date.now() - startTime;
31
- logger.debug(
32
- `[EMBEDDING-PROVIDER] embedText completed in ${duration}ms (${result.length} dimensions)`
33
- );
34
- return result;
35
- }
36
-
37
- async embedTexts(texts: string[]): Promise<number[][]> {
38
- if (texts.length === 0) return [];
39
- if (texts.length === 1) return [await this.embedText(texts[0])];
40
- logger.debug(`[EMBEDDING-PROVIDER] embedTexts called (${texts.length} texts)`);
41
- const startTime = Date.now();
42
- const results = await this.embeddings.embedDocuments(texts);
43
- const duration = Date.now() - startTime;
44
- logger.debug(
45
- `[EMBEDDING-PROVIDER] embedTexts completed in ${duration}ms (${texts.length} texts, ${results[0]?.length || 0} dimensions)`
46
- );
47
- return results;
26
+ return await this.embeddings.embedQuery(text);
48
27
  }
49
28
 
50
29
  getConfig(): EmbeddingProviderConfig {
@@ -486,18 +486,18 @@ export async function executeEventHelper(eventInstance: Instance, env?: Environm
486
486
  isLocalEnv = true;
487
487
  }
488
488
  let g: ExecGraph | undefined;
489
- let escalatedRole: string | undefined;
489
+ let assumedRole: string | undefined;
490
490
  if (!isAgentEventInstance(eventInstance)) {
491
491
  g = await generateExecutionGraph(fqn);
492
492
  if (!g) {
493
493
  throw new Error(`Failed to generate graph for event ${fqn}`);
494
494
  }
495
- escalatedRole = getWorkflowForEvent(fqn).getRoleEscalation();
495
+ assumedRole = getWorkflowForEvent(fqn).getRoleEscalation();
496
496
  }
497
497
  const oldModuleName = env.switchActiveModuleName(eventInstance.moduleName);
498
498
  env.bind(eventInstance.name, eventInstance);
499
499
  env.bind(eventInstance.getFqName(), eventInstance);
500
- if (escalatedRole) env.setEscalatedRole(escalatedRole);
500
+ if (assumedRole) env.setAssumedRole(assumedRole);
501
501
  try {
502
502
  if (g) {
503
503
  await executeGraph(g, env);
@@ -522,7 +522,7 @@ export async function executeEventHelper(eventInstance: Instance, env?: Environm
522
522
  }
523
523
  throw err;
524
524
  } finally {
525
- env.resetEscalatedRole();
525
+ env.resetAssumedRole();
526
526
  if (!isLocalEnv) env.switchActiveModuleName(oldModuleName);
527
527
  }
528
528
  }
@@ -182,7 +182,7 @@ export class Environment extends Instance {
182
182
  private agentMode: 'chat' | 'planner' | undefined = undefined;
183
183
  private agentChatId: string | undefined = undefined;
184
184
  private monitor: Monitor | undefined = undefined;
185
- private escalatedRole: string | undefined;
185
+ private assumedRole: string | undefined;
186
186
  private activeChatId: string | undefined;
187
187
 
188
188
  private activeUserData: any = undefined;
@@ -210,7 +210,7 @@ export class Environment extends Instance {
210
210
  this.eventExecutor = parent.eventExecutor;
211
211
  this.agentChatId = parent.agentChatId;
212
212
  this.monitor = parent.monitor;
213
- this.escalatedRole = parent.escalatedRole;
213
+ this.assumedRole = parent.assumedRole;
214
214
  this.activeChatId = parent.activeChatId;
215
215
  } else {
216
216
  this.activeModule = DefaultModuleName;
@@ -308,17 +308,17 @@ export class Environment extends Instance {
308
308
  return this;
309
309
  }
310
310
 
311
- setEscalatedRole(s: string): Environment {
312
- this.escalatedRole = s;
311
+ setAssumedRole(s: string): Environment {
312
+ this.assumedRole = s;
313
313
  return this;
314
314
  }
315
315
 
316
- getEscalatedRole(): string | undefined {
317
- return this.escalatedRole;
316
+ getAssumedRole(): string | undefined {
317
+ return this.assumedRole;
318
318
  }
319
319
 
320
- resetEscalatedRole(): Environment {
321
- this.escalatedRole = undefined;
320
+ resetAssumedRole(): Environment {
321
+ this.assumedRole = undefined;
322
322
  return this;
323
323
  }
324
324
 
@@ -856,7 +856,7 @@ export class Environment extends Instance {
856
856
  if (this.activeEventInstance && isCoreModule(this.activeEventInstance.moduleName)) {
857
857
  return this;
858
858
  }
859
- this.monitor = new Monitor(this.activeEventInstance, this.activeUser);
859
+ this.monitor = new Monitor(this.activeEventInstance, this.activeUser, this.assumedRole);
860
860
  }
861
861
  this.monitor.addEntry(new MonitorEntry(stmt));
862
862
  return this;
@@ -971,7 +971,7 @@ export let evaluate = async function (
971
971
  env = new Environment(eventInstance.name + '.env', activeEnv);
972
972
  env.setActiveEvent(eventInstance);
973
973
  const er = wf.getRoleEscalation();
974
- if (er) env.setEscalatedRole(er);
974
+ if (er) env.setAssumedRole(er);
975
975
  if (kernelCall) {
976
976
  env.setInKernelMode(true);
977
977
  }
@@ -1012,7 +1012,7 @@ export let evaluate = async function (
1012
1012
  throw err;
1013
1013
  }
1014
1014
  } finally {
1015
- env?.resetEscalatedRole();
1015
+ env?.resetAssumedRole();
1016
1016
  if (!txnRolledBack && env !== undefined && activeEnv === undefined) {
1017
1017
  await env.commitAllTransactions();
1018
1018
  }
@@ -1590,25 +1590,17 @@ async function maybeSetQueryClauses(
1590
1590
  inst.setOrderBy(qopts.orderByClause.colNames, qopts.orderByClause.order === '@desc');
1591
1591
  }
1592
1592
  if (qopts.limitClause) {
1593
- if (qopts.limitClause.value !== undefined) {
1594
- inst.setLimit(qopts.limitClause.value);
1595
- } else if (qopts.limitClause.expr) {
1596
- await evaluateExpression(qopts.limitClause.expr, env);
1597
- const v = env.getLastResult();
1598
- if (typeof v === 'number') {
1599
- inst.setLimit(v);
1600
- }
1593
+ await evaluateExpression(qopts.limitClause.value, env);
1594
+ const v = env.getLastResult();
1595
+ if (typeof v === 'number') {
1596
+ inst.setLimit(v);
1601
1597
  }
1602
1598
  }
1603
1599
  if (qopts.offsetClause) {
1604
- if (qopts.offsetClause.value !== undefined) {
1605
- inst.setOffset(qopts.offsetClause.value);
1606
- } else if (qopts.offsetClause.expr) {
1607
- await evaluateExpression(qopts.offsetClause.expr, env);
1608
- const v = env.getLastResult();
1609
- if (typeof v === 'number') {
1610
- inst.setOffset(v);
1611
- }
1600
+ await evaluateExpression(qopts.offsetClause.value, env);
1601
+ const v = env.getLastResult();
1602
+ if (typeof v === 'number') {
1603
+ inst.setOffset(v);
1612
1604
  }
1613
1605
  }
1614
1606
  }
@@ -2191,8 +2183,8 @@ const MAX_PLANNER_RETRIES = 3;
2191
2183
  async function agentInvoke(agent: AgentInstance, msg: string, env: Environment): Promise<void> {
2192
2184
  // log invocation details
2193
2185
  let invokeDebugMsg = `\nInvoking agent ${agent.name}:`;
2194
- if (agent.role) {
2195
- invokeDebugMsg = `${invokeDebugMsg} Role=${agent.role}`;
2186
+ if (agent.goal) {
2187
+ invokeDebugMsg = `${invokeDebugMsg} Goal=${agent.goal}`;
2196
2188
  }
2197
2189
  console.debug(invokeDebugMsg);
2198
2190
  invokeDebugMsg = `\nMessage=${msg}`;
@@ -2319,6 +2311,9 @@ export async function handleAgentInvocation(
2319
2311
  env: Environment
2320
2312
  ): Promise<void> {
2321
2313
  const agent: AgentInstance = await findAgentByName(agentEventInst.name, env);
2314
+ if (agent.role) {
2315
+ env.setAssumedRole(agent.role);
2316
+ }
2322
2317
  const chatId = agentEventInst.lookup('chatId');
2323
2318
  if (chatId) {
2324
2319
  env.setActiveChatId(chatId);
@@ -832,7 +832,14 @@ async function addAgentDefinition(
832
832
  }
833
833
  const ov = v;
834
834
  if (apdef.value.id || apdef.value.ref || apdef.value.array) {
835
- if (!(apdef.name === 'instruction' || apdef.name === 'role' || apdef.name === 'llm'))
835
+ if (
836
+ !(
837
+ apdef.name === 'instruction' ||
838
+ apdef.name === 'goal' ||
839
+ apdef.name === 'role' ||
840
+ apdef.name === 'llm'
841
+ )
842
+ )
836
843
  v = `"${v}"`;
837
844
  } else if (apdef.value.str) {
838
845
  v = `"${escapeSpecialChars(v)}"`;
@@ -867,9 +874,10 @@ async function addAgentDefinition(
867
874
  }
868
875
  if (attrs.get('type') === 'planner' || attrs.get('tools')) {
869
876
  const llmn = llmName || attrs.get('llm');
877
+ const agentRole = attrs.get('role') || 'admin';
870
878
  wf = `${wf}; {${CoreAIModuleName}/${AgentEntityName}
871
879
  {name "${name}_${AgentLearnerType}", moduleName "${moduleName}", llm "${llmn}",
872
- type "${AgentLearnerType}", role "You are an agent that summarizes user-provided scenarios."}, @upsert}`;
880
+ type "${AgentLearnerType}", role "${agentRole}", goal "You are an agent that summarizes user-provided scenarios."}, @upsert}`;
873
881
  }
874
882
  (await parseWorkflow(`workflow A {${wf}}`)).statements.forEach((stmt: Statement) => {
875
883
  addStandaloneStatement(stmt, moduleName, false);
@@ -36,17 +36,6 @@ 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
-
50
39
  logger = winston.createLogger({
51
40
  level: logLevel,
52
41
  format: winston.format.combine(
@@ -55,7 +44,7 @@ export function initializeLogger() {
55
44
  return `[${timestamp}] ${level}: ${message}`;
56
45
  })
57
46
  ),
58
- transports: [fileTransport, consoleTransport],
47
+ transports: [fileTransport],
59
48
  });
60
49
  } else {
61
50
  function mkLogger(tag: string): Function {
@@ -2859,46 +2859,6 @@ 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
-
2902
2862
  export function addGlobalRetry(r: Retry): Retry {
2903
2863
  if (GlobalRetries === undefined) {
2904
2864
  GlobalRetries = new Array<Retry>();
@@ -2995,19 +2955,6 @@ export function fetchModuleEntry(entryName: string, moduleName: string): ModuleE
2995
2955
  const module: Module = fetchModule(moduleName);
2996
2956
  return module.getEntry(entryName);
2997
2957
  }
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
- }
3011
2958
 
3012
2959
  const builtInChecks = new Map([
3013
2960
  ['String', isString],
@@ -3036,7 +2983,6 @@ const builtInChecks = new Map([
3036
2983
  return true;
3037
2984
  },
3038
2985
  ],
3039
- ['Topic', isTopicReference],
3040
2986
  ]);
3041
2987
 
3042
2988
  export const builtInTypes = new Set(Array.from(builtInChecks.keys()));
@@ -3060,16 +3006,7 @@ export const propertyNames = new Set([
3060
3006
  '@comment',
3061
3007
  ]);
3062
3008
 
3063
- const TextualTypes = new Set([
3064
- 'String',
3065
- 'Email',
3066
- 'UUID',
3067
- 'DateTime',
3068
- 'Date',
3069
- 'Time',
3070
- 'Path',
3071
- 'Topic',
3072
- ]);
3009
+ const TextualTypes = new Set(['String', 'Email', 'UUID', 'DateTime', 'Date', 'Time', 'Path']);
3073
3010
 
3074
3011
  function isTextualType(type: string): boolean {
3075
3012
  return TextualTypes.has(type);