@goreal-ai/echo-pdk 0.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.
Files changed (53) hide show
  1. package/dist/ai-judge/index.d.ts +177 -0
  2. package/dist/ai-judge/index.d.ts.map +1 -0
  3. package/dist/ai-judge/index.js +299 -0
  4. package/dist/ai-judge/index.js.map +1 -0
  5. package/dist/evaluator/evaluator.d.ts +136 -0
  6. package/dist/evaluator/evaluator.d.ts.map +1 -0
  7. package/dist/evaluator/evaluator.js +407 -0
  8. package/dist/evaluator/evaluator.js.map +1 -0
  9. package/dist/evaluator/index.d.ts +7 -0
  10. package/dist/evaluator/index.d.ts.map +1 -0
  11. package/dist/evaluator/index.js +8 -0
  12. package/dist/evaluator/index.js.map +1 -0
  13. package/dist/evaluator/operators.d.ts +105 -0
  14. package/dist/evaluator/operators.d.ts.map +1 -0
  15. package/dist/evaluator/operators.js +371 -0
  16. package/dist/evaluator/operators.js.map +1 -0
  17. package/dist/index.d.ts +115 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +388 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/parser/ast.d.ts +106 -0
  22. package/dist/parser/ast.d.ts.map +1 -0
  23. package/dist/parser/ast.js +260 -0
  24. package/dist/parser/ast.js.map +1 -0
  25. package/dist/parser/index.d.ts +8 -0
  26. package/dist/parser/index.d.ts.map +1 -0
  27. package/dist/parser/index.js +13 -0
  28. package/dist/parser/index.js.map +1 -0
  29. package/dist/parser/lexer.d.ts +199 -0
  30. package/dist/parser/lexer.d.ts.map +1 -0
  31. package/dist/parser/lexer.js +491 -0
  32. package/dist/parser/lexer.js.map +1 -0
  33. package/dist/parser/parser.d.ts +49 -0
  34. package/dist/parser/parser.d.ts.map +1 -0
  35. package/dist/parser/parser.js +615 -0
  36. package/dist/parser/parser.js.map +1 -0
  37. package/dist/plugins/index.d.ts +62 -0
  38. package/dist/plugins/index.d.ts.map +1 -0
  39. package/dist/plugins/index.js +170 -0
  40. package/dist/plugins/index.js.map +1 -0
  41. package/dist/renderer/index.d.ts +6 -0
  42. package/dist/renderer/index.d.ts.map +1 -0
  43. package/dist/renderer/index.js +5 -0
  44. package/dist/renderer/index.js.map +1 -0
  45. package/dist/renderer/renderer.d.ts +97 -0
  46. package/dist/renderer/renderer.d.ts.map +1 -0
  47. package/dist/renderer/renderer.js +243 -0
  48. package/dist/renderer/renderer.js.map +1 -0
  49. package/dist/types.d.ts +255 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +9 -0
  52. package/dist/types.js.map +1 -0
  53. package/package.json +54 -0
@@ -0,0 +1,407 @@
1
+ /**
2
+ * @fileoverview Echo Evaluator - Condition evaluation engine
3
+ *
4
+ * This file implements the evaluator for Echo DSL.
5
+ * The evaluator processes the AST and determines which nodes should be rendered
6
+ * based on the provided context and condition evaluation.
7
+ *
8
+ * KEY OPTIMIZATION: AI JUDGE PARALLELIZATION
9
+ * Before evaluating the AST, we:
10
+ * 1. Collect ALL #ai_judge conditions from the tree
11
+ * 2. Evaluate them in parallel using Promise.all
12
+ * 3. Cache the results
13
+ * 4. Use cached results during tree evaluation
14
+ *
15
+ * This prevents sequential blocking on AI calls.
16
+ */
17
+ import { collectAiJudgeConditions } from '../parser/ast.js';
18
+ import { getOperator } from './operators.js';
19
+ /**
20
+ * Resolve a variable path from context.
21
+ *
22
+ * Supports:
23
+ * - Simple: "name" -> context.name
24
+ * - Nested: "user.name" -> context.user.name
25
+ * - Array: "items[0]" -> context.items[0]
26
+ * - Mixed: "users[0].name" -> context.users[0].name
27
+ *
28
+ * @param path - The variable path
29
+ * @param context - The context object
30
+ * @param options - Resolution options
31
+ * @returns The resolved value or undefined
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const context = { user: { name: 'Alice' }, items: [1, 2, 3] };
36
+ * resolveVariable('user.name', context); // 'Alice'
37
+ * resolveVariable('items[0]', context); // 1
38
+ * ```
39
+ */
40
+ export function resolveVariable(path, context, options = {}) {
41
+ const { strict = false } = options;
42
+ // Handle array access within parts: "items[0].name" -> ["items[0]", "name"]
43
+ // Then further split "items[0]" into array access
44
+ const parts = path.split('.');
45
+ let current = context;
46
+ for (const part of parts) {
47
+ if (current === undefined || current === null) {
48
+ return undefined;
49
+ }
50
+ // Validate array access patterns before splitting
51
+ // This catches malformed patterns like items[], items[abc], items[-1]
52
+ if (strict) {
53
+ validateArrayAccessPattern(part, path);
54
+ }
55
+ // Check for array access pattern: "items[0]" or "items[0][1]"
56
+ const segments = part.split(/(\[\d+\])/g).filter(Boolean);
57
+ for (const segment of segments) {
58
+ if (current === undefined || current === null) {
59
+ return undefined;
60
+ }
61
+ const arrayMatch = segment.match(/^\[(\d+)\]$/);
62
+ if (arrayMatch && arrayMatch[1]) {
63
+ // Array index access
64
+ const index = parseInt(arrayMatch[1], 10);
65
+ if (Array.isArray(current)) {
66
+ current = current[index];
67
+ }
68
+ else {
69
+ if (strict) {
70
+ throw new Error(`Cannot access index [${index}] on non-array value in path "${path}"`);
71
+ }
72
+ return undefined;
73
+ }
74
+ }
75
+ else {
76
+ // Property access
77
+ current = current[segment];
78
+ }
79
+ }
80
+ }
81
+ return current;
82
+ }
83
+ /**
84
+ * Validate array access patterns in a path segment.
85
+ * Throws descriptive errors for malformed patterns in strict mode.
86
+ *
87
+ * @param segment - A single path segment (e.g., "items[0]" or "name")
88
+ * @param fullPath - The full path for error messages
89
+ */
90
+ function validateArrayAccessPattern(segment, fullPath) {
91
+ // Find all bracket patterns in the segment
92
+ const bracketPattern = /\[([^\]]*)\]/g;
93
+ let match;
94
+ while ((match = bracketPattern.exec(segment)) !== null) {
95
+ const bracketContent = match[1] ?? '';
96
+ // Empty brackets: items[]
97
+ if (bracketContent === '') {
98
+ throw new Error(`Invalid array access "[]" in path "${fullPath}". Array index must be a non-negative integer.`);
99
+ }
100
+ // Non-numeric content: items[abc]
101
+ if (!/^\d+$/.test(bracketContent)) {
102
+ // Check for negative index
103
+ if (/^-\d+$/.test(bracketContent)) {
104
+ throw new Error(`Invalid array access "[${bracketContent}]" in path "${fullPath}". Negative indices are not supported.`);
105
+ }
106
+ throw new Error(`Invalid array access "[${bracketContent}]" in path "${fullPath}". Array index must be a non-negative integer.`);
107
+ }
108
+ }
109
+ // Check for unclosed brackets: items[0
110
+ const openBrackets = (segment.match(/\[/g) || []).length;
111
+ const closeBrackets = (segment.match(/\]/g) || []).length;
112
+ if (openBrackets !== closeBrackets) {
113
+ throw new Error(`Malformed array access in path "${fullPath}". Unclosed or unmatched brackets.`);
114
+ }
115
+ }
116
+ // =============================================================================
117
+ // CONDITION EVALUATION
118
+ // =============================================================================
119
+ /**
120
+ * Evaluate a condition expression.
121
+ *
122
+ * @param condition - The condition to evaluate
123
+ * @param ctx - The evaluation context
124
+ * @returns true if condition is satisfied
125
+ */
126
+ export async function evaluateCondition(condition, ctx) {
127
+ // Get the variable value
128
+ const value = resolveVariable(condition.variable, ctx.variables, {
129
+ strict: ctx.config.strict,
130
+ });
131
+ // Check for pre-resolved AI judge result
132
+ if (condition.isAiJudge) {
133
+ const cacheKey = createAiJudgeCacheKey(condition.variable, value, condition.argument);
134
+ const cached = ctx.aiJudgeResults.get(cacheKey);
135
+ if (cached !== undefined) {
136
+ return cached;
137
+ }
138
+ // Fall through to operator evaluation if not cached
139
+ }
140
+ // Get the operator (strip # if present)
141
+ const operatorName = condition.operator.replace(/^#/, '');
142
+ const operator = ctx.operators.get(operatorName) ?? getOperator(operatorName);
143
+ if (!operator) {
144
+ // Unknown operator - treat as false in lenient mode, throw in strict
145
+ if (ctx.config.strict) {
146
+ throw new Error(`Unknown operator: #${operatorName}`);
147
+ }
148
+ return false;
149
+ }
150
+ // Evaluate the operator
151
+ try {
152
+ const result = await operator.handler(value, condition.argument);
153
+ return result;
154
+ }
155
+ catch (error) {
156
+ if (ctx.config.strict) {
157
+ throw error;
158
+ }
159
+ // Lenient mode: treat errors as false
160
+ return false;
161
+ }
162
+ }
163
+ /**
164
+ * Create a cache key for AI judge results.
165
+ */
166
+ function createAiJudgeCacheKey(variable, value, argument) {
167
+ return JSON.stringify({ variable, value, argument });
168
+ }
169
+ // =============================================================================
170
+ // AI JUDGE PARALLEL EVALUATION
171
+ // =============================================================================
172
+ /**
173
+ * Pre-evaluate all AI judge conditions in parallel.
174
+ *
175
+ * This is the key optimization for performance.
176
+ * Call this before evaluating the AST to pre-resolve all AI conditions.
177
+ *
178
+ * @param ast - The AST to scan for AI judges
179
+ * @param ctx - The evaluation context (will be mutated with results)
180
+ */
181
+ export async function preEvaluateAiJudges(ast, ctx) {
182
+ // Collect all AI judge conditions
183
+ const aiJudges = collectAiJudgeConditions(ast);
184
+ if (aiJudges.length === 0) {
185
+ return;
186
+ }
187
+ // Prepare evaluation promises
188
+ const evaluations = aiJudges.map(async ({ condition }) => {
189
+ const value = resolveVariable(condition.variable, ctx.variables, {
190
+ strict: ctx.config.strict,
191
+ });
192
+ const cacheKey = createAiJudgeCacheKey(condition.variable, value, condition.argument);
193
+ // Skip if already cached
194
+ if (ctx.aiJudgeResults.has(cacheKey)) {
195
+ return;
196
+ }
197
+ // Evaluate using the AI judge operator
198
+ const operator = ctx.operators.get('ai_judge') ?? getOperator('ai_judge');
199
+ if (!operator) {
200
+ throw new Error('AI Judge operator not available');
201
+ }
202
+ try {
203
+ const result = await operator.handler(value, condition.argument);
204
+ ctx.aiJudgeResults.set(cacheKey, result);
205
+ }
206
+ catch (error) {
207
+ // Handle AI evaluation error
208
+ if (ctx.config.strict) {
209
+ throw error;
210
+ }
211
+ // Lenient: default to false
212
+ ctx.aiJudgeResults.set(cacheKey, false);
213
+ }
214
+ });
215
+ // Evaluate all in parallel
216
+ await Promise.all(evaluations);
217
+ }
218
+ // =============================================================================
219
+ // AST EVALUATION
220
+ // =============================================================================
221
+ /**
222
+ * Evaluate a conditional node and determine which branch to render.
223
+ *
224
+ * @param node - The conditional node
225
+ * @param ctx - The evaluation context
226
+ * @returns The nodes to render (empty if condition is false with no else)
227
+ */
228
+ export async function evaluateConditional(node, ctx) {
229
+ // Evaluate the main condition
230
+ const conditionResult = await evaluateCondition(node.condition, ctx);
231
+ if (conditionResult) {
232
+ return node.consequent;
233
+ }
234
+ // Check alternate (ELSE IF or ELSE)
235
+ if (node.alternate) {
236
+ if (Array.isArray(node.alternate)) {
237
+ // ELSE branch
238
+ return node.alternate;
239
+ }
240
+ else {
241
+ // ELSE IF branch (recursive)
242
+ return evaluateConditional(node.alternate, ctx);
243
+ }
244
+ }
245
+ // No matching branch
246
+ return [];
247
+ }
248
+ /**
249
+ * Evaluate a single AST node.
250
+ *
251
+ * @param node - The node to evaluate
252
+ * @param ctx - The evaluation context
253
+ * @returns Array of nodes to render (may be empty, one, or many)
254
+ */
255
+ async function evaluateNode(node, ctx) {
256
+ switch (node.type) {
257
+ case 'text':
258
+ // Text nodes pass through unchanged
259
+ return [node];
260
+ case 'variable':
261
+ // Variable nodes pass through unchanged (resolved during rendering)
262
+ return [node];
263
+ case 'conditional': {
264
+ // Evaluate condition and get selected branch
265
+ const branchNodes = await evaluateConditional(node, ctx);
266
+ // Recursively evaluate the selected branch
267
+ return evaluateNodes(branchNodes, ctx);
268
+ }
269
+ case 'section': {
270
+ // Store section in context for later [#INCLUDE] references
271
+ ctx.sections.set(node.name, node.body);
272
+ // Sections are not rendered inline
273
+ return [];
274
+ }
275
+ case 'import':
276
+ // Import handling: In a full implementation, we would:
277
+ // 1. Read the imported file
278
+ // 2. Parse it
279
+ // 3. Evaluate and inline the result
280
+ // For now, we pass through and let the renderer warn
281
+ return [node];
282
+ case 'include': {
283
+ // Include handling: inline the section content
284
+ const includeNode = node;
285
+ const sectionContent = ctx.sections.get(includeNode.name);
286
+ if (sectionContent) {
287
+ // Recursively evaluate the section content
288
+ return evaluateNodes(sectionContent, ctx);
289
+ }
290
+ // Section not found - pass through and let renderer warn
291
+ if (ctx.config.strict) {
292
+ throw new Error(`Section not found: ${includeNode.name}`);
293
+ }
294
+ return [];
295
+ }
296
+ default: {
297
+ // Exhaustiveness check
298
+ const _exhaustive = node;
299
+ throw new Error(`Unknown node type: ${_exhaustive.type}`);
300
+ }
301
+ }
302
+ }
303
+ /**
304
+ * Evaluate an array of AST nodes.
305
+ *
306
+ * @param nodes - The nodes to evaluate
307
+ * @param ctx - The evaluation context
308
+ * @returns Flattened array of nodes to render
309
+ */
310
+ async function evaluateNodes(nodes, ctx) {
311
+ const results = [];
312
+ for (const node of nodes) {
313
+ const evaluated = await evaluateNode(node, ctx);
314
+ results.push(...evaluated);
315
+ }
316
+ return results;
317
+ }
318
+ // =============================================================================
319
+ // SECTION COLLECTION (First Pass)
320
+ // =============================================================================
321
+ /**
322
+ * Collect all section definitions from the AST.
323
+ * This is a first pass to ensure sections are available before includes.
324
+ *
325
+ * @param nodes - The AST nodes to scan
326
+ * @param sections - Map to store section definitions
327
+ */
328
+ function collectSections(nodes, sections) {
329
+ for (const node of nodes) {
330
+ if (node.type === 'section') {
331
+ const sectionNode = node;
332
+ sections.set(sectionNode.name, sectionNode.body);
333
+ // Also scan inside the section for nested sections
334
+ collectSections(sectionNode.body, sections);
335
+ }
336
+ else if (node.type === 'conditional') {
337
+ const conditionalNode = node;
338
+ collectSections(conditionalNode.consequent, sections);
339
+ if (conditionalNode.alternate) {
340
+ if (Array.isArray(conditionalNode.alternate)) {
341
+ collectSections(conditionalNode.alternate, sections);
342
+ }
343
+ else {
344
+ collectSections([conditionalNode.alternate], sections);
345
+ }
346
+ }
347
+ }
348
+ }
349
+ }
350
+ // =============================================================================
351
+ // MAIN EVALUATE FUNCTION
352
+ // =============================================================================
353
+ /**
354
+ * Evaluate an AST with the given context.
355
+ *
356
+ * This is the main entry point for AST evaluation. It:
357
+ * 1. Collects section definitions (first pass)
358
+ * 2. Pre-evaluates AI judge conditions in parallel
359
+ * 3. Evaluates the AST and selects conditional branches
360
+ * 4. Returns a flattened AST ready for rendering
361
+ *
362
+ * @param ast - The AST to evaluate
363
+ * @param context - Variable context
364
+ * @param config - Echo configuration
365
+ * @param operators - Custom operators (from plugins)
366
+ * @returns Evaluated AST and section map
367
+ *
368
+ * @example
369
+ * ```typescript
370
+ * const result = await evaluate(ast, { name: 'Alice', age: 25 });
371
+ * console.log(result.ast); // Flattened, evaluated AST
372
+ * ```
373
+ */
374
+ export async function evaluate(ast, context, config = {}, operators = new Map()) {
375
+ // Create evaluation context
376
+ const ctx = {
377
+ variables: context,
378
+ aiJudgeResults: new Map(),
379
+ config,
380
+ sections: new Map(),
381
+ operators,
382
+ };
383
+ // First pass: collect all section definitions
384
+ collectSections(ast, ctx.sections);
385
+ // Pre-evaluate AI judges in parallel (optimization!)
386
+ await preEvaluateAiJudges(ast, ctx);
387
+ // Second pass: evaluate the AST
388
+ const evaluatedAst = await evaluateNodes(ast, ctx);
389
+ return { ast: evaluatedAst, sections: ctx.sections };
390
+ }
391
+ /**
392
+ * Create an evaluation context manually.
393
+ * Useful for advanced use cases where you need more control.
394
+ *
395
+ * @param options - Context options
396
+ * @returns A new EvaluationContext
397
+ */
398
+ export function createEvaluationContext(options) {
399
+ return {
400
+ variables: options.variables,
401
+ aiJudgeResults: new Map(),
402
+ config: options.config ?? {},
403
+ sections: new Map(),
404
+ operators: options.operators ?? new Map(),
405
+ };
406
+ }
407
+ //# sourceMappingURL=evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../../src/evaluator/evaluator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Evaluator module exports
3
+ */
4
+ export { evaluate, evaluateCondition, evaluateConditional, resolveVariable, preEvaluateAiJudges, createEvaluationContext, } from './evaluator.js';
5
+ export type { EvaluationContext, EvaluatedNode } from './evaluator.js';
6
+ export { builtinOperators, getOperator, isAsyncOperator, equalsOperator, containsOperator, existsOperator, matchesOperator, gtOperator, gteOperator, ltOperator, lteOperator, inOperator, aiJudgeOperator, } from './operators.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evaluator/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEvE,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,eAAe,EAEf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,GAChB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Evaluator module exports
3
+ */
4
+ export { evaluate, evaluateCondition, evaluateConditional, resolveVariable, preEvaluateAiJudges, createEvaluationContext, } from './evaluator.js';
5
+ export { builtinOperators, getOperator, isAsyncOperator,
6
+ // Individual operators for testing
7
+ equalsOperator, containsOperator, existsOperator, matchesOperator, gtOperator, gteOperator, ltOperator, lteOperator, inOperator, aiJudgeOperator, } from './operators.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/evaluator/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,eAAe;AACf,mCAAmC;AACnC,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,GAChB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @fileoverview Built-in Operators for Echo DSL
3
+ *
4
+ * This file implements all built-in operators for the Echo DSL.
5
+ * Operators are used in conditions: [#IF {{var}} #operator(arg)]
6
+ *
7
+ * IMPLEMENTATION GUIDE:
8
+ *
9
+ * Each operator is a function that:
10
+ * - Takes a value (the variable being tested)
11
+ * - Takes an optional argument (the operator parameter)
12
+ * - Returns a boolean (or Promise<boolean> for async operators)
13
+ *
14
+ * BUILT-IN OPERATORS:
15
+ * - #equals(value) - Exact equality
16
+ * - #contains(value) - String/array contains
17
+ * - #exists - Value is defined and not empty
18
+ * - #matches(regex) - Regex pattern match
19
+ * - #gt(n), #lt(n) - Greater than, less than
20
+ * - #gte(n), #lte(n) - Greater/less than or equal
21
+ * - #in(a,b,c) - Value is in list
22
+ * - #ai_judge(question) - LLM-evaluated condition
23
+ */
24
+ import type { OperatorDefinition } from '../types.js';
25
+ /**
26
+ * #equals - Exact equality check
27
+ *
28
+ * @example {{genre}} #equals(Horror)
29
+ */
30
+ export declare const equalsOperator: OperatorDefinition;
31
+ /**
32
+ * #contains - Check if string/array contains a value
33
+ *
34
+ * @example {{companions}} #contains(Shimon)
35
+ */
36
+ export declare const containsOperator: OperatorDefinition;
37
+ /**
38
+ * #exists - Check if value is defined and not empty
39
+ *
40
+ * @example {{user.preferences}} #exists
41
+ */
42
+ export declare const existsOperator: OperatorDefinition;
43
+ /**
44
+ * #matches - Regex pattern match
45
+ *
46
+ * @example {{email}} #matches(.*@.*)
47
+ */
48
+ export declare const matchesOperator: OperatorDefinition;
49
+ /**
50
+ * #greater_than - Greater than (alias: #gt)
51
+ *
52
+ * @example {{age}} #greater_than(18)
53
+ */
54
+ export declare const gtOperator: OperatorDefinition;
55
+ /**
56
+ * #greater_than_or_equal - Greater than or equal (alias: #gte)
57
+ */
58
+ export declare const gteOperator: OperatorDefinition;
59
+ /**
60
+ * #less_than - Less than (alias: #lt)
61
+ */
62
+ export declare const ltOperator: OperatorDefinition;
63
+ /**
64
+ * #less_than_or_equal - Less than or equal (alias: #lte)
65
+ */
66
+ export declare const lteOperator: OperatorDefinition;
67
+ /**
68
+ * #one_of - Check if value is in a list (alias: #in)
69
+ *
70
+ * @example {{status}} #one_of(active,pending,completed)
71
+ */
72
+ export declare const inOperator: OperatorDefinition;
73
+ /**
74
+ * #ai_judge - LLM-evaluated boolean condition
75
+ *
76
+ * This operator queries an LLM to evaluate a boolean condition.
77
+ * It's async and results are cached for performance.
78
+ *
79
+ * @example {{content}} #ai_judge(Is this appropriate for children?)
80
+ */
81
+ export declare const aiJudgeOperator: OperatorDefinition;
82
+ /**
83
+ * All built-in operators.
84
+ *
85
+ * Operators have readable names for low-coders and short aliases for developers.
86
+ * Both forms work identically:
87
+ * - #greater_than(10) or #gt(10)
88
+ * - #one_of(a,b,c) or #in(a,b,c)
89
+ */
90
+ export declare const builtinOperators: Record<string, OperatorDefinition>;
91
+ /**
92
+ * Get an operator by name.
93
+ *
94
+ * @param name - The operator name (without #)
95
+ * @returns The operator definition or undefined
96
+ */
97
+ export declare function getOperator(name: string): OperatorDefinition | undefined;
98
+ /**
99
+ * Check if an operator is async (AI-based).
100
+ *
101
+ * @param name - The operator name
102
+ * @returns true if the operator is async
103
+ */
104
+ export declare function isAsyncOperator(name: string): boolean;
105
+ //# sourceMappingURL=operators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operators.d.ts","sourceRoot":"","sources":["../../src/evaluator/operators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMtD;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,kBAgB5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAsB9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,kBAe5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,kBAoB7B,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,kBAexB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,kBAezB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,kBAexB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,kBAezB,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,kBAuBxB,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,kBA+B7B,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAmB/D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAExE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD"}