lex-cognitive-gravity 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/.github/workflows/ci.yml +16 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +64 -0
- data/CLAUDE.md +123 -0
- data/Gemfile +11 -0
- data/README.md +47 -0
- data/lex-cognitive-gravity.gemspec +27 -0
- data/lib/legion/extensions/cognitive_gravity/client.rb +25 -0
- data/lib/legion/extensions/cognitive_gravity/helpers/attractor.rb +73 -0
- data/lib/legion/extensions/cognitive_gravity/helpers/constants.rb +72 -0
- data/lib/legion/extensions/cognitive_gravity/helpers/gravity_engine.rb +160 -0
- data/lib/legion/extensions/cognitive_gravity/helpers/orbiting_thought.rb +60 -0
- data/lib/legion/extensions/cognitive_gravity/runners/gravity.rb +128 -0
- data/lib/legion/extensions/cognitive_gravity/version.rb +9 -0
- data/lib/legion/extensions/cognitive_gravity.rb +16 -0
- metadata +77 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3b5fd5b947f6fdcf87b9a1ea06d1ea1c7d4751b0374710f1a31dbdd776415992
|
|
4
|
+
data.tar.gz: 79e9aa02e8a16d53fc050806e2f2a12b4a8f6fc46a23eaa6be6ad136ae9a21e4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2f0efb7bc240c78ce18cf5f2db4ce2821cadcdc19af7b16850e5170b896abebe3dd68826a69bd1b1be2d6271de5e67e4c04c2b89dd9d08de3c635786a673da61
|
|
7
|
+
data.tar.gz: 0311d5bec4510aa19a4fdfe49c3cd4a0ba6b8c9d3aef9e31bde14ea9f70de7e39e7bf7f1a6206f7963205c751f05099e8a50dadb23daff8df0ae00c9ab66f5aa
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
ci:
|
|
9
|
+
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
10
|
+
|
|
11
|
+
release:
|
|
12
|
+
needs: ci
|
|
13
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
14
|
+
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
15
|
+
secrets:
|
|
16
|
+
rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 3.4
|
|
3
|
+
NewCops: enable
|
|
4
|
+
SuggestExtensions: false
|
|
5
|
+
|
|
6
|
+
Layout/LineLength:
|
|
7
|
+
Max: 160
|
|
8
|
+
|
|
9
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
|
10
|
+
EnforcedStyle: space
|
|
11
|
+
|
|
12
|
+
Layout/HashAlignment:
|
|
13
|
+
EnforcedHashRocketStyle: table
|
|
14
|
+
EnforcedColonStyle: table
|
|
15
|
+
|
|
16
|
+
Metrics/MethodLength:
|
|
17
|
+
Max: 25
|
|
18
|
+
|
|
19
|
+
Metrics/ClassLength:
|
|
20
|
+
Max: 150
|
|
21
|
+
|
|
22
|
+
Metrics/ModuleLength:
|
|
23
|
+
Max: 1500
|
|
24
|
+
|
|
25
|
+
Metrics/BlockLength:
|
|
26
|
+
Max: 40
|
|
27
|
+
Exclude:
|
|
28
|
+
- 'spec/**/*'
|
|
29
|
+
|
|
30
|
+
Metrics/AbcSize:
|
|
31
|
+
Max: 25
|
|
32
|
+
|
|
33
|
+
Metrics/ParameterLists:
|
|
34
|
+
Max: 8
|
|
35
|
+
MaxOptionalParameters: 8
|
|
36
|
+
|
|
37
|
+
Metrics/CyclomaticComplexity:
|
|
38
|
+
Max: 15
|
|
39
|
+
|
|
40
|
+
Metrics/PerceivedComplexity:
|
|
41
|
+
Max: 17
|
|
42
|
+
|
|
43
|
+
Style/Documentation:
|
|
44
|
+
Enabled: false
|
|
45
|
+
|
|
46
|
+
Style/SymbolArray:
|
|
47
|
+
Enabled: true
|
|
48
|
+
|
|
49
|
+
Style/FrozenStringLiteralComment:
|
|
50
|
+
Enabled: true
|
|
51
|
+
EnforcedStyle: always
|
|
52
|
+
|
|
53
|
+
Style/OneClassPerFile:
|
|
54
|
+
Exclude:
|
|
55
|
+
- 'spec/spec_helper.rb'
|
|
56
|
+
|
|
57
|
+
Naming/FileName:
|
|
58
|
+
Enabled: false
|
|
59
|
+
|
|
60
|
+
Naming/PredicateMethod:
|
|
61
|
+
Enabled: false
|
|
62
|
+
|
|
63
|
+
Naming/PredicatePrefix:
|
|
64
|
+
Enabled: false
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# lex-cognitive-gravity
|
|
2
|
+
|
|
3
|
+
**Level 3 Leaf Documentation**
|
|
4
|
+
- **Parent**: `/Users/miverso2/rubymine/legion/extensions-agentic/CLAUDE.md`
|
|
5
|
+
- **Gem**: `lex-cognitive-gravity`
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Models attractor dynamics in cognition. Attractors are high-mass cognitive concepts that exert gravitational pull on orbiting thoughts. Thoughts within an attractor's capture radius are pulled in; those too distant escape. Each simulation tick determines captures and escapes based on mass and orbital distance. Attractors gain mass through accretion (reinforcement) and lose mass through erosion (decay). Collapsed attractors (mass < COLLAPSE_THRESHOLD) can no longer capture thoughts. Supermassive attractors (mass >= SUPERMASSIVE_THRESHOLD) have extended capture radius.
|
|
10
|
+
|
|
11
|
+
## Gem Info
|
|
12
|
+
|
|
13
|
+
| Field | Value |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Gem name | `lex-cognitive-gravity` |
|
|
16
|
+
| Version | `0.1.0` |
|
|
17
|
+
| Namespace | `Legion::Extensions::CognitiveGravity` |
|
|
18
|
+
| Ruby | `>= 3.4` |
|
|
19
|
+
| License | MIT |
|
|
20
|
+
| GitHub | https://github.com/LegionIO/lex-cognitive-gravity |
|
|
21
|
+
|
|
22
|
+
## File Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
lib/legion/extensions/cognitive_gravity/
|
|
26
|
+
cognitive_gravity.rb # Top-level require
|
|
27
|
+
version.rb # VERSION = '0.1.0'
|
|
28
|
+
client.rb # Client class
|
|
29
|
+
helpers/
|
|
30
|
+
constants.rb # Attractor domains, mass/density/orbit labels, thresholds
|
|
31
|
+
attractor.rb # Attractor value object
|
|
32
|
+
orbiting_thought.rb # OrbitingThought value object
|
|
33
|
+
gravity_engine.rb # Engine: attractors, thoughts, tick, accretion, erosion
|
|
34
|
+
runners/
|
|
35
|
+
gravity.rb # Runner module
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Key Constants
|
|
39
|
+
|
|
40
|
+
| Constant | Value | Meaning |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `MAX_ATTRACTORS` | 200 | Attractor cap |
|
|
43
|
+
| `MAX_ORBITING` | 500 | Orbiting thought cap |
|
|
44
|
+
| `DEFAULT_MASS` | 1.0 | Starting attractor mass |
|
|
45
|
+
| `MASS_ACCRETION` | 0.15 | Mass increase per accretion call |
|
|
46
|
+
| `MASS_EROSION` | 0.05 | Mass decrease per erosion call |
|
|
47
|
+
| `CAPTURE_RADIUS` | 0.2 | Default orbital radius within which thoughts are captured |
|
|
48
|
+
| `COLLAPSE_THRESHOLD` | 0.1 | Mass below this = collapsed; cannot capture |
|
|
49
|
+
| `SUPERMASSIVE_THRESHOLD` | 3.0 | Mass above this = supermassive; extended capture radius |
|
|
50
|
+
| `ATTRACTOR_DOMAINS` | array | `[:fear, :desire, :belief, :habit, :memory, :identity, :goal, :trauma]` |
|
|
51
|
+
| `MASS_LABELS` | hash | `supermassive` (3.0+) through `collapsed` |
|
|
52
|
+
| `DENSITY_LABELS` | hash | `dense` (0.8+) through `sparse` |
|
|
53
|
+
| `ORBIT_LABELS` | hash | `captured` through `escaped` |
|
|
54
|
+
|
|
55
|
+
## Helpers
|
|
56
|
+
|
|
57
|
+
### `Attractor`
|
|
58
|
+
|
|
59
|
+
A dominant cognitive concept with gravitational mass.
|
|
60
|
+
|
|
61
|
+
- `initialize(domain:, content:, mass: DEFAULT_MASS, attractor_id: nil)`
|
|
62
|
+
- `accrete!(rate)` — increases mass by `MASS_ACCRETION`
|
|
63
|
+
- `erode!(rate)` — decreases mass by `MASS_EROSION`, floor 0.0
|
|
64
|
+
- `collapsed?` — mass < `COLLAPSE_THRESHOLD`
|
|
65
|
+
- `supermassive?` — mass >= `SUPERMASSIVE_THRESHOLD`
|
|
66
|
+
- `capture_radius` — extended if supermassive
|
|
67
|
+
- `mass_label`
|
|
68
|
+
- `to_h`
|
|
69
|
+
|
|
70
|
+
### `OrbitingThought`
|
|
71
|
+
|
|
72
|
+
A cognitive element in orbital relationship with an attractor.
|
|
73
|
+
|
|
74
|
+
- `initialize(content:, domain:, orbital_distance: 0.5, thought_id: nil)`
|
|
75
|
+
- `captured?` — orbital_distance <= attractor's capture_radius
|
|
76
|
+
- `escaped?` — orbital_distance > 1.0
|
|
77
|
+
- `to_h`
|
|
78
|
+
|
|
79
|
+
### `GravityEngine`
|
|
80
|
+
|
|
81
|
+
- `add_attractor(domain:, content:, mass: DEFAULT_MASS)` — returns `{ added:, attractor_id:, attractor: }` or capacity error
|
|
82
|
+
- `add_orbiting_thought(content:, domain:, orbital_distance: 0.5)` — returns `{ added:, thought_id:, thought: }` or capacity error
|
|
83
|
+
- `simulate_tick` — for each non-collapsed attractor, evaluates all thoughts within capture radius (captures) and marks distant thoughts (escapes); returns capture/escape counts
|
|
84
|
+
- `accrete_attractor(attractor_id:)` — increases mass
|
|
85
|
+
- `erode_attractor(attractor_id:)` — decreases mass
|
|
86
|
+
- `strongest_attractors(limit: 10)` — sorted by mass descending
|
|
87
|
+
- `cognitive_density_map` — domain -> mean mass map
|
|
88
|
+
- `gravity_report` — full stats
|
|
89
|
+
|
|
90
|
+
## Runners
|
|
91
|
+
|
|
92
|
+
**Module**: `Legion::Extensions::CognitiveGravity::Runners::Gravity`
|
|
93
|
+
|
|
94
|
+
| Method | Key Args | Returns |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `create_attractor` | `domain:`, `content:`, `mass: DEFAULT_MASS` | `{ success:, attractor_id:, attractor: }` |
|
|
97
|
+
| `add_thought` | `content:`, `domain:`, `orbital_distance: 0.5` | `{ success:, thought_id:, thought: }` |
|
|
98
|
+
| `tick_gravity` | — | `{ success:, captures:, escapes: }` |
|
|
99
|
+
| `accrete` | `attractor_id:` | `{ success:, mass:, label: }` |
|
|
100
|
+
| `erode` | `attractor_id:` | `{ success:, mass:, label: }` |
|
|
101
|
+
| `strongest_attractors` | `limit: 10` | `{ success:, attractors: }` |
|
|
102
|
+
| `thought_distribution` | — | `{ success:, distribution: }` |
|
|
103
|
+
| `cognitive_density_map` | — | `{ success:, density_map: }` |
|
|
104
|
+
| `gravity_report` | — | Full report hash |
|
|
105
|
+
|
|
106
|
+
Private: `gravity_engine` — memoized `GravityEngine`. Logs via `log_debug` helper.
|
|
107
|
+
|
|
108
|
+
## Integration Points
|
|
109
|
+
|
|
110
|
+
- **`lex-memory`**: High-mass attractors correspond to high-strength memory traces. `simulate_tick` results (captured thoughts) can reinforce corresponding memory traces.
|
|
111
|
+
- **`lex-emotion`**: Attractor domains map to emotional categories (`:fear`, `:desire`). Strong emotional valence from `lex-emotion` can trigger accretion of matching domain attractors.
|
|
112
|
+
- **`lex-cognitive-inertia`**: Entrenched beliefs in `lex-cognitive-inertia` correspond to high-mass attractors in gravity. Both model resistance to change in different metaphors.
|
|
113
|
+
|
|
114
|
+
## Development Notes
|
|
115
|
+
|
|
116
|
+
- `simulate_tick` is an O(attractors × thoughts) operation. With MAX_ATTRACTORS=200 and MAX_ORBITING=500, the worst case is 100,000 comparisons per tick. Keep attractor and thought counts reasonable for performance.
|
|
117
|
+
- Collapsed attractors (`mass < 0.1`) are skipped during tick but remain in the store. Callers should prune collapsed attractors periodically.
|
|
118
|
+
- `add_orbiting_thought` assigns a random orbital distance if none is provided; callers can provide explicit distance for deterministic behavior.
|
|
119
|
+
- In-memory only.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
**Maintained By**: Matthew Iverson (@Esity)
|
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# lex-cognitive-gravity
|
|
2
|
+
|
|
3
|
+
Cognitive attractor dynamics engine for brain-modeled agentic AI in the LegionIO ecosystem.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Models gravitational attraction in thought space. Attractors are dominant cognitive concepts (fears, desires, beliefs, habits, goals) with mass that exerts pull on orbiting thoughts. Each simulation tick evaluates which thoughts fall within an attractor's capture radius (pulled in) and which escape. Attractors gain mass through accretion (reinforcement) and lose mass through erosion (decay). Collapsed attractors (mass below 0.1) can no longer capture thoughts. Supermassive attractors (mass >= 3.0) have extended capture radius.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
require 'legion/extensions/cognitive_gravity'
|
|
13
|
+
|
|
14
|
+
client = Legion::Extensions::CognitiveGravity::Client.new
|
|
15
|
+
|
|
16
|
+
# Create a dominant attractor concept
|
|
17
|
+
result = client.create_attractor(domain: :goal, content: 'build reliable distributed system', mass: 2.0)
|
|
18
|
+
attractor_id = result[:attractor_id]
|
|
19
|
+
|
|
20
|
+
# Add orbiting thoughts
|
|
21
|
+
client.add_thought(content: 'consider retry backoff strategy', domain: :goal, orbital_distance: 0.15)
|
|
22
|
+
client.add_thought(content: 'unrelated distraction', domain: :habit, orbital_distance: 0.8)
|
|
23
|
+
|
|
24
|
+
# Simulate gravitational tick
|
|
25
|
+
client.tick_gravity
|
|
26
|
+
# => { success: true, captures: 1, escapes: 0 }
|
|
27
|
+
|
|
28
|
+
# Strengthen an attractor
|
|
29
|
+
client.accrete(attractor_id: attractor_id)
|
|
30
|
+
# => { success: true, mass: 2.15, label: :heavy }
|
|
31
|
+
|
|
32
|
+
# See strongest attractors
|
|
33
|
+
client.strongest_attractors(limit: 5)
|
|
34
|
+
# => { success: true, attractors: [...] }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Development
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bundle install
|
|
41
|
+
bundle exec rspec
|
|
42
|
+
bundle exec rubocop
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/legion/extensions/cognitive_gravity/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'lex-cognitive-gravity'
|
|
7
|
+
spec.version = Legion::Extensions::CognitiveGravity::VERSION
|
|
8
|
+
spec.authors = ['Esity']
|
|
9
|
+
spec.email = ['matthewdiverson@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'LEX Cognitive Gravity'
|
|
12
|
+
spec.description = 'Attractor basins in thought space — cognitive gravity wells for LegionIO agentic AI'
|
|
13
|
+
spec.homepage = 'https://github.com/LegionIO/lex-cognitive-gravity'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = '>= 3.4'
|
|
16
|
+
|
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-cognitive-gravity'
|
|
19
|
+
spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-cognitive-gravity'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-cognitive-gravity'
|
|
21
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-cognitive-gravity/issues'
|
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
23
|
+
|
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?('spec/') }
|
|
25
|
+
spec.require_paths = ['lib']
|
|
26
|
+
spec.add_development_dependency 'legion-gaia'
|
|
27
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/cognitive_gravity/helpers/constants'
|
|
4
|
+
require 'legion/extensions/cognitive_gravity/helpers/attractor'
|
|
5
|
+
require 'legion/extensions/cognitive_gravity/helpers/orbiting_thought'
|
|
6
|
+
require 'legion/extensions/cognitive_gravity/helpers/gravity_engine'
|
|
7
|
+
require 'legion/extensions/cognitive_gravity/runners/gravity'
|
|
8
|
+
|
|
9
|
+
module Legion
|
|
10
|
+
module Extensions
|
|
11
|
+
module CognitiveGravity
|
|
12
|
+
class Client
|
|
13
|
+
include Runners::Gravity
|
|
14
|
+
|
|
15
|
+
def initialize(**)
|
|
16
|
+
@gravity_engine = Helpers::GravityEngine.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
attr_reader :gravity_engine
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module CognitiveGravity
|
|
8
|
+
module Helpers
|
|
9
|
+
class Attractor
|
|
10
|
+
attr_reader :id, :content, :domain, :mass, :pull_radius, :decay_rate, :created_at, :reinforcement_count
|
|
11
|
+
|
|
12
|
+
def initialize(content:, domain: :unknown, mass: Constants::DEFAULT_MASS,
|
|
13
|
+
pull_radius: 1.0, decay_rate: 0.01)
|
|
14
|
+
@id = SecureRandom.uuid
|
|
15
|
+
@content = content
|
|
16
|
+
@domain = domain
|
|
17
|
+
@mass = mass.to_f.round(10)
|
|
18
|
+
@pull_radius = pull_radius.clamp(0.01, Float::INFINITY)
|
|
19
|
+
@decay_rate = decay_rate.clamp(0.0, 1.0)
|
|
20
|
+
@created_at = Time.now.utc
|
|
21
|
+
@reinforcement_count = 0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def accrete!(amount = Constants::MASS_ACCRETION)
|
|
25
|
+
@mass = (@mass + amount.to_f).round(10)
|
|
26
|
+
@reinforcement_count += 1
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def erode!(amount = Constants::MASS_EROSION)
|
|
31
|
+
@mass = [(@mass - amount.to_f).round(10), 0.0].max
|
|
32
|
+
self
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def pull_strength_at(distance:)
|
|
36
|
+
return 0.0 if distance <= 0 || distance > @pull_radius
|
|
37
|
+
|
|
38
|
+
raw = (Constants::PULL_CONSTANT * @mass) / (distance**2)
|
|
39
|
+
raw.clamp(0.0, @mass)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def collapsed?
|
|
43
|
+
@mass < Constants::COLLAPSE_THRESHOLD
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def supermassive?
|
|
47
|
+
@mass >= Constants::SUPERMASSIVE_THRESHOLD
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def mass_label
|
|
51
|
+
Constants.label_for(Constants::MASS_LABELS, @mass)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def to_h
|
|
55
|
+
{
|
|
56
|
+
id: @id,
|
|
57
|
+
content: @content,
|
|
58
|
+
domain: @domain,
|
|
59
|
+
mass: @mass,
|
|
60
|
+
pull_radius: @pull_radius,
|
|
61
|
+
decay_rate: @decay_rate,
|
|
62
|
+
reinforcement_count: @reinforcement_count,
|
|
63
|
+
collapsed: collapsed?,
|
|
64
|
+
supermassive: supermassive?,
|
|
65
|
+
mass_label: mass_label,
|
|
66
|
+
created_at: @created_at
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveGravity
|
|
6
|
+
module Helpers
|
|
7
|
+
module Constants
|
|
8
|
+
MAX_ATTRACTORS = 200
|
|
9
|
+
MAX_ORBITING = 500
|
|
10
|
+
DEFAULT_MASS = 1.0
|
|
11
|
+
MASS_ACCRETION = 0.15
|
|
12
|
+
MASS_EROSION = 0.05
|
|
13
|
+
CAPTURE_RADIUS = 0.2
|
|
14
|
+
ESCAPE_RADIUS = 1.5
|
|
15
|
+
PULL_CONSTANT = 0.1
|
|
16
|
+
COLLAPSE_THRESHOLD = 0.1
|
|
17
|
+
SUPERMASSIVE_THRESHOLD = 3.0
|
|
18
|
+
|
|
19
|
+
ATTRACTOR_DOMAINS = %i[
|
|
20
|
+
problem
|
|
21
|
+
curiosity
|
|
22
|
+
anxiety
|
|
23
|
+
obsession
|
|
24
|
+
interest
|
|
25
|
+
fear
|
|
26
|
+
desire
|
|
27
|
+
unknown
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
30
|
+
MASS_LABELS = {
|
|
31
|
+
(0.0..0.1) => :collapsing,
|
|
32
|
+
(0.1..0.5) => :weak,
|
|
33
|
+
(0.5..1.0) => :nascent,
|
|
34
|
+
(1.0..2.0) => :moderate,
|
|
35
|
+
(2.0..3.0) => :strong,
|
|
36
|
+
(3.0..Float::INFINITY) => :supermassive
|
|
37
|
+
}.freeze
|
|
38
|
+
|
|
39
|
+
DENSITY_LABELS = {
|
|
40
|
+
(0..0) => :empty,
|
|
41
|
+
(1..2) => :sparse,
|
|
42
|
+
(3..5) => :light,
|
|
43
|
+
(6..10) => :moderate,
|
|
44
|
+
(11..20) => :dense,
|
|
45
|
+
(21..Float::INFINITY) => :crowded
|
|
46
|
+
}.freeze
|
|
47
|
+
|
|
48
|
+
ORBIT_LABELS = {
|
|
49
|
+
(0.0..0.2) => :captured,
|
|
50
|
+
(0.2..0.5) => :tight,
|
|
51
|
+
(0.5..1.0) => :stable,
|
|
52
|
+
(1.0..1.5) => :loose,
|
|
53
|
+
(1.5..Float::INFINITY) => :escaped
|
|
54
|
+
}.freeze
|
|
55
|
+
|
|
56
|
+
module_function
|
|
57
|
+
|
|
58
|
+
def label_for(labels_hash, value)
|
|
59
|
+
labels_hash.each do |range, label|
|
|
60
|
+
return label if range.cover?(value)
|
|
61
|
+
end
|
|
62
|
+
:unknown
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def valid_domain?(domain)
|
|
66
|
+
ATTRACTOR_DOMAINS.include?(domain)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveGravity
|
|
6
|
+
module Helpers
|
|
7
|
+
class GravityEngine
|
|
8
|
+
attr_reader :attractors, :orbiting_thoughts, :capture_events, :escape_events
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@attractors = {}
|
|
12
|
+
@orbiting_thoughts = {}
|
|
13
|
+
@capture_events = []
|
|
14
|
+
@escape_events = []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_attractor(content:, domain: :unknown, mass: Constants::DEFAULT_MASS,
|
|
18
|
+
pull_radius: 1.0, decay_rate: 0.01)
|
|
19
|
+
return { error: :capacity_exceeded, max: Constants::MAX_ATTRACTORS } if at_attractor_capacity?
|
|
20
|
+
|
|
21
|
+
attractor = Attractor.new(
|
|
22
|
+
content: content,
|
|
23
|
+
domain: domain,
|
|
24
|
+
mass: mass,
|
|
25
|
+
pull_radius: pull_radius,
|
|
26
|
+
decay_rate: decay_rate
|
|
27
|
+
)
|
|
28
|
+
@attractors[attractor.id] = attractor
|
|
29
|
+
attractor
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def add_orbiting_thought(content:, attractor_id:, orbital_distance: 1.0, velocity: 0.0)
|
|
33
|
+
return { error: :attractor_not_found } unless @attractors.key?(attractor_id)
|
|
34
|
+
return { error: :capacity_exceeded, max: Constants::MAX_ORBITING } if at_orbiting_capacity?
|
|
35
|
+
|
|
36
|
+
thought = OrbitingThought.new(
|
|
37
|
+
content: content,
|
|
38
|
+
attractor_id: attractor_id,
|
|
39
|
+
orbital_distance: orbital_distance,
|
|
40
|
+
velocity: velocity
|
|
41
|
+
)
|
|
42
|
+
@orbiting_thoughts[thought.id] = thought
|
|
43
|
+
thought
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def simulate_tick
|
|
47
|
+
captures = []
|
|
48
|
+
escapes = []
|
|
49
|
+
|
|
50
|
+
@attractors.each_value do |attractor|
|
|
51
|
+
next if attractor.collapsed?
|
|
52
|
+
|
|
53
|
+
thoughts_for(attractor.id).each do |thought|
|
|
54
|
+
pull = attractor.pull_strength_at(distance: thought.orbital_distance)
|
|
55
|
+
next unless pull.positive?
|
|
56
|
+
|
|
57
|
+
was_captured = thought.captured?
|
|
58
|
+
was_escaped = thought.escaped?
|
|
59
|
+
|
|
60
|
+
thought.approach!(pull)
|
|
61
|
+
|
|
62
|
+
if !was_captured && thought.captured?
|
|
63
|
+
event = build_event(:capture, attractor, thought)
|
|
64
|
+
captures << event
|
|
65
|
+
@capture_events << event
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
next unless !was_escaped && thought.escaped?
|
|
69
|
+
|
|
70
|
+
event = build_event(:escape, attractor, thought)
|
|
71
|
+
escapes << event
|
|
72
|
+
@escape_events << event
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
{ captures: captures, escapes: escapes, tick_processed: true }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def accrete_attractor(attractor_id, amount: Constants::MASS_ACCRETION)
|
|
80
|
+
attractor = @attractors[attractor_id]
|
|
81
|
+
return { error: :not_found } unless attractor
|
|
82
|
+
|
|
83
|
+
attractor.accrete!(amount)
|
|
84
|
+
{ accreted: true, id: attractor_id, mass: attractor.mass }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def erode_attractor(attractor_id, amount: Constants::MASS_EROSION)
|
|
88
|
+
attractor = @attractors[attractor_id]
|
|
89
|
+
return { error: :not_found } unless attractor
|
|
90
|
+
|
|
91
|
+
attractor.erode!(amount)
|
|
92
|
+
{ eroded: true, id: attractor_id, mass: attractor.mass, collapsed: attractor.collapsed? }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def strongest_attractors(limit: 5)
|
|
96
|
+
@attractors.values
|
|
97
|
+
.reject(&:collapsed?)
|
|
98
|
+
.sort_by { |a| -a.mass }
|
|
99
|
+
.first(limit)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def thought_distribution
|
|
103
|
+
@attractors.transform_values { |a| thoughts_for(a.id).size }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def cognitive_density_map
|
|
107
|
+
thought_distribution.transform_values do |count|
|
|
108
|
+
Constants.label_for(Constants::DENSITY_LABELS, count)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def gravity_report
|
|
113
|
+
collapsed, active = @attractors.values.partition(&:collapsed?)
|
|
114
|
+
supermass = @attractors.values.select(&:supermassive?)
|
|
115
|
+
captured = @orbiting_thoughts.values.select(&:captured?)
|
|
116
|
+
escaped = @orbiting_thoughts.values.select(&:escaped?)
|
|
117
|
+
|
|
118
|
+
{
|
|
119
|
+
total_attractors: @attractors.size,
|
|
120
|
+
active_attractors: active.size,
|
|
121
|
+
collapsed_attractors: collapsed.size,
|
|
122
|
+
supermassive_count: supermass.size,
|
|
123
|
+
total_orbiting: @orbiting_thoughts.size,
|
|
124
|
+
captured_count: captured.size,
|
|
125
|
+
escaped_count: escaped.size,
|
|
126
|
+
total_captures: @capture_events.size,
|
|
127
|
+
total_escapes: @escape_events.size,
|
|
128
|
+
strongest: strongest_attractors(limit: 3).map(&:to_h)
|
|
129
|
+
}
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
private
|
|
133
|
+
|
|
134
|
+
def thoughts_for(attractor_id)
|
|
135
|
+
@orbiting_thoughts.values.select { |t| t.attractor_id == attractor_id }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def at_attractor_capacity?
|
|
139
|
+
@attractors.size >= Constants::MAX_ATTRACTORS
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def at_orbiting_capacity?
|
|
143
|
+
@orbiting_thoughts.size >= Constants::MAX_ORBITING
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def build_event(type, attractor, thought)
|
|
147
|
+
{
|
|
148
|
+
type: type,
|
|
149
|
+
attractor_id: attractor.id,
|
|
150
|
+
thought_id: thought.id,
|
|
151
|
+
mass: attractor.mass,
|
|
152
|
+
distance: thought.orbital_distance,
|
|
153
|
+
at: Time.now.utc
|
|
154
|
+
}
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module CognitiveGravity
|
|
8
|
+
module Helpers
|
|
9
|
+
class OrbitingThought
|
|
10
|
+
attr_reader :id, :content, :attractor_id, :orbital_distance, :velocity, :created_at
|
|
11
|
+
|
|
12
|
+
def initialize(content:, attractor_id:, orbital_distance: 1.0, velocity: 0.0)
|
|
13
|
+
@id = SecureRandom.uuid
|
|
14
|
+
@content = content
|
|
15
|
+
@attractor_id = attractor_id
|
|
16
|
+
@orbital_distance = orbital_distance.clamp(0.0, Float::INFINITY).round(10)
|
|
17
|
+
@velocity = velocity.to_f.round(10)
|
|
18
|
+
@created_at = Time.now.utc
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def approach!(delta)
|
|
22
|
+
@orbital_distance = [(@orbital_distance - delta.abs).round(10), 0.0].max
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def escape!(delta)
|
|
27
|
+
@orbital_distance = (@orbital_distance + delta.abs).round(10)
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def captured?
|
|
32
|
+
@orbital_distance < Constants::CAPTURE_RADIUS
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def escaped?
|
|
36
|
+
@orbital_distance > Constants::ESCAPE_RADIUS
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def orbit_label
|
|
40
|
+
Constants.label_for(Constants::ORBIT_LABELS, @orbital_distance)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_h
|
|
44
|
+
{
|
|
45
|
+
id: @id,
|
|
46
|
+
content: @content,
|
|
47
|
+
attractor_id: @attractor_id,
|
|
48
|
+
orbital_distance: @orbital_distance,
|
|
49
|
+
velocity: @velocity,
|
|
50
|
+
captured: captured?,
|
|
51
|
+
escaped: escaped?,
|
|
52
|
+
orbit_label: orbit_label,
|
|
53
|
+
created_at: @created_at
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveGravity
|
|
6
|
+
module Runners
|
|
7
|
+
module Gravity
|
|
8
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
|
|
9
|
+
Legion::Extensions::Helpers.const_defined?(:Lex)
|
|
10
|
+
|
|
11
|
+
def create_attractor(content:, domain: :unknown, mass: Helpers::Constants::DEFAULT_MASS,
|
|
12
|
+
pull_radius: 1.0, decay_rate: 0.01, engine: nil, **)
|
|
13
|
+
eng = engine || gravity_engine
|
|
14
|
+
unless Helpers::Constants.valid_domain?(domain)
|
|
15
|
+
return { success: false, error: :invalid_domain,
|
|
16
|
+
valid_domains: Helpers::Constants::ATTRACTOR_DOMAINS }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
result = eng.add_attractor(
|
|
20
|
+
content: content,
|
|
21
|
+
domain: domain,
|
|
22
|
+
mass: mass,
|
|
23
|
+
pull_radius: pull_radius,
|
|
24
|
+
decay_rate: decay_rate
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if result.is_a?(Hash) && result[:error]
|
|
28
|
+
Legion::Logging.warn "[cognitive_gravity] create_attractor failed: #{result[:error]}"
|
|
29
|
+
return { success: false, **result }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Legion::Logging.debug "[cognitive_gravity] attractor created id=#{result.id[0..7]} " \
|
|
33
|
+
"domain=#{domain} mass=#{mass}"
|
|
34
|
+
{ success: true, attractor: result.to_h }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def add_thought(content:, attractor_id:, orbital_distance: 1.0, velocity: 0.0,
|
|
38
|
+
engine: nil, **)
|
|
39
|
+
eng = engine || gravity_engine
|
|
40
|
+
result = eng.add_orbiting_thought(
|
|
41
|
+
content: content,
|
|
42
|
+
attractor_id: attractor_id,
|
|
43
|
+
orbital_distance: orbital_distance,
|
|
44
|
+
velocity: velocity
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if result.is_a?(Hash) && result[:error]
|
|
48
|
+
Legion::Logging.warn "[cognitive_gravity] add_thought failed: #{result[:error]}"
|
|
49
|
+
return { success: false, **result }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Legion::Logging.debug "[cognitive_gravity] thought added id=#{result.id[0..7]} " \
|
|
53
|
+
"attractor=#{attractor_id[0..7]} distance=#{orbital_distance}"
|
|
54
|
+
{ success: true, thought: result.to_h }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def tick_gravity(engine: nil, **)
|
|
58
|
+
eng = engine || gravity_engine
|
|
59
|
+
result = eng.simulate_tick
|
|
60
|
+
Legion::Logging.debug "[cognitive_gravity] tick: captures=#{result[:captures].size} " \
|
|
61
|
+
"escapes=#{result[:escapes].size}"
|
|
62
|
+
{ success: true, **result }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def accrete(attractor_id:, amount: Helpers::Constants::MASS_ACCRETION, engine: nil, **)
|
|
66
|
+
eng = engine || gravity_engine
|
|
67
|
+
result = eng.accrete_attractor(attractor_id, amount: amount)
|
|
68
|
+
|
|
69
|
+
if result[:error]
|
|
70
|
+
Legion::Logging.warn "[cognitive_gravity] accrete failed: #{result[:error]}"
|
|
71
|
+
return { success: false, **result }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
Legion::Logging.debug "[cognitive_gravity] accreted id=#{attractor_id[0..7]} mass=#{result[:mass]}"
|
|
75
|
+
{ success: true, **result }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def erode(attractor_id:, amount: Helpers::Constants::MASS_EROSION, engine: nil, **)
|
|
79
|
+
eng = engine || gravity_engine
|
|
80
|
+
result = eng.erode_attractor(attractor_id, amount: amount)
|
|
81
|
+
|
|
82
|
+
if result[:error]
|
|
83
|
+
Legion::Logging.warn "[cognitive_gravity] erode failed: #{result[:error]}"
|
|
84
|
+
return { success: false, **result }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
Legion::Logging.debug "[cognitive_gravity] eroded id=#{attractor_id[0..7]} " \
|
|
88
|
+
"mass=#{result[:mass]} collapsed=#{result[:collapsed]}"
|
|
89
|
+
{ success: true, **result }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def strongest_attractors(limit: 5, engine: nil, **)
|
|
93
|
+
eng = engine || gravity_engine
|
|
94
|
+
attractors = eng.strongest_attractors(limit: limit)
|
|
95
|
+
Legion::Logging.debug "[cognitive_gravity] strongest_attractors count=#{attractors.size}"
|
|
96
|
+
{ success: true, attractors: attractors.map(&:to_h), count: attractors.size }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def thought_distribution(engine: nil, **)
|
|
100
|
+
eng = engine || gravity_engine
|
|
101
|
+
distribution = eng.thought_distribution
|
|
102
|
+
{ success: true, distribution: distribution }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def cognitive_density_map(engine: nil, **)
|
|
106
|
+
eng = engine || gravity_engine
|
|
107
|
+
density_map = eng.cognitive_density_map
|
|
108
|
+
{ success: true, density_map: density_map }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def gravity_report(engine: nil, **)
|
|
112
|
+
eng = engine || gravity_engine
|
|
113
|
+
report = eng.gravity_report
|
|
114
|
+
Legion::Logging.debug "[cognitive_gravity] report: attractors=#{report[:total_attractors]} " \
|
|
115
|
+
"orbiting=#{report[:total_orbiting]} supermassive=#{report[:supermassive_count]}"
|
|
116
|
+
{ success: true, report: report }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
def gravity_engine
|
|
122
|
+
@gravity_engine ||= Helpers::GravityEngine.new
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/cognitive_gravity/version'
|
|
4
|
+
require 'legion/extensions/cognitive_gravity/helpers/constants'
|
|
5
|
+
require 'legion/extensions/cognitive_gravity/helpers/attractor'
|
|
6
|
+
require 'legion/extensions/cognitive_gravity/helpers/orbiting_thought'
|
|
7
|
+
require 'legion/extensions/cognitive_gravity/helpers/gravity_engine'
|
|
8
|
+
require 'legion/extensions/cognitive_gravity/runners/gravity'
|
|
9
|
+
|
|
10
|
+
module Legion
|
|
11
|
+
module Extensions
|
|
12
|
+
module CognitiveGravity
|
|
13
|
+
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lex-cognitive-gravity
|
|
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: Attractor basins in thought space — cognitive gravity wells for LegionIO
|
|
27
|
+
agentic AI
|
|
28
|
+
email:
|
|
29
|
+
- matthewdiverson@gmail.com
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- ".github/workflows/ci.yml"
|
|
35
|
+
- ".gitignore"
|
|
36
|
+
- ".rspec"
|
|
37
|
+
- ".rubocop.yml"
|
|
38
|
+
- CLAUDE.md
|
|
39
|
+
- Gemfile
|
|
40
|
+
- README.md
|
|
41
|
+
- lex-cognitive-gravity.gemspec
|
|
42
|
+
- lib/legion/extensions/cognitive_gravity.rb
|
|
43
|
+
- lib/legion/extensions/cognitive_gravity/client.rb
|
|
44
|
+
- lib/legion/extensions/cognitive_gravity/helpers/attractor.rb
|
|
45
|
+
- lib/legion/extensions/cognitive_gravity/helpers/constants.rb
|
|
46
|
+
- lib/legion/extensions/cognitive_gravity/helpers/gravity_engine.rb
|
|
47
|
+
- lib/legion/extensions/cognitive_gravity/helpers/orbiting_thought.rb
|
|
48
|
+
- lib/legion/extensions/cognitive_gravity/runners/gravity.rb
|
|
49
|
+
- lib/legion/extensions/cognitive_gravity/version.rb
|
|
50
|
+
homepage: https://github.com/LegionIO/lex-cognitive-gravity
|
|
51
|
+
licenses:
|
|
52
|
+
- MIT
|
|
53
|
+
metadata:
|
|
54
|
+
homepage_uri: https://github.com/LegionIO/lex-cognitive-gravity
|
|
55
|
+
source_code_uri: https://github.com/LegionIO/lex-cognitive-gravity
|
|
56
|
+
documentation_uri: https://github.com/LegionIO/lex-cognitive-gravity
|
|
57
|
+
changelog_uri: https://github.com/LegionIO/lex-cognitive-gravity
|
|
58
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-gravity/issues
|
|
59
|
+
rubygems_mfa_required: 'true'
|
|
60
|
+
rdoc_options: []
|
|
61
|
+
require_paths:
|
|
62
|
+
- lib
|
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '3.4'
|
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '0'
|
|
73
|
+
requirements: []
|
|
74
|
+
rubygems_version: 3.6.9
|
|
75
|
+
specification_version: 4
|
|
76
|
+
summary: LEX Cognitive Gravity
|
|
77
|
+
test_files: []
|