chaos_to_the_rescue 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/.claude/CLAUDE.md +3 -0
- data/.claude/memory.sqlite3 +0 -0
- data/.claude/rules/claude_memory.generated.md +8 -0
- data/.claude/settings.local.json +9 -0
- data/.devcontainer/.env.example +12 -0
- data/.devcontainer/Dockerfile.standalone +30 -0
- data/.devcontainer/README.md +207 -0
- data/.devcontainer/devcontainer.json +54 -0
- data/.devcontainer/docker-compose.yml +32 -0
- data/CHANGELOG.md +18 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/FEATURES.md +306 -0
- data/LICENSE.txt +21 -0
- data/README.md +502 -0
- data/Rakefile +10 -0
- data/examples/guidance_and_verification.rb +226 -0
- data/lib/chaos_to_the_rescue/chaos_rescue.rb +336 -0
- data/lib/chaos_to_the_rescue/configuration.rb +157 -0
- data/lib/chaos_to_the_rescue/llm_client.rb +182 -0
- data/lib/chaos_to_the_rescue/logger.rb +82 -0
- data/lib/chaos_to_the_rescue/railtie.rb +24 -0
- data/lib/chaos_to_the_rescue/redactor.rb +76 -0
- data/lib/chaos_to_the_rescue/rescue_from.rb +156 -0
- data/lib/chaos_to_the_rescue/verifier.rb +277 -0
- data/lib/chaos_to_the_rescue/version.rb +5 -0
- data/lib/chaos_to_the_rescue.rb +57 -0
- data/lib/generators/chaos_to_the_rescue/install_generator.rb +37 -0
- data/lib/generators/chaos_to_the_rescue/templates/chaos_to_the_rescue.rb +97 -0
- data/sig/chaos_to_the_rescue.rbs +4 -0
- metadata +89 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChaosToTheRescue
|
|
4
|
+
# Verifies that method outputs match expected behavior using LLM analysis
|
|
5
|
+
class Verifier
|
|
6
|
+
# Result of a verification check
|
|
7
|
+
VerificationResult = Struct.new(:success, :diagnosis, :suggestion, :fixed_code, :actual_result, keyword_init: true) do
|
|
8
|
+
def passed?
|
|
9
|
+
success
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def failed?
|
|
13
|
+
!success
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@llm_client = LLMClient.new
|
|
19
|
+
@redactor = Redactor.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Verify a method call's output
|
|
23
|
+
# @param object [Object] the object to call the method on
|
|
24
|
+
# @param method_name [Symbol] the method to call
|
|
25
|
+
# @param args [Array] arguments to pass
|
|
26
|
+
# @param kwargs [Hash] keyword arguments to pass
|
|
27
|
+
# @param expected [Object] optional expected result (if known)
|
|
28
|
+
# @param auto_apply [Boolean] whether to automatically apply fixes
|
|
29
|
+
# @return [VerificationResult]
|
|
30
|
+
def verify(object:, method_name:, args: [], kwargs: {}, expected: nil, auto_apply: false)
|
|
31
|
+
ChaosToTheRescue.logger.info("🔍 Verifying #{object.class.name}##{method_name}")
|
|
32
|
+
|
|
33
|
+
# Call the method and capture the result
|
|
34
|
+
actual_result = if kwargs.empty?
|
|
35
|
+
object.send(method_name, *args)
|
|
36
|
+
else
|
|
37
|
+
object.send(method_name, *args, **kwargs)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Get any stored guidance for this method
|
|
41
|
+
guidance = get_method_guidance(object.class, method_name)
|
|
42
|
+
|
|
43
|
+
# Get the method source if possible
|
|
44
|
+
method_source = extract_method_source(object.class, method_name)
|
|
45
|
+
|
|
46
|
+
# Ask LLM to verify the result
|
|
47
|
+
verification = verify_with_llm(
|
|
48
|
+
class_name: object.class.name,
|
|
49
|
+
method_name: method_name,
|
|
50
|
+
args: args,
|
|
51
|
+
kwargs: kwargs,
|
|
52
|
+
actual_result: actual_result,
|
|
53
|
+
expected_result: expected,
|
|
54
|
+
guidance: guidance,
|
|
55
|
+
method_source: method_source
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if verification[:success]
|
|
59
|
+
ChaosToTheRescue.logger.info("✅ Verification passed for #{object.class.name}##{method_name}")
|
|
60
|
+
VerificationResult.new(
|
|
61
|
+
success: true,
|
|
62
|
+
diagnosis: verification[:diagnosis],
|
|
63
|
+
actual_result: actual_result
|
|
64
|
+
)
|
|
65
|
+
else
|
|
66
|
+
ChaosToTheRescue.logger.warn("❌ Verification failed for #{object.class.name}##{method_name}")
|
|
67
|
+
ChaosToTheRescue.logger.warn("Diagnosis: #{verification[:diagnosis]}")
|
|
68
|
+
|
|
69
|
+
result = VerificationResult.new(
|
|
70
|
+
success: false,
|
|
71
|
+
diagnosis: verification[:diagnosis],
|
|
72
|
+
suggestion: verification[:suggestion],
|
|
73
|
+
fixed_code: verification[:fixed_code],
|
|
74
|
+
actual_result: actual_result
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Auto-apply fix if requested
|
|
78
|
+
if auto_apply && verification[:fixed_code]
|
|
79
|
+
apply_fix(object.class, method_name, verification[:fixed_code])
|
|
80
|
+
ChaosToTheRescue.logger.info("🔧 Auto-applied fix for #{object.class.name}##{method_name}")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
result
|
|
84
|
+
end
|
|
85
|
+
rescue => e
|
|
86
|
+
ChaosToTheRescue.logger.error("Failed to verify method: #{e.message}")
|
|
87
|
+
VerificationResult.new(
|
|
88
|
+
success: false,
|
|
89
|
+
diagnosis: "Verification failed: #{e.message}",
|
|
90
|
+
actual_result: actual_result
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Verify a method call using a block
|
|
95
|
+
# @param auto_apply [Boolean] whether to automatically apply fixes
|
|
96
|
+
# @yield the method call to verify
|
|
97
|
+
# @return [VerificationResult]
|
|
98
|
+
def verify_block(auto_apply: false, &block)
|
|
99
|
+
# Use TracePoint to capture the method call
|
|
100
|
+
method_info = capture_method_call(&block)
|
|
101
|
+
|
|
102
|
+
verify(
|
|
103
|
+
object: method_info[:object],
|
|
104
|
+
method_name: method_info[:method_name],
|
|
105
|
+
args: method_info[:args],
|
|
106
|
+
kwargs: method_info[:kwargs],
|
|
107
|
+
auto_apply: auto_apply
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
# Capture method call information using TracePoint
|
|
114
|
+
def capture_method_call(&block)
|
|
115
|
+
captured = nil
|
|
116
|
+
|
|
117
|
+
trace = TracePoint.new(:call) do |tp|
|
|
118
|
+
captured = {
|
|
119
|
+
object: tp.self,
|
|
120
|
+
method_name: tp.method_id,
|
|
121
|
+
args: tp.binding.local_variables.map { |v| tp.binding.local_variable_get(v) }.compact,
|
|
122
|
+
kwargs: {}
|
|
123
|
+
}
|
|
124
|
+
trace.disable
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
trace.enable
|
|
128
|
+
result = block.call
|
|
129
|
+
trace.disable
|
|
130
|
+
|
|
131
|
+
captured[:result] = result
|
|
132
|
+
captured
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Get guidance for a method
|
|
136
|
+
def get_method_guidance(klass, method_name)
|
|
137
|
+
return nil unless klass.respond_to?(:chaos_method_guidance)
|
|
138
|
+
|
|
139
|
+
klass.chaos_method_guidance[method_name]
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Extract method source code
|
|
143
|
+
def extract_method_source(klass, method_name)
|
|
144
|
+
method = klass.instance_method(method_name)
|
|
145
|
+
source_location = method.source_location
|
|
146
|
+
return nil unless source_location
|
|
147
|
+
|
|
148
|
+
file_path, line_number = source_location
|
|
149
|
+
return nil unless File.exist?(file_path)
|
|
150
|
+
|
|
151
|
+
# Read the file and extract the method
|
|
152
|
+
lines = File.readlines(file_path)
|
|
153
|
+
method_lines = extract_method_lines(lines, line_number)
|
|
154
|
+
|
|
155
|
+
method_lines.join
|
|
156
|
+
rescue => e
|
|
157
|
+
ChaosToTheRescue.logger.debug("Could not extract method source: #{e.message}")
|
|
158
|
+
nil
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Extract method lines from source file
|
|
162
|
+
def extract_method_lines(lines, start_line)
|
|
163
|
+
result = []
|
|
164
|
+
indent_level = nil
|
|
165
|
+
in_method = false
|
|
166
|
+
|
|
167
|
+
lines[start_line - 1..].each do |line|
|
|
168
|
+
if line.strip.start_with?("def ")
|
|
169
|
+
in_method = true
|
|
170
|
+
indent_level = line.index("def")
|
|
171
|
+
result << line
|
|
172
|
+
elsif in_method
|
|
173
|
+
current_indent = line.index(/\S/)
|
|
174
|
+
if current_indent && current_indent <= indent_level && line.strip == "end"
|
|
175
|
+
result << line
|
|
176
|
+
break
|
|
177
|
+
else
|
|
178
|
+
result << line
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
result
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Verify with LLM
|
|
187
|
+
def verify_with_llm(class_name:, method_name:, args:, kwargs:, actual_result:, expected_result:, guidance:, method_source:)
|
|
188
|
+
prompt = build_verification_prompt(
|
|
189
|
+
class_name: class_name,
|
|
190
|
+
method_name: method_name,
|
|
191
|
+
args: args,
|
|
192
|
+
kwargs: kwargs,
|
|
193
|
+
actual_result: actual_result,
|
|
194
|
+
expected_result: expected_result,
|
|
195
|
+
guidance: guidance,
|
|
196
|
+
method_source: method_source
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
redacted_prompt = @redactor.redact(prompt)
|
|
200
|
+
response = @llm_client.send(:call_llm, redacted_prompt)
|
|
201
|
+
|
|
202
|
+
parse_verification_response(response)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Build verification prompt
|
|
206
|
+
def build_verification_prompt(class_name:, method_name:, args:, kwargs:, actual_result:, expected_result:, guidance:, method_source:)
|
|
207
|
+
<<~PROMPT
|
|
208
|
+
You are a Ruby code verification assistant. Analyze whether a method's output is correct.
|
|
209
|
+
|
|
210
|
+
Class: #{class_name}
|
|
211
|
+
Method: #{method_name}
|
|
212
|
+
Arguments: #{args.inspect}
|
|
213
|
+
#{"Keyword Arguments: #{kwargs.inspect}" unless kwargs.empty?}
|
|
214
|
+
|
|
215
|
+
Actual Result: #{actual_result.inspect}
|
|
216
|
+
#{"Expected Result: #{expected_result.inspect}" if expected_result}
|
|
217
|
+
|
|
218
|
+
#{guidance ? "Method Guidance:\n#{guidance}\n" : ""}
|
|
219
|
+
|
|
220
|
+
#{method_source ? "Method Source:\n```ruby\n#{method_source}\n```\n" : ""}
|
|
221
|
+
|
|
222
|
+
Based on the method name, arguments, and any provided guidance, determine if the actual result is correct.
|
|
223
|
+
|
|
224
|
+
Please respond in the following format:
|
|
225
|
+
SUCCESS: <true or false>
|
|
226
|
+
DIAGNOSIS: <explanation of whether the result is correct or what went wrong>
|
|
227
|
+
SUGGESTION: <if incorrect, suggest what the correct result should be>
|
|
228
|
+
FIXED_CODE:
|
|
229
|
+
<if incorrect and you have the source, provide fixed Ruby code>
|
|
230
|
+
PROMPT
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Parse verification response
|
|
234
|
+
def parse_verification_response(response)
|
|
235
|
+
lines = response.split("\n")
|
|
236
|
+
|
|
237
|
+
success_line = lines.find { |l| l.start_with?("SUCCESS:") }
|
|
238
|
+
success = success_line&.include?("true") || false
|
|
239
|
+
|
|
240
|
+
diagnosis_line = lines.find { |l| l.start_with?("DIAGNOSIS:") }
|
|
241
|
+
diagnosis = diagnosis_line&.sub("DIAGNOSIS:", "")&.strip || "No diagnosis provided"
|
|
242
|
+
|
|
243
|
+
suggestion_line = lines.find { |l| l.start_with?("SUGGESTION:") }
|
|
244
|
+
suggestion = suggestion_line&.sub("SUGGESTION:", "")&.strip
|
|
245
|
+
|
|
246
|
+
# Extract fixed code if present
|
|
247
|
+
code_start = lines.index { |l| l.strip == "FIXED_CODE:" }
|
|
248
|
+
fixed_code = if code_start
|
|
249
|
+
lines[(code_start + 1)..].join("\n").strip
|
|
250
|
+
else
|
|
251
|
+
nil
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
{
|
|
255
|
+
success: success,
|
|
256
|
+
diagnosis: diagnosis,
|
|
257
|
+
suggestion: suggestion,
|
|
258
|
+
fixed_code: fixed_code
|
|
259
|
+
}
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Apply a fix to a method
|
|
263
|
+
def apply_fix(klass, method_name, fixed_code)
|
|
264
|
+
ChaosToTheRescue.logger.info("🔧 Applying fix to #{klass.name}##{method_name}")
|
|
265
|
+
ChaosToTheRescue.logger.debug("Fixed code:\n#{fixed_code}")
|
|
266
|
+
|
|
267
|
+
begin
|
|
268
|
+
# WARNING: This executes LLM-generated code!
|
|
269
|
+
eval(fixed_code, TOPLEVEL_BINDING)
|
|
270
|
+
ChaosToTheRescue.logger.info("✅ Successfully applied fix to #{klass.name}##{method_name}")
|
|
271
|
+
rescue => e
|
|
272
|
+
ChaosToTheRescue.logger.error("❌ Failed to apply fix: #{e.message}")
|
|
273
|
+
raise
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "chaos_to_the_rescue/version"
|
|
4
|
+
require_relative "chaos_to_the_rescue/configuration"
|
|
5
|
+
require_relative "chaos_to_the_rescue/redactor"
|
|
6
|
+
require_relative "chaos_to_the_rescue/logger"
|
|
7
|
+
require_relative "chaos_to_the_rescue/llm_client"
|
|
8
|
+
require_relative "chaos_to_the_rescue/verifier"
|
|
9
|
+
require_relative "chaos_to_the_rescue/chaos_rescue"
|
|
10
|
+
|
|
11
|
+
# Load Rails integration if Rails is available
|
|
12
|
+
if defined?(Rails)
|
|
13
|
+
require_relative "chaos_to_the_rescue/railtie"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module ChaosToTheRescue
|
|
17
|
+
class Error < StandardError; end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
# Get the global configuration instance
|
|
21
|
+
# @return [Configuration]
|
|
22
|
+
def configuration
|
|
23
|
+
@configuration ||= Configuration.new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Configure the gem with a block
|
|
27
|
+
# @yield [Configuration] the configuration object
|
|
28
|
+
def configure
|
|
29
|
+
configuration.configure do |config|
|
|
30
|
+
yield config
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Reset configuration to defaults
|
|
35
|
+
def reset_configuration!
|
|
36
|
+
@configuration = Configuration.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Get the global logger instance
|
|
40
|
+
# @return [Logger]
|
|
41
|
+
def logger
|
|
42
|
+
@logger ||= ChaosToTheRescue::Logger.instance
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Verify a method call using a block
|
|
46
|
+
# @param auto_apply [Boolean] whether to automatically apply fixes
|
|
47
|
+
# @yield the method call to verify
|
|
48
|
+
# @return [Verifier::VerificationResult]
|
|
49
|
+
# @example
|
|
50
|
+
# result = ChaosToTheRescue.verify { Calculator.new.pow(-5, 2) }
|
|
51
|
+
# puts result.diagnosis if result.failed?
|
|
52
|
+
def verify(auto_apply: false, &block)
|
|
53
|
+
verifier = Verifier.new
|
|
54
|
+
verifier.verify_block(auto_apply: auto_apply, &block)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module ChaosToTheRescue
|
|
6
|
+
module Generators
|
|
7
|
+
# Rails generator for installing ChaosToTheRescue initializer
|
|
8
|
+
class InstallGenerator < Rails::Generators::Base
|
|
9
|
+
source_root File.expand_path("templates", __dir__)
|
|
10
|
+
|
|
11
|
+
desc "Creates a ChaosToTheRescue initializer in config/initializers"
|
|
12
|
+
|
|
13
|
+
def copy_initializer_file
|
|
14
|
+
copy_file "chaos_to_the_rescue.rb", "config/initializers/chaos_to_the_rescue.rb"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def show_readme
|
|
18
|
+
readme "INSTALL_README" if behavior == :invoke
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def readme(filename)
|
|
24
|
+
say "\n" + "=" * 80
|
|
25
|
+
say "ChaosToTheRescue has been installed!"
|
|
26
|
+
say "=" * 80
|
|
27
|
+
say "\nConfiguration file created at: config/initializers/chaos_to_the_rescue.rb"
|
|
28
|
+
say "\nIMPORTANT: ChaosToTheRescue is DISABLED by default for safety."
|
|
29
|
+
say "Edit the initializer to enable it and configure your preferences."
|
|
30
|
+
say "\nTo use LLM features, add to your Gemfile:"
|
|
31
|
+
say " gem 'ruby_llm', '~> 0.1'"
|
|
32
|
+
say "\nDocumentation: https://github.com/codenamev/chaos_to_the_rescue"
|
|
33
|
+
say "=" * 80 + "\n"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# ChaosToTheRescue Configuration
|
|
4
|
+
#
|
|
5
|
+
# This gem provides LLM-powered method generation and Rails exception rescue suggestions.
|
|
6
|
+
# It is DISABLED by default for safety. Enable only in development/test environments.
|
|
7
|
+
#
|
|
8
|
+
# Documentation: https://github.com/codenamev/chaos_to_the_rescue
|
|
9
|
+
|
|
10
|
+
ChaosToTheRescue.configure do |config|
|
|
11
|
+
# === CORE SETTINGS ===
|
|
12
|
+
|
|
13
|
+
# Enable/disable the gem globally (default: false)
|
|
14
|
+
# IMPORTANT: Only enable in development/test environments!
|
|
15
|
+
config.enabled = Rails.env.development? || Rails.env.test?
|
|
16
|
+
|
|
17
|
+
# Automatically define generated methods on classes (default: false)
|
|
18
|
+
# When false, generated code is only returned as a string
|
|
19
|
+
# When true, methods are dynamically defined (use with caution!)
|
|
20
|
+
# config.auto_define_methods = false
|
|
21
|
+
|
|
22
|
+
# === METHOD GENERATION ALLOWLIST ===
|
|
23
|
+
|
|
24
|
+
# Regex patterns for allowed method names
|
|
25
|
+
# Only methods matching these patterns will be generated
|
|
26
|
+
# Example: Allow methods starting with "calc_"
|
|
27
|
+
# config.allowed_method_name_patterns = [/^calc_/, /^compute_/]
|
|
28
|
+
config.allowed_method_name_patterns = []
|
|
29
|
+
|
|
30
|
+
# Explicit allowlist of method names (as strings or symbols)
|
|
31
|
+
# Example: Allow specific method names
|
|
32
|
+
# config.allowlist = [:my_dynamic_method, "another_method"]
|
|
33
|
+
config.allowlist = []
|
|
34
|
+
|
|
35
|
+
# === LLM SETTINGS ===
|
|
36
|
+
|
|
37
|
+
# LLM model to use (default: "gpt-4o-mini")
|
|
38
|
+
# Requires ruby_llm gem: gem "ruby_llm", "~> 0.1"
|
|
39
|
+
# config.model = "gpt-4o-mini"
|
|
40
|
+
|
|
41
|
+
# Maximum characters to send in prompts (default: 8000)
|
|
42
|
+
# Prevents accidentally sending huge prompts to LLM
|
|
43
|
+
# config.max_prompt_chars = 8000
|
|
44
|
+
|
|
45
|
+
# === LOGGING SETTINGS ===
|
|
46
|
+
|
|
47
|
+
# Log level (:debug, :info, :warn, :error, :fatal)
|
|
48
|
+
# config.log_level = :info
|
|
49
|
+
|
|
50
|
+
# Enable logging suggestions to file (default: true)
|
|
51
|
+
# config.log_suggestions = true
|
|
52
|
+
|
|
53
|
+
# Path for suggestion log file (default: "tmp/chaos_to_the_rescue_suggestions.log")
|
|
54
|
+
# config.suggestions_log_path = "tmp/chaos_to_the_rescue_suggestions.log"
|
|
55
|
+
|
|
56
|
+
# === SECURITY SETTINGS ===
|
|
57
|
+
|
|
58
|
+
# Additional regex patterns to redact from prompts
|
|
59
|
+
# Default patterns already cover: ENV vars, AWS keys, OpenAI tokens,
|
|
60
|
+
# GitHub tokens, Rails credentials, and generic API_KEY/SECRET/TOKEN patterns
|
|
61
|
+
#
|
|
62
|
+
# Add custom patterns if you have other sensitive data:
|
|
63
|
+
# config.redact_patterns << /CUSTOM_SECRET[=:]\s*['"]?([^'"\s]+)['"]?/i
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# === USAGE EXAMPLES ===
|
|
67
|
+
|
|
68
|
+
# 1. Method Generation with ChaosRescue module:
|
|
69
|
+
#
|
|
70
|
+
# class Calculator
|
|
71
|
+
# include ChaosToTheRescue::ChaosRescue
|
|
72
|
+
# chaos_rescue_enabled! # Enable for this class
|
|
73
|
+
# end
|
|
74
|
+
#
|
|
75
|
+
# calc = Calculator.new
|
|
76
|
+
# calc.calc_fibonacci(10) # Method generated on-the-fly if allowlisted
|
|
77
|
+
#
|
|
78
|
+
|
|
79
|
+
# 2. Rails rescue_from integration:
|
|
80
|
+
#
|
|
81
|
+
# class ApplicationController < ActionController::Base
|
|
82
|
+
# include ChaosToTheRescue::RescueFrom
|
|
83
|
+
#
|
|
84
|
+
# rescue_from StandardError do |exception|
|
|
85
|
+
# suggestion = chaos_suggest_fix(
|
|
86
|
+
# exception,
|
|
87
|
+
# guidance: "This is a payment processing error"
|
|
88
|
+
# )
|
|
89
|
+
#
|
|
90
|
+
# # Use suggestion to fix the issue or log it
|
|
91
|
+
# Rails.logger.info("Suggestion: #{suggestion[:title]}")
|
|
92
|
+
# Rails.logger.info("Diagnosis: #{suggestion[:diagnosis]}")
|
|
93
|
+
#
|
|
94
|
+
# # Render error page
|
|
95
|
+
# render "errors/500", status: :internal_server_error
|
|
96
|
+
# end
|
|
97
|
+
# end
|
metadata
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: chaos_to_the_rescue
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Valentino Stoll
|
|
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: logger
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.6'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.6'
|
|
26
|
+
description: ChaosToTheRescue uses LLMs to generate missing methods on-the-fly and
|
|
27
|
+
suggest fixes for Rails exceptions. Features comprehensive security (secret redaction,
|
|
28
|
+
opt-in behavior, no auto-execution) and is disabled by default for production safety.
|
|
29
|
+
email:
|
|
30
|
+
- v@codenamev.com
|
|
31
|
+
executables: []
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
files:
|
|
35
|
+
- ".claude/CLAUDE.md"
|
|
36
|
+
- ".claude/memory.sqlite3"
|
|
37
|
+
- ".claude/rules/claude_memory.generated.md"
|
|
38
|
+
- ".claude/settings.local.json"
|
|
39
|
+
- ".devcontainer/.env.example"
|
|
40
|
+
- ".devcontainer/Dockerfile.standalone"
|
|
41
|
+
- ".devcontainer/README.md"
|
|
42
|
+
- ".devcontainer/devcontainer.json"
|
|
43
|
+
- ".devcontainer/docker-compose.yml"
|
|
44
|
+
- CHANGELOG.md
|
|
45
|
+
- CODE_OF_CONDUCT.md
|
|
46
|
+
- FEATURES.md
|
|
47
|
+
- LICENSE.txt
|
|
48
|
+
- README.md
|
|
49
|
+
- Rakefile
|
|
50
|
+
- examples/guidance_and_verification.rb
|
|
51
|
+
- lib/chaos_to_the_rescue.rb
|
|
52
|
+
- lib/chaos_to_the_rescue/chaos_rescue.rb
|
|
53
|
+
- lib/chaos_to_the_rescue/configuration.rb
|
|
54
|
+
- lib/chaos_to_the_rescue/llm_client.rb
|
|
55
|
+
- lib/chaos_to_the_rescue/logger.rb
|
|
56
|
+
- lib/chaos_to_the_rescue/railtie.rb
|
|
57
|
+
- lib/chaos_to_the_rescue/redactor.rb
|
|
58
|
+
- lib/chaos_to_the_rescue/rescue_from.rb
|
|
59
|
+
- lib/chaos_to_the_rescue/verifier.rb
|
|
60
|
+
- lib/chaos_to_the_rescue/version.rb
|
|
61
|
+
- lib/generators/chaos_to_the_rescue/install_generator.rb
|
|
62
|
+
- lib/generators/chaos_to_the_rescue/templates/chaos_to_the_rescue.rb
|
|
63
|
+
- sig/chaos_to_the_rescue.rbs
|
|
64
|
+
homepage: https://github.com/codenamev/chaos_to_the_rescue
|
|
65
|
+
licenses:
|
|
66
|
+
- MIT
|
|
67
|
+
metadata:
|
|
68
|
+
allowed_push_host: https://rubygems.org
|
|
69
|
+
homepage_uri: https://github.com/codenamev/chaos_to_the_rescue
|
|
70
|
+
source_code_uri: https://github.com/codenamev/chaos_to_the_rescue
|
|
71
|
+
changelog_uri: https://github.com/codenamev/chaos_to_the_rescue/blob/main/CHANGELOG.md
|
|
72
|
+
rdoc_options: []
|
|
73
|
+
require_paths:
|
|
74
|
+
- lib
|
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: 3.2.0
|
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '0'
|
|
85
|
+
requirements: []
|
|
86
|
+
rubygems_version: 4.0.4
|
|
87
|
+
specification_version: 4
|
|
88
|
+
summary: Safe-by-default LLM-powered method generation and Rails error rescue suggestions
|
|
89
|
+
test_files: []
|