@agentix-e/nl2spel 0.0.0 → 1.1.0
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 +69 -39
- package/dist/__tests__/auto-fixer.test.d.ts +2 -0
- package/dist/__tests__/auto-fixer.test.d.ts.map +1 -0
- package/dist/__tests__/auto-fixer.test.js +285 -0
- package/dist/__tests__/auto-fixer.test.js.map +1 -0
- package/dist/__tests__/chinese-number-parser.test.d.ts +2 -0
- package/dist/__tests__/chinese-number-parser.test.d.ts.map +1 -0
- package/dist/__tests__/chinese-number-parser.test.js +106 -0
- package/dist/__tests__/chinese-number-parser.test.js.map +1 -0
- package/dist/__tests__/context-extractor.test.d.ts +2 -0
- package/dist/__tests__/context-extractor.test.d.ts.map +1 -0
- package/dist/__tests__/context-extractor.test.js +347 -0
- package/dist/__tests__/context-extractor.test.js.map +1 -0
- package/dist/__tests__/coverage-gaps.test.d.ts +2 -0
- package/dist/__tests__/coverage-gaps.test.d.ts.map +1 -0
- package/dist/__tests__/coverage-gaps.test.js +578 -0
- package/dist/__tests__/coverage-gaps.test.js.map +1 -0
- package/dist/__tests__/intent-classifier.test.d.ts +2 -0
- package/dist/__tests__/intent-classifier.test.d.ts.map +1 -0
- package/dist/__tests__/intent-classifier.test.js +384 -0
- package/dist/__tests__/intent-classifier.test.js.map +1 -0
- package/dist/__tests__/nl2spel-engine.test.d.ts +2 -0
- package/dist/__tests__/nl2spel-engine.test.d.ts.map +1 -0
- package/dist/__tests__/nl2spel-engine.test.js +344 -0
- package/dist/__tests__/nl2spel-engine.test.js.map +1 -0
- package/dist/__tests__/pattern-matcher.test.d.ts +2 -0
- package/dist/__tests__/pattern-matcher.test.d.ts.map +1 -0
- package/dist/__tests__/pattern-matcher.test.js +754 -0
- package/dist/__tests__/pattern-matcher.test.js.map +1 -0
- package/dist/__tests__/prompt-builder.test.d.ts +2 -0
- package/dist/__tests__/prompt-builder.test.d.ts.map +1 -0
- package/dist/__tests__/prompt-builder.test.js +99 -0
- package/dist/__tests__/prompt-builder.test.js.map +1 -0
- package/dist/__tests__/provider-registry.test.d.ts +2 -0
- package/dist/__tests__/provider-registry.test.d.ts.map +1 -0
- package/dist/__tests__/provider-registry.test.js +240 -0
- package/dist/__tests__/provider-registry.test.js.map +1 -0
- package/dist/__tests__/schema-formatter.test.d.ts +2 -0
- package/dist/__tests__/schema-formatter.test.d.ts.map +1 -0
- package/dist/__tests__/schema-formatter.test.js +298 -0
- package/dist/__tests__/schema-formatter.test.js.map +1 -0
- package/dist/__tests__/self-correction-loop.test.d.ts +2 -0
- package/dist/__tests__/self-correction-loop.test.d.ts.map +1 -0
- package/dist/__tests__/self-correction-loop.test.js +253 -0
- package/dist/__tests__/self-correction-loop.test.js.map +1 -0
- package/dist/__tests__/strategy-router.test.d.ts +2 -0
- package/dist/__tests__/strategy-router.test.d.ts.map +1 -0
- package/dist/__tests__/strategy-router.test.js +493 -0
- package/dist/__tests__/strategy-router.test.js.map +1 -0
- package/dist/__tests__/template-engine.test.d.ts +2 -0
- package/dist/__tests__/template-engine.test.d.ts.map +1 -0
- package/dist/__tests__/template-engine.test.js +367 -0
- package/dist/__tests__/template-engine.test.js.map +1 -0
- package/dist/__tests__/validation-pipeline.test.d.ts +2 -0
- package/dist/__tests__/validation-pipeline.test.d.ts.map +1 -0
- package/dist/__tests__/validation-pipeline.test.js +262 -0
- package/dist/__tests__/validation-pipeline.test.js.map +1 -0
- package/dist/context/context-extractor.d.ts +82 -0
- package/dist/context/context-extractor.d.ts.map +1 -0
- package/dist/context/context-extractor.js +166 -0
- package/dist/context/context-extractor.js.map +1 -0
- package/dist/context/schema-formatter.d.ts +20 -0
- package/dist/context/schema-formatter.d.ts.map +1 -0
- package/dist/context/schema-formatter.js +104 -0
- package/dist/context/schema-formatter.js.map +1 -0
- package/dist/engine/nl2spel-engine.d.ts +145 -0
- package/dist/engine/nl2spel-engine.d.ts.map +1 -0
- package/dist/engine/nl2spel-engine.js +132 -0
- package/dist/engine/nl2spel-engine.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/pattern/builtin-patterns.d.ts +12 -0
- package/dist/pattern/builtin-patterns.d.ts.map +1 -0
- package/dist/pattern/builtin-patterns.js +812 -0
- package/dist/pattern/builtin-patterns.js.map +1 -0
- package/dist/pattern/pattern-definition.d.ts +49 -0
- package/dist/pattern/pattern-definition.d.ts.map +1 -0
- package/dist/pattern/pattern-definition.js +2 -0
- package/dist/pattern/pattern-definition.js.map +1 -0
- package/dist/pattern/pattern-matcher.d.ts +55 -0
- package/dist/pattern/pattern-matcher.d.ts.map +1 -0
- package/dist/pattern/pattern-matcher.js +216 -0
- package/dist/pattern/pattern-matcher.js.map +1 -0
- package/dist/provider/llm-provider.d.ts +146 -0
- package/dist/provider/llm-provider.d.ts.map +1 -0
- package/dist/provider/llm-provider.js +2 -0
- package/dist/provider/llm-provider.js.map +1 -0
- package/dist/provider/provider-registry.d.ts +28 -0
- package/dist/provider/provider-registry.d.ts.map +1 -0
- package/dist/provider/provider-registry.js +65 -0
- package/dist/provider/provider-registry.js.map +1 -0
- package/dist/strategy/strategy-router.d.ts +79 -0
- package/dist/strategy/strategy-router.d.ts.map +1 -0
- package/dist/strategy/strategy-router.js +182 -0
- package/dist/strategy/strategy-router.js.map +1 -0
- package/dist/template/intent-classifier.d.ts +56 -0
- package/dist/template/intent-classifier.d.ts.map +1 -0
- package/dist/template/intent-classifier.js +251 -0
- package/dist/template/intent-classifier.js.map +1 -0
- package/dist/template/nl-intent.d.ts +38 -0
- package/dist/template/nl-intent.d.ts.map +1 -0
- package/dist/template/nl-intent.js +39 -0
- package/dist/template/nl-intent.js.map +1 -0
- package/dist/template/prompts/prompt-builder.d.ts +20 -0
- package/dist/template/prompts/prompt-builder.d.ts.map +1 -0
- package/dist/template/prompts/prompt-builder.js +243 -0
- package/dist/template/prompts/prompt-builder.js.map +1 -0
- package/dist/template/template-engine.d.ts +27 -0
- package/dist/template/template-engine.d.ts.map +1 -0
- package/dist/template/template-engine.js +378 -0
- package/dist/template/template-engine.js.map +1 -0
- package/dist/utils/chinese-number-parser.d.ts +30 -0
- package/dist/utils/chinese-number-parser.d.ts.map +1 -0
- package/dist/utils/chinese-number-parser.js +92 -0
- package/dist/utils/chinese-number-parser.js.map +1 -0
- package/dist/validation/auto-fixer.d.ts +14 -0
- package/dist/validation/auto-fixer.d.ts.map +1 -0
- package/dist/validation/auto-fixer.js +111 -0
- package/dist/validation/auto-fixer.js.map +1 -0
- package/dist/validation/self-correction-loop.d.ts +46 -0
- package/dist/validation/self-correction-loop.d.ts.map +1 -0
- package/dist/validation/self-correction-loop.js +141 -0
- package/dist/validation/self-correction-loop.js.map +1 -0
- package/dist/validation/validation-pipeline.d.ts +81 -0
- package/dist/validation/validation-pipeline.d.ts.map +1 -0
- package/dist/validation/validation-pipeline.js +306 -0
- package/dist/validation/validation-pipeline.js.map +1 -0
- package/package.json +45 -7
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { SchemaFormatter } from '../context/schema-formatter.js';
|
|
3
|
+
function createBasicSchema() {
|
|
4
|
+
return {
|
|
5
|
+
root: {
|
|
6
|
+
name: 'order',
|
|
7
|
+
type: 'Order',
|
|
8
|
+
fields: {
|
|
9
|
+
amount: {
|
|
10
|
+
type: 'number',
|
|
11
|
+
description: 'Order amount',
|
|
12
|
+
example: 1000,
|
|
13
|
+
},
|
|
14
|
+
status: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Order status',
|
|
17
|
+
example: '已发货',
|
|
18
|
+
},
|
|
19
|
+
paid: {
|
|
20
|
+
type: 'boolean',
|
|
21
|
+
nullable: true,
|
|
22
|
+
},
|
|
23
|
+
items: {
|
|
24
|
+
type: 'array',
|
|
25
|
+
isCollection: true,
|
|
26
|
+
elementType: 'object',
|
|
27
|
+
description: 'Order items',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
methods: {},
|
|
31
|
+
},
|
|
32
|
+
variables: {
|
|
33
|
+
user: {
|
|
34
|
+
type: 'User',
|
|
35
|
+
description: 'Current user',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
beans: {
|
|
39
|
+
discountService: {
|
|
40
|
+
type: 'DiscountService',
|
|
41
|
+
description: 'Discount calculation service',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
types: {
|
|
45
|
+
OrderStatus: {
|
|
46
|
+
description: 'Order status enum',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
functions: {
|
|
50
|
+
sum: {
|
|
51
|
+
returnType: 'number',
|
|
52
|
+
params: [{ name: 'values', type: 'array' }],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
describe('SchemaFormatter', () => {
|
|
58
|
+
const formatter = new SchemaFormatter();
|
|
59
|
+
describe('formatForLLM', () => {
|
|
60
|
+
it('should format root object with fields', () => {
|
|
61
|
+
const schema = createBasicSchema();
|
|
62
|
+
const output = formatter.formatForLLM(schema);
|
|
63
|
+
expect(output).toContain('## Context Schema');
|
|
64
|
+
expect(output).toContain('Root Object (accessible as #order)');
|
|
65
|
+
expect(output).toContain('Type: Order');
|
|
66
|
+
expect(output).toContain('Fields:');
|
|
67
|
+
expect(output).toContain('amount: number');
|
|
68
|
+
expect(output).toContain('(Order amount)');
|
|
69
|
+
expect(output).toContain('(e.g. 1000)');
|
|
70
|
+
});
|
|
71
|
+
it('should format variables section', () => {
|
|
72
|
+
const schema = createBasicSchema();
|
|
73
|
+
const output = formatter.formatForLLM(schema);
|
|
74
|
+
expect(output).toContain('Variables:');
|
|
75
|
+
expect(output).toContain('#user: User');
|
|
76
|
+
expect(output).toContain('(Current user)');
|
|
77
|
+
});
|
|
78
|
+
it('should format beans section', () => {
|
|
79
|
+
const schema = createBasicSchema();
|
|
80
|
+
const output = formatter.formatForLLM(schema);
|
|
81
|
+
expect(output).toContain('Beans:');
|
|
82
|
+
expect(output).toContain('@discountService: DiscountService');
|
|
83
|
+
expect(output).toContain('(Discount calculation service)');
|
|
84
|
+
});
|
|
85
|
+
it('should format types section', () => {
|
|
86
|
+
const schema = createBasicSchema();
|
|
87
|
+
const output = formatter.formatForLLM(schema);
|
|
88
|
+
expect(output).toContain('Types (accessible via T(typeName)):');
|
|
89
|
+
expect(output).toContain('OrderStatus: Order status enum');
|
|
90
|
+
});
|
|
91
|
+
it('should format functions section', () => {
|
|
92
|
+
const schema = createBasicSchema();
|
|
93
|
+
const output = formatter.formatForLLM(schema);
|
|
94
|
+
expect(output).toContain('Functions:');
|
|
95
|
+
expect(output).toContain('#sum(values: array): number');
|
|
96
|
+
});
|
|
97
|
+
it('should indicate nullable fields', () => {
|
|
98
|
+
const output = formatter.formatForLLM(createBasicSchema());
|
|
99
|
+
expect(output).toContain('[nullable]');
|
|
100
|
+
});
|
|
101
|
+
it('should indicate collection fields', () => {
|
|
102
|
+
const output = formatter.formatForLLM(createBasicSchema());
|
|
103
|
+
expect(output).toContain('[array of object]');
|
|
104
|
+
});
|
|
105
|
+
it('should skip variables section when empty', () => {
|
|
106
|
+
const schema = {
|
|
107
|
+
root: null,
|
|
108
|
+
variables: {},
|
|
109
|
+
beans: {},
|
|
110
|
+
types: {},
|
|
111
|
+
functions: {},
|
|
112
|
+
};
|
|
113
|
+
const output = formatter.formatForLLM(schema);
|
|
114
|
+
expect(output).not.toContain('Variables:');
|
|
115
|
+
});
|
|
116
|
+
it('should skip beans section when empty', () => {
|
|
117
|
+
const schema = {
|
|
118
|
+
root: null,
|
|
119
|
+
variables: {},
|
|
120
|
+
beans: {},
|
|
121
|
+
types: {},
|
|
122
|
+
functions: {},
|
|
123
|
+
};
|
|
124
|
+
const output = formatter.formatForLLM(schema);
|
|
125
|
+
expect(output).not.toContain('Beans:');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
describe('formatForHuman', () => {
|
|
129
|
+
it('should format root object in human-readable form', () => {
|
|
130
|
+
const output = formatter.formatForHuman(createBasicSchema());
|
|
131
|
+
expect(output).toContain('Context Schema (Human-Readable)');
|
|
132
|
+
expect(output).toContain('Root: #order');
|
|
133
|
+
expect(output).toContain('Type: Order');
|
|
134
|
+
expect(output).toContain('amount (number)');
|
|
135
|
+
expect(output).toContain('nullable');
|
|
136
|
+
expect(output).toContain('collection<object>');
|
|
137
|
+
});
|
|
138
|
+
it('should show field count', () => {
|
|
139
|
+
const output = formatter.formatForHuman(createBasicSchema());
|
|
140
|
+
expect(output).toContain('4 fields total');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
// Coverage: beans/types without description (lines 45, 55 false branches)
|
|
144
|
+
describe('beans/types without description', () => {
|
|
145
|
+
it('should format bean without description (line 45 false branch)', () => {
|
|
146
|
+
const schema = {
|
|
147
|
+
root: null,
|
|
148
|
+
variables: {},
|
|
149
|
+
beans: { myService: { type: 'MyService' } },
|
|
150
|
+
types: {},
|
|
151
|
+
functions: {},
|
|
152
|
+
};
|
|
153
|
+
const output = formatter.formatForLLM(schema);
|
|
154
|
+
expect(output).toContain('@myService: MyService');
|
|
155
|
+
});
|
|
156
|
+
it('should format type without description (line 55 false branch)', () => {
|
|
157
|
+
const schema = {
|
|
158
|
+
root: null,
|
|
159
|
+
variables: {},
|
|
160
|
+
beans: {},
|
|
161
|
+
types: { MyEnum: {} },
|
|
162
|
+
functions: {},
|
|
163
|
+
};
|
|
164
|
+
const output = formatter.formatForLLM(schema);
|
|
165
|
+
expect(output).toContain('MyEnum');
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
// Coverage: isCollection field missing elementType (lines 96, 113 'unknown' fallback)
|
|
169
|
+
describe('collection field without elementType', () => {
|
|
170
|
+
it('should use "unknown" when elementType is missing in formatForHuman (line 96)', () => {
|
|
171
|
+
const schema = {
|
|
172
|
+
root: {
|
|
173
|
+
name: 'order',
|
|
174
|
+
type: 'Order',
|
|
175
|
+
fields: {
|
|
176
|
+
tags: {
|
|
177
|
+
type: 'array',
|
|
178
|
+
isCollection: true,
|
|
179
|
+
description: 'Tag list',
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
methods: {},
|
|
183
|
+
},
|
|
184
|
+
variables: {},
|
|
185
|
+
beans: {},
|
|
186
|
+
types: {},
|
|
187
|
+
functions: {},
|
|
188
|
+
};
|
|
189
|
+
const output = formatter.formatForHuman(schema);
|
|
190
|
+
expect(output).toContain('collection<unknown>');
|
|
191
|
+
});
|
|
192
|
+
it('should use "unknown" when elementType is missing in formatForLLM (line 113)', () => {
|
|
193
|
+
const schema = {
|
|
194
|
+
root: {
|
|
195
|
+
name: 'order',
|
|
196
|
+
type: 'Order',
|
|
197
|
+
fields: {
|
|
198
|
+
tags: {
|
|
199
|
+
type: 'array',
|
|
200
|
+
isCollection: true,
|
|
201
|
+
description: 'Tag list',
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
methods: {},
|
|
205
|
+
},
|
|
206
|
+
variables: {},
|
|
207
|
+
beans: {},
|
|
208
|
+
types: {},
|
|
209
|
+
functions: {},
|
|
210
|
+
};
|
|
211
|
+
const output = formatter.formatForLLM(schema);
|
|
212
|
+
expect(output).toContain('[array of unknown]');
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
// Coverage: formatForHuman for-loop prefix branching (├─ vs └─)
|
|
216
|
+
describe('formatForHuman prefix branching', () => {
|
|
217
|
+
it('should use └─ for last field (single field exercises └─ prefix path)', () => {
|
|
218
|
+
const schema = {
|
|
219
|
+
root: {
|
|
220
|
+
name: 'item',
|
|
221
|
+
type: 'Item',
|
|
222
|
+
fields: {
|
|
223
|
+
id: {
|
|
224
|
+
type: 'number',
|
|
225
|
+
description: 'Item ID',
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
methods: {},
|
|
229
|
+
},
|
|
230
|
+
variables: {},
|
|
231
|
+
beans: {},
|
|
232
|
+
types: {},
|
|
233
|
+
functions: {},
|
|
234
|
+
};
|
|
235
|
+
const output = formatter.formatForHuman(schema);
|
|
236
|
+
expect(output).toContain('└─ id');
|
|
237
|
+
expect(output).toContain('1 fields total');
|
|
238
|
+
});
|
|
239
|
+
it('should use ├─ for non-last and └─ for last with many fields', () => {
|
|
240
|
+
const schema = createBasicSchema();
|
|
241
|
+
const output = formatter.formatForHuman(schema);
|
|
242
|
+
expect(output).toContain('├─ amount');
|
|
243
|
+
expect(output).toContain('├─ status');
|
|
244
|
+
expect(output).toContain('├─ paid');
|
|
245
|
+
expect(output).toContain('└─ items');
|
|
246
|
+
expect(output).toContain('4 fields total');
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
// Coverage: functions with description
|
|
250
|
+
describe('functions with description', () => {
|
|
251
|
+
it('should format function that has a description property', () => {
|
|
252
|
+
const schema = {
|
|
253
|
+
root: null,
|
|
254
|
+
variables: {},
|
|
255
|
+
beans: {},
|
|
256
|
+
types: {},
|
|
257
|
+
functions: {
|
|
258
|
+
calculateDiscount: {
|
|
259
|
+
returnType: 'number',
|
|
260
|
+
description: 'Calculate discount for order',
|
|
261
|
+
params: [{ name: 'order', type: 'Order' }],
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
const output = formatter.formatForLLM(schema);
|
|
266
|
+
expect(output).toContain('#calculateDiscount(order: Order)');
|
|
267
|
+
expect(output).toContain('number');
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
describe('empty schema', () => {
|
|
271
|
+
it('should handle null root gracefully', () => {
|
|
272
|
+
const schema = {
|
|
273
|
+
root: null,
|
|
274
|
+
variables: { x: { type: 'string' } },
|
|
275
|
+
beans: {},
|
|
276
|
+
types: {},
|
|
277
|
+
functions: {},
|
|
278
|
+
};
|
|
279
|
+
const llmOutput = formatter.formatForLLM(schema);
|
|
280
|
+
expect(llmOutput).not.toContain('Root Object');
|
|
281
|
+
expect(llmOutput).toContain('Variables:');
|
|
282
|
+
expect(llmOutput).toContain('#x: string');
|
|
283
|
+
});
|
|
284
|
+
it('should handle completely empty schema', () => {
|
|
285
|
+
const schema = {
|
|
286
|
+
root: null,
|
|
287
|
+
variables: {},
|
|
288
|
+
beans: {},
|
|
289
|
+
types: {},
|
|
290
|
+
functions: {},
|
|
291
|
+
};
|
|
292
|
+
const output = formatter.formatForLLM(schema);
|
|
293
|
+
// Should not throw; just header
|
|
294
|
+
expect(output).toContain('## Context Schema');
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
//# sourceMappingURL=schema-formatter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-formatter.test.js","sourceRoot":"","sources":["../../src/__tests__/schema-formatter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-correction-loop.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/self-correction-loop.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { SelfCorrectionLoop } from '../validation/self-correction-loop.js';
|
|
3
|
+
import { ValidationPipeline } from '../validation/validation-pipeline.js';
|
|
4
|
+
import { AutoFixer } from '../validation/auto-fixer.js';
|
|
5
|
+
const TEST_SCHEMA = {
|
|
6
|
+
root: {
|
|
7
|
+
name: 'order',
|
|
8
|
+
type: 'Order',
|
|
9
|
+
fields: {
|
|
10
|
+
amount: { type: 'number', description: '订单金额' },
|
|
11
|
+
status: { type: 'string', description: '订单状态' },
|
|
12
|
+
paid: { type: 'boolean', description: '是否支付' },
|
|
13
|
+
},
|
|
14
|
+
methods: {},
|
|
15
|
+
},
|
|
16
|
+
variables: {},
|
|
17
|
+
beans: {},
|
|
18
|
+
types: {},
|
|
19
|
+
functions: {},
|
|
20
|
+
};
|
|
21
|
+
const TEST_PROMPT = {
|
|
22
|
+
system: 'Generate SpEL.',
|
|
23
|
+
user: '金额大于1000',
|
|
24
|
+
contextSchema: TEST_SCHEMA,
|
|
25
|
+
examples: [],
|
|
26
|
+
};
|
|
27
|
+
function createSuccessfulResponse(text) {
|
|
28
|
+
return {
|
|
29
|
+
text,
|
|
30
|
+
model: 'mock-model',
|
|
31
|
+
usage: { promptTokens: 100, completionTokens: 50, totalTokens: 150 },
|
|
32
|
+
latencyMs: 50,
|
|
33
|
+
finishReason: 'stop',
|
|
34
|
+
providerName: 'mock',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
describe('SelfCorrectionLoop', () => {
|
|
38
|
+
// ===== Correct expressions pass without iterations =====
|
|
39
|
+
it('should pass valid expression without correction', async () => {
|
|
40
|
+
const loop = new SelfCorrectionLoop();
|
|
41
|
+
const generateFn = vi.fn();
|
|
42
|
+
const result = await loop.correct('#order.amount > 1000', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
43
|
+
expect(result.valid).toBe(true);
|
|
44
|
+
expect(result.correctionAttempts).toBe(0);
|
|
45
|
+
expect(generateFn).not.toHaveBeenCalled();
|
|
46
|
+
});
|
|
47
|
+
// ===== AutoFix corrects JS operators =====
|
|
48
|
+
it('should auto-fix === without LLM correction', async () => {
|
|
49
|
+
const loop = new SelfCorrectionLoop();
|
|
50
|
+
const generateFn = vi.fn();
|
|
51
|
+
const result = await loop.correct('#order.amount === 1000', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
52
|
+
expect(result.valid).toBe(true);
|
|
53
|
+
expect(result.correctionAttempts).toBeLessThanOrEqual(1);
|
|
54
|
+
expect(result.expression).not.toContain('===');
|
|
55
|
+
// Should have been auto-fixed
|
|
56
|
+
const autoFixCorrection = result.corrections.find(c => c.autoFixed);
|
|
57
|
+
expect(autoFixCorrection).toBeDefined();
|
|
58
|
+
});
|
|
59
|
+
it('should auto-fix && without LLM correction', async () => {
|
|
60
|
+
const loop = new SelfCorrectionLoop();
|
|
61
|
+
const generateFn = vi.fn();
|
|
62
|
+
const result = await loop.correct('#order.amount > 100 && #order.paid == true', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
63
|
+
expect(result.valid).toBe(true);
|
|
64
|
+
expect(result.expression).not.toContain('&&');
|
|
65
|
+
});
|
|
66
|
+
// ===== LLM correction flow =====
|
|
67
|
+
it('should call LLM when auto-fix is insufficient', async () => {
|
|
68
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 2, enableAutoFix: false });
|
|
69
|
+
const generateFn = vi
|
|
70
|
+
.fn()
|
|
71
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount > 1000'));
|
|
72
|
+
const result = await loop.correct('#invalid syntax [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
73
|
+
expect(generateFn).toHaveBeenCalledTimes(1);
|
|
74
|
+
expect(result.valid).toBe(true);
|
|
75
|
+
expect(result.correctionAttempts).toBe(1);
|
|
76
|
+
expect(result.corrections.length).toBeGreaterThan(0);
|
|
77
|
+
});
|
|
78
|
+
it('should retry up to max attempts', async () => {
|
|
79
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 3, enableAutoFix: false });
|
|
80
|
+
const generateFn = vi
|
|
81
|
+
.fn()
|
|
82
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#bad expression [[['))
|
|
83
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#still bad [[['))
|
|
84
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount > 1000'));
|
|
85
|
+
const result = await loop.correct('#bad expression [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
86
|
+
expect(generateFn).toHaveBeenCalledTimes(3);
|
|
87
|
+
expect(result.valid).toBe(true);
|
|
88
|
+
expect(result.correctionAttempts).toBe(3);
|
|
89
|
+
});
|
|
90
|
+
it('should report failed corrections', async () => {
|
|
91
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 1, enableAutoFix: false });
|
|
92
|
+
const generateFn = vi.fn().mockResolvedValueOnce(createSuccessfulResponse('#still bad [[['));
|
|
93
|
+
const result = await loop.correct('#bad expression [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
94
|
+
expect(result.valid).toBe(false);
|
|
95
|
+
expect(result.correctionAttempts).toBe(1);
|
|
96
|
+
});
|
|
97
|
+
// ===== Configuration =====
|
|
98
|
+
it('should respect maxAttempts config', async () => {
|
|
99
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 1, enableAutoFix: false });
|
|
100
|
+
const generateFn = vi.fn().mockResolvedValue(createSuccessfulResponse('#bad [[['));
|
|
101
|
+
const result = await loop.correct('#bad [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
102
|
+
expect(generateFn.mock.calls.length).toBeLessThanOrEqual(1);
|
|
103
|
+
});
|
|
104
|
+
it('should respect enableAutoFix config', async () => {
|
|
105
|
+
const loop = new SelfCorrectionLoop({ enableAutoFix: false });
|
|
106
|
+
const generateFn = vi
|
|
107
|
+
.fn()
|
|
108
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount > 1000'));
|
|
109
|
+
const result = await loop.correct('#order.amount === 1000', // Would be auto-fixed normally
|
|
110
|
+
TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
111
|
+
// With auto-fix disabled, the AutoFix check passes but still needs correction if invalid
|
|
112
|
+
// But === IS detected by validation pipeline, so LLM should be called
|
|
113
|
+
expect(result.valid).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
// ===== Correction log tracking =====
|
|
116
|
+
it('should include corrections log for each attempt', async () => {
|
|
117
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 2, enableAutoFix: false });
|
|
118
|
+
const generateFn = vi
|
|
119
|
+
.fn()
|
|
120
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#bad [[['))
|
|
121
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount > 1000'));
|
|
122
|
+
const result = await loop.correct('#bad [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
123
|
+
expect(result.corrections.length).toBe(2);
|
|
124
|
+
expect(result.corrections[0].attempt).toBe(1);
|
|
125
|
+
// Expression gets auto-fixed (bracket fixing) after each LLM call
|
|
126
|
+
expect(result.corrections[0].expression).toContain('#bad');
|
|
127
|
+
expect(result.corrections[1].attempt).toBe(2);
|
|
128
|
+
expect(result.corrections[1].expression).toContain('#order.amount');
|
|
129
|
+
});
|
|
130
|
+
it('should track total latency', async () => {
|
|
131
|
+
const loop = new SelfCorrectionLoop({ enableAutoFix: false });
|
|
132
|
+
const generateFn = vi
|
|
133
|
+
.fn()
|
|
134
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount > 1000'));
|
|
135
|
+
const result = await loop.correct('#bad [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
136
|
+
expect(result.totalLatencyMs).toBeGreaterThanOrEqual(0);
|
|
137
|
+
});
|
|
138
|
+
// ===== Additional Coverage Tests =====
|
|
139
|
+
describe('Additional Coverage', () => {
|
|
140
|
+
it('correct expression passes immediately without any correction', async () => {
|
|
141
|
+
const loop = new SelfCorrectionLoop();
|
|
142
|
+
const generateFn = vi.fn();
|
|
143
|
+
const result = await loop.correct('#order.paid == true', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
144
|
+
expect(result.valid).toBe(true);
|
|
145
|
+
expect(result.correctionAttempts).toBe(0);
|
|
146
|
+
expect(result.corrections).toHaveLength(0);
|
|
147
|
+
expect(generateFn).not.toHaveBeenCalled();
|
|
148
|
+
});
|
|
149
|
+
it('expression that becomes valid after AutoFix only (no LLM needed)', async () => {
|
|
150
|
+
const loop = new SelfCorrectionLoop();
|
|
151
|
+
const generateFn = vi.fn();
|
|
152
|
+
const result = await loop.correct('#order.amount === 1000', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
153
|
+
expect(result.valid).toBe(true);
|
|
154
|
+
expect(result.correctionAttempts).toBeLessThanOrEqual(1);
|
|
155
|
+
expect(result.expression).not.toContain('===');
|
|
156
|
+
expect(result.expression).toContain('==');
|
|
157
|
+
expect(generateFn).not.toHaveBeenCalled();
|
|
158
|
+
// Auto-fix correction log should exist
|
|
159
|
+
const autoFixEntry = result.corrections.find(c => c.autoFixed);
|
|
160
|
+
expect(autoFixEntry).toBeDefined();
|
|
161
|
+
expect(autoFixEntry.autoFixChanges.some(c => c.includes('==='))).toBe(true);
|
|
162
|
+
});
|
|
163
|
+
it('expression needing exactly 2 correction attempts', async () => {
|
|
164
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 2, enableAutoFix: false });
|
|
165
|
+
const generateFn = vi
|
|
166
|
+
.fn()
|
|
167
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#bad [[['))
|
|
168
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount > 1000'));
|
|
169
|
+
const result = await loop.correct('#bad [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
170
|
+
expect(result.valid).toBe(true);
|
|
171
|
+
expect(result.correctionAttempts).toBe(2);
|
|
172
|
+
expect(generateFn).toHaveBeenCalledTimes(2);
|
|
173
|
+
expect(result.corrections).toHaveLength(2);
|
|
174
|
+
expect(result.corrections[0].attempt).toBe(1);
|
|
175
|
+
expect(result.corrections[1].attempt).toBe(2);
|
|
176
|
+
});
|
|
177
|
+
it('maxAttempts=0 should return immediately with valid=false', async () => {
|
|
178
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 0, enableAutoFix: false });
|
|
179
|
+
const generateFn = vi.fn();
|
|
180
|
+
const result = await loop.correct('#invalid [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
181
|
+
expect(result.valid).toBe(false);
|
|
182
|
+
expect(result.correctionAttempts).toBe(0);
|
|
183
|
+
expect(generateFn).not.toHaveBeenCalled();
|
|
184
|
+
});
|
|
185
|
+
it('LLM throws during correction (error handling)', async () => {
|
|
186
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 2, enableAutoFix: false });
|
|
187
|
+
const generateFn = vi.fn().mockRejectedValue(new Error('LLM service unavailable'));
|
|
188
|
+
const result = await loop.correct('#bad [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
189
|
+
expect(result.valid).toBe(false);
|
|
190
|
+
expect(result.correctionAttempts).toBe(2);
|
|
191
|
+
expect(generateFn).toHaveBeenCalledTimes(2);
|
|
192
|
+
// Correction log entries should record the failure
|
|
193
|
+
expect(result.corrections.every(c => !c.valid)).toBe(true);
|
|
194
|
+
for (const entry of result.corrections) {
|
|
195
|
+
expect(entry.errorCount).toBe(1);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
it('double auto-fix with quote fix', async () => {
|
|
199
|
+
const loop = new SelfCorrectionLoop();
|
|
200
|
+
const generateFn = vi.fn();
|
|
201
|
+
const result = await loop.correct('#order.status === "pending', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
202
|
+
expect(result.valid).toBe(true);
|
|
203
|
+
expect(result.expression).not.toContain('===');
|
|
204
|
+
expect(generateFn).not.toHaveBeenCalled();
|
|
205
|
+
// Should have a correction log entry for the auto-fix
|
|
206
|
+
expect(result.corrections.length).toBeGreaterThanOrEqual(1);
|
|
207
|
+
const autoFixEntry = result.corrections.find(c => c.autoFixed);
|
|
208
|
+
expect(autoFixEntry).toBeDefined();
|
|
209
|
+
// Auto-fix should include both === fix and double-quote fix
|
|
210
|
+
expect(autoFixEntry.autoFixChanges.some(c => c.includes('==='))).toBe(true);
|
|
211
|
+
expect(autoFixEntry.autoFixChanges.some(c => c.includes('quote'))).toBe(true);
|
|
212
|
+
});
|
|
213
|
+
it('verify correction log entry format and content', async () => {
|
|
214
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 1, enableAutoFix: false });
|
|
215
|
+
const generateFn = vi
|
|
216
|
+
.fn()
|
|
217
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount > 1000'));
|
|
218
|
+
const result = await loop.correct('#bad [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
219
|
+
expect(result.corrections.length).toBeGreaterThan(0);
|
|
220
|
+
for (const entry of result.corrections) {
|
|
221
|
+
// Verify all required fields are present with correct types
|
|
222
|
+
expect(entry).toHaveProperty('attempt');
|
|
223
|
+
expect(entry).toHaveProperty('expression');
|
|
224
|
+
expect(entry).toHaveProperty('valid');
|
|
225
|
+
expect(entry).toHaveProperty('errorCount');
|
|
226
|
+
expect(entry).toHaveProperty('warningCount');
|
|
227
|
+
expect(entry).toHaveProperty('autoFixed');
|
|
228
|
+
expect(entry).toHaveProperty('autoFixChanges');
|
|
229
|
+
expect(typeof entry.attempt).toBe('number');
|
|
230
|
+
expect(typeof entry.expression).toBe('string');
|
|
231
|
+
expect(typeof entry.valid).toBe('boolean');
|
|
232
|
+
expect(typeof entry.errorCount).toBe('number');
|
|
233
|
+
expect(typeof entry.warningCount).toBe('number');
|
|
234
|
+
expect(typeof entry.autoFixed).toBe('boolean');
|
|
235
|
+
expect(Array.isArray(entry.autoFixChanges)).toBe(true);
|
|
236
|
+
// attempt should be a positive integer (1-based for LLM corrections)
|
|
237
|
+
expect(entry.attempt).toBeGreaterThan(0);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
it('should apply auto-fix after LLM correction inside the loop', async () => {
|
|
241
|
+
// enableAutoFix: true (default), LLM returns expression with === that auto-fix can handle
|
|
242
|
+
const loop = new SelfCorrectionLoop({ maxAttempts: 2 });
|
|
243
|
+
const generateFn = vi
|
|
244
|
+
.fn()
|
|
245
|
+
.mockResolvedValueOnce(createSuccessfulResponse('#order.amount === 1000'));
|
|
246
|
+
const result = await loop.correct('#invalid [[[', TEST_SCHEMA, generateFn, TEST_PROMPT);
|
|
247
|
+
// Auto-fix at line 169 should fix ===
|
|
248
|
+
expect(result.valid).toBe(true);
|
|
249
|
+
expect(result.expression).not.toContain('===');
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
//# sourceMappingURL=self-correction-loop.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-correction-loop.test.js","sourceRoot":"","sources":["../../src/__tests__/self-correction-loop.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-router.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/strategy-router.test.ts"],"names":[],"mappings":""}
|