decision_agent 0.1.7 → 0.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.
- checksums.yaml +4 -4
- data/README.md +41 -1
- data/bin/decision_agent +104 -0
- data/lib/decision_agent/dmn/adapter.rb +135 -0
- data/lib/decision_agent/dmn/cache.rb +306 -0
- data/lib/decision_agent/dmn/decision_graph.rb +327 -0
- data/lib/decision_agent/dmn/decision_tree.rb +192 -0
- data/lib/decision_agent/dmn/errors.rb +30 -0
- data/lib/decision_agent/dmn/exporter.rb +217 -0
- data/lib/decision_agent/dmn/feel/evaluator.rb +797 -0
- data/lib/decision_agent/dmn/feel/functions.rb +420 -0
- data/lib/decision_agent/dmn/feel/parser.rb +349 -0
- data/lib/decision_agent/dmn/feel/simple_parser.rb +276 -0
- data/lib/decision_agent/dmn/feel/transformer.rb +372 -0
- data/lib/decision_agent/dmn/feel/types.rb +276 -0
- data/lib/decision_agent/dmn/importer.rb +77 -0
- data/lib/decision_agent/dmn/model.rb +197 -0
- data/lib/decision_agent/dmn/parser.rb +191 -0
- data/lib/decision_agent/dmn/testing.rb +333 -0
- data/lib/decision_agent/dmn/validator.rb +315 -0
- data/lib/decision_agent/dmn/versioning.rb +229 -0
- data/lib/decision_agent/dmn/visualizer.rb +513 -0
- data/lib/decision_agent/dsl/condition_evaluator.rb +1132 -12
- data/lib/decision_agent/dsl/schema_validator.rb +12 -1
- data/lib/decision_agent/evaluators/dmn_evaluator.rb +221 -0
- data/lib/decision_agent/version.rb +1 -1
- data/lib/decision_agent/web/dmn_editor.rb +426 -0
- data/lib/decision_agent/web/public/app.js +119 -1
- data/lib/decision_agent/web/public/dmn-editor.css +596 -0
- data/lib/decision_agent/web/public/dmn-editor.html +250 -0
- data/lib/decision_agent/web/public/dmn-editor.js +553 -0
- data/lib/decision_agent/web/public/index.html +71 -0
- data/lib/decision_agent/web/public/styles.css +21 -0
- data/lib/decision_agent/web/server.rb +465 -0
- data/spec/ab_testing/ab_testing_agent_spec.rb +174 -0
- data/spec/advanced_operators_spec.rb +2147 -0
- data/spec/auth/rbac_adapter_spec.rb +228 -0
- data/spec/dmn/decision_graph_spec.rb +282 -0
- data/spec/dmn/decision_tree_spec.rb +203 -0
- data/spec/dmn/feel/errors_spec.rb +18 -0
- data/spec/dmn/feel/functions_spec.rb +400 -0
- data/spec/dmn/feel/simple_parser_spec.rb +274 -0
- data/spec/dmn/feel/types_spec.rb +176 -0
- data/spec/dmn/feel_parser_spec.rb +489 -0
- data/spec/dmn/hit_policy_spec.rb +202 -0
- data/spec/dmn/integration_spec.rb +226 -0
- data/spec/examples.txt +1909 -0
- data/spec/fixtures/dmn/complex_decision.dmn +81 -0
- data/spec/fixtures/dmn/invalid_structure.dmn +31 -0
- data/spec/fixtures/dmn/simple_decision.dmn +40 -0
- data/spec/monitoring/metrics_collector_spec.rb +37 -35
- data/spec/monitoring/monitored_agent_spec.rb +14 -11
- data/spec/performance_optimizations_spec.rb +10 -3
- data/spec/thread_safety_spec.rb +10 -2
- data/spec/web_ui_rack_spec.rb +294 -0
- metadata +66 -1
|
@@ -307,12 +307,80 @@ class RuleBuilder {
|
|
|
307
307
|
'between': '[min, max] or {"min": 0, "max": 100}',
|
|
308
308
|
'modulo': '[divisor, remainder] or {"divisor": 2, "remainder": 0}',
|
|
309
309
|
|
|
310
|
+
// Mathematical functions
|
|
311
|
+
'sin': 'expected result (e.g., 0.0)',
|
|
312
|
+
'cos': 'expected result (e.g., 1.0)',
|
|
313
|
+
'tan': 'expected result (e.g., 0.0)',
|
|
314
|
+
'sqrt': 'expected result (e.g., 3.0)',
|
|
315
|
+
'power': '[exponent, result] or {"exponent": 2, "result": 4}',
|
|
316
|
+
'exp': 'expected result (e.g., 2.718)',
|
|
317
|
+
'log': 'expected result (e.g., 0.0)',
|
|
318
|
+
'round': 'expected rounded value (e.g., 3)',
|
|
319
|
+
'floor': 'expected floor value (e.g., 3)',
|
|
320
|
+
'ceil': 'expected ceiling value (e.g., 4)',
|
|
321
|
+
'abs': 'expected absolute value (e.g., 5)',
|
|
322
|
+
'min': 'expected minimum value (e.g., 1)',
|
|
323
|
+
'max': 'expected maximum value (e.g., 10)',
|
|
324
|
+
|
|
325
|
+
// Statistical aggregations
|
|
326
|
+
'sum': 'expected sum (e.g., 100) or {"min": 50, "max": 150}',
|
|
327
|
+
'average': 'expected average (e.g., 25.5) or {"gt": 20, "lt": 30}',
|
|
328
|
+
'mean': 'expected mean (e.g., 25.5) or {"gt": 20, "lt": 30}',
|
|
329
|
+
'median': 'expected median (e.g., 25) or {"gt": 20}',
|
|
330
|
+
'stddev': 'expected stddev (e.g., 5.2) or {"lt": 10}',
|
|
331
|
+
'standard_deviation': 'expected stddev (e.g., 5.2) or {"lt": 10}',
|
|
332
|
+
'variance': 'expected variance (e.g., 27.04) or {"lt": 100}',
|
|
333
|
+
'percentile': '{"percentile": 95, "threshold": 200} or {"percentile": 95, "gt": 100}',
|
|
334
|
+
'count': 'expected count (e.g., 10) or {"min": 5, "max": 20}',
|
|
335
|
+
|
|
310
336
|
// Date/time operators
|
|
311
337
|
'before_date': '2025-12-31',
|
|
312
338
|
'after_date': '2024-01-01',
|
|
313
339
|
'within_days': '7',
|
|
314
340
|
'day_of_week': 'monday or 1',
|
|
315
341
|
|
|
342
|
+
// Duration calculations
|
|
343
|
+
'duration_seconds': '{"end": "now", "max": 3600} or {"end": "field.end_time", "min": 60}',
|
|
344
|
+
'duration_minutes': '{"end": "now", "max": 60} or {"end": "field.end_time", "min": 5}',
|
|
345
|
+
'duration_hours': '{"end": "now", "max": 24} or {"end": "field.end_time", "min": 1}',
|
|
346
|
+
'duration_days': '{"end": "now", "max": 7} or {"end": "field.end_time", "min": 1}',
|
|
347
|
+
|
|
348
|
+
// Date arithmetic
|
|
349
|
+
'add_days': '{"days": 7, "compare": "lt", "target": "now"}',
|
|
350
|
+
'subtract_days': '{"days": 1, "compare": "gt", "target": "now"}',
|
|
351
|
+
'add_hours': '{"hours": 2, "compare": "lt", "target": "now"}',
|
|
352
|
+
'subtract_hours': '{"hours": 1, "compare": "gt", "target": "now"}',
|
|
353
|
+
'add_minutes': '{"minutes": 30, "compare": "lt", "target": "now"}',
|
|
354
|
+
'subtract_minutes': '{"minutes": 15, "compare": "gt", "target": "now"}',
|
|
355
|
+
|
|
356
|
+
// Time components
|
|
357
|
+
'hour_of_day': '9 or {"min": 9, "max": 17}',
|
|
358
|
+
'day_of_month': '15 or {"gte": 1, "lte": 31}',
|
|
359
|
+
'month': '12 or {"gte": 1, "lte": 12}',
|
|
360
|
+
'year': '2025 or {"gte": 2024}',
|
|
361
|
+
'week_of_year': '25 or {"gte": 1, "lte": 52}',
|
|
362
|
+
|
|
363
|
+
// Rate calculations
|
|
364
|
+
'rate_per_second': '{"max": 10} or {"min": 5, "max": 100}',
|
|
365
|
+
'rate_per_minute': '{"max": 600} or {"min": 50, "max": 1000}',
|
|
366
|
+
'rate_per_hour': '{"max": 36000} or {"min": 5000, "max": 50000}',
|
|
367
|
+
|
|
368
|
+
// Moving window
|
|
369
|
+
'moving_average': '{"window": 5, "threshold": 100} or {"window": 5, "gt": 50}',
|
|
370
|
+
'moving_sum': '{"window": 10, "threshold": 1000} or {"window": 10, "lt": 2000}',
|
|
371
|
+
'moving_max': '{"window": 5, "threshold": 200} or {"window": 5, "gt": 100}',
|
|
372
|
+
'moving_min': '{"window": 5, "threshold": 10} or {"window": 5, "lt": 50}',
|
|
373
|
+
|
|
374
|
+
// Financial calculations
|
|
375
|
+
'compound_interest': '{"rate": 0.05, "periods": 12, "result": 1050}',
|
|
376
|
+
'present_value': '{"rate": 0.05, "periods": 10, "result": 613.91}',
|
|
377
|
+
'future_value': '{"rate": 0.05, "periods": 10, "result": 1628.89}',
|
|
378
|
+
'payment': '{"rate": 0.05, "periods": 12, "result": 100}',
|
|
379
|
+
|
|
380
|
+
// String aggregations
|
|
381
|
+
'join': '{"separator": ",", "result": "a,b,c"} or {"separator": ",", "contains": "a"}',
|
|
382
|
+
'length': '{"max": 500} or {"min": 10, "max": 100}',
|
|
383
|
+
|
|
316
384
|
// Collection operators
|
|
317
385
|
'contains_all': '["item1", "item2"]',
|
|
318
386
|
'contains_any': '["item1", "item2"]',
|
|
@@ -332,9 +400,59 @@ class RuleBuilder {
|
|
|
332
400
|
'modulo': 'Modulo: [divisor, remainder] or {"divisor": 2, "remainder": 0}',
|
|
333
401
|
'matches': 'Regular expression pattern (e.g., ^user@company\\.com$)',
|
|
334
402
|
'within_days': 'Number of days from now (e.g., 7 for within a week)',
|
|
403
|
+
'sum': 'Numeric or {"min": 50, "max": 150}',
|
|
404
|
+
'average': 'Numeric or {"gt": 20, "lt": 30}',
|
|
405
|
+
'mean': 'Numeric or {"gt": 20, "lt": 30}',
|
|
406
|
+
'median': 'Numeric or {"gt": 20}',
|
|
407
|
+
'stddev': 'Numeric or {"lt": 10}',
|
|
408
|
+
'standard_deviation': 'Numeric or {"lt": 10}',
|
|
409
|
+
'variance': 'Numeric or {"lt": 100}',
|
|
410
|
+
'percentile': '{"percentile": 95, "threshold": 200}',
|
|
411
|
+
'count': 'Numeric or {"min": 5, "max": 20}',
|
|
412
|
+
'duration_seconds': '{"end": "now" or "field.path", "max": 3600}',
|
|
413
|
+
'duration_minutes': '{"end": "now" or "field.path", "max": 60}',
|
|
414
|
+
'duration_hours': '{"end": "now" or "field.path", "max": 24}',
|
|
415
|
+
'duration_days': '{"end": "now" or "field.path", "max": 7}',
|
|
416
|
+
'add_days': '{"days": 7, "compare": "lt", "target": "now" or "field.path"}',
|
|
417
|
+
'subtract_days': '{"days": 1, "compare": "gt", "target": "now" or "field.path"}',
|
|
418
|
+
'add_hours': '{"hours": 2, "compare": "lt", "target": "now" or "field.path"}',
|
|
419
|
+
'subtract_hours': '{"hours": 1, "compare": "gt", "target": "now" or "field.path"}',
|
|
420
|
+
'add_minutes': '{"minutes": 30, "compare": "lt", "target": "now" or "field.path"}',
|
|
421
|
+
'subtract_minutes': '{"minutes": 15, "compare": "gt", "target": "now" or "field.path"}',
|
|
422
|
+
'hour_of_day': 'Numeric (0-23) or {"min": 9, "max": 17}',
|
|
423
|
+
'day_of_month': 'Numeric (1-31) or {"gte": 1, "lte": 31}',
|
|
424
|
+
'month': 'Numeric (1-12) or {"gte": 1, "lte": 12}',
|
|
425
|
+
'year': 'Numeric or {"gte": 2024}',
|
|
426
|
+
'week_of_year': 'Numeric (1-52) or {"gte": 1, "lte": 52}',
|
|
427
|
+
'rate_per_second': '{"max": 10} or {"min": 5, "max": 100}',
|
|
428
|
+
'rate_per_minute': '{"max": 600} or {"min": 50, "max": 1000}',
|
|
429
|
+
'rate_per_hour': '{"max": 36000} or {"min": 5000, "max": 50000}',
|
|
430
|
+
'moving_average': '{"window": 5, "threshold": 100}',
|
|
431
|
+
'moving_sum': '{"window": 10, "threshold": 1000}',
|
|
432
|
+
'moving_max': '{"window": 5, "threshold": 200}',
|
|
433
|
+
'moving_min': '{"window": 5, "threshold": 10}',
|
|
434
|
+
'compound_interest': '{"rate": 0.05, "periods": 12, "result": 1050}',
|
|
435
|
+
'present_value': '{"rate": 0.05, "periods": 10, "result": 613.91}',
|
|
436
|
+
'future_value': '{"rate": 0.05, "periods": 10, "result": 1628.89}',
|
|
437
|
+
'payment': '{"rate": 0.05, "periods": 12, "result": 100}',
|
|
438
|
+
'join': '{"separator": ",", "result": "a,b,c"}',
|
|
439
|
+
'length': '{"max": 500} or {"min": 10, "max": 100}',
|
|
335
440
|
'day_of_week': 'Day name (monday) or number (0=Sunday, 1=Monday, ...)',
|
|
336
441
|
'within_radius': 'JSON: {"center": {"lat": y, "lon": x}, "radius": km}',
|
|
337
|
-
'in_polygon': 'Array of coordinates: [{"lat": y, "lon": x}, ...]'
|
|
442
|
+
'in_polygon': 'Array of coordinates: [{"lat": y, "lon": x}, ...]',
|
|
443
|
+
'sin': 'Expected result of sin(field_value). Example: 0.0 for sin(0)',
|
|
444
|
+
'cos': 'Expected result of cos(field_value). Example: 1.0 for cos(0)',
|
|
445
|
+
'tan': 'Expected result of tan(field_value). Example: 0.0 for tan(0)',
|
|
446
|
+
'sqrt': 'Expected result of sqrt(field_value). Example: 3.0 for sqrt(9)',
|
|
447
|
+
'power': 'Power: [exponent, result] or {"exponent": 2, "result": 4}. Checks if field^exponent == result',
|
|
448
|
+
'exp': 'Expected result of exp(field_value) = e^field_value. Example: 2.718 for exp(1)',
|
|
449
|
+
'log': 'Expected result of log(field_value) = natural logarithm. Example: 0.0 for log(1)',
|
|
450
|
+
'round': 'Expected rounded value. Example: 3 for round(3.4)',
|
|
451
|
+
'floor': 'Expected floor value. Example: 3 for floor(3.9)',
|
|
452
|
+
'ceil': 'Expected ceiling value. Example: 4 for ceil(3.1)',
|
|
453
|
+
'abs': 'Expected absolute value. Example: 5 for abs(-5) or abs(5)',
|
|
454
|
+
'min': 'Expected minimum value from array. Example: 1 for min([3, 1, 5, 2])',
|
|
455
|
+
'max': 'Expected maximum value from array. Example: 5 for max([3, 1, 5, 2])'
|
|
338
456
|
};
|
|
339
457
|
|
|
340
458
|
if (hints[operator]) {
|