@agentix-e/nl2spel 1.2.1 → 1.3.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.
Files changed (76) hide show
  1. package/README.md +3 -1
  2. package/dist/index.cjs +3062 -0
  3. package/dist/index.d.cts +917 -0
  4. package/dist/index.d.ts +917 -28
  5. package/dist/index.js +3021 -24
  6. package/package.json +18 -7
  7. package/dist/context/context-extractor.d.ts +0 -86
  8. package/dist/context/context-extractor.d.ts.map +0 -1
  9. package/dist/context/context-extractor.js +0 -181
  10. package/dist/context/context-extractor.js.map +0 -1
  11. package/dist/context/schema-formatter.d.ts +0 -20
  12. package/dist/context/schema-formatter.d.ts.map +0 -1
  13. package/dist/context/schema-formatter.js +0 -104
  14. package/dist/context/schema-formatter.js.map +0 -1
  15. package/dist/engine/nl2spel-engine.d.ts +0 -145
  16. package/dist/engine/nl2spel-engine.d.ts.map +0 -1
  17. package/dist/engine/nl2spel-engine.js +0 -130
  18. package/dist/engine/nl2spel-engine.js.map +0 -1
  19. package/dist/index.d.ts.map +0 -1
  20. package/dist/index.js.map +0 -1
  21. package/dist/pattern/builtin-patterns.d.ts +0 -12
  22. package/dist/pattern/builtin-patterns.d.ts.map +0 -1
  23. package/dist/pattern/builtin-patterns.js +0 -812
  24. package/dist/pattern/builtin-patterns.js.map +0 -1
  25. package/dist/pattern/pattern-definition.d.ts +0 -49
  26. package/dist/pattern/pattern-definition.d.ts.map +0 -1
  27. package/dist/pattern/pattern-definition.js +0 -2
  28. package/dist/pattern/pattern-definition.js.map +0 -1
  29. package/dist/pattern/pattern-matcher.d.ts +0 -55
  30. package/dist/pattern/pattern-matcher.d.ts.map +0 -1
  31. package/dist/pattern/pattern-matcher.js +0 -216
  32. package/dist/pattern/pattern-matcher.js.map +0 -1
  33. package/dist/provider/llm-provider.d.ts +0 -146
  34. package/dist/provider/llm-provider.d.ts.map +0 -1
  35. package/dist/provider/llm-provider.js +0 -2
  36. package/dist/provider/llm-provider.js.map +0 -1
  37. package/dist/provider/provider-registry.d.ts +0 -28
  38. package/dist/provider/provider-registry.d.ts.map +0 -1
  39. package/dist/provider/provider-registry.js +0 -65
  40. package/dist/provider/provider-registry.js.map +0 -1
  41. package/dist/strategy/strategy-router.d.ts +0 -79
  42. package/dist/strategy/strategy-router.d.ts.map +0 -1
  43. package/dist/strategy/strategy-router.js +0 -182
  44. package/dist/strategy/strategy-router.js.map +0 -1
  45. package/dist/template/intent-classifier.d.ts +0 -56
  46. package/dist/template/intent-classifier.d.ts.map +0 -1
  47. package/dist/template/intent-classifier.js +0 -251
  48. package/dist/template/intent-classifier.js.map +0 -1
  49. package/dist/template/nl-intent.d.ts +0 -38
  50. package/dist/template/nl-intent.d.ts.map +0 -1
  51. package/dist/template/nl-intent.js +0 -39
  52. package/dist/template/nl-intent.js.map +0 -1
  53. package/dist/template/prompts/prompt-builder.d.ts +0 -20
  54. package/dist/template/prompts/prompt-builder.d.ts.map +0 -1
  55. package/dist/template/prompts/prompt-builder.js +0 -243
  56. package/dist/template/prompts/prompt-builder.js.map +0 -1
  57. package/dist/template/template-engine.d.ts +0 -27
  58. package/dist/template/template-engine.d.ts.map +0 -1
  59. package/dist/template/template-engine.js +0 -378
  60. package/dist/template/template-engine.js.map +0 -1
  61. package/dist/utils/chinese-number-parser.d.ts +0 -30
  62. package/dist/utils/chinese-number-parser.d.ts.map +0 -1
  63. package/dist/utils/chinese-number-parser.js +0 -92
  64. package/dist/utils/chinese-number-parser.js.map +0 -1
  65. package/dist/validation/auto-fixer.d.ts +0 -13
  66. package/dist/validation/auto-fixer.d.ts.map +0 -1
  67. package/dist/validation/auto-fixer.js +0 -110
  68. package/dist/validation/auto-fixer.js.map +0 -1
  69. package/dist/validation/self-correction-loop.d.ts +0 -46
  70. package/dist/validation/self-correction-loop.d.ts.map +0 -1
  71. package/dist/validation/self-correction-loop.js +0 -132
  72. package/dist/validation/self-correction-loop.js.map +0 -1
  73. package/dist/validation/validation-pipeline.d.ts +0 -81
  74. package/dist/validation/validation-pipeline.d.ts.map +0 -1
  75. package/dist/validation/validation-pipeline.js +0 -306
  76. package/dist/validation/validation-pipeline.js.map +0 -1
@@ -0,0 +1,917 @@
1
+ import { ContextSchema, SpelEvaluator } from '@agentix-e/spel-ts';
2
+ export { BeanSchema, ContextSchema, FieldSchema, FunctionSchema, MethodSchema, ParseError, ParseResult, RootObjectSchema, SpelEvaluator, TypeSchema, VariableSchema } from '@agentix-e/spel-ts';
3
+
4
+ /**
5
+ * LLMProvider interface — NL2Spel's pluggable LLM contract.
6
+ *
7
+ * Design principles:
8
+ * 1. Minimal interface: only exposes generate + generateStream + lifecycle
9
+ * 2. Capability declaration: capabilities let StrategyRouter make routing decisions
10
+ * 3. Async lifecycle: supports Providers that need init/dispose (e.g. WebLLM)
11
+ * 4. Stream support: optional generateStream for progressive generation
12
+ */
13
+ interface LLMProvider {
14
+ /** Provider unique name, used for logging/debugging/Provider selection */
15
+ readonly name: string;
16
+ /** Provider capability declaration */
17
+ readonly capabilities: LLMCapabilities;
18
+ /**
19
+ * Generate a SpEL expression (core method)
20
+ */
21
+ generate(prompt: LLMPrompt, options?: LLMGenerateOptions): Promise<LLMResponse>;
22
+ /**
23
+ * Stream generate a SpEL expression (optional implementation)
24
+ */
25
+ generateStream?(prompt: LLMPrompt, options?: LLMGenerateOptions): AsyncIterable<LLMStreamChunk>;
26
+ /**
27
+ * Check if the Provider is currently available
28
+ */
29
+ isAvailable(): Promise<boolean>;
30
+ /**
31
+ * Initialize the Provider (optional)
32
+ */
33
+ initialize?(): Promise<void>;
34
+ /**
35
+ * Release Provider resources (optional)
36
+ */
37
+ dispose?(): Promise<void>;
38
+ }
39
+ /**
40
+ * LLMProvider capability declaration.
41
+ *
42
+ * Declares what the provider CAN do — facts the engine can verify.
43
+ * Provider ordering is user-controlled via {@link ProviderRegistry.register} priority.
44
+ */
45
+ interface LLMCapabilities {
46
+ /** Maximum context window (tokens) */
47
+ maxContextTokens: number;
48
+ /** Whether Grammar Constraint (GBNF, etc.) is supported */
49
+ supportsGrammarConstraint: boolean;
50
+ /** Whether streaming output is supported */
51
+ supportsStreaming: boolean;
52
+ /** Whether Structured Output (JSON mode) is supported */
53
+ supportsStructuredOutput: boolean;
54
+ /** Whether available offline (no network required) */
55
+ offlineAvailable: boolean;
56
+ }
57
+ /**
58
+ * Standardized LLM Prompt structure.
59
+ */
60
+ interface LLMPrompt {
61
+ /** System prompt */
62
+ system: string;
63
+ /** User input */
64
+ user: string;
65
+ /** Context Schema */
66
+ contextSchema: ContextSchema;
67
+ /** Few-Shot example list */
68
+ examples: FewShotExample[];
69
+ /** Grammar constraint string (GBNF format) */
70
+ grammar?: string;
71
+ }
72
+ /**
73
+ * Few-Shot example
74
+ */
75
+ interface FewShotExample {
76
+ /** Natural language input */
77
+ nl: string;
78
+ /** Expected SpEL expression */
79
+ spel: string;
80
+ /** Difficulty level */
81
+ difficulty: 'easy' | 'medium' | 'hard';
82
+ /** Category */
83
+ category: string;
84
+ }
85
+ /**
86
+ * LLM generation options
87
+ */
88
+ interface LLMGenerateOptions {
89
+ /** Temperature (0-2), default 0.1 */
90
+ temperature?: number;
91
+ /** Maximum output tokens */
92
+ maxTokens?: number;
93
+ /** Top-p sampling */
94
+ topP?: number;
95
+ /** Stop sequences */
96
+ stopSequences?: string[];
97
+ /** Whether to enable stream */
98
+ stream?: boolean;
99
+ /** Custom model override */
100
+ model?: string;
101
+ /** Timeout (ms), default 30000 */
102
+ timeout?: number;
103
+ /** Maximum retry count */
104
+ maxRetries?: number;
105
+ }
106
+ /**
107
+ * LLM generation response
108
+ */
109
+ interface LLMResponse {
110
+ /** Raw generated text */
111
+ text: string;
112
+ /** Actual model used */
113
+ model: string;
114
+ /** Token usage statistics */
115
+ usage: LLMUsage;
116
+ /** Generation latency (ms) */
117
+ latencyMs: number;
118
+ /** Finish reason */
119
+ finishReason: 'stop' | 'length' | 'content_filter' | 'error';
120
+ /** Provider name */
121
+ providerName: string;
122
+ }
123
+ /**
124
+ * LLM Stream Chunk
125
+ */
126
+ interface LLMStreamChunk {
127
+ /** Delta text */
128
+ delta: string;
129
+ /** Accumulated text */
130
+ accumulated: string;
131
+ /** Whether done */
132
+ done: boolean;
133
+ /** Finish reason */
134
+ finishReason?: string;
135
+ }
136
+ /**
137
+ * Token usage statistics
138
+ */
139
+ interface LLMUsage {
140
+ promptTokens: number;
141
+ completionTokens: number;
142
+ totalTokens: number;
143
+ }
144
+
145
+ /**
146
+ * ProviderRegistry — manages registered LLMProvider instances.
147
+ *
148
+ * Provider ordering is user-controlled:
149
+ * 1. Offline providers first (engine-enforced — offline capability is a binary fact)
150
+ * 2. User-assigned priority (lower = preferred; default = registration order)
151
+ * 3. Registration order (tiebreaker when priorities are equal)
152
+ */
153
+ declare class ProviderRegistry {
154
+ private _providers;
155
+ private _nextIndex;
156
+ /**
157
+ * Register a Provider.
158
+ * @param provider LLMProvider instance
159
+ * @param options.priority User-assigned priority (lower = preferred). Defaults to registration order.
160
+ */
161
+ register(provider: LLMProvider, options?: {
162
+ priority?: number;
163
+ }): void;
164
+ /** Unregister a Provider */
165
+ unregister(name: string): void;
166
+ /** Get a Provider by name */
167
+ get(name: string): LLMProvider | undefined;
168
+ /**
169
+ * Get available Providers sorted by priority.
170
+ * Sort rule: offline first → user priority (asc) → registration order (asc)
171
+ */
172
+ getPrioritized(): Promise<LLMProvider[]>;
173
+ /**
174
+ * Explicitly reorder providers by name.
175
+ * Providers not listed retain their position after the reordered ones.
176
+ */
177
+ reorder(providerNames: string[]): void;
178
+ /** List all registered Providers */
179
+ list(): LLMProvider[];
180
+ /** Number of registered Providers */
181
+ get count(): number;
182
+ }
183
+
184
+ /**
185
+ * ContextExtractor — builds a ContextSchema from plain data structures.
186
+ *
187
+ * Decoupled from any concrete SpEL implementation, accepts only:
188
+ * - rootObject: any object (for extracting property types)
189
+ * - variables: Record<string, { type: string; value?: unknown }>
190
+ * - beans: string[]
191
+ * - types: string[]
192
+ */
193
+ declare class ContextExtractor {
194
+ /**
195
+ * Extract ContextSchema from plain data structures (no spel-ts dependency)
196
+ */
197
+ extract(context: {
198
+ rootObject?: unknown;
199
+ rootName?: string;
200
+ variables?: Record<string, {
201
+ type: string;
202
+ value?: unknown;
203
+ description?: string;
204
+ nullable?: boolean;
205
+ }>;
206
+ beans?: Array<{
207
+ name: string;
208
+ type: string;
209
+ description?: string;
210
+ singleton?: boolean;
211
+ }>;
212
+ types?: Array<{
213
+ name: string;
214
+ className?: string;
215
+ description?: string;
216
+ }>;
217
+ functions?: Array<{
218
+ name: string;
219
+ returnType: string;
220
+ params: Array<{
221
+ name: string;
222
+ type: string;
223
+ }>;
224
+ description?: string;
225
+ }>;
226
+ }): ContextSchema;
227
+ /**
228
+ * Extract root object schema
229
+ */
230
+ private extractRoot;
231
+ /**
232
+ * Extract object fields
233
+ */
234
+ /**
235
+ * Recursively extract fields from an object, following nested objects
236
+ * all the way to leaf values. Uses a visited set to prevent circular references.
237
+ */
238
+ private extractFields;
239
+ /**
240
+ * Infer SpEL type
241
+ */
242
+ private inferSpelType;
243
+ /**
244
+ * Generate field description
245
+ */
246
+ private generateDescription;
247
+ /**
248
+ * Safely get example value
249
+ */
250
+ private safeExample;
251
+ /**
252
+ * Extract variables
253
+ */
254
+ private extractVariables;
255
+ /**
256
+ * Extract beans
257
+ */
258
+ private extractBeans;
259
+ /**
260
+ * Extract types
261
+ */
262
+ private extractTypes;
263
+ /**
264
+ * Extract functions
265
+ */
266
+ private extractFunctions;
267
+ }
268
+
269
+ /**
270
+ * SchemaFormatter — formats ContextSchema into readable text.
271
+ *
272
+ * Two formats:
273
+ * 1. formatForLLM(): optimized for LLM prompts (compact, key info first)
274
+ * 2. formatForHuman(): human-readable format (complete, indent-friendly)
275
+ */
276
+ declare class SchemaFormatter {
277
+ /**
278
+ * LLM-optimized format — compact, injected into the User part of the prompt
279
+ */
280
+ formatForLLM(schema: ContextSchema): string;
281
+ /**
282
+ * Human-readable format
283
+ */
284
+ formatForHuman(schema: ContextSchema): string;
285
+ private formatFieldForLLM;
286
+ }
287
+
288
+ /**
289
+ * Pattern definition — core data structures for Layer 0.
290
+ *
291
+ * Each PatternDefinition describes a mapping from natural language pattern to SpEL expression.
292
+ * Supports both Chinese and English languages.
293
+ */
294
+ interface PatternDefinition {
295
+ /** Unique identifier */
296
+ id: string;
297
+ /**
298
+ * Match regex (at least one language)
299
+ * Uses named capture groups (?<slotName>...) to extract slots
300
+ */
301
+ match: RegExp;
302
+ /**
303
+ * SpEL template string
304
+ * Uses {slotName} placeholders to reference capture groups
305
+ */
306
+ spelTemplate: string;
307
+ /**
308
+ * Slot definitions (capture groups mapped to SpEL types)
309
+ */
310
+ slots: Record<string, SlotDefinition>;
311
+ /** Priority (0-100), higher priority matched first */
312
+ priority: number;
313
+ /** Tags (for classification and debugging) */
314
+ tags: string[];
315
+ /** Example input/output pairs */
316
+ examples: Array<{
317
+ nl: string;
318
+ spel: string;
319
+ }>;
320
+ /** Difficulty level */
321
+ difficulty: 'easy' | 'medium';
322
+ /** Confidence (0-1) */
323
+ confidence: number;
324
+ }
325
+ interface SlotDefinition {
326
+ /** Key appearing in spelTemplate */
327
+ key: string;
328
+ /** SpEL value type: 'number' | 'string' | 'boolean' | 'variable' | 'literal' */
329
+ type: 'number' | 'string' | 'boolean' | 'variable' | 'literal';
330
+ /** Optional: value transformer (e.g. Chinese numbers → number) */
331
+ transform?: SlotTransform;
332
+ /** Optional: default value */
333
+ defaultValue?: string;
334
+ }
335
+ type SlotTransform = 'toNumber' | 'toBoolean' | 'toString' | 'trim' | 'lowercase' | 'normalize';
336
+
337
+ interface PatternMatchResult {
338
+ /** Whether matched */
339
+ matched: boolean;
340
+ /** The matching PatternDefinition */
341
+ pattern?: PatternDefinition;
342
+ /** Generated SpEL expression (if matched) */
343
+ spel?: string;
344
+ /** Confidence (0-1) */
345
+ confidence: number;
346
+ /** Match latency (ms) */
347
+ latencyMs: number;
348
+ /** Extracted slot values */
349
+ slots?: Record<string, string>;
350
+ }
351
+ /**
352
+ * PatternMatcher — Layer 0 pattern matching core.
353
+ */
354
+ declare class PatternMatcher {
355
+ private _patterns;
356
+ constructor(patterns?: PatternDefinition[]);
357
+ get patternCount(): number;
358
+ register(pattern: PatternDefinition): void;
359
+ registerAll(patterns: PatternDefinition[]): void;
360
+ private sortByPriority;
361
+ /**
362
+ * Match natural language input, return the best match
363
+ */
364
+ match(nl: string): PatternMatchResult;
365
+ /**
366
+ * Batch match
367
+ */
368
+ matchAll(nl: string, maxResults?: number): PatternMatchResult[];
369
+ /**
370
+ * Input normalization
371
+ */
372
+ private normalize;
373
+ /**
374
+ * Infer SpEL root object name from Chinese input
375
+ */
376
+ private inferRoot;
377
+ /**
378
+ * Extract Chinese field names from input and map to SpEL fields
379
+ */
380
+ private extractChineseField;
381
+ /**
382
+ * Template filling and value transformation
383
+ */
384
+ private fillTemplate;
385
+ /**
386
+ * Infer SpEL field name from capture group
387
+ */
388
+ private inferFieldFromCapture;
389
+ }
390
+
391
+ /**
392
+ * Built-in pattern library — covers ≥80% Easy scenarios, 63 PatternDefinitions.
393
+ *
394
+ * Core design:
395
+ * 1. All patterns use named capture groups `(?<field>…)` or `(?<value>…)` to extract parameters
396
+ * 2. Separate Chinese/English patterns (don't mix keywords, avoids cross-language false matches)
397
+ * 3. High-specificity patterns have higher priority ("not empty" > "not")
398
+ * 4. Sorted by priority descending
399
+ */
400
+ declare const BUILTIN_PATTERNS: PatternDefinition[];
401
+
402
+ /**
403
+ * NLIntent — Natural language intent classification system.
404
+ *
405
+ * 15 intent types covering all common SpEL usage scenarios.
406
+ */
407
+ declare enum NLIntent {
408
+ /** Numeric comparison: "amount > 100", "年龄大于18" */
409
+ COMPARISON = "COMPARISON",
410
+ /** Permission check: "hasRole('admin')", "用户是VIP" */
411
+ PERMISSION_CHECK = "PERMISSION_CHECK",
412
+ /** Null check: "== null", "!= null", "不为空" */
413
+ NULL_CHECK = "NULL_CHECK",
414
+ /** Logical combination: "a and b", "金额大于100且已确认" */
415
+ LOGICAL = "LOGICAL",
416
+ /** String matching: "contains('keyword')", "以ORD开头" */
417
+ STRING_MATCH = "STRING_MATCH",
418
+ /** Collection operations: "list.contains('x')", "items.isEmpty()" */
419
+ COLLECTION = "COLLECTION",
420
+ /** Range check: "between {1, 10}", "年龄在18到60之间" */
421
+ RANGE = "RANGE",
422
+ /** Selection (filter): ".?[condition]", "all matching conditions" */
423
+ SELECTION = "SELECTION",
424
+ /** Projection: ".![field]", "each item's name" */
425
+ PROJECTION = "PROJECTION",
426
+ /** Type check: "instanceof", "是否是Admin类型" */
427
+ TYPE_CHECK = "TYPE_CHECK",
428
+ /** Boolean property: "isVIP", "是否已支付" */
429
+ BOOLEAN = "BOOLEAN",
430
+ /** Date comparison: "after/before", "after a certain date" */
431
+ DATE = "DATE",
432
+ /** Elvis default: "a ?: default", "or default value" */
433
+ ELVIS = "ELVIS",
434
+ /** Assignment: "a = value", "set field to" */
435
+ ASSIGNMENT = "ASSIGNMENT",
436
+ /** Arithmetic: "amount * price", "total = unit price × quantity" */
437
+ ARITHMETIC = "ARITHMETIC"
438
+ }
439
+
440
+ /**
441
+ * Intent classification result
442
+ */
443
+ interface IntentResult {
444
+ /** Primary intent (highest confidence) */
445
+ primaryIntent: NLIntent;
446
+ /** All possible intents with confidence scores */
447
+ intents: Array<{
448
+ intent: NLIntent;
449
+ confidence: number;
450
+ }>;
451
+ /** Extracted entities */
452
+ entities: IntentEntity[];
453
+ /** Recognized operators */
454
+ operators: string[];
455
+ /** Recognized logical connectors */
456
+ logicalConnectors: string[];
457
+ /** Complexity score (0-100) */
458
+ complexity: number;
459
+ }
460
+ interface IntentEntity {
461
+ text: string;
462
+ type: 'field' | 'value' | 'operator' | 'logic' | 'quantifier';
463
+ position: {
464
+ start: number;
465
+ end: number;
466
+ };
467
+ }
468
+ declare class IntentClassifier {
469
+ /**
470
+ * Main method for classifying natural language input
471
+ */
472
+ classify(input: string): IntentResult;
473
+ /**
474
+ * Entity extraction
475
+ */
476
+ private extractEntities;
477
+ /**
478
+ * Operator recognition
479
+ */
480
+ private extractOperators;
481
+ /**
482
+ * Logical connector recognition
483
+ */
484
+ private extractLogicalConnectors;
485
+ /**
486
+ * Complexity calculation
487
+ */
488
+ private calculateComplexity;
489
+ /**
490
+ * Input normalization
491
+ */
492
+ private normalize;
493
+ }
494
+
495
+ interface TemplateResult {
496
+ /** Generated SpEL expression */
497
+ expression: string;
498
+ /** Intent used */
499
+ intent: NLIntent;
500
+ /** Template name used */
501
+ templateName: string;
502
+ /** Confidence */
503
+ confidence: number;
504
+ /** Unfilled slots needing further LLM processing */
505
+ unfilledSlots: string[];
506
+ }
507
+ declare class TemplateEngine {
508
+ private contextSchema?;
509
+ constructor(contextSchema?: ContextSchema);
510
+ setContext(schema: ContextSchema): void;
511
+ /**
512
+ * Generate a SpEL expression based on intent classification results
513
+ */
514
+ generate(input: string, intentResult: IntentResult): TemplateResult | null;
515
+ private selectBestTemplate;
516
+ private fillTemplate;
517
+ }
518
+
519
+ interface PromptBuilderOptions {
520
+ /** Language (zh/en) */
521
+ language?: 'zh' | 'en';
522
+ /** Whether to include EBNF grammar block */
523
+ includeEBNF?: boolean;
524
+ }
525
+ declare class PromptBuilder {
526
+ private readonly formatter;
527
+ /**
528
+ * Build a complete LLM Prompt
529
+ */
530
+ build(userInput: string, contextSchema?: ContextSchema, options?: PromptBuilderOptions): LLMPrompt;
531
+ /**
532
+ * Build Few-Shot example string
533
+ */
534
+ private buildExamples;
535
+ }
536
+
537
+ interface ValidationResult {
538
+ /** Whether all validation stages passed */
539
+ valid: boolean;
540
+ /** Stage results */
541
+ stages: {
542
+ parse: StageResult;
543
+ type: StageResult;
544
+ semantic: StageResult;
545
+ context: StageResult;
546
+ };
547
+ /** All errors */
548
+ errors: ValidationError[];
549
+ /** All warnings */
550
+ warnings: ValidationWarning[];
551
+ }
552
+ interface StageResult {
553
+ passed: boolean;
554
+ errors: ValidationError[];
555
+ warnings: ValidationWarning[];
556
+ }
557
+ interface ValidationError {
558
+ code: string;
559
+ message: string;
560
+ /** Error position in expression */
561
+ position?: number;
562
+ /** Stage the error belongs to */
563
+ stage: 'parse' | 'type' | 'semantic' | 'context';
564
+ /** Whether LLM regeneration is needed */
565
+ requiresLLM?: boolean;
566
+ }
567
+ interface ValidationWarning {
568
+ code: string;
569
+ message: string;
570
+ /** Warning position in expression */
571
+ position?: number;
572
+ /** Stage the warning belongs to */
573
+ stage: 'parse' | 'type' | 'semantic' | 'context';
574
+ }
575
+ /**
576
+ * ValidationPipeline — four-stage validation pipeline.
577
+ *
578
+ * 1. Parse: syntax validity (depends on SpelEvaluator)
579
+ * 2. Type: type checking (operator-operand type matching)
580
+ * 3. Semantic: semantic reasonableness (is the expression meaningful)
581
+ * 4. Context: context references (do all references exist in ContextSchema)
582
+ */
583
+ declare class ValidationPipeline {
584
+ private evaluator;
585
+ constructor(evaluator?: SpelEvaluator | null);
586
+ setEvaluator(evaluator: SpelEvaluator): void;
587
+ /**
588
+ * Run the full validation pipeline
589
+ */
590
+ validate(expression: string, contextSchema?: ContextSchema): Promise<ValidationResult>;
591
+ /**
592
+ * Stage 1: Parse Check — syntax validation
593
+ */
594
+ private validateParse;
595
+ /**
596
+ * Stage 2: Type Check — type validation
597
+ */
598
+ private validateTypes;
599
+ /**
600
+ * Stage 3: Semantic Check — semantic reasonableness validation
601
+ */
602
+ private validateSemantic;
603
+ /**
604
+ * Stage 4: Context Check — context reference validation
605
+ */
606
+ private validateContext;
607
+ /**
608
+ * Check if parentheses are balanced
609
+ */
610
+ private hasBalancedParentheses;
611
+ /**
612
+ * Extract all identifier references from expression
613
+ */
614
+ private extractReferences;
615
+ }
616
+
617
+ /**
618
+ * AutoFixer — automatically fixes common SpEL syntax errors from LLM output.
619
+ */
620
+ declare class AutoFixer {
621
+ fix(expression: string): AutoFixResult;
622
+ private fixAllBrackets;
623
+ }
624
+ interface AutoFixResult {
625
+ expression: string;
626
+ wasFixed: boolean;
627
+ changes: string[];
628
+ }
629
+
630
+ interface SelfCorrectionResult {
631
+ /** Final expression */
632
+ expression: string;
633
+ /** Whether validation passed */
634
+ valid: boolean;
635
+ /** Original LLM output */
636
+ originalOutput: string;
637
+ /** Number of correction attempts */
638
+ correctionAttempts: number;
639
+ /** Log of each correction round */
640
+ corrections: CorrectionLog[];
641
+ /** Total latency (ms) */
642
+ totalLatencyMs: number;
643
+ }
644
+ interface CorrectionLog {
645
+ attempt: number;
646
+ expression: string;
647
+ valid: boolean;
648
+ errorCount: number;
649
+ warningCount: number;
650
+ autoFixed: boolean;
651
+ autoFixChanges: string[];
652
+ }
653
+ interface SelfCorrectionConfig {
654
+ /** Maximum correction attempts (default 3) */
655
+ maxAttempts?: number;
656
+ /** Minimum confidence threshold (default 0.7) */
657
+ minConfidence?: number;
658
+ /** Whether AutoFix is enabled (default true) */
659
+ enableAutoFix?: boolean;
660
+ }
661
+ declare class SelfCorrectionLoop {
662
+ private readonly pipeline;
663
+ private readonly autoFixer;
664
+ private readonly config;
665
+ constructor(config?: SelfCorrectionConfig, pipeline?: ValidationPipeline, autoFixer?: AutoFixer);
666
+ /**
667
+ * Execute the self-correction loop
668
+ */
669
+ correct(expression: string, contextSchema: ContextSchema, generateFn: (prompt: LLMPrompt) => Promise<LLMResponse>, originalPrompt: LLMPrompt): Promise<SelfCorrectionResult>;
670
+ }
671
+
672
+ type StrategyType = 'pattern' | 'template' | 'llm-api' | 'llm-fallback' | 'none';
673
+ interface StrategyResult {
674
+ /** Generated SpEL expression */
675
+ expression: string;
676
+ /** Strategy used */
677
+ strategy: StrategyType;
678
+ /** Confidence (0-1) */
679
+ confidence: number;
680
+ /** Strategy-related metadata */
681
+ metadata: StrategyMetadata;
682
+ /** Generation latency (ms) */
683
+ latencyMs: number;
684
+ }
685
+ interface StrategyMetadata {
686
+ /** Matched pattern ID (pattern strategy only) */
687
+ patternId?: string;
688
+ /** Intent type (template strategy only) */
689
+ intent?: string;
690
+ /** Template name (template strategy only) */
691
+ templateName?: string;
692
+ /** LLM Provider name (llm strategy only) */
693
+ providerName?: string;
694
+ /** LLM model (llm strategy only) */
695
+ model?: string;
696
+ /** Correction count (llm strategy + self-correction only) */
697
+ corrections?: number;
698
+ /** Raw LLM output (llm strategy only) */
699
+ rawOutput?: string;
700
+ }
701
+ interface StrategyRouterConfig {
702
+ /** Pattern confidence threshold (default 0.7) */
703
+ patternMinConfidence?: number;
704
+ /** Template confidence threshold (default 0.6) */
705
+ templateMinConfidence?: number;
706
+ /** LLM confidence threshold (default 0.5) */
707
+ llmMinConfidence?: number;
708
+ /** Whether Self-Correction is enabled (default true) */
709
+ enableSelfCorrection?: boolean;
710
+ /** Maximum Self-Correction attempts (default 3) */
711
+ maxCorrectionAttempts?: number;
712
+ }
713
+ declare class StrategyRouter {
714
+ private readonly patternMatcher;
715
+ private readonly intentClassifier;
716
+ private readonly templateEngine;
717
+ private readonly promptBuilder;
718
+ private readonly validationPipeline;
719
+ private readonly autoFixer;
720
+ private readonly providerRegistry;
721
+ private readonly config;
722
+ constructor(providerRegistry: ProviderRegistry, config?: StrategyRouterConfig);
723
+ /**
724
+ * Execute the full generation strategy routing
725
+ */
726
+ generate(nl: string, contextSchema?: ContextSchema, forceLLMProvider?: string): Promise<StrategyResult>;
727
+ /**
728
+ * Get PatternMatcher (for external testing/debugging)
729
+ */
730
+ getPatternMatcher(): PatternMatcher;
731
+ /**
732
+ * Get TemplateEngine
733
+ */
734
+ getTemplateEngine(): TemplateEngine;
735
+ /**
736
+ * Get PromptBuilder
737
+ */
738
+ getPromptBuilder(): PromptBuilder;
739
+ /**
740
+ * Set SpelEvaluator for validation pipeline.
741
+ * Must be called before generate() if parse-level validation is needed.
742
+ */
743
+ setEvaluator(evaluator: SpelEvaluator): void;
744
+ }
745
+
746
+ interface GenerateOptions {
747
+ /** Context Schema (optional) */
748
+ contextSchema?: ContextSchema;
749
+ /** Raw context object (auto-extracted to ContextSchema) */
750
+ context?: {
751
+ rootObject?: unknown;
752
+ rootName?: string;
753
+ variables?: Record<string, {
754
+ type: string;
755
+ value?: unknown;
756
+ description?: string;
757
+ nullable?: boolean;
758
+ }>;
759
+ beans?: Array<{
760
+ name: string;
761
+ type: string;
762
+ description?: string;
763
+ }>;
764
+ types?: Array<{
765
+ name: string;
766
+ className?: string;
767
+ description?: string;
768
+ }>;
769
+ };
770
+ /** Force using a specific LLM Provider */
771
+ preferredProvider?: string;
772
+ /** Minimum confidence threshold (default 0.5) */
773
+ minConfidence?: number;
774
+ /** Offline only (Pattern + Template, no LLM calls) */
775
+ offlineOnly?: boolean;
776
+ /** Whether validation is enabled (default true) */
777
+ enableValidation?: boolean;
778
+ /** Whether self-correction is enabled (default true) */
779
+ enableSelfCorrection?: boolean;
780
+ /** Language (default auto-detect) */
781
+ language?: 'zh' | 'en';
782
+ /** Whether to return debug information */
783
+ debug?: boolean;
784
+ }
785
+ interface GenerateResult {
786
+ /** Generated SpEL expression */
787
+ expression: string;
788
+ /** Strategy used */
789
+ strategy: string;
790
+ /** Confidence (0-1) */
791
+ confidence: number;
792
+ /** Generation latency (ms) */
793
+ latencyMs: number;
794
+ /** Debug info (only when debug=true) */
795
+ debugInfo?: DebugInfo;
796
+ }
797
+ interface DebugInfo {
798
+ /** Pattern match result */
799
+ patternMatch?: {
800
+ matched: boolean;
801
+ patternId?: string;
802
+ spel?: string;
803
+ };
804
+ /** Intent classification result */
805
+ intent?: {
806
+ primary: string;
807
+ complexity: number;
808
+ };
809
+ /** Template generation result */
810
+ template?: {
811
+ expression?: string;
812
+ templateName?: string;
813
+ };
814
+ /** LLM Provider info */
815
+ provider?: {
816
+ name: string;
817
+ model: string;
818
+ };
819
+ /** Self-correction info */
820
+ corrections?: {
821
+ attempts: number;
822
+ };
823
+ }
824
+ interface ExplainResult {
825
+ /** Input text */
826
+ input: string;
827
+ /** Strategy used */
828
+ strategy: string;
829
+ /** Intent information */
830
+ intent: {
831
+ primary: string;
832
+ complexity: number;
833
+ all: Array<{
834
+ intent: string;
835
+ confidence: number;
836
+ }>;
837
+ };
838
+ /** Whether pattern was matched */
839
+ patternMatched: boolean;
840
+ /** Matched Pattern ID */
841
+ patternId?: string;
842
+ /** Final expression */
843
+ expression: string;
844
+ /** All possible expressions (from different strategies) */
845
+ alternatives: string[];
846
+ }
847
+ declare class NL2SpelEngine {
848
+ private readonly router;
849
+ private readonly providerRegistry;
850
+ private evaluatorInstance;
851
+ constructor(config?: StrategyRouterConfig);
852
+ /**
853
+ * Register an LLM Provider
854
+ */
855
+ registerProvider(provider: LLMProvider): void;
856
+ /**
857
+ * Unregister an LLM Provider
858
+ */
859
+ unregisterProvider(name: string): void;
860
+ /**
861
+ * Register a custom Pattern
862
+ */
863
+ registerPattern(pattern: PatternDefinition): void;
864
+ /**
865
+ * Set SpelEvaluator for validation pipeline.
866
+ * Must be called before generate() if parse-level validation is required.
867
+ */
868
+ setSpelEvaluator(evaluator: SpelEvaluator): void;
869
+ /**
870
+ * Extract ContextSchema from raw context object
871
+ */
872
+ extractContextSchema(context: NonNullable<GenerateOptions['context']>): ContextSchema;
873
+ /**
874
+ * Core generation API
875
+ */
876
+ generate(nl: string, options?: GenerateOptions): Promise<GenerateResult>;
877
+ /**
878
+ * Batch generation
879
+ */
880
+ generateBatch(nls: string[], options?: GenerateOptions): Promise<GenerateResult[]>;
881
+ /**
882
+ * Debug explanation
883
+ */
884
+ explain(nl: string, options?: GenerateOptions): Promise<ExplainResult>;
885
+ }
886
+
887
+ /**
888
+ * Chinese number parser — converts Chinese number strings to Arabic numerals.
889
+ *
890
+ * Supports:
891
+ * - Basic digits: 零一二三四五六七八九十百千万亿
892
+ * - Leading "十": "十五" → 15
893
+ * - Thousands/hundred-millions grouping: "一万二千三百四十五" → 12345
894
+ * - Zero padding: "一千零一" → 1001
895
+ */
896
+ declare class ChineseNumberParser {
897
+ private static readonly DIGITS;
898
+ private static readonly UNITS;
899
+ private static readonly CHINESE_NUM_PATTERN;
900
+ /**
901
+ * Check if a string is pure Chinese numbers
902
+ */
903
+ static isChineseNumber(text: string): boolean;
904
+ /**
905
+ * Parse Chinese numbers → Arabic numerals
906
+ *
907
+ * @param text Chinese number string
908
+ * @returns Parsed number, returns NaN on failure
909
+ */
910
+ static parse(text: string): number;
911
+ /**
912
+ * Safe parse: returns null if parsing fails
913
+ */
914
+ static parseSafe(text: string): number | null;
915
+ }
916
+
917
+ export { type AutoFixResult, AutoFixer, BUILTIN_PATTERNS, ChineseNumberParser, ContextExtractor, type CorrectionLog, type DebugInfo, type ExplainResult, type FewShotExample, type GenerateOptions, type GenerateResult, IntentClassifier, type IntentEntity, type IntentResult, type LLMCapabilities, type LLMGenerateOptions, type LLMPrompt, type LLMProvider, type LLMResponse, type LLMStreamChunk, type LLMUsage, NL2SpelEngine, NLIntent, type PatternDefinition, type PatternMatchResult, PatternMatcher, PromptBuilder, type PromptBuilderOptions, ProviderRegistry, SchemaFormatter, type SelfCorrectionConfig, SelfCorrectionLoop, type SelfCorrectionResult, type SlotDefinition, type SlotTransform, type StageResult, type StrategyMetadata, type StrategyResult, StrategyRouter, type StrategyRouterConfig, type StrategyType, TemplateEngine, type TemplateResult, type ValidationError, ValidationPipeline, type ValidationResult, type ValidationWarning };