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.
- package/README.md +22 -9
- package/out/extension/main.cjs +250 -250
- package/out/extension/main.cjs.map +2 -2
- package/out/language/generated/ast.d.ts +2 -12
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +0 -8
- 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 +18 -52
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +522 -564
- package/out/language/main.cjs.map +3 -3
- package/out/language/parser.d.ts.map +1 -1
- package/out/language/parser.js +10 -3
- package/out/language/parser.js.map +1 -1
- package/out/runtime/api.d.ts.map +1 -1
- package/out/runtime/api.js +0 -14
- package/out/runtime/api.js.map +1 -1
- package/out/runtime/defs.d.ts +0 -1
- package/out/runtime/defs.d.ts.map +1 -1
- package/out/runtime/defs.js +1 -2
- package/out/runtime/defs.js.map +1 -1
- package/out/runtime/embeddings/chunker.d.ts +0 -18
- package/out/runtime/embeddings/chunker.d.ts.map +1 -1
- package/out/runtime/embeddings/chunker.js +15 -47
- package/out/runtime/embeddings/chunker.js.map +1 -1
- package/out/runtime/embeddings/openai.d.ts.map +1 -1
- package/out/runtime/embeddings/openai.js +11 -22
- package/out/runtime/embeddings/openai.js.map +1 -1
- package/out/runtime/embeddings/provider.d.ts +0 -1
- package/out/runtime/embeddings/provider.d.ts.map +1 -1
- package/out/runtime/embeddings/provider.js +1 -20
- package/out/runtime/embeddings/provider.js.map +1 -1
- package/out/runtime/exec-graph.js +5 -5
- package/out/runtime/exec-graph.js.map +1 -1
- package/out/runtime/interpreter.d.ts +4 -4
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +23 -30
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +6 -2
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/logger.d.ts.map +1 -1
- package/out/runtime/logger.js +1 -8
- package/out/runtime/logger.js.map +1 -1
- package/out/runtime/module.d.ts +0 -6
- package/out/runtime/module.d.ts.map +1 -1
- package/out/runtime/module.js +1 -58
- package/out/runtime/module.js.map +1 -1
- package/out/runtime/modules/ai.d.ts +4 -4
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +70 -166
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/modules/auth.d.ts.map +1 -1
- package/out/runtime/modules/auth.js +6 -4
- package/out/runtime/modules/auth.js.map +1 -1
- package/out/runtime/monitor.d.ts +2 -1
- package/out/runtime/monitor.d.ts.map +1 -1
- package/out/runtime/monitor.js +5 -1
- package/out/runtime/monitor.js.map +1 -1
- package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/database.js +126 -128
- package/out/runtime/resolvers/sqldb/database.js.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.d.ts +0 -1
- package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.js +0 -3
- package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
- package/out/runtime/services/documentFetcher.d.ts.map +1 -1
- package/out/runtime/services/documentFetcher.js +6 -21
- package/out/runtime/services/documentFetcher.js.map +1 -1
- package/out/runtime/state.d.ts +0 -14
- package/out/runtime/state.d.ts.map +1 -1
- package/out/runtime/state.js +0 -28
- package/out/runtime/state.js.map +1 -1
- package/package.json +19 -19
- package/src/language/agentlang.langium +2 -2
- package/src/language/generated/ast.ts +2 -12
- package/src/language/generated/grammar.ts +18 -52
- package/src/language/parser.ts +9 -2
- package/src/runtime/api.ts +0 -15
- package/src/runtime/defs.ts +1 -2
- package/src/runtime/embeddings/chunker.ts +14 -52
- package/src/runtime/embeddings/openai.ts +9 -27
- package/src/runtime/embeddings/provider.ts +1 -22
- package/src/runtime/exec-graph.ts +4 -4
- package/src/runtime/interpreter.ts +24 -29
- package/src/runtime/loader.ts +10 -2
- package/src/runtime/logger.ts +1 -12
- package/src/runtime/module.ts +1 -64
- package/src/runtime/modules/ai.ts +81 -206
- package/src/runtime/modules/auth.ts +6 -4
- package/src/runtime/monitor.ts +10 -1
- package/src/runtime/resolvers/sqldb/database.ts +130 -142
- package/src/runtime/resolvers/sqldb/impl.ts +0 -4
- package/src/runtime/services/documentFetcher.ts +6 -21
- package/src/runtime/state.ts +0 -29
- package/out/runtime/document-retriever.d.ts +0 -24
- package/out/runtime/document-retriever.d.ts.map +0 -1
- package/out/runtime/document-retriever.js +0 -258
- package/out/runtime/document-retriever.js.map +0 -1
- package/out/runtime/resolvers/vector/lancedb-store.d.ts +0 -16
- package/out/runtime/resolvers/vector/lancedb-store.d.ts.map +0 -1
- package/out/runtime/resolvers/vector/lancedb-store.js +0 -159
- package/out/runtime/resolvers/vector/lancedb-store.js.map +0 -1
- package/out/runtime/resolvers/vector/types.d.ts +0 -32
- package/out/runtime/resolvers/vector/types.d.ts.map +0 -1
- package/out/runtime/resolvers/vector/types.js +0 -2
- package/out/runtime/resolvers/vector/types.js.map +0 -1
- package/src/runtime/document-retriever.ts +0 -311
- package/src/runtime/resolvers/vector/lancedb-store.ts +0 -187
- 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": "
|
|
4363
|
-
"
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
"
|
|
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
|
-
|
|
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": "
|
|
4416
|
-
"
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
"
|
|
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
|
-
|
|
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",
|
package/src/language/parser.ts
CHANGED
|
@@ -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
|
|
337
|
+
cp.limit = exprToLimitOffset(opts.limitClause.value);
|
|
331
338
|
}
|
|
332
339
|
if (opts.offsetClause) {
|
|
333
|
-
cp.offset = opts.offsetClause.value
|
|
340
|
+
cp.offset = exprToLimitOffset(opts.offsetClause.value);
|
|
334
341
|
}
|
|
335
342
|
cp.isCreate = false;
|
|
336
343
|
cp.isQueryUpdate = false;
|
package/src/runtime/api.ts
CHANGED
|
@@ -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
|
}
|
package/src/runtime/defs.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
11
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
29
|
-
|
|
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
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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
|
|
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.
|
|
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
|
-
|
|
312
|
-
this.
|
|
311
|
+
setAssumedRole(s: string): Environment {
|
|
312
|
+
this.assumedRole = s;
|
|
313
313
|
return this;
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
-
|
|
317
|
-
return this.
|
|
316
|
+
getAssumedRole(): string | undefined {
|
|
317
|
+
return this.assumedRole;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
|
|
321
|
-
this.
|
|
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.
|
|
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?.
|
|
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
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
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
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
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.
|
|
2195
|
-
invokeDebugMsg = `${invokeDebugMsg}
|
|
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);
|
package/src/runtime/loader.ts
CHANGED
|
@@ -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 (
|
|
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);
|
package/src/runtime/logger.ts
CHANGED
|
@@ -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
|
|
47
|
+
transports: [fileTransport],
|
|
59
48
|
});
|
|
60
49
|
} else {
|
|
61
50
|
function mkLogger(tag: string): Function {
|
package/src/runtime/module.ts
CHANGED
|
@@ -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);
|