decision_agent 0.2.0 → 1.0.1

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +313 -8
  3. data/bin/decision_agent +104 -0
  4. data/lib/decision_agent/agent.rb +72 -1
  5. data/lib/decision_agent/context.rb +1 -0
  6. data/lib/decision_agent/data_enrichment/cache/memory_adapter.rb +86 -0
  7. data/lib/decision_agent/data_enrichment/cache_adapter.rb +49 -0
  8. data/lib/decision_agent/data_enrichment/circuit_breaker.rb +135 -0
  9. data/lib/decision_agent/data_enrichment/client.rb +220 -0
  10. data/lib/decision_agent/data_enrichment/config.rb +78 -0
  11. data/lib/decision_agent/data_enrichment/errors.rb +36 -0
  12. data/lib/decision_agent/decision.rb +102 -2
  13. data/lib/decision_agent/dmn/adapter.rb +135 -0
  14. data/lib/decision_agent/dmn/cache.rb +306 -0
  15. data/lib/decision_agent/dmn/decision_graph.rb +327 -0
  16. data/lib/decision_agent/dmn/decision_tree.rb +192 -0
  17. data/lib/decision_agent/dmn/errors.rb +30 -0
  18. data/lib/decision_agent/dmn/exporter.rb +217 -0
  19. data/lib/decision_agent/dmn/feel/evaluator.rb +819 -0
  20. data/lib/decision_agent/dmn/feel/functions.rb +420 -0
  21. data/lib/decision_agent/dmn/feel/parser.rb +349 -0
  22. data/lib/decision_agent/dmn/feel/simple_parser.rb +276 -0
  23. data/lib/decision_agent/dmn/feel/transformer.rb +372 -0
  24. data/lib/decision_agent/dmn/feel/types.rb +276 -0
  25. data/lib/decision_agent/dmn/importer.rb +77 -0
  26. data/lib/decision_agent/dmn/model.rb +197 -0
  27. data/lib/decision_agent/dmn/parser.rb +191 -0
  28. data/lib/decision_agent/dmn/testing.rb +333 -0
  29. data/lib/decision_agent/dmn/validator.rb +315 -0
  30. data/lib/decision_agent/dmn/versioning.rb +229 -0
  31. data/lib/decision_agent/dmn/visualizer.rb +513 -0
  32. data/lib/decision_agent/dsl/condition_evaluator.rb +984 -838
  33. data/lib/decision_agent/dsl/schema_validator.rb +53 -14
  34. data/lib/decision_agent/evaluators/dmn_evaluator.rb +308 -0
  35. data/lib/decision_agent/evaluators/json_rule_evaluator.rb +69 -9
  36. data/lib/decision_agent/explainability/condition_trace.rb +83 -0
  37. data/lib/decision_agent/explainability/explainability_result.rb +52 -0
  38. data/lib/decision_agent/explainability/rule_trace.rb +39 -0
  39. data/lib/decision_agent/explainability/trace_collector.rb +24 -0
  40. data/lib/decision_agent/monitoring/alert_manager.rb +5 -1
  41. data/lib/decision_agent/simulation/errors.rb +18 -0
  42. data/lib/decision_agent/simulation/impact_analyzer.rb +498 -0
  43. data/lib/decision_agent/simulation/monte_carlo_simulator.rb +635 -0
  44. data/lib/decision_agent/simulation/replay_engine.rb +486 -0
  45. data/lib/decision_agent/simulation/scenario_engine.rb +318 -0
  46. data/lib/decision_agent/simulation/scenario_library.rb +163 -0
  47. data/lib/decision_agent/simulation/shadow_test_engine.rb +287 -0
  48. data/lib/decision_agent/simulation/what_if_analyzer.rb +1002 -0
  49. data/lib/decision_agent/simulation.rb +17 -0
  50. data/lib/decision_agent/version.rb +1 -1
  51. data/lib/decision_agent/versioning/activerecord_adapter.rb +23 -8
  52. data/lib/decision_agent/web/dmn_editor.rb +426 -0
  53. data/lib/decision_agent/web/public/app.js +119 -0
  54. data/lib/decision_agent/web/public/dmn-editor.css +596 -0
  55. data/lib/decision_agent/web/public/dmn-editor.html +250 -0
  56. data/lib/decision_agent/web/public/dmn-editor.js +553 -0
  57. data/lib/decision_agent/web/public/index.html +52 -0
  58. data/lib/decision_agent/web/public/simulation.html +130 -0
  59. data/lib/decision_agent/web/public/simulation_impact.html +478 -0
  60. data/lib/decision_agent/web/public/simulation_replay.html +551 -0
  61. data/lib/decision_agent/web/public/simulation_shadow.html +546 -0
  62. data/lib/decision_agent/web/public/simulation_whatif.html +532 -0
  63. data/lib/decision_agent/web/public/styles.css +86 -0
  64. data/lib/decision_agent/web/server.rb +1059 -23
  65. data/lib/decision_agent.rb +60 -2
  66. metadata +105 -61
  67. data/spec/ab_testing/ab_test_assignment_spec.rb +0 -253
  68. data/spec/ab_testing/ab_test_manager_spec.rb +0 -612
  69. data/spec/ab_testing/ab_test_spec.rb +0 -270
  70. data/spec/ab_testing/ab_testing_agent_spec.rb +0 -481
  71. data/spec/ab_testing/storage/adapter_spec.rb +0 -64
  72. data/spec/ab_testing/storage/memory_adapter_spec.rb +0 -485
  73. data/spec/activerecord_thread_safety_spec.rb +0 -553
  74. data/spec/advanced_operators_spec.rb +0 -3150
  75. data/spec/agent_spec.rb +0 -289
  76. data/spec/api_contract_spec.rb +0 -430
  77. data/spec/audit_adapters_spec.rb +0 -92
  78. data/spec/auth/access_audit_logger_spec.rb +0 -394
  79. data/spec/auth/authenticator_spec.rb +0 -112
  80. data/spec/auth/password_reset_spec.rb +0 -294
  81. data/spec/auth/permission_checker_spec.rb +0 -207
  82. data/spec/auth/permission_spec.rb +0 -73
  83. data/spec/auth/rbac_adapter_spec.rb +0 -550
  84. data/spec/auth/rbac_config_spec.rb +0 -82
  85. data/spec/auth/role_spec.rb +0 -51
  86. data/spec/auth/session_manager_spec.rb +0 -172
  87. data/spec/auth/session_spec.rb +0 -112
  88. data/spec/auth/user_spec.rb +0 -130
  89. data/spec/comprehensive_edge_cases_spec.rb +0 -1777
  90. data/spec/context_spec.rb +0 -127
  91. data/spec/decision_agent_spec.rb +0 -96
  92. data/spec/decision_spec.rb +0 -423
  93. data/spec/dsl/condition_evaluator_spec.rb +0 -774
  94. data/spec/dsl_validation_spec.rb +0 -648
  95. data/spec/edge_cases_spec.rb +0 -353
  96. data/spec/evaluation_spec.rb +0 -364
  97. data/spec/evaluation_validator_spec.rb +0 -165
  98. data/spec/examples/feedback_aware_evaluator_spec.rb +0 -460
  99. data/spec/examples.txt +0 -1633
  100. data/spec/issue_verification_spec.rb +0 -759
  101. data/spec/json_rule_evaluator_spec.rb +0 -587
  102. data/spec/monitoring/alert_manager_spec.rb +0 -378
  103. data/spec/monitoring/metrics_collector_spec.rb +0 -499
  104. data/spec/monitoring/monitored_agent_spec.rb +0 -222
  105. data/spec/monitoring/prometheus_exporter_spec.rb +0 -242
  106. data/spec/monitoring/storage/activerecord_adapter_spec.rb +0 -498
  107. data/spec/monitoring/storage/base_adapter_spec.rb +0 -61
  108. data/spec/monitoring/storage/memory_adapter_spec.rb +0 -247
  109. data/spec/performance_optimizations_spec.rb +0 -486
  110. data/spec/replay_edge_cases_spec.rb +0 -699
  111. data/spec/replay_spec.rb +0 -210
  112. data/spec/rfc8785_canonicalization_spec.rb +0 -215
  113. data/spec/scoring_spec.rb +0 -225
  114. data/spec/spec_helper.rb +0 -60
  115. data/spec/testing/batch_test_importer_spec.rb +0 -693
  116. data/spec/testing/batch_test_runner_spec.rb +0 -307
  117. data/spec/testing/test_coverage_analyzer_spec.rb +0 -292
  118. data/spec/testing/test_result_comparator_spec.rb +0 -392
  119. data/spec/testing/test_scenario_spec.rb +0 -113
  120. data/spec/thread_safety_spec.rb +0 -482
  121. data/spec/thread_safety_spec.rb.broken +0 -878
  122. data/spec/versioning/adapter_spec.rb +0 -156
  123. data/spec/versioning_spec.rb +0 -1030
  124. data/spec/web/middleware/auth_middleware_spec.rb +0 -133
  125. data/spec/web/middleware/permission_middleware_spec.rb +0 -247
  126. data/spec/web_ui_rack_spec.rb +0 -1840
@@ -1,156 +0,0 @@
1
- require "spec_helper"
2
- require "fileutils"
3
- require "tempfile"
4
- require "decision_agent/versioning/adapter"
5
- require "decision_agent/versioning/file_storage_adapter"
6
-
7
- RSpec.describe DecisionAgent::Versioning::Adapter do
8
- let(:temp_dir) { Dir.mktmpdir }
9
- let(:adapter) { DecisionAgent::Versioning::FileStorageAdapter.new(storage_path: temp_dir) }
10
- let(:rule_id) { "test_rule_001" }
11
- let(:rule_content) do
12
- {
13
- version: "1.0",
14
- ruleset: "test_ruleset",
15
- rules: [
16
- {
17
- id: "rule_1",
18
- if: { field: "amount", op: "gt", value: 100 },
19
- then: { decision: "approve", weight: 0.8, reason: "High value" }
20
- }
21
- ]
22
- }
23
- end
24
-
25
- after do
26
- FileUtils.rm_rf(temp_dir)
27
- end
28
-
29
- describe "#compare_versions" do
30
- it "returns nil when first version doesn't exist" do
31
- v2 = adapter.create_version(rule_id: rule_id, content: rule_content)
32
-
33
- comparison = adapter.compare_versions(version_id_1: "nonexistent", version_id_2: v2[:id])
34
- expect(comparison).to be_nil
35
- end
36
-
37
- it "returns nil when second version doesn't exist" do
38
- v1 = adapter.create_version(rule_id: rule_id, content: rule_content)
39
-
40
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: "nonexistent")
41
- expect(comparison).to be_nil
42
- end
43
-
44
- it "calculates differences correctly with added keys" do
45
- content1 = { key1: "value1", key2: "value2" }
46
- content2 = { key1: "value1", key2: "value2", key3: "value3" }
47
-
48
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
49
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
50
-
51
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
52
-
53
- expect(comparison[:differences][:added]).not_to be_empty
54
- end
55
-
56
- it "calculates differences correctly with removed keys" do
57
- content1 = { key1: "value1", key2: "value2", key3: "value3" }
58
- content2 = { key1: "value1", key2: "value2" }
59
-
60
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
61
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
62
-
63
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
64
-
65
- expect(comparison[:differences][:removed]).not_to be_empty
66
- end
67
-
68
- it "calculates differences correctly with changed values" do
69
- content1 = { key1: "value1", key2: "value2" }
70
- content2 = { key1: "value1", key2: "value2_changed" }
71
-
72
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
73
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
74
-
75
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
76
-
77
- expect(comparison[:differences][:changed]).to have_key(:key2)
78
- expect(comparison[:differences][:changed][:key2][:old]).to eq("value2")
79
- expect(comparison[:differences][:changed][:key2][:new]).to eq("value2_changed")
80
- end
81
-
82
- it "does not include nil values in changed differences" do
83
- content1 = { key1: "value1", key2: "value2" }
84
- content2 = { key1: "value1", key2: nil }
85
-
86
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
87
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
88
-
89
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
90
-
91
- # key2 should not be in changed since new value is nil
92
- expect(comparison[:differences][:changed]).not_to have_key(:key2)
93
- end
94
-
95
- it "returns identical versions with empty differences" do
96
- v1 = adapter.create_version(rule_id: rule_id, content: rule_content)
97
- v2 = adapter.create_version(rule_id: "rule_2", content: rule_content)
98
-
99
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
100
-
101
- expect(comparison[:differences][:added]).to be_empty
102
- expect(comparison[:differences][:removed]).to be_empty
103
- expect(comparison[:differences][:changed]).to be_empty
104
- end
105
- end
106
-
107
- describe "abstract methods" do
108
- # Test that abstract methods raise NotImplementedError when called on base class
109
- # We use a minimal test adapter class for this
110
- let(:abstract_adapter) do
111
- Class.new(DecisionAgent::Versioning::Adapter).new
112
- end
113
-
114
- it "raises NotImplementedError for create_version" do
115
- expect do
116
- abstract_adapter.create_version(rule_id: "test", content: {})
117
- end.to raise_error(NotImplementedError)
118
- end
119
-
120
- it "raises NotImplementedError for list_versions" do
121
- expect do
122
- abstract_adapter.list_versions(rule_id: "test")
123
- end.to raise_error(NotImplementedError)
124
- end
125
-
126
- it "raises NotImplementedError for get_version" do
127
- expect do
128
- abstract_adapter.get_version(version_id: "test")
129
- end.to raise_error(NotImplementedError)
130
- end
131
-
132
- it "raises NotImplementedError for get_version_by_number" do
133
- expect do
134
- abstract_adapter.get_version_by_number(rule_id: "test", version_number: 1)
135
- end.to raise_error(NotImplementedError)
136
- end
137
-
138
- it "raises NotImplementedError for get_active_version" do
139
- expect do
140
- abstract_adapter.get_active_version(rule_id: "test")
141
- end.to raise_error(NotImplementedError)
142
- end
143
-
144
- it "raises NotImplementedError for activate_version" do
145
- expect do
146
- abstract_adapter.activate_version(version_id: "test")
147
- end.to raise_error(NotImplementedError)
148
- end
149
-
150
- it "raises NotImplementedError for delete_version" do
151
- expect do
152
- abstract_adapter.delete_version(version_id: "test")
153
- end.to raise_error(NotImplementedError)
154
- end
155
- end
156
- end