langium-ai-tools 4.1.0 → 4.1.2

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 CHANGED
@@ -26,10 +26,10 @@ Langium AI tools tracks tightly with Langium releases. If you're using Langium 3
26
26
 
27
27
  ```bash
28
28
  # if you're using Langium 4.1.X
29
- npm i --save langium@^4.1.0
29
+ npm i --save langium-ai-tools@^4.1.0
30
30
 
31
31
  # or 3.5.X
32
- npm i --save langium@^3.5.0
32
+ npm i --save langium-ai-tools@^3.5.0
33
33
  ```
34
34
 
35
35
  We don't actively support Langium 2.X or earlier.
@@ -45,7 +45,7 @@ Langium AI Tools presents various splitting utilities that are simple but flexib
45
45
 
46
46
  For example, if you have a DSL that looks like this:
47
47
 
48
- ```dsl
48
+ ```
49
49
  // A dsl that allows writing functions...
50
50
  function foo() { ... }
51
51
  function bar() { ... }
@@ -66,7 +66,7 @@ const chunks: string[] = splitByNode(
66
66
  ```
67
67
 
68
68
  And you would get back something like this:
69
- ```json
69
+ ```
70
70
  [
71
71
  'function foo() { ... }',
72
72
  'function bar() { ... }'
@@ -100,7 +100,7 @@ const programMap: string[] = mapper.map(myProg);
100
100
 
101
101
  Which would give you an output like so:
102
102
 
103
- ```json
103
+ ```
104
104
  [
105
105
  'func foo',
106
106
  'func bar'
@@ -0,0 +1,126 @@
1
+ /******************************************************************************
2
+ * Copyright 2025 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ *
6
+ * @author Dennis Hübner
7
+ ******************************************************************************/
8
+ import { Grammar, GrammarAST, LangiumDocument } from "langium";
9
+ import { LangiumServices } from "langium/lsp";
10
+ import { EvaluationContext } from "../evaluator/document-evaluator.js";
11
+ import { EvaluatorResult } from "../evaluator/evaluator.js";
12
+ import { LangiumEvaluator, LangiumEvaluatorResultData } from "../evaluator/langium-evaluator.js";
13
+ /**
14
+ * Extends LangiumEvaluator and adds analysis capabilities.
15
+ */
16
+ export declare class LangiumDocumentAnalyzer<T extends LangiumServices> extends LangiumEvaluator<T> {
17
+ static readonly METADATA_KEY = "syntax_statistics";
18
+ private readonly analysisOptions;
19
+ /**
20
+ * Creates an instance of LangiumDocumentAnalyzer.
21
+ * @param services Langium services
22
+ * @param analysisOptions Analysis options
23
+ * @example
24
+ * ```typescript
25
+ * const analyzer = new LangiumDocumentAnalyzer(services, {
26
+ * analysisMode: AnalysisMode.ALL,
27
+ * excludeRules: ['DeprecatedRule'],
28
+ * computeDiversity: false
29
+ * });
30
+ * ```
31
+ */
32
+ constructor(services: T, analysisOptions?: Partial<AnalysisOptions>);
33
+ evaluateDocument(doc: LangiumDocument, ctx: EvaluationContext): EvaluatorResult<LangiumEvaluatorResultData>;
34
+ collectSyntaxUsageStatistics(doc: LangiumDocument, grammar: Grammar): SyntaxStatistic;
35
+ /**
36
+ * Computes coverage as percentage of used rules over all available rules
37
+ */
38
+ computeCoverage(ruleUsage: Record<string, number>): number;
39
+ /**
40
+ * Computes Shannon entropy - measure of information diversity
41
+ * Higher values indicate more diverse usage patterns
42
+ */
43
+ computeEntropy(ruleUsage: Record<string, number>): number;
44
+ /**
45
+ * Computes Gini coefficient - measure of inequality in rule usage
46
+ * 0 = perfect equality, 1 = maximum inequality
47
+ */
48
+ computeGiniCoefficient(ruleUsage: Record<string, number>): number;
49
+ /**
50
+ * Computes Simpson's diversity index - probability that two randomly selected items are different
51
+ * Higher values indicate more diversity
52
+ */
53
+ computeSimpsonIndex(ruleUsage: Record<string, number>): number;
54
+ /**
55
+ * Extracts syntax statistics from the evaluation result.
56
+ * @param result The evaluation result.
57
+ * @returns The extracted syntax statistics or undefined if not found.
58
+ */
59
+ extractStatisticsFromResult(result: Partial<EvaluatorResult> | undefined): SyntaxStatistic | undefined;
60
+ protected collectAllRules(grammar: Grammar): GrammarAST.AbstractRule[];
61
+ protected createEmptySyntaxStatistic(): SyntaxStatistic;
62
+ }
63
+ /**
64
+ * Analysis mode for controlling what analysis operations to perform
65
+ */
66
+ export declare enum AnalysisMode {
67
+ ALL = "ALL",
68
+ NO_STATISTIC = "NO_STATISTIC"
69
+ }
70
+ interface AnalysisOptions {
71
+ analysisMode: AnalysisMode;
72
+ /**
73
+ * Filter for specific rules (e.g deprecated) to exclude in the analysis.
74
+ * Rule WS (whitespace) is always excluded.
75
+ */
76
+ excludeRules: string[];
77
+ /**
78
+ * Whether to include rules from imported grammars. Default is true.
79
+ */
80
+ includeImportedRules: boolean;
81
+ /**
82
+ * Whether to include hidden tokens (like comments, whitespace) in the analysis. Default is false.
83
+ * Rule WS (whitespace) is always excluded.
84
+ */
85
+ includeHiddenRules: boolean;
86
+ /**
87
+ * Whether to compute diversity metrics for rule usage. Default is true.
88
+ */
89
+ computeDiversity: boolean;
90
+ }
91
+ /**
92
+ * Type representing syntax usage statistics.
93
+ */
94
+ export type SyntaxStatistic = {
95
+ /** Map of rule names to their usage counts */
96
+ ruleUsage: Record<string, number>;
97
+ /** Percentage of used rules compared to all available rules */
98
+ coverage: number;
99
+ /** Diversity metrics for rule usage patterns */
100
+ diversity: {
101
+ /**
102
+ * Shannon entropy - information diversity measure.
103
+ * **Range:** 0 to log₂(n) where n = number of rules.
104
+ * - **Low (0-1):** dominated by few rules
105
+ * - **Medium (1-3):** moderate diversity
106
+ * - **High (>3):** high diversity
107
+ */
108
+ entropy: number;
109
+ /**
110
+ * Gini coefficient - inequality measure. Range: 0 to 1.
111
+ * - **Low (0-0.3):** equal distribution
112
+ * - **Medium (0.3-0.7):** moderate inequality
113
+ * - **High (0.7-1):** high inequality
114
+ */
115
+ giniCoefficient: number;
116
+ /**
117
+ * Simpson's diversity index - probability that two randomly selected items are different. **Range:** 0 to 1.
118
+ * - **Low (0-0.3):** low diversity
119
+ * - **Medium (0.3-0.7):** moderate diversity
120
+ * - **High (0.7-1):** high diversity
121
+ */
122
+ simpsonIndex: number;
123
+ };
124
+ };
125
+ export {};
126
+ //# sourceMappingURL=document-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/document-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;gFAMgF;AAEhF,OAAO,EAAY,OAAO,EAAE,UAAU,EAAE,eAAe,EAAiB,MAAM,SAAS,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAEjG;;GAEG;AACH,qBAAa,uBAAuB,CAAC,CAAC,SAAS,eAAe,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAEvF,gBAAuB,YAAY,uBAAuB;IAE1D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAElD;;;;;;;;;;;;OAYG;gBACS,QAAQ,EAAE,CAAC,EAAE,eAAe,GAAE,OAAO,CAAC,eAAe,CAAM;IAKvE,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,0BAA0B,CAAC;IAU3G,4BAA4B,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;IAqDrF;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAK1D;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAczD;;;OAGG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAejE;;;OAGG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAa9D;;;;OAIG;IACH,2BAA2B,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS;IAQtG,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC,YAAY,EAAE;IAWtE,SAAS,CAAC,0BAA0B,IAAI,eAAe;CAW1D;AAED;;GAEG;AACH,oBAAY,YAAY;IACpB,GAAG,QAAQ;IACX,YAAY,iBAAiB;CAChC;AAED,UAAU,eAAe;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B;;;OAGG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;OAEG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAUD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC1B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IAEjB,gDAAgD;IAChD,SAAS,EAAE;QAEP;;;;;;WAMG;QACH,OAAO,EAAE,MAAM,CAAC;QAEhB;;;;;WAKG;QACH,eAAe,EAAE,MAAM,CAAC;QAExB;;;;;WAKG;QACH,YAAY,EAAE,MAAM,CAAC;KACxB,CAAC;CACL,CAAA"}
@@ -0,0 +1,193 @@
1
+ /******************************************************************************
2
+ * Copyright 2025 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ *
6
+ * @author Dennis Hübner
7
+ ******************************************************************************/
8
+ import { CstUtils, GrammarAST, isLeafCstNode } from "langium";
9
+ import { resolveTransitiveImports, } from 'langium/grammar';
10
+ import { LangiumEvaluator } from "../evaluator/langium-evaluator.js";
11
+ /**
12
+ * Extends LangiumEvaluator and adds analysis capabilities.
13
+ */
14
+ export class LangiumDocumentAnalyzer extends LangiumEvaluator {
15
+ /**
16
+ * Creates an instance of LangiumDocumentAnalyzer.
17
+ * @param services Langium services
18
+ * @param analysisOptions Analysis options
19
+ * @example
20
+ * ```typescript
21
+ * const analyzer = new LangiumDocumentAnalyzer(services, {
22
+ * analysisMode: AnalysisMode.ALL,
23
+ * excludeRules: ['DeprecatedRule'],
24
+ * computeDiversity: false
25
+ * });
26
+ * ```
27
+ */
28
+ constructor(services, analysisOptions = {}) {
29
+ super(services);
30
+ this.analysisOptions = { ...DEFAULT_OPTIONS, ...analysisOptions };
31
+ }
32
+ evaluateDocument(doc, ctx) {
33
+ const validationResult = super.evaluateDocument(doc, ctx);
34
+ if (this.analysisOptions.analysisMode !== AnalysisMode.NO_STATISTIC && validationResult.data.failures === 0) {
35
+ // Add syntax usage statistics only if build was successful
36
+ const statistics = this.collectSyntaxUsageStatistics(doc, this.services.Grammar);
37
+ validationResult.metadata[LangiumDocumentAnalyzer.METADATA_KEY] = statistics;
38
+ }
39
+ return validationResult;
40
+ }
41
+ collectSyntaxUsageStatistics(doc, grammar) {
42
+ const rootCstNode = doc.parseResult.value.$cstNode;
43
+ if (!rootCstNode) {
44
+ return this.createEmptySyntaxStatistic();
45
+ }
46
+ const { includeImportedRules, excludeRules, computeDiversity, includeHiddenRules } = this.analysisOptions;
47
+ const excludedRules = new Set(excludeRules);
48
+ const isRuleExcluded = (ruleName) => ruleName === 'WS' || excludedRules.has(ruleName);
49
+ const allRules = includeImportedRules ? this.collectAllRules(grammar) : grammar.rules;
50
+ const ruleUsage = {};
51
+ // Initialize rule usage map, excluding rules specified in excludeRules. Also skip entry rule.
52
+ for (const rule of allRules) {
53
+ if (!isRuleExcluded(rule.name)) {
54
+ if ((GrammarAST.isParserRule(rule) && rule.entry)
55
+ || (GrammarAST.isTerminalRule(rule) && rule.hidden && !includeHiddenRules)) {
56
+ continue;
57
+ }
58
+ ruleUsage[rule.name] = 0;
59
+ }
60
+ }
61
+ for (const cstNode of CstUtils.streamCst(rootCstNode)) {
62
+ const grammarSource = cstNode.grammarSource;
63
+ const addIfNotExcluded = (ruleName) => {
64
+ if (!isRuleExcluded(ruleName)) {
65
+ ruleUsage[ruleName] = (ruleUsage[ruleName] ?? 0) + 1;
66
+ }
67
+ };
68
+ if (grammarSource && GrammarAST.isRuleCall(grammarSource)) {
69
+ // For now handle only RuleCalls
70
+ addIfNotExcluded(grammarSource.rule.ref?.name ?? 'unknown');
71
+ }
72
+ else if (includeHiddenRules && cstNode.hidden && isLeafCstNode(cstNode)) {
73
+ addIfNotExcluded(cstNode.tokenType.name);
74
+ }
75
+ }
76
+ let diversity = { entropy: 0, giniCoefficient: 0, simpsonIndex: 0 };
77
+ if (computeDiversity) {
78
+ diversity = {
79
+ entropy: this.computeEntropy(ruleUsage),
80
+ giniCoefficient: this.computeGiniCoefficient(ruleUsage),
81
+ simpsonIndex: this.computeSimpsonIndex(ruleUsage)
82
+ };
83
+ }
84
+ const coverage = this.computeCoverage(ruleUsage);
85
+ return { ruleUsage, coverage, diversity };
86
+ }
87
+ /**
88
+ * Computes coverage as percentage of used rules over all available rules
89
+ */
90
+ computeCoverage(ruleUsage) {
91
+ const usedRules = Object.values(ruleUsage).filter(count => count > 0).length;
92
+ return usedRules > 0 ? (usedRules / Object.keys(ruleUsage).length) * 100 : 0;
93
+ }
94
+ /**
95
+ * Computes Shannon entropy - measure of information diversity
96
+ * Higher values indicate more diverse usage patterns
97
+ */
98
+ computeEntropy(ruleUsage) {
99
+ const totalUsage = Object.values(ruleUsage).reduce((sum, count) => sum + count, 0);
100
+ if (totalUsage === 0)
101
+ return 0;
102
+ let entropy = 0;
103
+ for (const count of Object.values(ruleUsage)) {
104
+ if (count > 0) {
105
+ const probability = count / totalUsage;
106
+ entropy -= probability * Math.log2(probability);
107
+ }
108
+ }
109
+ return entropy;
110
+ }
111
+ /**
112
+ * Computes Gini coefficient - measure of inequality in rule usage
113
+ * 0 = perfect equality, 1 = maximum inequality
114
+ */
115
+ computeGiniCoefficient(ruleUsage) {
116
+ const counts = Object.values(ruleUsage).sort((a, b) => a - b);
117
+ const n = counts.length;
118
+ if (n === 0)
119
+ return 0;
120
+ const sum = counts.reduce((acc, val) => acc + val, 0);
121
+ if (sum === 0)
122
+ return 0;
123
+ let numerator = 0;
124
+ for (let i = 0; i < n; i++) {
125
+ numerator += (2 * (i + 1) - n - 1) * counts[i];
126
+ }
127
+ return numerator / (n * sum);
128
+ }
129
+ /**
130
+ * Computes Simpson's diversity index - probability that two randomly selected items are different
131
+ * Higher values indicate more diversity
132
+ */
133
+ computeSimpsonIndex(ruleUsage) {
134
+ const totalUsage = Object.values(ruleUsage).reduce((sum, count) => sum + count, 0);
135
+ if (totalUsage === 0)
136
+ return 0;
137
+ let sum = 0;
138
+ for (const count of Object.values(ruleUsage)) {
139
+ const probability = count / totalUsage;
140
+ sum += probability * probability;
141
+ }
142
+ return 1 - sum; // Simpson's diversity index (1-D)
143
+ }
144
+ /**
145
+ * Extracts syntax statistics from the evaluation result.
146
+ * @param result The evaluation result.
147
+ * @returns The extracted syntax statistics or undefined if not found.
148
+ */
149
+ extractStatisticsFromResult(result) {
150
+ const metadata = result?.metadata;
151
+ if (metadata && metadata[LangiumDocumentAnalyzer.METADATA_KEY]) {
152
+ return metadata[LangiumDocumentAnalyzer.METADATA_KEY];
153
+ }
154
+ return undefined;
155
+ }
156
+ collectAllRules(grammar) {
157
+ try {
158
+ return grammar.rules.concat(resolveTransitiveImports(this.services.shared.workspace.LangiumDocuments, grammar).map(g => g.rules).flat());
159
+ }
160
+ catch (e) {
161
+ console.error('Error resolving imports: ', e);
162
+ return [];
163
+ }
164
+ }
165
+ createEmptySyntaxStatistic() {
166
+ return {
167
+ ruleUsage: {},
168
+ coverage: 0,
169
+ diversity: {
170
+ entropy: 0,
171
+ giniCoefficient: 0,
172
+ simpsonIndex: 0
173
+ }
174
+ };
175
+ }
176
+ }
177
+ LangiumDocumentAnalyzer.METADATA_KEY = 'syntax_statistics';
178
+ /**
179
+ * Analysis mode for controlling what analysis operations to perform
180
+ */
181
+ export var AnalysisMode;
182
+ (function (AnalysisMode) {
183
+ AnalysisMode["ALL"] = "ALL";
184
+ AnalysisMode["NO_STATISTIC"] = "NO_STATISTIC";
185
+ })(AnalysisMode || (AnalysisMode = {}));
186
+ const DEFAULT_OPTIONS = {
187
+ analysisMode: AnalysisMode.ALL,
188
+ excludeRules: [],
189
+ includeImportedRules: true,
190
+ includeHiddenRules: true,
191
+ computeDiversity: true
192
+ };
193
+ //# sourceMappingURL=document-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/document-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /******************************************************************************
2
+ * Copyright 2025 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ export * from './document-analyzer.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /******************************************************************************
2
+ * Copyright 2025 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ export * from './document-analyzer.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /******************************************************************************
2
+ * Copyright 2024 - 2025 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ /**
7
+ * Langium Document Evaluator (evaluates on a Langium document)
8
+ */
9
+ import { LangiumDocument } from "langium";
10
+ import { LangiumServices } from "langium/lsp";
11
+ import { Evaluator, EvaluatorResult, EvaluatorResultData } from "./evaluator.js";
12
+ export declare abstract class AbstractDocumentEvaluator<T extends LangiumServices, RD extends FailureAwarenessData = FailureAwarenessData> extends Evaluator {
13
+ /**
14
+ * Services to use for evaluation
15
+ */
16
+ protected services: T;
17
+ constructor(services: T);
18
+ /**
19
+ * Validate an agent response as if it's a langium program. If we can parse it, we attempt to validate it.
20
+ */
21
+ evaluate(input: string, fileExtension?: string | undefined): Promise<Partial<EvaluatorResult<RD>>>;
22
+ abstract evaluateDocument(doc: LangiumDocument, ctx: EvaluationContext): Partial<EvaluatorResult<RD>>;
23
+ protected handleBuildError(e: unknown, ctx: EvaluationContext): Partial<EvaluatorResult<RD>>;
24
+ }
25
+ export type FailureAwarenessData = EvaluatorResultData & {
26
+ /**
27
+ * Number of validation failures
28
+ */
29
+ failures: number;
30
+ };
31
+ export type EvaluationContext = {
32
+ input: string;
33
+ };
34
+ //# sourceMappingURL=document-evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/document-evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAO,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGjF,8BAAsB,yBAAyB,CAAC,CAAC,SAAS,eAAe,EAAE,EAAE,SAAS,oBAAoB,GAAG,oBAAoB,CAAE,SAAQ,SAAS;IAEhJ;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEV,QAAQ,EAAE,CAAC;IAKvB;;OAEG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,GAAE,MAAM,GAAG,SAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;IAoBnH,QAAQ,CAAC,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAGrG,SAAS,CAAC,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;CAS/F;AAED,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG;IACrD;;MAEE;IACF,QAAQ,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /******************************************************************************
2
+ * Copyright 2024 - 2025 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ /**
7
+ * Langium Document Evaluator (evaluates on a Langium document)
8
+ */
9
+ import { URI } from "langium";
10
+ import { Evaluator } from "./evaluator.js";
11
+ export class AbstractDocumentEvaluator extends Evaluator {
12
+ constructor(services) {
13
+ super();
14
+ this.services = services;
15
+ }
16
+ /**
17
+ * Validate an agent response as if it's a langium program. If we can parse it, we attempt to validate it.
18
+ */
19
+ async evaluate(input, fileExtension = undefined) {
20
+ if (input.includes('```')) {
21
+ // take the first code block instead, if present (assuming it's a langium grammar)
22
+ const codeBlock = input.split(/```[a-z-]*/)[1];
23
+ input = codeBlock;
24
+ }
25
+ const fileExt = fileExtension ? fileExtension : this.services.LanguageMetaData.fileExtensions[0];
26
+ const doc = this.services.shared.workspace.LangiumDocumentFactory.fromString(input, URI.parse(`memory:/test.${fileExt}`));
27
+ const context = {
28
+ input: input
29
+ };
30
+ try {
31
+ await this.services.shared.workspace.DocumentBuilder.build([doc], { validation: true });
32
+ return this.evaluateDocument(doc, context);
33
+ }
34
+ catch (e) {
35
+ return this.handleBuildError(e, context);
36
+ }
37
+ }
38
+ handleBuildError(e, ctx) {
39
+ console.error('Error during evaluation: ', e);
40
+ return {
41
+ name: this.constructor.name,
42
+ data: {
43
+ failures: 1
44
+ }
45
+ };
46
+ }
47
+ }
48
+ //# sourceMappingURL=document-evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-evaluator.js","sourceRoot":"","sources":["../../src/evaluator/document-evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF;;GAEG;AAEH,OAAO,EAAmB,GAAG,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAwC,MAAM,gBAAgB,CAAC;AAGjF,MAAM,OAAgB,yBAA6G,SAAQ,SAAS;IAOhJ,YAAY,QAAW;QACnB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,gBAAoC,SAAS;QAEvE,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,kFAAkF;YAClF,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,KAAK,GAAG,SAAS,CAAC;QACtB,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACjG,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1H,MAAM,OAAO,GAAsB;YAC/B,KAAK,EAAE,KAAK;SACf,CAAC;QACF,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QAC5C,CAAC;IACL,CAAC;IAKS,gBAAgB,CAAC,CAAU,EAAE,GAAsB;QACzD,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC,CAAC,CAAC;QAC9C,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YAC3B,IAAI,EAAwB;gBACxB,QAAQ,EAAE,CAAC;aACG;SACrB,CAAC;IACN,CAAC;CACJ"}
@@ -9,7 +9,7 @@ export type EvaluatorResultData = Record<string, unknown> & {
9
9
  /**
10
10
  * Evaluator result type
11
11
  */
12
- export type EvaluatorResult = {
12
+ export type EvaluatorResult<T = EvaluatorResultData> = {
13
13
  /**
14
14
  * Name of this evaluation
15
15
  */
@@ -21,7 +21,7 @@ export type EvaluatorResult = {
21
21
  /**
22
22
  * Data for this evaluation
23
23
  */
24
- data: EvaluatorResultData;
24
+ data: T;
25
25
  };
26
26
  /**
27
27
  * Helper to process a set of results, averaging all runs of each runner-evaluator-case combination
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAShF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC1B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE9B;;OAEG;IACH,IAAI,EAAE,mBAAmB,CAAC;CAE7B,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CA4ChF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAiDlF;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE,CAgC7E;AAED;;GAEG;AACH,8BAAsB,SAAS;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;CAEpG;AAED,wBAAgB,eAAe,CAAC,GAAG,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,CAGrE"}
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAShF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,GAAG,mBAAmB,IAAI;IACnD;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE9B;;OAEG;IACH,IAAI,EAAE,CAAC,CAAC;CAEX,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CA4ChF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAiDlF;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE,CAgC7E;AAED;;GAEG;AACH,8BAAsB,SAAS;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;CAEpG;AAED,wBAAgB,eAAe,CAAC,GAAG,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,CAGrE"}
@@ -6,17 +6,15 @@
6
6
  /**
7
7
  * Base Langium DSL validator (taps into Langium's validator messages to provide better results)
8
8
  */
9
+ import { LangiumDocument } from "langium";
9
10
  import { LangiumServices } from "langium/lsp";
10
11
  import { Diagnostic } from "vscode-languageserver-types";
11
- import { Evaluator, EvaluatorResult, EvaluatorResultData } from "./evaluator.js";
12
+ import { AbstractDocumentEvaluator, EvaluationContext, FailureAwarenessData } from "./document-evaluator.js";
13
+ import { EvaluatorResult } from "./evaluator.js";
12
14
  /**
13
15
  * Langium-specific evaluator result data
14
16
  */
15
- export interface LangiumEvaluatorResultData extends EvaluatorResultData {
16
- /**
17
- * Number of validation failures
18
- */
19
- failures: number;
17
+ export interface LangiumEvaluatorResultData extends FailureAwarenessData {
20
18
  /**
21
19
  * Number of errors
22
20
  */
@@ -46,15 +44,11 @@ export interface LangiumEvaluatorResultData extends EvaluatorResultData {
46
44
  */
47
45
  diagnostics: Diagnostic[];
48
46
  }
49
- export declare class LangiumEvaluator<T extends LangiumServices> extends Evaluator {
50
- /**
51
- * Services to use for evaluation
52
- */
53
- protected services: T;
54
- constructor(services: T);
47
+ export declare class LangiumEvaluator<T extends LangiumServices> extends AbstractDocumentEvaluator<T, LangiumEvaluatorResultData> {
55
48
  /**
56
49
  * Validate an agent response as if it's a langium program. If we can parse it, we attempt to validate it.
57
50
  */
58
- evaluate(response: string): Promise<Partial<EvaluatorResult>>;
51
+ evaluateDocument(doc: LangiumDocument, ctx: EvaluationContext): EvaluatorResult<LangiumEvaluatorResultData>;
52
+ protected createEmptyResultData(): LangiumEvaluatorResultData;
59
53
  }
60
54
  //# sourceMappingURL=langium-evaluator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"langium-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/langium-evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGjF;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,mBAAmB;IAEnE;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B;AAED,qBAAa,gBAAgB,CAAC,CAAC,SAAS,eAAe,CAAE,SAAQ,SAAS;IAEtE;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEV,QAAQ,EAAE,CAAC;IAKvB;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;CAqEtE"}
1
+ {"version":3,"file":"langium-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/langium-evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAE,eAAe,EAAuB,MAAM,gBAAgB,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,oBAAoB;IAEpE;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B;AAED,qBAAa,gBAAgB,CAAC,CAAC,SAAS,eAAe,CAAE,SAAQ,yBAAyB,CAAC,CAAC,EAAE,0BAA0B,CAAC;IAGrH;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,0BAA0B,CAAC;IAwC3G,SAAS,CAAC,qBAAqB,IAAI,0BAA0B;CAYhE"}
@@ -3,78 +3,56 @@
3
3
  * This program and the accompanying materials are made available under the
4
4
  * terms of the MIT License, which is available in the project root.
5
5
  ******************************************************************************/
6
- import { Evaluator } from "./evaluator.js";
7
- import { URI } from "langium";
8
- export class LangiumEvaluator extends Evaluator {
9
- constructor(services) {
10
- super();
11
- this.services = services;
12
- }
6
+ import { AbstractDocumentEvaluator } from "./document-evaluator.js";
7
+ export class LangiumEvaluator extends AbstractDocumentEvaluator {
13
8
  /**
14
9
  * Validate an agent response as if it's a langium program. If we can parse it, we attempt to validate it.
15
10
  */
16
- async evaluate(response) {
17
- if (response.includes('```')) {
18
- // take the first code block instead, if present (assuming it's a langium grammar)
19
- const codeBlock = response.split(/```[a-z-]*/)[1];
20
- response = codeBlock;
21
- }
22
- const doc = this.services.shared.workspace.LangiumDocumentFactory.fromString(response, URI.parse('memory://test.langium'));
23
- try {
24
- await this.services.shared.workspace.DocumentBuilder.build([doc], { validation: true });
25
- const validationResults = doc.diagnostics ?? [];
26
- // count the number of each type of diagnostic
27
- let evalData = {
28
- failures: 0,
29
- errors: 0,
30
- warnings: 0,
31
- infos: 0,
32
- hints: 0,
33
- unassigned: 0,
34
- // include length of the response for checking
35
- response_length: response.length,
36
- // include the diagnostics for debugging if desired
37
- diagnostics: validationResults
38
- };
39
- for (const diagnostic of validationResults) {
40
- if (diagnostic.severity) {
41
- switch (diagnostic.severity) {
42
- case 1:
43
- evalData.errors++;
44
- break;
45
- case 2:
46
- evalData.warnings++;
47
- break;
48
- case 3:
49
- evalData.infos++;
50
- break;
51
- case 4:
52
- evalData.hints++;
53
- break;
54
- default:
55
- evalData.unassigned++;
56
- break;
57
- }
11
+ evaluateDocument(doc, ctx) {
12
+ const validationResults = doc.diagnostics ?? [];
13
+ const evalData = this.createEmptyResultData();
14
+ // include length of the response for checking
15
+ evalData.response_length = ctx.input.length;
16
+ // include the diagnostics for debugging if desired
17
+ evalData.diagnostics = validationResults;
18
+ for (const diagnostic of validationResults) {
19
+ if (diagnostic.severity) {
20
+ switch (diagnostic.severity) {
21
+ case 1:
22
+ evalData.errors++;
23
+ break;
24
+ case 2:
25
+ evalData.warnings++;
26
+ break;
27
+ case 3:
28
+ evalData.infos++;
29
+ break;
30
+ case 4:
31
+ evalData.hints++;
32
+ break;
33
+ default:
34
+ evalData.unassigned++;
35
+ break;
58
36
  }
59
37
  }
60
- return {
61
- data: evalData
62
- };
63
- }
64
- catch (e) {
65
- console.error('Error during evaluation: ', e);
66
- return {
67
- data: {
68
- failures: 1,
69
- errors: 0,
70
- warnings: 0,
71
- infos: 0,
72
- hints: 0,
73
- unassigned: 0,
74
- response_length: response.length
75
- }
76
- };
77
38
  }
39
+ return {
40
+ name: this.constructor.name,
41
+ metadata: {},
42
+ data: evalData
43
+ };
44
+ }
45
+ createEmptyResultData() {
46
+ return {
47
+ failures: 0,
48
+ errors: 0,
49
+ warnings: 0,
50
+ infos: 0,
51
+ hints: 0,
52
+ unassigned: 0,
53
+ response_length: 0,
54
+ diagnostics: []
55
+ };
78
56
  }
79
57
  }
80
58
  //# sourceMappingURL=langium-evaluator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"langium-evaluator.js","sourceRoot":"","sources":["../../src/evaluator/langium-evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAQhF,OAAO,EAAE,SAAS,EAAwC,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAgD9B,MAAM,OAAO,gBAA4C,SAAQ,SAAS;IAOtE,YAAY,QAAW;QACnB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAgB;QAE3B,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,kFAAkF;YAClF,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAClD,QAAQ,GAAG,SAAS,CAAC;QACzB,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAE3H,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YACxF,MAAM,iBAAiB,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;YAEhD,8CAA8C;YAC9C,IAAI,QAAQ,GAA+B;gBACvC,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,CAAC;gBACT,QAAQ,EAAE,CAAC;gBACX,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,CAAC;gBACR,UAAU,EAAE,CAAC;gBACb,8CAA8C;gBAC9C,eAAe,EAAE,QAAQ,CAAC,MAAM;gBAChC,mDAAmD;gBACnD,WAAW,EAAE,iBAAiB;aACjC,CAAC;YAEF,KAAK,MAAM,UAAU,IAAI,iBAAiB,EAAE,CAAC;gBACzC,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;oBACtB,QAAQ,UAAU,CAAC,QAAQ,EAAE,CAAC;wBAC1B,KAAK,CAAC;4BACF,QAAQ,CAAC,MAAM,EAAE,CAAC;4BAClB,MAAM;wBACV,KAAK,CAAC;4BACF,QAAQ,CAAC,QAAQ,EAAE,CAAC;4BACpB,MAAM;wBACV,KAAK,CAAC;4BACF,QAAQ,CAAC,KAAK,EAAE,CAAC;4BACjB,MAAM;wBACV,KAAK,CAAC;4BACF,QAAQ,CAAC,KAAK,EAAE,CAAC;4BACjB,MAAM;wBACV;4BACI,QAAQ,CAAC,UAAU,EAAE,CAAC;4BACtB,MAAM;oBACd,CAAC;gBACL,CAAC;YACL,CAAC;YAED,OAAO;gBACH,IAAI,EAAE,QAAQ;aACjB,CAAC;QAEN,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC,CAAC,CAAC;YAC9C,OAAO;gBACH,IAAI,EAAE;oBACF,QAAQ,EAAE,CAAC;oBACX,MAAM,EAAE,CAAC;oBACT,QAAQ,EAAE,CAAC;oBACX,KAAK,EAAE,CAAC;oBACR,KAAK,EAAE,CAAC;oBACR,UAAU,EAAE,CAAC;oBACb,eAAe,EAAE,QAAQ,CAAC,MAAM;iBACL;aAClC,CAAC;QACN,CAAC;IACL,CAAC;CACJ"}
1
+ {"version":3,"file":"langium-evaluator.js","sourceRoot":"","sources":["../../src/evaluator/langium-evaluator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAShF,OAAO,EAAE,yBAAyB,EAA2C,MAAM,yBAAyB,CAAC;AA4C7G,MAAM,OAAO,gBAA4C,SAAQ,yBAAwD;IAGrH;;OAEG;IACH,gBAAgB,CAAC,GAAoB,EAAE,GAAsB;QAEzD,MAAM,iBAAiB,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;QAEhD,MAAM,QAAQ,GAA+B,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC1E,8CAA8C;QAC9C,QAAQ,CAAC,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5C,mDAAmD;QACnD,QAAQ,CAAC,WAAW,GAAG,iBAAiB,CAAC;QAGzC,KAAK,MAAM,UAAU,IAAI,iBAAiB,EAAE,CAAC;YACzC,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;gBACtB,QAAQ,UAAU,CAAC,QAAQ,EAAE,CAAC;oBAC1B,KAAK,CAAC;wBACF,QAAQ,CAAC,MAAM,EAAE,CAAC;wBAClB,MAAM;oBACV,KAAK,CAAC;wBACF,QAAQ,CAAC,QAAQ,EAAE,CAAC;wBACpB,MAAM;oBACV,KAAK,CAAC;wBACF,QAAQ,CAAC,KAAK,EAAE,CAAC;wBACjB,MAAM;oBACV,KAAK,CAAC;wBACF,QAAQ,CAAC,KAAK,EAAE,CAAC;wBACjB,MAAM;oBACV;wBACI,QAAQ,CAAC,UAAU,EAAE,CAAC;wBACtB,MAAM;gBACd,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YAC3B,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,QAAQ;SACjB,CAAC;IACN,CAAC;IAES,qBAAqB;QAC3B,OAAO;YACH,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,CAAC;YACX,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,CAAC;YACR,UAAU,EAAE,CAAC;YACb,eAAe,EAAE,CAAC;YAClB,WAAW,EAAE,EAAE;SAClB,CAAC;IACN,CAAC;CACJ"}
package/dist/index.d.ts CHANGED
@@ -4,5 +4,6 @@
4
4
  * terms of the MIT License, which is available in the project root.
5
5
  ******************************************************************************/
6
6
  export * from './evaluator/index.js';
7
+ export * from './analyzer/index.js';
7
8
  export * from './splitter/index.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -4,5 +4,6 @@
4
4
  * terms of the MIT License, which is available in the project root.
5
5
  ******************************************************************************/
6
6
  export * from './evaluator/index.js';
7
+ export * from './analyzer/index.js';
7
8
  export * from './splitter/index.js';
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langium-ai-tools",
3
- "version": "4.1.0",
3
+ "version": "4.1.2",
4
4
  "description": "Tooling for building AI Applications that leverage Langium DSLs",
5
5
  "repository": {
6
6
  "type": "git",
@@ -54,8 +54,5 @@
54
54
  "npm": "10.2.3"
55
55
  },
56
56
  "devDependencies": {
57
- "rimraf": "^6.0.1",
58
- "typescript": "^5.4.5",
59
- "vitest": "^3.0.9"
60
57
  }
61
58
  }