lex-embodied-simulation 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.
- checksums.yaml +7 -0
- data/lib/legion/extensions/embodied_simulation/client.rb +15 -0
- data/lib/legion/extensions/embodied_simulation/helpers/constants.rb +45 -0
- data/lib/legion/extensions/embodied_simulation/helpers/simulation.rb +132 -0
- data/lib/legion/extensions/embodied_simulation/helpers/simulation_engine.rb +176 -0
- data/lib/legion/extensions/embodied_simulation/helpers/simulation_step.rb +45 -0
- data/lib/legion/extensions/embodied_simulation/runners/embodied_simulation.rb +95 -0
- data/lib/legion/extensions/embodied_simulation/version.rb +9 -0
- metadata +68 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8c0a42550d81eb660131739e12d4413bac5aaf0a68392880c008568a231e3bfa
|
|
4
|
+
data.tar.gz: e38b1c187179a9a0de618c25fa28af58bf095cf8fd5906ed977e0066fb5eb807
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 28c09ac49bc090736f6bb3696a3c555f929b1d6130ffbc9fb16a9af85d3fbb17e96f4df334810b32208347d3969f8ee5f46f2e17c53bdebff0821ab32cd53e71
|
|
7
|
+
data.tar.gz: c40107b484e1bdd2ad77620ce8b9e9edd4a46d0cda1ac5c38b33439b4537b7eecda2df36b01a85a25e5f4ee97eb00e9277e2e35991cdd1858bac3b01b99be0cf
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module EmbodiedSimulation
|
|
6
|
+
class Client
|
|
7
|
+
include Runners::EmbodiedSimulation
|
|
8
|
+
|
|
9
|
+
def initialize(engine: nil)
|
|
10
|
+
@engine = engine || Helpers::SimulationEngine.new
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module EmbodiedSimulation
|
|
6
|
+
module Helpers
|
|
7
|
+
module Constants
|
|
8
|
+
MAX_SIMULATIONS = 30
|
|
9
|
+
MAX_STEPS_PER_SIM = 20
|
|
10
|
+
MAX_HISTORY = 200
|
|
11
|
+
MAX_SCENARIOS = 50
|
|
12
|
+
|
|
13
|
+
DEFAULT_FIDELITY = 0.5
|
|
14
|
+
FIDELITY_FLOOR = 0.1
|
|
15
|
+
FIDELITY_DECAY = 0.01
|
|
16
|
+
FIDELITY_BOOST = 0.05
|
|
17
|
+
|
|
18
|
+
OUTCOME_CONFIDENCE_FLOOR = 0.05
|
|
19
|
+
CALIBRATION_ALPHA = 0.1
|
|
20
|
+
|
|
21
|
+
SIMULATION_TYPES = %i[
|
|
22
|
+
action_rehearsal counterfactual empathic
|
|
23
|
+
predictive exploratory defensive
|
|
24
|
+
].freeze
|
|
25
|
+
|
|
26
|
+
SIMULATION_STATES = %i[
|
|
27
|
+
pending running completed failed aborted
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
30
|
+
OUTCOME_VALENCES = %i[
|
|
31
|
+
positive negative neutral ambiguous
|
|
32
|
+
].freeze
|
|
33
|
+
|
|
34
|
+
FIDELITY_LABELS = {
|
|
35
|
+
(0.8..) => :vivid,
|
|
36
|
+
(0.6...0.8) => :clear,
|
|
37
|
+
(0.4...0.6) => :hazy,
|
|
38
|
+
(0.2...0.4) => :vague,
|
|
39
|
+
(..0.2) => :phantom
|
|
40
|
+
}.freeze
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module EmbodiedSimulation
|
|
6
|
+
module Helpers
|
|
7
|
+
class Simulation
|
|
8
|
+
include Constants
|
|
9
|
+
|
|
10
|
+
attr_reader :id, :simulation_type, :domain, :initial_state, :steps,
|
|
11
|
+
:state, :outcome_valence, :fidelity, :created_at
|
|
12
|
+
|
|
13
|
+
def initialize(id:, simulation_type:, domain:, initial_state:, fidelity: DEFAULT_FIDELITY)
|
|
14
|
+
raise ArgumentError, "invalid type: #{simulation_type}" unless SIMULATION_TYPES.include?(simulation_type)
|
|
15
|
+
|
|
16
|
+
@id = id
|
|
17
|
+
@simulation_type = simulation_type
|
|
18
|
+
@domain = domain
|
|
19
|
+
@initial_state = initial_state
|
|
20
|
+
@steps = []
|
|
21
|
+
@state = :pending
|
|
22
|
+
@outcome_valence = nil
|
|
23
|
+
@fidelity = fidelity.to_f.clamp(FIDELITY_FLOOR, 1.0)
|
|
24
|
+
@created_at = Time.now.utc
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def add_step(action:, expected_state:, confidence: DEFAULT_FIDELITY, somatic_signal: 0.0)
|
|
28
|
+
return nil if @steps.size >= MAX_STEPS_PER_SIM
|
|
29
|
+
return nil unless %i[pending running].include?(@state)
|
|
30
|
+
|
|
31
|
+
@state = :running if @state == :pending
|
|
32
|
+
step = SimulationStep.new(
|
|
33
|
+
index: @steps.size, action: action, expected_state: expected_state,
|
|
34
|
+
confidence: confidence, somatic_signal: somatic_signal
|
|
35
|
+
)
|
|
36
|
+
@steps << step
|
|
37
|
+
step
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def complete(valence:)
|
|
41
|
+
return nil unless OUTCOME_VALENCES.include?(valence)
|
|
42
|
+
return nil unless %i[pending running].include?(@state)
|
|
43
|
+
|
|
44
|
+
@state = :completed
|
|
45
|
+
@outcome_valence = valence
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def abort_simulation
|
|
49
|
+
return nil if @state == :completed
|
|
50
|
+
|
|
51
|
+
@state = :aborted
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def fail_simulation
|
|
55
|
+
return nil if @state == :completed
|
|
56
|
+
|
|
57
|
+
@state = :failed
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def running?
|
|
61
|
+
@state == :running
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def completed?
|
|
65
|
+
@state == :completed
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def successful?
|
|
69
|
+
@state == :completed && @outcome_valence == :positive
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def aggregate_somatic
|
|
73
|
+
return 0.0 if @steps.empty?
|
|
74
|
+
|
|
75
|
+
@steps.sum(&:somatic_signal) / @steps.size
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def aggregate_confidence
|
|
79
|
+
return 0.0 if @steps.empty?
|
|
80
|
+
|
|
81
|
+
@steps.sum(&:confidence) / @steps.size
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def negative_signals?
|
|
85
|
+
@steps.any?(&:negative_signal?)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def step_count
|
|
89
|
+
@steps.size
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def counterfactual?
|
|
93
|
+
@simulation_type == :counterfactual
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def rehearsal?
|
|
97
|
+
@simulation_type == :action_rehearsal
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def empathic?
|
|
101
|
+
@simulation_type == :empathic
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def fidelity_label
|
|
105
|
+
FIDELITY_LABELS.each { |range, lbl| return lbl if range.cover?(@fidelity) }
|
|
106
|
+
:phantom
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def decay_fidelity
|
|
110
|
+
@fidelity = [@fidelity - FIDELITY_DECAY, FIDELITY_FLOOR].max
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_h
|
|
114
|
+
{
|
|
115
|
+
id: @id,
|
|
116
|
+
simulation_type: @simulation_type,
|
|
117
|
+
domain: @domain,
|
|
118
|
+
state: @state,
|
|
119
|
+
step_count: @steps.size,
|
|
120
|
+
outcome_valence: @outcome_valence,
|
|
121
|
+
fidelity: @fidelity.round(4),
|
|
122
|
+
fidelity_label: fidelity_label,
|
|
123
|
+
somatic_avg: aggregate_somatic.round(4),
|
|
124
|
+
confidence_avg: aggregate_confidence.round(4),
|
|
125
|
+
created_at: @created_at
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module EmbodiedSimulation
|
|
6
|
+
module Helpers
|
|
7
|
+
class SimulationEngine
|
|
8
|
+
include Constants
|
|
9
|
+
|
|
10
|
+
attr_reader :simulations, :history, :calibration
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@simulations = {}
|
|
14
|
+
@counter = 0
|
|
15
|
+
@history = []
|
|
16
|
+
@calibration = 0.5
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def create_simulation(simulation_type:, domain:, initial_state:, fidelity: DEFAULT_FIDELITY)
|
|
20
|
+
return nil unless SIMULATION_TYPES.include?(simulation_type)
|
|
21
|
+
return nil if @simulations.size >= MAX_SIMULATIONS
|
|
22
|
+
|
|
23
|
+
@counter += 1
|
|
24
|
+
sim_id = :"sim_#{@counter}"
|
|
25
|
+
sim = Simulation.new(
|
|
26
|
+
id: sim_id, simulation_type: simulation_type,
|
|
27
|
+
domain: domain, initial_state: initial_state, fidelity: fidelity
|
|
28
|
+
)
|
|
29
|
+
@simulations[sim_id] = sim
|
|
30
|
+
sim
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add_step(sim_id:, action:, expected_state:, confidence: DEFAULT_FIDELITY, somatic_signal: 0.0)
|
|
34
|
+
sim = @simulations[sim_id]
|
|
35
|
+
return nil unless sim
|
|
36
|
+
|
|
37
|
+
sim.add_step(action: action, expected_state: expected_state,
|
|
38
|
+
confidence: confidence, somatic_signal: somatic_signal)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def complete_simulation(sim_id:, valence:)
|
|
42
|
+
sim = @simulations[sim_id]
|
|
43
|
+
return nil unless sim
|
|
44
|
+
|
|
45
|
+
result = sim.complete(valence: valence)
|
|
46
|
+
record_completion(sim) if result
|
|
47
|
+
result
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def abort_simulation(sim_id:)
|
|
51
|
+
sim = @simulations[sim_id]
|
|
52
|
+
return nil unless sim
|
|
53
|
+
|
|
54
|
+
sim.abort_simulation
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def rehearse(domain:, action_sequence:, initial_state: {})
|
|
58
|
+
sim = create_simulation(
|
|
59
|
+
simulation_type: :action_rehearsal, domain: domain,
|
|
60
|
+
initial_state: initial_state
|
|
61
|
+
)
|
|
62
|
+
return nil unless sim
|
|
63
|
+
|
|
64
|
+
run_sequence(sim, action_sequence)
|
|
65
|
+
sim
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def counterfactual(domain:, actual_outcome:, alternative_actions:, initial_state: {})
|
|
69
|
+
sim = create_simulation(
|
|
70
|
+
simulation_type: :counterfactual, domain: domain,
|
|
71
|
+
initial_state: initial_state.merge(actual_outcome: actual_outcome)
|
|
72
|
+
)
|
|
73
|
+
return nil unless sim
|
|
74
|
+
|
|
75
|
+
run_sequence(sim, alternative_actions)
|
|
76
|
+
sim
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def evaluate_simulation(sim_id:)
|
|
80
|
+
sim = @simulations[sim_id]
|
|
81
|
+
return nil unless sim
|
|
82
|
+
|
|
83
|
+
build_evaluation(sim)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def compare_simulations(*sim_ids)
|
|
87
|
+
sims = sim_ids.filter_map { |id| @simulations[id] }
|
|
88
|
+
return [] if sims.empty?
|
|
89
|
+
|
|
90
|
+
sims.sort_by { |s| -(s.aggregate_somatic + s.aggregate_confidence) }.map(&:to_h)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def simulations_for(domain:)
|
|
94
|
+
@simulations.values.select { |s| s.domain == domain }.map(&:to_h)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def active_simulations
|
|
98
|
+
@simulations.values.select(&:running?).map(&:to_h)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def completed_simulations
|
|
102
|
+
@simulations.values.select(&:completed?).map(&:to_h)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def calibrate(sim_id:, actual_valence:)
|
|
106
|
+
sim = @simulations[sim_id]
|
|
107
|
+
return nil unless sim&.completed?
|
|
108
|
+
|
|
109
|
+
match = sim.outcome_valence == actual_valence ? 1.0 : 0.0
|
|
110
|
+
@calibration += CALIBRATION_ALPHA * (match - @calibration)
|
|
111
|
+
@calibration = @calibration.clamp(0.0, 1.0)
|
|
112
|
+
sim.fidelity_label
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def decay_all
|
|
116
|
+
@simulations.each_value(&:decay_fidelity)
|
|
117
|
+
@simulations.reject! { |_, s| s.fidelity <= FIDELITY_FLOOR && s.completed? }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def to_h
|
|
121
|
+
{
|
|
122
|
+
simulation_count: @simulations.size,
|
|
123
|
+
active_count: @simulations.values.count(&:running?),
|
|
124
|
+
completed_count: @simulations.values.count(&:completed?),
|
|
125
|
+
calibration: @calibration.round(4),
|
|
126
|
+
history_size: @history.size
|
|
127
|
+
}
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
def run_sequence(sim, actions)
|
|
133
|
+
actions.each_with_index do |act, _i|
|
|
134
|
+
sim.add_step(
|
|
135
|
+
action: act[:action] || act,
|
|
136
|
+
expected_state: act[:expected_state] || {},
|
|
137
|
+
confidence: act[:confidence] || DEFAULT_FIDELITY,
|
|
138
|
+
somatic_signal: act[:somatic_signal] || 0.0
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def record_completion(sim)
|
|
144
|
+
@history << {
|
|
145
|
+
id: sim.id, type: sim.simulation_type, domain: sim.domain,
|
|
146
|
+
valence: sim.outcome_valence, steps: sim.step_count, at: Time.now.utc
|
|
147
|
+
}
|
|
148
|
+
@history.shift while @history.size > MAX_HISTORY
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def build_evaluation(sim)
|
|
152
|
+
{
|
|
153
|
+
id: sim.id,
|
|
154
|
+
state: sim.state,
|
|
155
|
+
recommendation: recommend(sim),
|
|
156
|
+
somatic_avg: sim.aggregate_somatic.round(4),
|
|
157
|
+
confidence_avg: sim.aggregate_confidence.round(4),
|
|
158
|
+
has_warnings: sim.negative_signals?,
|
|
159
|
+
fidelity: sim.fidelity.round(4),
|
|
160
|
+
step_count: sim.step_count
|
|
161
|
+
}
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def recommend(sim)
|
|
165
|
+
return :insufficient_data if sim.steps.empty?
|
|
166
|
+
return :abort if sim.aggregate_somatic < -0.5
|
|
167
|
+
return :proceed_with_caution if sim.negative_signals?
|
|
168
|
+
return :proceed if sim.aggregate_somatic >= 0.0 && sim.aggregate_confidence >= 0.5
|
|
169
|
+
|
|
170
|
+
:reconsider
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module EmbodiedSimulation
|
|
6
|
+
module Helpers
|
|
7
|
+
class SimulationStep
|
|
8
|
+
include Constants
|
|
9
|
+
|
|
10
|
+
attr_reader :index, :action, :expected_state, :confidence, :somatic_signal
|
|
11
|
+
|
|
12
|
+
def initialize(index:, action:, expected_state:, confidence: DEFAULT_FIDELITY, somatic_signal: 0.0)
|
|
13
|
+
@index = index
|
|
14
|
+
@action = action
|
|
15
|
+
@expected_state = expected_state
|
|
16
|
+
@confidence = confidence.to_f.clamp(0.0, 1.0)
|
|
17
|
+
@somatic_signal = somatic_signal.to_f.clamp(-1.0, 1.0)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def positive_signal?
|
|
21
|
+
@somatic_signal > 0.2
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def negative_signal?
|
|
25
|
+
@somatic_signal < -0.2
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def high_confidence?
|
|
29
|
+
@confidence >= 0.7
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_h
|
|
33
|
+
{
|
|
34
|
+
index: @index,
|
|
35
|
+
action: @action,
|
|
36
|
+
expected_state: @expected_state,
|
|
37
|
+
confidence: @confidence.round(4),
|
|
38
|
+
somatic_signal: @somatic_signal.round(4)
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module EmbodiedSimulation
|
|
6
|
+
module Runners
|
|
7
|
+
module EmbodiedSimulation
|
|
8
|
+
include Helpers::Constants
|
|
9
|
+
|
|
10
|
+
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
11
|
+
|
|
12
|
+
def create_simulation(simulation_type:, domain:, initial_state: {}, fidelity: DEFAULT_FIDELITY, **)
|
|
13
|
+
sim = engine.create_simulation(
|
|
14
|
+
simulation_type: simulation_type, domain: domain,
|
|
15
|
+
initial_state: initial_state, fidelity: fidelity
|
|
16
|
+
)
|
|
17
|
+
return { success: false, reason: :limit_or_invalid_type } unless sim
|
|
18
|
+
|
|
19
|
+
{ success: true, simulation_id: sim.id, simulation_type: sim.simulation_type, domain: sim.domain }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_simulation_step(sim_id:, action:, expected_state: {}, confidence: DEFAULT_FIDELITY,
|
|
23
|
+
somatic_signal: 0.0, **)
|
|
24
|
+
step = engine.add_step(
|
|
25
|
+
sim_id: sim_id, action: action, expected_state: expected_state,
|
|
26
|
+
confidence: confidence, somatic_signal: somatic_signal
|
|
27
|
+
)
|
|
28
|
+
return { success: false, reason: :not_found_or_full } unless step
|
|
29
|
+
|
|
30
|
+
{ success: true, step_index: step.index, action: step.action }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def complete_simulation(sim_id:, valence:, **)
|
|
34
|
+
result = engine.complete_simulation(sim_id: sim_id, valence: valence)
|
|
35
|
+
return { success: false, reason: :not_found_or_invalid } unless result
|
|
36
|
+
|
|
37
|
+
{ success: true, simulation_id: sim_id, valence: valence }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def rehearse_action(domain:, action_sequence:, initial_state: {}, **)
|
|
41
|
+
sim = engine.rehearse(domain: domain, action_sequence: action_sequence, initial_state: initial_state)
|
|
42
|
+
return { success: false, reason: :limit_reached } unless sim
|
|
43
|
+
|
|
44
|
+
{ success: true, simulation_id: sim.id, step_count: sim.step_count,
|
|
45
|
+
somatic_avg: sim.aggregate_somatic.round(4) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def run_counterfactual(domain:, actual_outcome:, alternative_actions:, initial_state: {}, **)
|
|
49
|
+
sim = engine.counterfactual(
|
|
50
|
+
domain: domain, actual_outcome: actual_outcome,
|
|
51
|
+
alternative_actions: alternative_actions, initial_state: initial_state
|
|
52
|
+
)
|
|
53
|
+
return { success: false, reason: :limit_reached } unless sim
|
|
54
|
+
|
|
55
|
+
{ success: true, simulation_id: sim.id, step_count: sim.step_count }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def evaluate_simulation(sim_id:, **)
|
|
59
|
+
result = engine.evaluate_simulation(sim_id: sim_id)
|
|
60
|
+
return { success: false, reason: :not_found } unless result
|
|
61
|
+
|
|
62
|
+
{ success: true }.merge(result)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def compare_simulations(sim_ids:, **)
|
|
66
|
+
ranked = engine.compare_simulations(*sim_ids)
|
|
67
|
+
{ success: true, ranked: ranked, count: ranked.size }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def calibrate_simulation(sim_id:, actual_valence:, **)
|
|
71
|
+
label = engine.calibrate(sim_id: sim_id, actual_valence: actual_valence)
|
|
72
|
+
return { success: false, reason: :not_found_or_incomplete } unless label
|
|
73
|
+
|
|
74
|
+
{ success: true, calibration: engine.calibration.round(4), fidelity_label: label }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def update_embodied_simulation(**)
|
|
78
|
+
engine.decay_all
|
|
79
|
+
{ success: true }.merge(engine.to_h)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def embodied_simulation_stats(**)
|
|
83
|
+
{ success: true }.merge(engine.to_h)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def engine
|
|
89
|
+
@engine ||= Helpers::SimulationEngine.new
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lex-embodied-simulation
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Esity
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: legion-gaia
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
description: Embodied simulation engine for LegionIO — mental rehearsal, action simulation,
|
|
27
|
+
and counterfactual reasoning
|
|
28
|
+
email:
|
|
29
|
+
- matthewdiverson@gmail.com
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- lib/legion/extensions/embodied_simulation/client.rb
|
|
35
|
+
- lib/legion/extensions/embodied_simulation/helpers/constants.rb
|
|
36
|
+
- lib/legion/extensions/embodied_simulation/helpers/simulation.rb
|
|
37
|
+
- lib/legion/extensions/embodied_simulation/helpers/simulation_engine.rb
|
|
38
|
+
- lib/legion/extensions/embodied_simulation/helpers/simulation_step.rb
|
|
39
|
+
- lib/legion/extensions/embodied_simulation/runners/embodied_simulation.rb
|
|
40
|
+
- lib/legion/extensions/embodied_simulation/version.rb
|
|
41
|
+
homepage: https://github.com/LegionIO/lex-embodied-simulation
|
|
42
|
+
licenses:
|
|
43
|
+
- MIT
|
|
44
|
+
metadata:
|
|
45
|
+
homepage_uri: https://github.com/LegionIO/lex-embodied-simulation
|
|
46
|
+
source_code_uri: https://github.com/LegionIO/lex-embodied-simulation
|
|
47
|
+
documentation_uri: https://github.com/LegionIO/lex-embodied-simulation/blob/master/README.md
|
|
48
|
+
changelog_uri: https://github.com/LegionIO/lex-embodied-simulation/blob/master/CHANGELOG.md
|
|
49
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-embodied-simulation/issues
|
|
50
|
+
rubygems_mfa_required: 'true'
|
|
51
|
+
rdoc_options: []
|
|
52
|
+
require_paths:
|
|
53
|
+
- lib
|
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '3.4'
|
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '0'
|
|
64
|
+
requirements: []
|
|
65
|
+
rubygems_version: 3.6.9
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: Barsalou's grounded cognition for LegionIO
|
|
68
|
+
test_files: []
|