agentlang 0.10.1 → 0.10.3
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 +7 -14
- package/out/api/http.d.ts +4 -0
- package/out/api/http.d.ts.map +1 -1
- package/out/api/http.js +307 -26
- package/out/api/http.js.map +1 -1
- package/out/cli/main.d.ts.map +1 -1
- package/out/cli/main.js +3 -0
- package/out/cli/main.js.map +1 -1
- package/out/extension/main.cjs +250 -250
- package/out/extension/main.cjs.map +2 -2
- package/out/language/agentlang-validator.d.ts.map +1 -1
- package/out/language/agentlang-validator.js +4 -0
- package/out/language/agentlang-validator.js.map +1 -1
- package/out/language/error-reporter.d.ts +53 -0
- package/out/language/error-reporter.d.ts.map +1 -0
- package/out/language/error-reporter.js +879 -0
- package/out/language/error-reporter.js.map +1 -0
- package/out/language/generated/ast.d.ts +77 -2
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +60 -0
- 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 +342 -206
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +901 -710
- package/out/language/main.cjs.map +3 -3
- package/out/language/parser.d.ts +4 -2
- package/out/language/parser.d.ts.map +1 -1
- package/out/language/parser.js +58 -99
- package/out/language/parser.js.map +1 -1
- package/out/language/syntax.d.ts +16 -0
- package/out/language/syntax.d.ts.map +1 -1
- package/out/language/syntax.js +66 -27
- package/out/language/syntax.js.map +1 -1
- package/out/runtime/api.d.ts +2 -0
- package/out/runtime/api.d.ts.map +1 -1
- package/out/runtime/api.js +25 -0
- package/out/runtime/api.js.map +1 -1
- package/out/runtime/datefns.d.ts +34 -0
- package/out/runtime/datefns.d.ts.map +1 -0
- package/out/runtime/datefns.js +82 -0
- package/out/runtime/datefns.js.map +1 -0
- package/out/runtime/defs.d.ts +1 -0
- package/out/runtime/defs.d.ts.map +1 -1
- package/out/runtime/defs.js +2 -1
- package/out/runtime/defs.js.map +1 -1
- package/out/runtime/document-retriever.d.ts +24 -0
- package/out/runtime/document-retriever.d.ts.map +1 -0
- package/out/runtime/document-retriever.js +258 -0
- package/out/runtime/document-retriever.js.map +1 -0
- package/out/runtime/embeddings/chunker.d.ts +18 -0
- package/out/runtime/embeddings/chunker.d.ts.map +1 -1
- package/out/runtime/embeddings/chunker.js +47 -15
- 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 +22 -9
- package/out/runtime/embeddings/openai.js.map +1 -1
- package/out/runtime/embeddings/provider.d.ts +1 -0
- package/out/runtime/embeddings/provider.d.ts.map +1 -1
- package/out/runtime/embeddings/provider.js +20 -1
- package/out/runtime/embeddings/provider.js.map +1 -1
- package/out/runtime/exec-graph.d.ts.map +1 -1
- package/out/runtime/exec-graph.js +22 -3
- package/out/runtime/exec-graph.js.map +1 -1
- package/out/runtime/integration-client.d.ts +21 -0
- package/out/runtime/integration-client.d.ts.map +1 -0
- package/out/runtime/integration-client.js +112 -0
- package/out/runtime/integration-client.js.map +1 -0
- package/out/runtime/integrations.d.ts.map +1 -1
- package/out/runtime/integrations.js +20 -9
- package/out/runtime/integrations.js.map +1 -1
- package/out/runtime/interpreter.d.ts +10 -0
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +221 -22
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +70 -7
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/logger.d.ts.map +1 -1
- package/out/runtime/logger.js +8 -1
- package/out/runtime/logger.js.map +1 -1
- package/out/runtime/module.d.ts +18 -0
- package/out/runtime/module.d.ts.map +1 -1
- package/out/runtime/module.js +91 -3
- package/out/runtime/module.js.map +1 -1
- package/out/runtime/modules/ai.d.ts +16 -5
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +286 -88
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/modules/core.d.ts.map +1 -1
- package/out/runtime/modules/core.js +5 -1
- package/out/runtime/modules/core.js.map +1 -1
- package/out/runtime/monitor.d.ts +6 -0
- package/out/runtime/monitor.d.ts.map +1 -1
- package/out/runtime/monitor.js +21 -1
- package/out/runtime/monitor.js.map +1 -1
- package/out/runtime/relgraph.d.ts.map +1 -1
- package/out/runtime/relgraph.js +7 -3
- package/out/runtime/relgraph.js.map +1 -1
- package/out/runtime/resolvers/interface.d.ts +7 -2
- package/out/runtime/resolvers/interface.d.ts.map +1 -1
- package/out/runtime/resolvers/interface.js +17 -3
- package/out/runtime/resolvers/interface.js.map +1 -1
- package/out/runtime/resolvers/sqldb/database.d.ts +2 -0
- package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/database.js +142 -126
- package/out/runtime/resolvers/sqldb/database.js.map +1 -1
- package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/dbutil.js +25 -4
- package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.d.ts +2 -1
- package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.js +24 -7
- package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
- package/out/runtime/resolvers/vector/lancedb-store.d.ts +16 -0
- package/out/runtime/resolvers/vector/lancedb-store.d.ts.map +1 -0
- package/out/runtime/resolvers/vector/lancedb-store.js +159 -0
- package/out/runtime/resolvers/vector/lancedb-store.js.map +1 -0
- package/out/runtime/resolvers/vector/types.d.ts +32 -0
- package/out/runtime/resolvers/vector/types.d.ts.map +1 -0
- package/out/runtime/resolvers/vector/types.js +2 -0
- package/out/runtime/resolvers/vector/types.js.map +1 -0
- package/out/runtime/services/documentFetcher.d.ts.map +1 -1
- package/out/runtime/services/documentFetcher.js +21 -6
- package/out/runtime/services/documentFetcher.js.map +1 -1
- package/out/runtime/state.d.ts +19 -1
- package/out/runtime/state.d.ts.map +1 -1
- package/out/runtime/state.js +36 -1
- package/out/runtime/state.js.map +1 -1
- package/out/runtime/util.d.ts +3 -2
- package/out/runtime/util.d.ts.map +1 -1
- package/out/runtime/util.js +13 -2
- package/out/runtime/util.js.map +1 -1
- package/out/syntaxes/agentlang.monarch.js +1 -1
- package/out/syntaxes/agentlang.monarch.js.map +1 -1
- package/out/test-harness.d.ts +36 -0
- package/out/test-harness.d.ts.map +1 -0
- package/out/test-harness.js +341 -0
- package/out/test-harness.js.map +1 -0
- package/package.json +22 -19
- package/src/api/http.ts +336 -38
- package/src/cli/main.ts +3 -0
- package/src/language/agentlang-validator.ts +3 -0
- package/src/language/agentlang.langium +6 -2
- package/src/language/error-reporter.ts +1028 -0
- package/src/language/generated/ast.ts +94 -1
- package/src/language/generated/grammar.ts +342 -206
- package/src/language/parser.ts +64 -101
- package/src/language/syntax.ts +79 -24
- package/src/runtime/api.ts +36 -0
- package/src/runtime/datefns.ts +112 -0
- package/src/runtime/defs.ts +2 -1
- package/src/runtime/document-retriever.ts +311 -0
- package/src/runtime/embeddings/chunker.ts +52 -14
- package/src/runtime/embeddings/openai.ts +27 -9
- package/src/runtime/embeddings/provider.ts +22 -1
- package/src/runtime/exec-graph.ts +23 -2
- package/src/runtime/integration-client.ts +158 -0
- package/src/runtime/integrations.ts +20 -11
- package/src/runtime/interpreter.ts +221 -15
- package/src/runtime/loader.ts +83 -5
- package/src/runtime/logger.ts +12 -1
- package/src/runtime/module.ts +104 -3
- package/src/runtime/modules/ai.ts +341 -107
- package/src/runtime/modules/core.ts +5 -1
- package/src/runtime/monitor.ts +27 -1
- package/src/runtime/relgraph.ts +7 -3
- package/src/runtime/resolvers/interface.ts +23 -3
- package/src/runtime/resolvers/sqldb/database.ts +158 -130
- package/src/runtime/resolvers/sqldb/dbutil.ts +28 -6
- package/src/runtime/resolvers/sqldb/impl.ts +25 -7
- package/src/runtime/resolvers/vector/lancedb-store.ts +187 -0
- package/src/runtime/resolvers/vector/types.ts +39 -0
- package/src/runtime/services/documentFetcher.ts +21 -6
- package/src/runtime/state.ts +40 -1
- package/src/runtime/util.ts +19 -2
- package/src/syntaxes/agentlang.monarch.ts +1 -1
- package/src/test-harness.ts +423 -0
|
@@ -101,6 +101,10 @@ export class EmbeddingService {
|
|
|
101
101
|
return await this.provider.embedText(query);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
async embedTexts(texts: string[]): Promise<number[][]> {
|
|
105
|
+
return await this.provider.embedTexts(texts);
|
|
106
|
+
}
|
|
107
|
+
|
|
104
108
|
private averageEmbeddings(embeddings: number[][]): number[] {
|
|
105
109
|
if (embeddings.length === 0) return [];
|
|
106
110
|
const dimension = embeddings[0].length;
|
|
@@ -402,6 +406,8 @@ export class SqlDbResolver extends Resolver {
|
|
|
402
406
|
joinClauses: undefined,
|
|
403
407
|
intoSpec: undefined,
|
|
404
408
|
whereClauses: undefined,
|
|
409
|
+
limit: inst.limit,
|
|
410
|
+
offset: inst.offset,
|
|
405
411
|
};
|
|
406
412
|
const readOnlyAttrs = inst.record.getWriteOnlyAttributes();
|
|
407
413
|
const rslt: any =
|
|
@@ -480,16 +486,17 @@ export class SqlDbResolver extends Resolver {
|
|
|
480
486
|
public override async queryConnectedInstances(
|
|
481
487
|
relationship: Relationship,
|
|
482
488
|
connectedInstance: Instance,
|
|
483
|
-
inst: Instance
|
|
489
|
+
inst: Instance,
|
|
490
|
+
connectedAlias?: string
|
|
484
491
|
): Promise<Instance[]> {
|
|
485
492
|
let result = SqlDbResolver.EmptyResultSet;
|
|
486
493
|
if (relationship.isOneToOne()) {
|
|
487
|
-
const col = relationship.
|
|
494
|
+
const col = relationship.getAliasForConnected(connectedInstance, connectedAlias);
|
|
488
495
|
inst.addQuery(col, '=', connectedInstance.lookup(PathAttributeName));
|
|
489
496
|
return await this.queryInstances(inst, false);
|
|
490
497
|
} else {
|
|
491
|
-
const from = relationship.
|
|
492
|
-
const to = relationship.
|
|
498
|
+
const from = relationship.getAliasForConnected(connectedInstance, connectedAlias);
|
|
499
|
+
const to = relationship.getInverseAliasForConnected(connectedInstance, connectedAlias);
|
|
493
500
|
await getAllConnected(
|
|
494
501
|
asTableReference(inst.moduleName, inst.name),
|
|
495
502
|
inst.queryAttributesAsObject(),
|
|
@@ -566,6 +573,8 @@ export class SqlDbResolver extends Resolver {
|
|
|
566
573
|
joinClauses,
|
|
567
574
|
whereClauses,
|
|
568
575
|
intoSpec,
|
|
576
|
+
limit: inst.limit,
|
|
577
|
+
offset: inst.offset,
|
|
569
578
|
};
|
|
570
579
|
const rslt: any = await getManyByJoin(tableName, qspec, this.getDbContext(inst.getFqName()));
|
|
571
580
|
return rslt;
|
|
@@ -797,9 +806,18 @@ function ensureOneToOneAttributes(inst: Instance) {
|
|
|
797
806
|
const betRels = getAllBetweenRelationships();
|
|
798
807
|
getAllOneToOneRelationshipsForEntity(inst.moduleName, inst.name, betRels).forEach(
|
|
799
808
|
(re: Relationship) => {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
809
|
+
if (re.isSelfReferencing()) {
|
|
810
|
+
// Self-referencing one-to-one: ensure both alias columns have placeholder values
|
|
811
|
+
[re.node1.alias, re.node2.alias].forEach((n: string) => {
|
|
812
|
+
if (!inst.attributes.has(n)) {
|
|
813
|
+
inst.attributes.set(n, crypto.randomUUID());
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
} else {
|
|
817
|
+
const n = re.getInverseAliasFor(inst);
|
|
818
|
+
if (!inst.attributes.has(n)) {
|
|
819
|
+
inst.attributes.set(n, crypto.randomUUID());
|
|
820
|
+
}
|
|
803
821
|
}
|
|
804
822
|
}
|
|
805
823
|
);
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import * as lancedb from '@lancedb/lancedb';
|
|
2
|
+
import { Schema, Field, Float32, Utf8, FixedSizeList } from 'apache-arrow';
|
|
3
|
+
import { logger } from '../../logger.js';
|
|
4
|
+
import { VectorStore, VectorRecord, SearchResult, VectorStoreConfig } from './types.js';
|
|
5
|
+
|
|
6
|
+
export class LanceDBVectorStore implements VectorStore {
|
|
7
|
+
private db: lancedb.Connection | null = null;
|
|
8
|
+
private table: lancedb.Table | null = null;
|
|
9
|
+
private config: VectorStoreConfig;
|
|
10
|
+
|
|
11
|
+
constructor(config: VectorStoreConfig) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async init(): Promise<void> {
|
|
16
|
+
try {
|
|
17
|
+
const dbPath = this.config.inMemory
|
|
18
|
+
? 'memory://'
|
|
19
|
+
: this.config.dbname || `./data/vector-store/${this.config.moduleName}.lance`;
|
|
20
|
+
|
|
21
|
+
this.db = await lancedb.connect(dbPath);
|
|
22
|
+
|
|
23
|
+
const tableName = 'embeddings';
|
|
24
|
+
const tableNames = await this.db.tableNames();
|
|
25
|
+
|
|
26
|
+
if (tableNames.includes(tableName)) {
|
|
27
|
+
this.table = await this.db.openTable(tableName);
|
|
28
|
+
logger.info(`LanceDB table ${tableName} opened`);
|
|
29
|
+
} else {
|
|
30
|
+
const schema = new Schema([
|
|
31
|
+
new Field('id', new Utf8(), false),
|
|
32
|
+
new Field(
|
|
33
|
+
'embedding',
|
|
34
|
+
new FixedSizeList(this.config.vectorDimension, new Field('item', new Float32())),
|
|
35
|
+
false
|
|
36
|
+
),
|
|
37
|
+
new Field('tenantId', new Utf8(), true),
|
|
38
|
+
new Field('agentId', new Utf8(), true),
|
|
39
|
+
new Field('documentId', new Utf8(), true),
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
this.table = await this.db.createEmptyTable(tableName, schema);
|
|
43
|
+
logger.info(`LanceDB table ${tableName} created`);
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error('Failed to initialize LanceDB vector store:', error);
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async addEmbedding(record: VectorRecord): Promise<void> {
|
|
52
|
+
if (!this.table) {
|
|
53
|
+
throw new Error('Vector store not initialized. Call init() first.');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
await this.table.add([
|
|
58
|
+
{
|
|
59
|
+
id: record.id,
|
|
60
|
+
embedding: record.embedding,
|
|
61
|
+
tenantId: record.tenantId || null,
|
|
62
|
+
agentId: record.agentId || null,
|
|
63
|
+
documentId: record.documentId || null,
|
|
64
|
+
},
|
|
65
|
+
]);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
logger.error(`Failed to add embedding ${record.id}:`, error);
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async addEmbeddings(records: VectorRecord[]): Promise<void> {
|
|
73
|
+
if (!this.table) {
|
|
74
|
+
throw new Error('Vector store not initialized. Call init() first.');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const data = records.map(record => ({
|
|
79
|
+
id: record.id,
|
|
80
|
+
embedding: record.embedding,
|
|
81
|
+
tenantId: record.tenantId || null,
|
|
82
|
+
agentId: record.agentId || null,
|
|
83
|
+
documentId: record.documentId || null,
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
await this.table.add(data);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
logger.error(`Failed to add ${records.length} embeddings:`, error);
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async search(
|
|
94
|
+
embedding: number[],
|
|
95
|
+
tenantId?: string,
|
|
96
|
+
agentId?: string,
|
|
97
|
+
limit: number = 10
|
|
98
|
+
): Promise<SearchResult[]> {
|
|
99
|
+
if (!this.table) {
|
|
100
|
+
throw new Error('Vector store not initialized. Call init() first.');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
let query = this.table.vectorSearch(embedding).limit(limit);
|
|
105
|
+
|
|
106
|
+
// Build filter conditions for agent-level isolation
|
|
107
|
+
const filters: string[] = [];
|
|
108
|
+
|
|
109
|
+
if (tenantId) {
|
|
110
|
+
// Use parameterized filtering to prevent SQL injection
|
|
111
|
+
const escapedTenantId = tenantId.replace(/'/g, "''");
|
|
112
|
+
filters.push(`tenantId = '${escapedTenantId}'`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (agentId) {
|
|
116
|
+
// Add agent-level filtering for strict agent isolation
|
|
117
|
+
const escapedAgentId = agentId.replace(/'/g, "''");
|
|
118
|
+
filters.push(`agentId = '${escapedAgentId}'`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (filters.length > 0) {
|
|
122
|
+
query = query.where(filters.join(' AND '));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const results = await query.toArray();
|
|
126
|
+
|
|
127
|
+
return results.map((row: any) => ({
|
|
128
|
+
id: row.id,
|
|
129
|
+
distance: row._distance || 0,
|
|
130
|
+
tenantId: row.tenantId,
|
|
131
|
+
agentId: row.agentId,
|
|
132
|
+
documentId: row.documentId,
|
|
133
|
+
}));
|
|
134
|
+
} catch (error) {
|
|
135
|
+
logger.error('Failed to search embeddings:', error);
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async delete(id: string): Promise<void> {
|
|
141
|
+
if (!this.table) {
|
|
142
|
+
throw new Error('Vector store not initialized. Call init() first.');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
await this.table.delete(`id = '${id}'`);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
logger.error(`Failed to delete embedding ${id}:`, error);
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async exists(id: string): Promise<boolean> {
|
|
154
|
+
if (!this.table) {
|
|
155
|
+
throw new Error('Vector store not initialized. Call init() first.');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
const results = await this.table.query().where(`id = '${id}'`).limit(1).toArray();
|
|
160
|
+
return results.length > 0;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
logger.error(`Failed to check existence of ${id}:`, error);
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async close(): Promise<void> {
|
|
168
|
+
try {
|
|
169
|
+
if (this.table) {
|
|
170
|
+
// LanceDB tables don't have explicit close method
|
|
171
|
+
this.table = null;
|
|
172
|
+
}
|
|
173
|
+
if (this.db) {
|
|
174
|
+
// Note: LanceDB connection doesn't have explicit close method
|
|
175
|
+
this.db = null;
|
|
176
|
+
}
|
|
177
|
+
logger.info('LanceDB vector store closed');
|
|
178
|
+
} catch (error) {
|
|
179
|
+
logger.error('Failed to close LanceDB vector store:', error);
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function createLanceDBStore(config: VectorStoreConfig): VectorStore {
|
|
186
|
+
return new LanceDBVectorStore(config);
|
|
187
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface VectorRecord {
|
|
2
|
+
id: string;
|
|
3
|
+
embedding: number[];
|
|
4
|
+
tenantId?: string;
|
|
5
|
+
agentId?: string;
|
|
6
|
+
documentId?: string;
|
|
7
|
+
metadata?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface SearchResult {
|
|
11
|
+
id: string;
|
|
12
|
+
distance: number;
|
|
13
|
+
tenantId?: string;
|
|
14
|
+
agentId?: string;
|
|
15
|
+
documentId?: string;
|
|
16
|
+
metadata?: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface VectorStore {
|
|
20
|
+
init(): Promise<void>;
|
|
21
|
+
addEmbedding(record: VectorRecord): Promise<void>;
|
|
22
|
+
addEmbeddings(records: VectorRecord[]): Promise<void>;
|
|
23
|
+
search(
|
|
24
|
+
embedding: number[],
|
|
25
|
+
tenantId?: string,
|
|
26
|
+
agentId?: string,
|
|
27
|
+
limit?: number
|
|
28
|
+
): Promise<SearchResult[]>;
|
|
29
|
+
delete(id: string): Promise<void>;
|
|
30
|
+
exists(id: string): Promise<boolean>;
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface VectorStoreConfig {
|
|
35
|
+
dbname?: string;
|
|
36
|
+
moduleName: string;
|
|
37
|
+
vectorDimension: number;
|
|
38
|
+
inMemory?: boolean;
|
|
39
|
+
}
|
|
@@ -68,6 +68,7 @@ class DocumentFetcherService {
|
|
|
68
68
|
|
|
69
69
|
async fetchDocument(config: DocumentConfig): Promise<FetchedDocument | null> {
|
|
70
70
|
this.ensureNodeEnv();
|
|
71
|
+
logger.info(`[DOC-FETCH] Starting fetch for: ${config.title}`);
|
|
71
72
|
const cacheKey = `${config.title}:${config.url || config.documentServiceId}`;
|
|
72
73
|
const cached = this.documentCache.get(cacheKey);
|
|
73
74
|
|
|
@@ -79,6 +80,7 @@ class DocumentFetcherService {
|
|
|
79
80
|
try {
|
|
80
81
|
let content: string;
|
|
81
82
|
let sourceUrl: string;
|
|
83
|
+
logger.info(`[DOC-FETCH] Fetching from URL: ${config.url}`);
|
|
82
84
|
|
|
83
85
|
if (config.url?.startsWith('document-service://')) {
|
|
84
86
|
if (!config.retrievalConfig || config.retrievalConfig.provider !== 'document-service') {
|
|
@@ -144,8 +146,10 @@ class DocumentFetcherService {
|
|
|
144
146
|
content = await this.fetchFromUrl(config.url);
|
|
145
147
|
sourceUrl = config.url;
|
|
146
148
|
} else if (config.url) {
|
|
149
|
+
logger.info(`[DOC-FETCH] Fetching from local file: ${config.url}`);
|
|
147
150
|
content = await this.fetchFromLocal(config.url);
|
|
148
151
|
sourceUrl = config.url;
|
|
152
|
+
logger.info(`[DOC-FETCH] Local file fetched successfully: ${content.length} chars`);
|
|
149
153
|
} else {
|
|
150
154
|
if (this.documentServiceConfig) {
|
|
151
155
|
const docId = await this.lookupDocumentByTitle(config.title);
|
|
@@ -171,7 +175,9 @@ class DocumentFetcherService {
|
|
|
171
175
|
|
|
172
176
|
this.documentCache.set(cacheKey, document);
|
|
173
177
|
|
|
178
|
+
logger.info(`[DOC-FETCH] Creating Document entity for: ${config.title}`);
|
|
174
179
|
await this.createDocumentEntity(document);
|
|
180
|
+
logger.info(`[DOC-FETCH] Document entity created successfully for: ${config.title}`);
|
|
175
181
|
|
|
176
182
|
return document;
|
|
177
183
|
} catch (error) {
|
|
@@ -443,11 +449,14 @@ class DocumentFetcherService {
|
|
|
443
449
|
|
|
444
450
|
private async fetchFromLocal(filePath: string): Promise<string> {
|
|
445
451
|
try {
|
|
452
|
+
logger.info(`[DOC-FETCH] Reading local file: ${filePath}`);
|
|
446
453
|
const content = await readFile(filePath);
|
|
454
|
+
logger.info(`[DOC-FETCH] File read successfully: ${content.length} chars`);
|
|
447
455
|
const lowerPath = filePath.toLowerCase();
|
|
448
456
|
const isMarkdown = lowerPath.endsWith('.md') || lowerPath.endsWith('.markdown');
|
|
449
457
|
|
|
450
458
|
if (isMarkdown) {
|
|
459
|
+
logger.info(`[DOC-FETCH] Parsing markdown...`);
|
|
451
460
|
return this.parseMarkdownText(content);
|
|
452
461
|
}
|
|
453
462
|
|
|
@@ -547,10 +556,11 @@ class DocumentFetcherService {
|
|
|
547
556
|
// Lazy load PDF parser
|
|
548
557
|
if (!this.pdfParser) {
|
|
549
558
|
try {
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
559
|
+
const { PDFParse } = await import('pdf-parse');
|
|
560
|
+
if (!PDFParse) {
|
|
561
|
+
throw new Error('pdf-parse does not export PDFParse');
|
|
562
|
+
}
|
|
563
|
+
this.pdfParser = PDFParse;
|
|
554
564
|
} catch (error) {
|
|
555
565
|
logger.error('Failed to load PDF parser', { error });
|
|
556
566
|
throw new Error(
|
|
@@ -560,11 +570,16 @@ class DocumentFetcherService {
|
|
|
560
570
|
}
|
|
561
571
|
|
|
562
572
|
try {
|
|
563
|
-
const
|
|
573
|
+
const parser = new this.pdfParser({ data: buffer });
|
|
574
|
+
const result = await parser.getText();
|
|
575
|
+
if (typeof parser.destroy === 'function') {
|
|
576
|
+
await parser.destroy();
|
|
577
|
+
}
|
|
564
578
|
return result.text || '';
|
|
565
579
|
} catch (error) {
|
|
566
580
|
logger.error('PDF parsing failed', { error });
|
|
567
|
-
|
|
581
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
582
|
+
throw new Error(`Failed to parse PDF: ${message}`);
|
|
568
583
|
}
|
|
569
584
|
}
|
|
570
585
|
|
package/src/runtime/state.ts
CHANGED
|
@@ -35,6 +35,21 @@ export const ConfigSchema = z.object({
|
|
|
35
35
|
type: z.literal('sqlite'),
|
|
36
36
|
dbname: z.string().optional(),
|
|
37
37
|
}),
|
|
38
|
+
z.object({
|
|
39
|
+
type: z.literal('lancedb'),
|
|
40
|
+
path: z.string().optional(),
|
|
41
|
+
}),
|
|
42
|
+
])
|
|
43
|
+
.optional(),
|
|
44
|
+
vectorStore: z
|
|
45
|
+
.discriminatedUnion('type', [
|
|
46
|
+
z.object({
|
|
47
|
+
type: z.literal('pgvector'),
|
|
48
|
+
}),
|
|
49
|
+
z.object({
|
|
50
|
+
type: z.literal('lancedb'),
|
|
51
|
+
dbname: z.string().optional(),
|
|
52
|
+
}),
|
|
38
53
|
])
|
|
39
54
|
.optional(),
|
|
40
55
|
integrations: z
|
|
@@ -42,7 +57,17 @@ export const ConfigSchema = z.object({
|
|
|
42
57
|
host: z.string(),
|
|
43
58
|
username: z.string().optional(),
|
|
44
59
|
password: z.string().optional(),
|
|
45
|
-
connections: z.record(
|
|
60
|
+
connections: z.record(
|
|
61
|
+
z.string(),
|
|
62
|
+
z.union([
|
|
63
|
+
z.string(),
|
|
64
|
+
z.object({
|
|
65
|
+
config: z.string(),
|
|
66
|
+
resolvers: z.array(z.string()),
|
|
67
|
+
}),
|
|
68
|
+
])
|
|
69
|
+
),
|
|
70
|
+
oauth: z.boolean().default(false),
|
|
46
71
|
})
|
|
47
72
|
.optional(),
|
|
48
73
|
graphql: z
|
|
@@ -71,6 +96,11 @@ export const ConfigSchema = z.object({
|
|
|
71
96
|
enabled: z.boolean().default(false),
|
|
72
97
|
})
|
|
73
98
|
.optional(),
|
|
99
|
+
knowledgeGraph: z
|
|
100
|
+
.object({
|
|
101
|
+
serviceUrl: z.string().default('#js process.env.KNOWLEDGE_SERVICE_URL || ""'),
|
|
102
|
+
})
|
|
103
|
+
.optional(),
|
|
74
104
|
authentication: z
|
|
75
105
|
.discriminatedUnion('service', [
|
|
76
106
|
z.object({
|
|
@@ -155,6 +185,15 @@ export function isMonitoringEnabled(): boolean {
|
|
|
155
185
|
return internalMonitoringEnabled || AppConfig?.monitoring?.enabled === true;
|
|
156
186
|
}
|
|
157
187
|
|
|
188
|
+
export function isKnowledgeGraphEnabled(): boolean {
|
|
189
|
+
const url = AppConfig?.knowledgeGraph?.serviceUrl?.trim();
|
|
190
|
+
return !!(url && url.length > 0) || !!process.env.KNOWLEDGE_SERVICE_URL;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function getKnowledgeGraphConfig(): Config['knowledgeGraph'] | undefined {
|
|
194
|
+
return AppConfig?.knowledgeGraph;
|
|
195
|
+
}
|
|
196
|
+
|
|
158
197
|
type TtlCacheEntry<T> = {
|
|
159
198
|
value: T;
|
|
160
199
|
expireTime: number;
|
package/src/runtime/util.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { isNodeEnv, path } from '../utils/runtime.js';
|
|
|
2
2
|
import {
|
|
3
3
|
AliasSpec,
|
|
4
4
|
CatchSpec,
|
|
5
|
+
EmptySpec,
|
|
5
6
|
ExtendsClause,
|
|
6
7
|
isLiteral,
|
|
7
8
|
MapEntry,
|
|
@@ -441,6 +442,18 @@ export function firstCatchSpec(stmt: Statement): CatchSpec | undefined {
|
|
|
441
442
|
return undefined;
|
|
442
443
|
}
|
|
443
444
|
|
|
445
|
+
export function firstEmptySpec(stmt: Statement): EmptySpec | undefined {
|
|
446
|
+
if (stmt.hints) {
|
|
447
|
+
for (let i = 0; i < stmt.hints.length; ++i) {
|
|
448
|
+
const rh = stmt.hints[i];
|
|
449
|
+
if (rh.emptySpec) {
|
|
450
|
+
return rh.emptySpec;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return undefined;
|
|
455
|
+
}
|
|
456
|
+
|
|
444
457
|
function maybeExtractEntryName(n: string): string {
|
|
445
458
|
const i = n.indexOf('$');
|
|
446
459
|
if (i > 0) {
|
|
@@ -671,7 +684,11 @@ export type ExtractedText = {
|
|
|
671
684
|
};
|
|
672
685
|
|
|
673
686
|
// extract all data between a given xml tag from within an arbitray text.
|
|
674
|
-
export function extractAndRemoveAllXmlTaggedText(
|
|
687
|
+
export function extractAndRemoveAllXmlTaggedText(
|
|
688
|
+
text: string,
|
|
689
|
+
tagName: string,
|
|
690
|
+
replaceWith: string = ''
|
|
691
|
+
): ExtractedText {
|
|
675
692
|
const pattern = `<${tagName}\\b[^>]*>([\\s\\S]*?)</${tagName}>`;
|
|
676
693
|
const regex = new RegExp(pattern, 'gi');
|
|
677
694
|
|
|
@@ -683,7 +700,7 @@ export function extractAndRemoveAllXmlTaggedText(text: string, tagName: string):
|
|
|
683
700
|
extracted.push(match[1]);
|
|
684
701
|
}
|
|
685
702
|
|
|
686
|
-
updatedText = text.replace(regex,
|
|
703
|
+
updatedText = text.replace(regex, replaceWith);
|
|
687
704
|
|
|
688
705
|
return { extracted, updatedText };
|
|
689
706
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Monarch syntax highlighting for the agentlang language.
|
|
2
2
|
export default {
|
|
3
3
|
keywords: [
|
|
4
|
-
'@actions','@after','@as','@asc','@async','@before','@catch','@desc','@distinct','@enum','@expr','@from','@full_join','@groupBy','@inner_join','@into','@join','@left_join','@meta','@oneof','@orderBy','@public','@rbac','@ref','@right_join','@then','@upsert','@where','@withRole','@with_unique','agent','agentlang/retry','allow','and','attempts','await','backoff','between','case','commitTransaction','contains','create','decision','delete','directive','else','entity','error','eval','event','extends','false','flow','for','glossaryEntry','if','import','in','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','rollbackTransaction','scenario','startTransaction','subscribe','throw','true','update','upsert','where','workflow'
|
|
4
|
+
'@actions','@after','@as','@asc','@async','@before','@catch','@desc','@distinct','@empty','@enum','@expr','@from','@full_join','@groupBy','@inner_join','@into','@join','@left_join','@limit','@meta','@offset','@oneof','@orderBy','@public','@rbac','@ref','@right_join','@then','@upsert','@where','@withRole','@with_unique','agent','agentlang/retry','allow','and','attempts','await','backoff','between','case','commitTransaction','contains','create','decision','delete','directive','else','entity','error','eval','event','extends','false','flow','for','glossaryEntry','if','import','in','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','rollbackTransaction','scenario','startTransaction','subscribe','throw','true','update','upsert','where','workflow'
|
|
5
5
|
],
|
|
6
6
|
operators: [
|
|
7
7
|
'!=','*','+',',','-','-->','.','/',':',';','<','<=','<>','=','==','>','>=','?','@'
|