decision_agent 0.3.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.
- checksums.yaml +4 -4
- data/README.md +272 -7
- data/lib/decision_agent/agent.rb +72 -1
- data/lib/decision_agent/context.rb +1 -0
- data/lib/decision_agent/data_enrichment/cache/memory_adapter.rb +86 -0
- data/lib/decision_agent/data_enrichment/cache_adapter.rb +49 -0
- data/lib/decision_agent/data_enrichment/circuit_breaker.rb +135 -0
- data/lib/decision_agent/data_enrichment/client.rb +220 -0
- data/lib/decision_agent/data_enrichment/config.rb +78 -0
- data/lib/decision_agent/data_enrichment/errors.rb +36 -0
- data/lib/decision_agent/decision.rb +102 -2
- data/lib/decision_agent/dmn/feel/evaluator.rb +28 -6
- data/lib/decision_agent/dsl/condition_evaluator.rb +982 -839
- data/lib/decision_agent/dsl/schema_validator.rb +51 -13
- data/lib/decision_agent/evaluators/dmn_evaluator.rb +106 -19
- data/lib/decision_agent/evaluators/json_rule_evaluator.rb +69 -9
- data/lib/decision_agent/explainability/condition_trace.rb +83 -0
- data/lib/decision_agent/explainability/explainability_result.rb +52 -0
- data/lib/decision_agent/explainability/rule_trace.rb +39 -0
- data/lib/decision_agent/explainability/trace_collector.rb +24 -0
- data/lib/decision_agent/monitoring/alert_manager.rb +5 -1
- data/lib/decision_agent/simulation/errors.rb +18 -0
- data/lib/decision_agent/simulation/impact_analyzer.rb +498 -0
- data/lib/decision_agent/simulation/monte_carlo_simulator.rb +635 -0
- data/lib/decision_agent/simulation/replay_engine.rb +486 -0
- data/lib/decision_agent/simulation/scenario_engine.rb +318 -0
- data/lib/decision_agent/simulation/scenario_library.rb +163 -0
- data/lib/decision_agent/simulation/shadow_test_engine.rb +287 -0
- data/lib/decision_agent/simulation/what_if_analyzer.rb +1002 -0
- data/lib/decision_agent/simulation.rb +17 -0
- data/lib/decision_agent/version.rb +1 -1
- data/lib/decision_agent/versioning/activerecord_adapter.rb +23 -8
- data/lib/decision_agent/web/public/app.js +119 -0
- data/lib/decision_agent/web/public/index.html +49 -0
- data/lib/decision_agent/web/public/simulation.html +130 -0
- data/lib/decision_agent/web/public/simulation_impact.html +478 -0
- data/lib/decision_agent/web/public/simulation_replay.html +551 -0
- data/lib/decision_agent/web/public/simulation_shadow.html +546 -0
- data/lib/decision_agent/web/public/simulation_whatif.html +532 -0
- data/lib/decision_agent/web/public/styles.css +65 -0
- data/lib/decision_agent/web/server.rb +594 -23
- data/lib/decision_agent.rb +60 -2
- metadata +53 -73
- data/spec/ab_testing/ab_test_assignment_spec.rb +0 -253
- data/spec/ab_testing/ab_test_manager_spec.rb +0 -612
- data/spec/ab_testing/ab_test_spec.rb +0 -270
- data/spec/ab_testing/ab_testing_agent_spec.rb +0 -655
- data/spec/ab_testing/storage/adapter_spec.rb +0 -64
- data/spec/ab_testing/storage/memory_adapter_spec.rb +0 -485
- data/spec/activerecord_thread_safety_spec.rb +0 -553
- data/spec/advanced_operators_spec.rb +0 -3150
- data/spec/agent_spec.rb +0 -289
- data/spec/api_contract_spec.rb +0 -430
- data/spec/audit_adapters_spec.rb +0 -92
- data/spec/auth/access_audit_logger_spec.rb +0 -394
- data/spec/auth/authenticator_spec.rb +0 -112
- data/spec/auth/password_reset_spec.rb +0 -294
- data/spec/auth/permission_checker_spec.rb +0 -207
- data/spec/auth/permission_spec.rb +0 -73
- data/spec/auth/rbac_adapter_spec.rb +0 -778
- data/spec/auth/rbac_config_spec.rb +0 -82
- data/spec/auth/role_spec.rb +0 -51
- data/spec/auth/session_manager_spec.rb +0 -172
- data/spec/auth/session_spec.rb +0 -112
- data/spec/auth/user_spec.rb +0 -130
- data/spec/comprehensive_edge_cases_spec.rb +0 -1777
- data/spec/context_spec.rb +0 -127
- data/spec/decision_agent_spec.rb +0 -96
- data/spec/decision_spec.rb +0 -423
- data/spec/dmn/decision_graph_spec.rb +0 -282
- data/spec/dmn/decision_tree_spec.rb +0 -203
- data/spec/dmn/feel/errors_spec.rb +0 -18
- data/spec/dmn/feel/functions_spec.rb +0 -400
- data/spec/dmn/feel/simple_parser_spec.rb +0 -274
- data/spec/dmn/feel/types_spec.rb +0 -176
- data/spec/dmn/feel_parser_spec.rb +0 -489
- data/spec/dmn/hit_policy_spec.rb +0 -202
- data/spec/dmn/integration_spec.rb +0 -226
- data/spec/dsl/condition_evaluator_spec.rb +0 -774
- data/spec/dsl_validation_spec.rb +0 -648
- data/spec/edge_cases_spec.rb +0 -353
- data/spec/evaluation_spec.rb +0 -364
- data/spec/evaluation_validator_spec.rb +0 -165
- data/spec/examples/feedback_aware_evaluator_spec.rb +0 -460
- data/spec/examples.txt +0 -1909
- data/spec/fixtures/dmn/complex_decision.dmn +0 -81
- data/spec/fixtures/dmn/invalid_structure.dmn +0 -31
- data/spec/fixtures/dmn/simple_decision.dmn +0 -40
- data/spec/issue_verification_spec.rb +0 -759
- data/spec/json_rule_evaluator_spec.rb +0 -587
- data/spec/monitoring/alert_manager_spec.rb +0 -378
- data/spec/monitoring/metrics_collector_spec.rb +0 -501
- data/spec/monitoring/monitored_agent_spec.rb +0 -225
- data/spec/monitoring/prometheus_exporter_spec.rb +0 -242
- data/spec/monitoring/storage/activerecord_adapter_spec.rb +0 -498
- data/spec/monitoring/storage/base_adapter_spec.rb +0 -61
- data/spec/monitoring/storage/memory_adapter_spec.rb +0 -247
- data/spec/performance_optimizations_spec.rb +0 -493
- data/spec/replay_edge_cases_spec.rb +0 -699
- data/spec/replay_spec.rb +0 -210
- data/spec/rfc8785_canonicalization_spec.rb +0 -215
- data/spec/scoring_spec.rb +0 -225
- data/spec/spec_helper.rb +0 -60
- data/spec/testing/batch_test_importer_spec.rb +0 -693
- data/spec/testing/batch_test_runner_spec.rb +0 -307
- data/spec/testing/test_coverage_analyzer_spec.rb +0 -292
- data/spec/testing/test_result_comparator_spec.rb +0 -392
- data/spec/testing/test_scenario_spec.rb +0 -113
- data/spec/thread_safety_spec.rb +0 -490
- data/spec/thread_safety_spec.rb.broken +0 -878
- data/spec/versioning/adapter_spec.rb +0 -156
- data/spec/versioning_spec.rb +0 -1030
- data/spec/web/middleware/auth_middleware_spec.rb +0 -133
- data/spec/web/middleware/permission_middleware_spec.rb +0 -247
- data/spec/web_ui_rack_spec.rb +0 -2134
|
@@ -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
|