self_agency 0.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 (78) hide show
  1. checksums.yaml +7 -0
  2. data/.envrc +1 -0
  3. data/.github/workflows/deploy-github-pages.yml +40 -0
  4. data/.irbrc +22 -0
  5. data/CHANGELOG.md +5 -0
  6. data/COMMITS.md +196 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +177 -0
  9. data/Rakefile +8 -0
  10. data/docs/api/configuration.md +85 -0
  11. data/docs/api/errors.md +166 -0
  12. data/docs/api/index.md +37 -0
  13. data/docs/api/self-agency-module.md +198 -0
  14. data/docs/architecture/overview.md +181 -0
  15. data/docs/architecture/security.md +101 -0
  16. data/docs/assets/images/self_agency.gif +0 -0
  17. data/docs/assets/images/self_agency.mp4 +0 -0
  18. data/docs/development/contributing.md +45 -0
  19. data/docs/development/setup.md +81 -0
  20. data/docs/development/testing.md +70 -0
  21. data/docs/examples/autonomous-robots.md +109 -0
  22. data/docs/examples/basic-examples.md +237 -0
  23. data/docs/examples/collaborative-robots.md +98 -0
  24. data/docs/examples/full-workflow.md +100 -0
  25. data/docs/examples/index.md +36 -0
  26. data/docs/getting-started/installation.md +71 -0
  27. data/docs/getting-started/quick-start.md +94 -0
  28. data/docs/guide/configuration.md +113 -0
  29. data/docs/guide/generating-methods.md +146 -0
  30. data/docs/guide/how-to-use.md +144 -0
  31. data/docs/guide/lifecycle-hooks.md +86 -0
  32. data/docs/guide/prompt-templates.md +189 -0
  33. data/docs/guide/saving-methods.md +84 -0
  34. data/docs/guide/scopes.md +74 -0
  35. data/docs/guide/source-inspection.md +96 -0
  36. data/docs/index.md +77 -0
  37. data/examples/01_basic_usage.rb +27 -0
  38. data/examples/02_multiple_methods.rb +43 -0
  39. data/examples/03_scopes.rb +40 -0
  40. data/examples/04_source_inspection.rb +46 -0
  41. data/examples/05_lifecycle_hook.rb +55 -0
  42. data/examples/06_configuration.rb +97 -0
  43. data/examples/07_error_handling.rb +103 -0
  44. data/examples/08_class_context.rb +64 -0
  45. data/examples/09_method_override.rb +52 -0
  46. data/examples/10_full_workflow.rb +118 -0
  47. data/examples/11_collaborative_robots/atlas.rb +31 -0
  48. data/examples/11_collaborative_robots/echo.rb +30 -0
  49. data/examples/11_collaborative_robots/main.rb +190 -0
  50. data/examples/11_collaborative_robots/nova.rb +71 -0
  51. data/examples/11_collaborative_robots/robot.rb +119 -0
  52. data/examples/12_autonomous_robots/analyst.rb +193 -0
  53. data/examples/12_autonomous_robots/collector.rb +78 -0
  54. data/examples/12_autonomous_robots/main.rb +166 -0
  55. data/examples/12_autonomous_robots/planner.rb +125 -0
  56. data/examples/12_autonomous_robots/robot.rb +284 -0
  57. data/examples/generated/from_range_class.rb +3 -0
  58. data/examples/generated/mean_instance.rb +4 -0
  59. data/examples/generated/median_instance.rb +15 -0
  60. data/examples/generated/report_singleton.rb +3 -0
  61. data/examples/generated/standard_deviation_instance.rb +8 -0
  62. data/examples/lib/message_bus.rb +57 -0
  63. data/examples/lib/setup.rb +8 -0
  64. data/lib/self_agency/configuration.rb +76 -0
  65. data/lib/self_agency/errors.rb +35 -0
  66. data/lib/self_agency/generator.rb +47 -0
  67. data/lib/self_agency/prompts/generate/system.txt.erb +15 -0
  68. data/lib/self_agency/prompts/generate/user.txt.erb +13 -0
  69. data/lib/self_agency/prompts/shape/system.txt.erb +26 -0
  70. data/lib/self_agency/prompts/shape/user.txt.erb +10 -0
  71. data/lib/self_agency/sandbox.rb +17 -0
  72. data/lib/self_agency/saver.rb +62 -0
  73. data/lib/self_agency/validator.rb +64 -0
  74. data/lib/self_agency/version.rb +5 -0
  75. data/lib/self_agency.rb +315 -0
  76. data/mkdocs.yml +156 -0
  77. data/sig/self_agency.rbs +4 -0
  78. metadata +163 -0
@@ -0,0 +1,315 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "method_source"
4
+ require_relative "self_agency/version"
5
+ require_relative "self_agency/errors"
6
+ require_relative "self_agency/configuration"
7
+ require_relative "self_agency/sandbox"
8
+ require_relative "self_agency/validator"
9
+ require_relative "self_agency/generator"
10
+ require_relative "self_agency/saver"
11
+
12
+ # SelfAgency — a standalone mixin that gives any class the ability to
13
+ # generate and install methods at runtime via an LLM.
14
+ #
15
+ # Usage:
16
+ # SelfAgency.configure do |config|
17
+ # config.provider = :ollama
18
+ # config.model = "qwen3-coder:30b"
19
+ # config.api_base = "http://localhost:11434/v1"
20
+ # end
21
+ #
22
+ # class Foo
23
+ # include SelfAgency
24
+ # end
25
+ #
26
+ # foo = Foo.new
27
+ # method_name = foo._("an instance method to add two integers, return the result")
28
+ # foo.send(method_name, 1, 1) #=> 2
29
+ #
30
+ module SelfAgency
31
+ # ---------------------------------------------------------------------------
32
+ # Class-level API — added to including classes via self.included
33
+ # ---------------------------------------------------------------------------
34
+
35
+ module ClassMethods
36
+ # Return the generated source code for +method_name+, or nil if unavailable.
37
+ # Checks LLM-generated source first, then falls back to method_source.
38
+ # LLM-generated methods include the original description as a comment header.
39
+ def _source_for(method_name)
40
+ name = method_name.to_sym
41
+ if (code = self_agency_class_sources[name])
42
+ self_agency_comment_header(self_agency_class_descriptions[name]) + code
43
+ else
44
+ self_agency_file_source(instance_method(name))
45
+ end
46
+ rescue NameError, MethodSource::SourceNotFoundError
47
+ nil
48
+ end
49
+
50
+ # Return the version history for +method_name+, or an empty array.
51
+ # Each entry is a Hash with keys :code, :description, :instance_id, :at.
52
+ def _source_versions_for(method_name)
53
+ self_agency_class_source_versions[method_name.to_sym] || []
54
+ end
55
+
56
+ def self_agency_class_sources
57
+ @self_agency_class_sources ||= {}
58
+ end
59
+
60
+ def self_agency_class_descriptions
61
+ @self_agency_class_descriptions ||= {}
62
+ end
63
+
64
+ def self_agency_class_source_versions
65
+ @self_agency_class_source_versions ||= {}
66
+ end
67
+
68
+ # Return the per-class mutex used to serialize the _() pipeline.
69
+ def self_agency_mutex
70
+ @self_agency_mutex
71
+ end
72
+
73
+ # Return the cached sandbox module for the given scope, creating and
74
+ # prepending it on first access. Reusing a single module per scope
75
+ # prevents anonymous-module accumulation in the ancestor chain.
76
+ def self_agency_sandbox_module(scope)
77
+ case scope
78
+ when :instance
79
+ @self_agency_instance_sandbox ||= begin
80
+ mod = Module.new { include SelfAgency::Sandbox }
81
+ prepend(mod)
82
+ mod
83
+ end
84
+ when :class
85
+ @self_agency_class_sandbox ||= begin
86
+ mod = Module.new { include SelfAgency::Sandbox }
87
+ singleton_class.prepend(mod)
88
+ mod
89
+ end
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def self_agency_comment_header(description)
96
+ return "" unless description
97
+ description.lines.map { |line| "# #{line.chomp}\n" }.join
98
+ end
99
+
100
+ def self_agency_file_source(meth)
101
+ comment = meth.comment.to_s
102
+ source = meth.source
103
+ comment.empty? ? source : comment + source
104
+ end
105
+ end
106
+
107
+ # ---------------------------------------------------------------------------
108
+ # Public instance API
109
+ # ---------------------------------------------------------------------------
110
+
111
+ # Generate and install a method described by +description+.
112
+ #
113
+ # @param description [String] natural-language description of the method
114
+ # @param scope [Symbol] :instance, :singleton, or :class
115
+ # @return [Array<Symbol>] the names of the newly defined methods
116
+ # @raise [GenerationError] if the LLM returns nil
117
+ # @raise [ValidationError] if the generated code fails validation
118
+ # @raise [SecurityError] if the generated code contains dangerous patterns
119
+ def _(description, scope: :instance)
120
+ self.class.self_agency_mutex.synchronize do
121
+ SelfAgency.ensure_configured!
122
+
123
+ self_agency_log(:shape, "Shaping prompt for #{self.class.name} (#{scope})")
124
+ shaped = self_agency_shape(description, scope)
125
+ unless shaped
126
+ raise GenerationError.new("Prompt shaping failed (LLM returned nil)", stage: :shape)
127
+ end
128
+ self_agency_log(:shape, "Shaped spec received")
129
+
130
+ max_attempts = SelfAgency.configuration.generation_retries
131
+ last_error = nil
132
+ gen_vars = self_agency_generation_vars.merge(shaped_spec: shaped, previous_error: nil, previous_code: nil)
133
+ code = nil
134
+
135
+ max_attempts.times.each do |attempt|
136
+ self_agency_log(:generate, "Generation attempt #{attempt + 1}/#{max_attempts}")
137
+ raw = self_agency_ask_with_template(:generate, **gen_vars)
138
+ unless raw
139
+ raise GenerationError.new(
140
+ "Code generation failed (LLM returned nil)",
141
+ stage: :generate, attempt: attempt + 1
142
+ )
143
+ end
144
+ self_agency_log(:generate, "Raw code received")
145
+
146
+ code = self_agency_sanitize(raw)
147
+ begin
148
+ self_agency_validate!(code)
149
+ self_agency_log(:validate, "Validation passed")
150
+ last_error = nil
151
+ break
152
+ rescue ValidationError => e
153
+ self_agency_log(:validate, "Validation failed: #{e.message}")
154
+ last_error = ValidationError.new(e.message, generated_code: e.generated_code, attempt: attempt + 1)
155
+ gen_vars = gen_vars.merge(previous_error: e.message, previous_code: code)
156
+ self_agency_log(:retry, "Retrying due to: #{e.message}") if attempt + 1 < max_attempts
157
+ rescue SecurityError => e
158
+ self_agency_log(:validate, "Security check failed: #{e.message}")
159
+ last_error = SecurityError.new(e.message, matched_pattern: e.matched_pattern, generated_code: e.generated_code)
160
+ gen_vars = gen_vars.merge(previous_error: e.message, previous_code: code)
161
+ self_agency_log(:retry, "Retrying due to: #{e.message}") if attempt + 1 < max_attempts
162
+ end
163
+ end
164
+
165
+ raise last_error if last_error
166
+
167
+ self_agency_eval(code, scope)
168
+
169
+ method_blocks = self_agency_split_methods(code)
170
+ method_names = method_blocks.map do |name, block|
171
+ self_agency_sources[name] = block
172
+ self_agency_descriptions[name] = description
173
+ self.class.self_agency_class_sources[name] = block
174
+ self.class.self_agency_class_descriptions[name] = description
175
+ (self.class.self_agency_class_source_versions[name] ||= []) << {
176
+ code: block,
177
+ description: description,
178
+ instance_id: object_id,
179
+ at: Time.now
180
+ }
181
+ on_method_generated(name, scope, block)
182
+ name
183
+ end
184
+
185
+ self_agency_log(:complete, "Installed #{method_names.size} method(s): #{method_names.join(', ')}")
186
+ method_names
187
+ end
188
+ end
189
+
190
+ alias_method :self_agency_generate, :_
191
+
192
+ # Return the generated source code for +method_name+, or nil if unavailable.
193
+ # Checks LLM-generated source first, then falls back to method_source.
194
+ # LLM-generated methods include the original description as a comment header.
195
+ def _source_for(method_name)
196
+ name = method_name.to_sym
197
+ if (code = self_agency_sources[name])
198
+ self_agency_comment_header(self_agency_descriptions[name]) + code
199
+ else
200
+ self_agency_file_source(method(name))
201
+ end
202
+ rescue NameError, MethodSource::SourceNotFoundError
203
+ nil
204
+ end
205
+
206
+ # Save the object's generated methods as a subclass in a Ruby source file.
207
+ #
208
+ # @param as [String, Symbol] the subclass name (snake_case is converted to CamelCase)
209
+ # @param path [String, nil] output file path (defaults to snake_cased name + .rb)
210
+ # @return [String] the path written to
211
+ # @raise [ArgumentError] if as: is not a String or Symbol
212
+ # @raise [Error] if there are no generated methods to save
213
+ def _save!(as:, path: nil)
214
+ raise ArgumentError, "as: must be a String or Symbol" unless as.is_a?(String) || as.is_a?(Symbol)
215
+ raise Error, "no generated methods to save" if self_agency_sources.empty?
216
+
217
+ class_name = self_agency_to_class_name(as)
218
+ file_path = path || "#{self_agency_to_snake_case(class_name)}.rb"
219
+ parent_name = self.class.name
220
+ raise Error, "cannot save anonymous class" unless parent_name
221
+
222
+ parent_source = Object.const_source_location(parent_name)&.first
223
+
224
+ require_path = if parent_source
225
+ self_agency_relative_require(file_path, parent_source)
226
+ end
227
+
228
+ source = self_agency_build_subclass_source(
229
+ class_name, parent_name, require_path,
230
+ self_agency_sources, self_agency_descriptions
231
+ )
232
+
233
+ File.write(file_path, source)
234
+ file_path
235
+ end
236
+
237
+ # Override in your class to persist or log generated methods.
238
+ def on_method_generated(method_name, scope, code)
239
+ # no-op by default
240
+ end
241
+
242
+ # ---------------------------------------------------------------------------
243
+ # Private helpers
244
+ # ---------------------------------------------------------------------------
245
+ private
246
+
247
+ def self_agency_comment_header(description)
248
+ return "" unless description
249
+ description.lines.map { |line| "# #{line.chomp}\n" }.join
250
+ end
251
+
252
+ def self_agency_file_source(meth)
253
+ comment = meth.comment.to_s
254
+ source = meth.source
255
+ comment.empty? ? source : comment + source
256
+ end
257
+
258
+ # Lazily initialized Hash storing generated source code keyed by method name.
259
+ def self_agency_sources
260
+ @self_agency_sources ||= {}
261
+ end
262
+
263
+ def self_agency_descriptions
264
+ @self_agency_descriptions ||= {}
265
+ end
266
+
267
+ # Split code containing one or more method definitions into
268
+ # an Array of [method_name_symbol, method_source_string] pairs.
269
+ def self_agency_split_methods(code)
270
+ blocks = code.scan(/^(def\s+(?:self\.)?\w+[?!=]?.*?^end)/m)
271
+ blocks.map do |match|
272
+ block = match[0]
273
+ name = block.match(/\bdef\s+(self\.)?(\w+[?!=]?)/)[2].to_sym
274
+ [name, block]
275
+ end
276
+ end
277
+
278
+ # Evaluate the code inside the cached sandboxed module for this scope.
279
+ # Reuses a single module per scope to avoid MRO accumulation.
280
+ def self_agency_eval(code, scope)
281
+ case scope
282
+ when :instance
283
+ self.class.self_agency_sandbox_module(:instance).module_eval(code)
284
+ when :singleton
285
+ self_agency_singleton_sandbox_module.module_eval(code)
286
+ when :class
287
+ class_code = code.sub(/\bdef\s+self\./, "def ")
288
+ self.class.self_agency_sandbox_module(:class).module_eval(class_code)
289
+ else
290
+ raise ValidationError, "unknown scope: #{scope.inspect}"
291
+ end
292
+ end
293
+
294
+ # Log a pipeline event via the configured logger.
295
+ # Accepts a callable (receives stage, message) or a Logger-compatible object.
296
+ def self_agency_log(stage, message)
297
+ logger = SelfAgency.configuration.logger
298
+ return unless logger
299
+
300
+ if logger.respond_to?(:call)
301
+ logger.call(stage, message)
302
+ elsif logger.respond_to?(:debug)
303
+ logger.debug("[SelfAgency:#{stage}] #{message}")
304
+ end
305
+ end
306
+
307
+ # Return the cached singleton-scope sandbox module for this instance.
308
+ def self_agency_singleton_sandbox_module
309
+ @self_agency_singleton_sandbox ||= begin
310
+ mod = Module.new { include SelfAgency::Sandbox }
311
+ singleton_class.prepend(mod)
312
+ mod
313
+ end
314
+ end
315
+ end
data/mkdocs.yml ADDED
@@ -0,0 +1,156 @@
1
+ # MkDocs Configuration for SelfAgency Documentation
2
+ site_name: SelfAgency
3
+ site_description: LLM-powered runtime method generation for Ruby classes
4
+ site_author: Dewayne VanHoozer
5
+ site_url: https://madbomber.github.io/self_agency
6
+ copyright: Copyright &copy; 2025 Dewayne VanHoozer
7
+
8
+ # Repository information
9
+ repo_name: madbomber/self_agency
10
+ repo_url: https://github.com/madbomber/self_agency
11
+ edit_uri: edit/main/docs/
12
+
13
+ # Configuration
14
+ theme:
15
+ name: material
16
+
17
+ palette:
18
+ - scheme: default
19
+ primary: deep purple
20
+ accent: amber
21
+ toggle:
22
+ icon: material/brightness-7
23
+ name: Switch to dark mode
24
+
25
+ - scheme: slate
26
+ primary: deep purple
27
+ accent: amber
28
+ toggle:
29
+ icon: material/brightness-4
30
+ name: Switch to light mode
31
+
32
+ font:
33
+ text: Roboto
34
+ code: Roboto Mono
35
+
36
+ icon:
37
+ repo: fontawesome/brands/github
38
+
39
+ features:
40
+ - navigation.instant
41
+ - navigation.tracking
42
+ - navigation.tabs
43
+ - navigation.tabs.sticky
44
+ - navigation.path
45
+ - navigation.indexes
46
+ - navigation.top
47
+ - navigation.footer
48
+ - toc.follow
49
+ - search.suggest
50
+ - search.highlight
51
+ - search.share
52
+ - header.autohide
53
+ - content.code.copy
54
+ - content.code.annotate
55
+ - content.tabs.link
56
+ - content.tooltips
57
+ - content.action.edit
58
+ - content.action.view
59
+
60
+ # Plugins
61
+ plugins:
62
+ - search:
63
+ separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
64
+ - tags
65
+
66
+ # Extensions
67
+ markdown_extensions:
68
+ - abbr
69
+ - admonition
70
+ - attr_list
71
+ - def_list
72
+ - footnotes
73
+ - md_in_html
74
+ - tables
75
+ - toc:
76
+ permalink: true
77
+ title: On this page
78
+
79
+ - pymdownx.betterem:
80
+ smart_enable: all
81
+ - pymdownx.caret
82
+ - pymdownx.critic
83
+ - pymdownx.details
84
+ - pymdownx.emoji:
85
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
86
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
87
+ - pymdownx.highlight:
88
+ anchor_linenums: true
89
+ line_spans: __span
90
+ pygments_lang_class: true
91
+ - pymdownx.inlinehilite
92
+ - pymdownx.keys
93
+ - pymdownx.magiclink:
94
+ repo_url_shorthand: true
95
+ user: madbomber
96
+ repo: self_agency
97
+ normalize_issue_symbols: true
98
+ - pymdownx.mark
99
+ - pymdownx.smartsymbols
100
+ - pymdownx.snippets:
101
+ check_paths: true
102
+ - pymdownx.superfences:
103
+ custom_fences:
104
+ - name: mermaid
105
+ class: mermaid
106
+ format: !!python/name:pymdownx.superfences.fence_code_format
107
+ - pymdownx.tabbed:
108
+ alternate_style: true
109
+ - pymdownx.tasklist:
110
+ custom_checkbox: true
111
+ - pymdownx.tilde
112
+
113
+ # Social media and extra configuration
114
+ extra:
115
+ social:
116
+ - icon: fontawesome/brands/github
117
+ link: https://github.com/madbomber/self_agency
118
+ name: SelfAgency on GitHub
119
+ - icon: fontawesome/solid/gem
120
+ link: https://rubygems.org/gems/self_agency
121
+ name: SelfAgency on RubyGems
122
+
123
+ # Navigation
124
+ nav:
125
+ - Home:
126
+ - Overview: index.md
127
+ - Getting Started:
128
+ - Installation: getting-started/installation.md
129
+ - Quick Start: getting-started/quick-start.md
130
+ - Guide:
131
+ - How to Use: guide/how-to-use.md
132
+ - Generating Methods: guide/generating-methods.md
133
+ - Scopes: guide/scopes.md
134
+ - Source Inspection: guide/source-inspection.md
135
+ - Saving Methods: guide/saving-methods.md
136
+ - Lifecycle Hooks: guide/lifecycle-hooks.md
137
+ - Configuration: guide/configuration.md
138
+ - Prompt Templates: guide/prompt-templates.md
139
+ - Architecture:
140
+ - Overview: architecture/overview.md
141
+ - Security: architecture/security.md
142
+ - API Reference:
143
+ - api/index.md
144
+ - SelfAgency Module: api/self-agency-module.md
145
+ - Configuration: api/configuration.md
146
+ - Errors: api/errors.md
147
+ - Examples:
148
+ - examples/index.md
149
+ - "Basic (01\u201309)": examples/basic-examples.md
150
+ - "Full Workflow (10)": examples/full-workflow.md
151
+ - "Collaborative Robots (11)": examples/collaborative-robots.md
152
+ - "Autonomous Robots (12)": examples/autonomous-robots.md
153
+ - Development:
154
+ - Setup: development/setup.md
155
+ - Testing: development/testing.md
156
+ - Contributing: development/contributing.md
@@ -0,0 +1,4 @@
1
+ module SelfAgency
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: self_agency
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dewayne VanHoozer
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: method_source
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: ruby_llm
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: ruby_llm-template
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ description: A mixin that gives any Ruby class the ability to generate and install
55
+ methods at runtime via an LLM. Describe what you want in plain English and get a
56
+ working method back.
57
+ email:
58
+ - dewayne@vanhoozer.me
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".envrc"
64
+ - ".github/workflows/deploy-github-pages.yml"
65
+ - ".irbrc"
66
+ - CHANGELOG.md
67
+ - COMMITS.md
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - docs/api/configuration.md
72
+ - docs/api/errors.md
73
+ - docs/api/index.md
74
+ - docs/api/self-agency-module.md
75
+ - docs/architecture/overview.md
76
+ - docs/architecture/security.md
77
+ - docs/assets/images/self_agency.gif
78
+ - docs/assets/images/self_agency.mp4
79
+ - docs/development/contributing.md
80
+ - docs/development/setup.md
81
+ - docs/development/testing.md
82
+ - docs/examples/autonomous-robots.md
83
+ - docs/examples/basic-examples.md
84
+ - docs/examples/collaborative-robots.md
85
+ - docs/examples/full-workflow.md
86
+ - docs/examples/index.md
87
+ - docs/getting-started/installation.md
88
+ - docs/getting-started/quick-start.md
89
+ - docs/guide/configuration.md
90
+ - docs/guide/generating-methods.md
91
+ - docs/guide/how-to-use.md
92
+ - docs/guide/lifecycle-hooks.md
93
+ - docs/guide/prompt-templates.md
94
+ - docs/guide/saving-methods.md
95
+ - docs/guide/scopes.md
96
+ - docs/guide/source-inspection.md
97
+ - docs/index.md
98
+ - examples/01_basic_usage.rb
99
+ - examples/02_multiple_methods.rb
100
+ - examples/03_scopes.rb
101
+ - examples/04_source_inspection.rb
102
+ - examples/05_lifecycle_hook.rb
103
+ - examples/06_configuration.rb
104
+ - examples/07_error_handling.rb
105
+ - examples/08_class_context.rb
106
+ - examples/09_method_override.rb
107
+ - examples/10_full_workflow.rb
108
+ - examples/11_collaborative_robots/atlas.rb
109
+ - examples/11_collaborative_robots/echo.rb
110
+ - examples/11_collaborative_robots/main.rb
111
+ - examples/11_collaborative_robots/nova.rb
112
+ - examples/11_collaborative_robots/robot.rb
113
+ - examples/12_autonomous_robots/analyst.rb
114
+ - examples/12_autonomous_robots/collector.rb
115
+ - examples/12_autonomous_robots/main.rb
116
+ - examples/12_autonomous_robots/planner.rb
117
+ - examples/12_autonomous_robots/robot.rb
118
+ - examples/generated/from_range_class.rb
119
+ - examples/generated/mean_instance.rb
120
+ - examples/generated/median_instance.rb
121
+ - examples/generated/report_singleton.rb
122
+ - examples/generated/standard_deviation_instance.rb
123
+ - examples/lib/message_bus.rb
124
+ - examples/lib/setup.rb
125
+ - lib/self_agency.rb
126
+ - lib/self_agency/configuration.rb
127
+ - lib/self_agency/errors.rb
128
+ - lib/self_agency/generator.rb
129
+ - lib/self_agency/prompts/generate/system.txt.erb
130
+ - lib/self_agency/prompts/generate/user.txt.erb
131
+ - lib/self_agency/prompts/shape/system.txt.erb
132
+ - lib/self_agency/prompts/shape/user.txt.erb
133
+ - lib/self_agency/sandbox.rb
134
+ - lib/self_agency/saver.rb
135
+ - lib/self_agency/validator.rb
136
+ - lib/self_agency/version.rb
137
+ - mkdocs.yml
138
+ - sig/self_agency.rbs
139
+ homepage: https://github.com/madbomber/self_agency
140
+ licenses:
141
+ - MIT
142
+ metadata:
143
+ homepage_uri: https://github.com/madbomber/self_agency
144
+ source_code_uri: https://github.com/madbomber/self_agency
145
+ changelog_uri: https://github.com/madbomber/self_agency/blob/main/CHANGELOG.md
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: 3.2.0
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubygems_version: 4.0.5
161
+ specification_version: 4
162
+ summary: LLM-powered runtime method generation for Ruby classes
163
+ test_files: []