llm_rescuer 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6ccbd1c233b14f52a25b9718471106654feecc940a6a5e437307793b1a64d974
4
+ data.tar.gz: 1a2e08037d1a3acf18e694473b77246a4d67e53269b7b8bfcc03106032c0bdf3
5
+ SHA512:
6
+ metadata.gz: 0a579571e96a250591237dead0cfd33a9f87966a62c24f4707138acf7dd087ed19c3e2362cc973246a7bbf6385289b2df7db6ee757c3b3355d460790db29dfba
7
+ data.tar.gz: 3f7db8460e977a030c18d3d94e6f82de41449702a2dea95d442099c018256ddb4b11ebf069d66b235e9b7d797e51fbfaeb8a2e358b6ffcf5c82ce4d246a967f2
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.standard.yml ADDED
@@ -0,0 +1,3 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/standardrb/standard
3
+ ruby_version: 3.4
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-10-23
4
+
5
+ - Initial release
@@ -0,0 +1,132 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the overall
26
+ community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or advances of
31
+ any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email address,
35
+ without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official email address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement at
63
+ [INSERT CONTACT METHOD].
64
+ All complaints will be reviewed and investigated promptly and fairly.
65
+
66
+ All community leaders are obligated to respect the privacy and security of the
67
+ reporter of any incident.
68
+
69
+ ## Enforcement Guidelines
70
+
71
+ Community leaders will follow these Community Impact Guidelines in determining
72
+ the consequences for any action they deem in violation of this Code of Conduct:
73
+
74
+ ### 1. Correction
75
+
76
+ **Community Impact**: Use of inappropriate language or other behavior deemed
77
+ unprofessional or unwelcome in the community.
78
+
79
+ **Consequence**: A private, written warning from community leaders, providing
80
+ clarity around the nature of the violation and an explanation of why the
81
+ behavior was inappropriate. A public apology may be requested.
82
+
83
+ ### 2. Warning
84
+
85
+ **Community Impact**: A violation through a single incident or series of
86
+ actions.
87
+
88
+ **Consequence**: A warning with consequences for continued behavior. No
89
+ interaction with the people involved, including unsolicited interaction with
90
+ those enforcing the Code of Conduct, for a specified period of time. This
91
+ includes avoiding interactions in community spaces as well as external channels
92
+ like social media. Violating these terms may lead to a temporary or permanent
93
+ ban.
94
+
95
+ ### 3. Temporary Ban
96
+
97
+ **Community Impact**: A serious violation of community standards, including
98
+ sustained inappropriate behavior.
99
+
100
+ **Consequence**: A temporary ban from any sort of interaction or public
101
+ communication with the community for a specified period of time. No public or
102
+ private interaction with the people involved, including unsolicited interaction
103
+ with those enforcing the Code of Conduct, is allowed during this period.
104
+ Violating these terms may lead to a permanent ban.
105
+
106
+ ### 4. Permanent Ban
107
+
108
+ **Community Impact**: Demonstrating a pattern of violation of community
109
+ standards, including sustained inappropriate behavior, harassment of an
110
+ individual, or aggression toward or disparagement of classes of individuals.
111
+
112
+ **Consequence**: A permanent ban from any sort of public interaction within the
113
+ community.
114
+
115
+ ## Attribution
116
+
117
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118
+ version 2.1, available at
119
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120
+
121
+ Community Impact Guidelines were inspired by
122
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
123
+
124
+ For answers to common questions about this code of conduct, see the FAQ at
125
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
126
+ [https://www.contributor-covenant.org/translations][translations].
127
+
128
+ [homepage]: https://www.contributor-covenant.org
129
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
130
+ [Mozilla CoC]: https://github.com/mozilla/diversity
131
+ [FAQ]: https://www.contributor-covenant.org/faq
132
+ [translations]: https://www.contributor-covenant.org/translations
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Paul Chobert
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # LLM Rescuer 🤖💰
2
+
3
+ > ⚠️ **EXPERIMENTAL PROJECT - NOT FOR PRODUCTION USE**
4
+ >
5
+ > This project is an experimental proof-of-concept developed for educational purposes and pure, unadulterated fun. It uses AI to dynamically handle runtime errors, which introduces unpredictable behavior and potential security risks that would make your security team cry. **Never use this in production environments unless you enjoy explaining to your boss why the AI decided your user's name should be "🐱 Mr. Whiskers".**
6
+
7
+ ## The Mission: Fixing the Billion Dollar Mistake... With a Billion Dollars Worth of LLM Tokens
8
+
9
+ In 1965, Tony Hoare invented the null reference and later called it his ["billion-dollar mistake"](https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/). Well, we're here to fix it by potentially spending a billion dollars in OpenAI API tokens! 💸
10
+
11
+ Because clearly, the best way to solve a problem caused by the absence of a value is to throw artificial intelligence at it until it hallucinates a reasonable response. What could possibly go wrong?
12
+
13
+ ## What This Abomination Does
14
+
15
+ LLM Rescuer is a Ruby gem that catches your `NoMethodError`s when you call methods on `nil` and asks GPT to guess what you _probably_ wanted. It's like having a very expensive, overly-confident intern who's read your entire codebase and thinks they know what you meant.
16
+
17
+ ```ruby
18
+ user = nil
19
+ puts user.name # Instead of crashing, might return "John Doe" or "undefined" or "🎭"
20
+ # depending on what the AI thinks is funny today
21
+ ```
22
+
23
+ ## How This Beautiful Disaster Works
24
+
25
+ 1. **The Trap**: We monkey-patch `NilClass` because why not break fundamental assumptions?
26
+ 2. **The Analysis**: When you call a method on `nil`, we pause everything and ask an LLM to read your mind
27
+ 3. **The Oracle**: GPT-5 analyzes your code like a digital Sherlock Holmes with ADHD
28
+ 4. **The Guess**: It returns what it thinks you wanted, which is right about 73.2% of the time\*
29
+ 5. **The Magic**: Your code continues running, probably doing something completely different than intended
30
+
31
+ \*Statistics may be made up
32
+
33
+ ## Installation (AKA "How to Spend Your OpenAI Credits")
34
+
35
+ Add this line to your application's Gemfile (and say goodbye to your API budget):
36
+
37
+ ```ruby
38
+ gem 'llm_rescuer'
39
+ ```
40
+
41
+ Then execute:
42
+
43
+ ```bash
44
+ bundle install
45
+ # Also install a second mortgage for your OpenAI bills
46
+ ```
47
+
48
+ ## Configuration
49
+
50
+ 1. **Feed the AI overlords**:
51
+
52
+ ```bash
53
+ export OPENAI_API_KEY="prepare-your-wallet"
54
+ ```
55
+
56
+ 2. **Set your project scope** (so it only ruins _your_ code):
57
+
58
+ ```ruby
59
+ LlmRescuer.prefix = "/path/to/your/beautiful/disaster"
60
+ ```
61
+
62
+ 3. **Embrace the chaos**:
63
+ ```ruby
64
+ require 'llm_rescuer'
65
+ LlmRescuer.setup
66
+ # You have chosen... poorly
67
+ ```
68
+
69
+ ## Real-World Usage Examples
70
+
71
+ ```ruby
72
+ # Classic nil safety
73
+ user = find_user(id: "nonexistent") # returns nil
74
+ puts user.email
75
+ # AI: "Analyzing context... user seems to need an email...
76
+ # returning 'no-reply@example.com'"
77
+
78
+ # Shopping cart magic
79
+ cart = session[:cart] # nil because session expired
80
+ total = cart.total_price
81
+ # AI: "This looks like e-commerce. Based on similar patterns,
82
+ # I'll return 0.0 to avoid charging $nil"
83
+
84
+ # The existential crisis
85
+ meaning_of_life = nil
86
+ answer = meaning_of_life.to_i
87
+ # AI: "Clearly this should be 42. I've read Douglas Adams."
88
+ ```
89
+
90
+ ## What Could Go Wrong? 🤔
91
+
92
+ - Your nil users might suddenly become named "ChatGPT's Best Friend"
93
+ - Your shopping cart totals might be replaced with haikus about commerce
94
+ - Your boolean flags might return philosophical treatises on truth
95
+ - Your API might start responding with interpretive dance descriptions
96
+ - You might accidentally achieve sentience in your nil objects
97
+
98
+ ## Cost Analysis 💰
99
+
100
+ - **Traditional nil handling**: Free, but your app crashes
101
+ - **LLM Rescuer**: $0.002 per nil rescue (estimated)
102
+ - **Your sanity**: Priceless (and rapidly depleting)
103
+
104
+ For a typical Rails app with healthy nil hygiene, expect to spend approximately:
105
+
106
+ - **Development**: $50-100/month (because you test things, right?)
107
+ - **Production**: $500-5000/month (depending on how nil-happy your code is)
108
+ - **Black Friday**: Your firstborn child
109
+
110
+ ## Dependencies (The Usual Suspects)
111
+
112
+ - `ruby_llm` (~> 1.8.2) - For talking to our AI overlords
113
+ - `ruby_llm-schema` (~> 0.2.1) - For making sure AI responses are structured chaos
114
+ - `binding_of_caller` (~> 1.0.1) - For context that the AI will probably ignore anyway
115
+ - A sense of humor (>= 1.0.0, required)
116
+ - A healthy bank account (recommended)
117
+
118
+ ## Development
119
+
120
+ After checking out the repo and questioning your life choices:
121
+
122
+ ```bash
123
+ bin/setup # Install dependencies
124
+ rake spec # Run tests (spoiler: they're as unpredictable as AI)
125
+ bin/console # Interactive prompt for immediate regret
126
+ ```
127
+
128
+ ## Contributing
129
+
130
+ Found a bug? That might be a feature! Found a feature? That might be a bug!
131
+
132
+ Submit PRs, issues, or interpretive dance videos explaining your problems. We accept contributions in all forms except sensible ones.
133
+
134
+ ## Success Stories
135
+
136
+ > "LLM Rescuer saved my app from crashing! Sure, all my users are now named 'Anonymous Penguin' and my prices are in Bitcoin, but it didn't crash!" - Definitely Real User
137
+
138
+ > "I deployed this to production and my nil errors went down 100%! My AWS bill went up 400%, but correlation isn't causation, right?" - Another Real Person
139
+
140
+ ## The Philosophy
141
+
142
+ Why fix your code when you can train an AI to guess what your code should have done? It's like pair programming, except your pair is a probabilistic text generator that's read the entire internet and has strong opinions about variable naming.
143
+
144
+ ## License
145
+
146
+ This project is licensed under the MIT License, which gives you the right to use, modify, and distribute this code. It does not give you the right to sue us when your production app starts writing poetry instead of processing payments.
147
+
148
+ ## Final Words
149
+
150
+ Remember: null references were a billion-dollar mistake, but with today's AI API pricing, we can make it a trillion-dollar mistake! 🚀
151
+
152
+ ---
153
+
154
+ _"In a world without nil safety, one gem dares to ask: 'What if we just guessed?'"_ 🎬
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[spec standard]
@@ -0,0 +1,65 @@
1
+ module LlmRescuer
2
+ def self.prefix=(prefix)
3
+ @prefix = prefix
4
+ end
5
+
6
+ def self.prefix = @prefix
7
+
8
+ module NilExtension
9
+ class ResponseSchema < RubyLLM::Schema
10
+ string :ruby_expression, description: "ruby expression to evaluate to recover from the exception"
11
+ string :comment, description: "comment about the response"
12
+ string :error_message, description: "error message from the exception"
13
+ end
14
+
15
+ def method_missing(method_name, *args, &block)
16
+ chat =
17
+ RubyLLM
18
+ .chat
19
+ .with_tool(Tools::ReadSourceCodeTool)
20
+ .on_tool_call do |tool_call|
21
+ # Called when the AI decides to use a tool
22
+ puts "Calling tool: #{tool_call.name}"
23
+ puts "Arguments: #{tool_call.arguments}"
24
+ end
25
+ .on_tool_result do |result|
26
+ # Called after the tool returns its result
27
+ puts "Tool returned: #{result}"
28
+ end
29
+
30
+ chat.with_instructions <<~SYSTEM_PROMPT
31
+ A ruby program is about to crash or test about to fail because the method `#{method_name}` has been called on `nil`.
32
+ We are trying to determine what the return value of `NilClass.method_missing` should be so the program can resume.
33
+ You can use the `read_source_code` tool to read the source code of a file.
34
+ Generate a response with a ruby expression to evaluate.
35
+
36
+ Some examples of expression could be:
37
+ - super if we want to raise the error
38
+ - `nil` if we want to behave like &.
39
+ - a boolean
40
+ - a number
41
+ - a new instance of a class
42
+
43
+ The goal is to help the program to resume successfully with the best possible expression.
44
+ You need to look at the business logic of the caller to determine the best expression.
45
+ SYSTEM_PROMPT
46
+
47
+ filtered_caller = caller.filter { |line| line.start_with?(LlmRescuer.prefix) }.join("\n")
48
+
49
+ prompt = <<~PROMPT
50
+ Here is the failing method call:
51
+ method name: #{method_name}
52
+ arguments: #{args.inspect}
53
+ backtrace:
54
+ #{filtered_caller}
55
+ PROMPT
56
+ response = chat.with_schema(ResponseSchema).ask(prompt)
57
+ eval(response.content["ruby_expression"]) # standard:disable Security/Eval
58
+ end
59
+
60
+ def respond_to_missing?(method_name, include_private = false)
61
+ first_caller = caller(1..1).first
62
+ first_caller&.start_with?(LlmRescuer.prefix) || false
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,35 @@
1
+ module LlmRescuer
2
+ module Tools
3
+ class ReadSourceCodeTool < RubyLLM::Tool
4
+ description "Reads the source code of a given file"
5
+
6
+ param :file_path, desc: "The full path to the file to read, without the line number"
7
+ param :around_line_number, desc: "The line number around which to read the source code"
8
+ param :context_lines, desc: "The number of lines of context to include around the specified line number"
9
+
10
+ def execute(file_path:, around_line_number:, context_lines:)
11
+ around_line_number = around_line_number.to_i
12
+ context_lines = context_lines.to_i
13
+ return {error: "Unauthorized file path"} unless file_path.start_with?(LlmRescuer.prefix)
14
+
15
+ return {error: "File not found"} unless File.file?(file_path)
16
+
17
+ lines = File.readlines(file_path)
18
+
19
+ start = [around_line_number - context_lines - 1, 0].max
20
+ end_ = [around_line_number + context_lines - 1, lines.size - 1].min
21
+
22
+ snippet = lines[start..end_].each_with_index.map do |src, i|
23
+ num = start + i + 1
24
+ prefix = (num == around_line_number) ? "=> " : " "
25
+ format("#{prefix}%4d | %s", num, src)
26
+ end
27
+
28
+ puts "#{file_path}:#{around_line_number}\n\n"
29
+ puts snippet.join
30
+ rescue => e
31
+ {error: e.message}
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LlmRescuer
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby_llm"
4
+ require "ruby_llm/schema"
5
+
6
+ require_relative "llm_rescuer/version"
7
+ require_relative "llm_rescuer/nil_extension"
8
+ require_relative "llm_rescuer/tools/read_source_code_tool"
9
+
10
+ RubyLLM.configure do |config|
11
+ config.openai_api_key = ENV.fetch("OPENAI_API_KEY")
12
+ config.default_model = "gpt-5"
13
+ end
14
+
15
+ module LlmRescuer
16
+ def self.setup
17
+ NilClass.prepend(LlmRescuer::NilExtension)
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ module LlmRescuer
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: llm_rescuer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Paul Chobert
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: binding_of_caller
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 1.0.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 1.0.1
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: 1.8.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.8.2
40
+ - !ruby/object:Gem::Dependency
41
+ name: ruby_llm-schema
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.2.1
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.2.1
54
+ description: "LLM Rescuer uses artificial intelligence to guess what you probably
55
+ meant when you called a method on nil. Instead of crashing with NoMethodError, it
56
+ asks GPT to analyze your code and hallucinate a reasonable response. Because clearly,
57
+ the best way to solve Tony Hoare's billion-dollar mistake is to throw AI at it until
58
+ it works. What could possibly go wrong? \U0001F3AD"
59
+ email:
60
+ - paul@chobert.fr
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - ".rspec"
66
+ - ".standard.yml"
67
+ - CHANGELOG.md
68
+ - CODE_OF_CONDUCT.md
69
+ - LICENSE.txt
70
+ - README.md
71
+ - Rakefile
72
+ - lib/llm_rescuer.rb
73
+ - lib/llm_rescuer/nil_extension.rb
74
+ - lib/llm_rescuer/tools/read_source_code_tool.rb
75
+ - lib/llm_rescuer/version.rb
76
+ - sig/llm_rescuer.rbs
77
+ homepage: https://github.com/barodeur/llm_rescuer
78
+ licenses:
79
+ - MIT
80
+ metadata:
81
+ allowed_push_host: https://rubygems.org
82
+ homepage_uri: https://github.com/barodeur/llm_rescuer
83
+ source_code_uri: https://github.com/paul/llm_rescuer
84
+ changelog_uri: https://github.com/paul/llm_rescuer/blob/main/CHANGELOG.md
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 3.1.0
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubygems_version: 3.6.7
100
+ specification_version: 4
101
+ summary: "Fix the billion-dollar mistake by spending billions on LLM tokens! \U0001F916\U0001F4B0"
102
+ test_files: []