reprompt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 13fa55af8b7e2e77547d77b1df26c68d47b1814c6de4908289391cc0949c3449
4
+ data.tar.gz: '07548880dfcf028f0d915aa93650b8702b9461003782d338e7d0c83b87b006c6'
5
+ SHA512:
6
+ metadata.gz: c2708cbec2de58e96fd3bbd3bc574750102d3ab48887972c8232c863fb1cfc58a1bc954c3bd946da6fe7a0933a3c485ca688f911567b211bd52cb428a48cc5f2
7
+ data.tar.gz: 436bce970274e743914da901726dff36d0df5d7a0035c3ab5168f457efd418f43973c46a28dff729e732969757b464af297594adb4e71323134defc396d6b17e
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Jim Jones
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,217 @@
1
+ # Reprompt
2
+
3
+ Provides a pattern for iteratively prompting an LLM and asking follow up questions based on the response.
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ $ bundle add reprompt
10
+
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ $ gem install reprompt
14
+
15
+ The only client adapter at the current moment is for Ollama. So you'll have to run a model locally.
16
+
17
+ Mistral is really good.
18
+
19
+ ```
20
+ brew install ollama
21
+ brew services start ollama
22
+ ollama pull mistral
23
+ ```
24
+
25
+ ## Pattern
26
+
27
+ Take a look in `reprompt/templates`. Return a `true/false` for the `stop_condition` callback.
28
+ Return a string (question, response, etc) for the `follow_up_on` callback.
29
+
30
+ Here's the basic pattern.
31
+
32
+ ```ruby
33
+ require_relative 'base'
34
+
35
+ class TechnicalOutline < Base
36
+ def prompt(question)
37
+ @conversation = Conversation.new(client, max_responses) do
38
+ stop_condition do |depth, response|
39
+ response.include?("we are done") || depth >= max_responses
40
+ end
41
+
42
+ follow_up_on do |response|
43
+ # We'll have the Mistral LLM create our next follow up question
44
+ prompt "What is a good follow up question for #{response}? Or are we done?"
45
+ end
46
+ end
47
+
48
+ conversation.start(question)
49
+ end
50
+ end
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ ```ruby
56
+ template = TechnicalOutline.new
57
+ template.prompt("Outline the difference between a Ruby include vs prepend")
58
+ ```
59
+
60
+ ### The Resulting Article
61
+
62
+ ### Q: Outline the difference between a Ruby include vs prepend
63
+ #### A: In Ruby, `include` and `prepend` are two methods used to add functionality to a class or module. However, they serve different purposes:
64
+
65
+ 1. **Include:** The `include` method adds the methods (and constants, if any) of one module into another module or class. When you include a module into a class, all the methods defined in that module become available in the class. The instance methods are mixed-in and will be accessible on instances of the class. The class itself does not inherit from the included module.
66
+
67
+ 2. **Prepend:** The `prepend` method also adds the functionality of one module into another module or class, but it does so in a different way. When you prepend a module to a class, the methods defined in that module are added at the beginning (before all other instances and class methods) of the class's method chain. This can be useful when you want to modify or extend existing methods without overriding them completely.
68
+
69
+ Here is an example to illustrate the difference between `include` and `prepend`. Let's assume we have two modules: `MyModule1` and `MyModule2`. Both modules define a method called `my_method`.
70
+
71
+ ```ruby
72
+ module MyModule1
73
+ def my_method
74
+ puts "MyModule1: my_method"
75
+ end
76
+ end
77
+
78
+ module MyModule2
79
+ def my_method
80
+ puts "MyModule2: my_method"
81
+ end
82
+ end
83
+ ```
84
+
85
+ Now, let's see how we can use these modules with the `include` and `prepend` methods:
86
+
87
+ **Using include:**
88
+
89
+ ```ruby
90
+ class MyClass
91
+ include MyModule1
92
+ include MyModule2
93
+ end
94
+
95
+ MyClass.new.my_method # Output: "MyModule1: my_method" (because MyModule1 is included last)
96
+ ```
97
+
98
+ In this example, `MyModule1` and `MyModule2` are included in the order they appear, so when you call `my_method` on an instance of `MyClass`, it will output "MyModule1: my_method". If we want to change the order, we would have to change the order in which the modules are included.
99
+
100
+ **Using prepend:**
101
+
102
+ ```ruby
103
+ class MyClass
104
+ prepend MyModule2
105
+ include MyModule1
106
+ end
107
+
108
+ MyClass.new.my_method # Output: "MyModule2: my_method" (because MyModule2 is prepended)
109
+ ```
110
+
111
+ In this example, `MyModule2` is prepended to the class before including `MyModule1`. When you call `my_method` on an instance of `MyClass`, it will output "MyModule2: my_method" because `MyModule2` is added at the beginning of the method chain.
112
+ ### Q: A possible follow-up question could be:
113
+
114
+ Can you explain some use cases where it would be more appropriate to use `include` instead of `prepend`, and vice versa, when extending or modifying the functionality of a class or module in Ruby? Also, are there any limitations or drawbacks to using one method over the other, depending on the specific scenario?
115
+ #### A: Sure! The choice between `include` and `prepend` depends on your specific use case and the desired outcome. Here are some common scenarios where each method might be more appropriate:
116
+
117
+ **Use Cases for Include:**
118
+
119
+ 1. When you want to add new methods or functionalities to an existing class or module, without modifying any of the existing methods. This is because `include` adds the methods at the end of the class's method chain.
120
+ 2. When you have multiple modules that define similar but not identical functionality and you want to mix them into a single class or module. The order in which you include these modules may impact the behavior of your class/module, so consider the dependencies carefully.
121
+ 3. When the added methods are optional or can be easily overridden by other methods in the class/module.
122
+ 4. When working with mixins or libraries that provide additional functionality to your classes or modules.
123
+
124
+ **Use Cases for Prepend:**
125
+
126
+ 1. When you want to modify existing methods without overriding them completely. By prepending a module, you can add new behavior at the beginning of the method chain, which will be executed before the original implementation of the method. This is useful when you need to perform some additional setup or validation for a method.
127
+ 2. When dealing with third-party libraries that provide methods or functionalities that you want to modify or extend without modifying the library's source code directly. Prepending your custom module allows you to hook into existing methods and add new functionality while keeping the original behavior intact.
128
+ 3. When working on deeply nested inheritance hierarchies, where you need to modify the behavior of a method at a specific level in the hierarchy. By prepending the modifying module at that level, you can modify the behavior without affecting other levels in the hierarchy.
129
+
130
+ Limitations and Drawbacks:
131
+
132
+ 1. **Naming Conflicts:** If two included modules or prepended modules define methods with the same name, there will be a naming conflict. In this case, you need to provide an alias or rename one of the conflicting methods.
133
+ 2. **Complexity:** Using both `include` and `prepend` in the same class/module can make the codebase more complex and harder to understand for other developers. Try to keep your use of these methods clear and concise.
134
+ 3. **Ordering Dependencies:** The order in which you include or prepend modules matters, as it impacts the method chain. Make sure to consider the dependencies carefully and provide a clear ordering if necessary.
135
+ ### Q: What are some best practices for managing the order of dependencies when using `include` and `prepend` in Ruby?
136
+ #### A: When managing dependencies in Ruby with `include` and `prepend`, here are some best practices to ensure clear and consistent code:
137
+
138
+ 1. **Declare dependencies explicitly:** Make sure to declare all dependencies (included modules or prepended modules) at the beginning of your class definition, preferably in the order they should be processed. This makes it easier for other developers to understand the flow of your code.
139
+
140
+ 2. **Use descriptive names:** Give meaningful and descriptive names to your modules to make it clear what functionality they provide. This helps when determining the correct order of dependencies.
141
+
142
+ 3. **Minimize the number of dependencies:** Try to keep the number of dependencies to a minimum, as more dependencies lead to increased complexity and potential for conflicts. If possible, refactor your code to reduce the number of dependencies.
143
+
144
+ 4. **Consider encapsulation:** Encapsulate related functionality within the same module or library to minimize dependency conflicts and simplify the ordering process.
145
+
146
+ 5. **Maintain a clear documentation:** Clearly document each module's purpose and intended use, along with any specific requirements or dependencies. This will help other developers understand the context of your code.
147
+
148
+ 6. **Test thoroughly:** Thoroughly test your code to ensure that the order of dependencies does not impact the functionality or behavior of your classes or modules. This can help you identify and resolve potential conflicts early in the development process.
149
+ ### Q: A possible follow-up question could be: "What are some common pitfalls to avoid when managing dependencies with `include` and `prepend` in Ruby?" or "Can you provide examples of how these best practices for managing dependencies with `include` and `prepend` in Ruby can be implemented in practice?"
150
+ #### A: When managing dependencies with `include` and `prepend` in Ruby, there are some common pitfalls to avoid:
151
+
152
+ 1. **Naming conflicts:** As mentioned earlier, if two included modules or prepended modules define methods with the same name, there will be a naming conflict. To avoid this, you can provide an alias or rename one of the conflicting methods. Make sure to check for potential naming conflicts before incorporating new dependencies into your codebase.
153
+ 2. **Complexity:** Using both `include` and `prepend` in the same class/module can make the codebase more complex and harder to understand for other developers. Try to keep your use of these methods clear and concise, and avoid adding unnecessary dependencies.
154
+ 3. **Inconsistent ordering:** The order in which you include or prepend modules matters. If dependencies are not declared consistently across your codebase, it can lead to unexpected behavior or bugs. Be sure to declare all dependencies at the beginning of your class definition, preferably in the correct order.
155
+ 4. **Circular dependencies:** Circular dependencies occur when modules A and B each depend on the other. This can create a deadlock situation where neither module can be loaded properly. Avoid circular dependencies by ensuring that each module depends only on its direct dependencies and not on indirect dependencies.
156
+ 5. **Lack of documentation:** Failing to document your dependencies clearly can lead to confusion and misinterpretation of your code. Be sure to provide clear and concise documentation for each module, including its purpose, intended use, and any specific requirements or dependencies.
157
+
158
+ Here's an example of how you might implement some of these best practices in practice:
159
+
160
+ ```ruby
161
+ # Define a simple logging module with two methods: info and error
162
+ module Logging
163
+ def log_info(message)
164
+ puts "[INFO] #{message}"
165
+ end
166
+
167
+ def log_error(message)
168
+ puts "[ERROR] #{message}"
169
+ end
170
+ end
171
+
172
+ # Define a validation module with two methods: validate_presence and validate_format
173
+ module Validation
174
+ def validate_presence(attribute, value)
175
+ raise "Attribute '#{attribute}' is missing" if value.nil?
176
+ end
177
+
178
+ def validate_format(attribute, format)
179
+ raise "Invalid format for attribute '#{attribute}' (expected: #{format})" unless value =~ /#{format}/
180
+ end
181
+ end
182
+
183
+ # Define a User class that includes Logging and Validation modules
184
+ class User
185
+ include Logging
186
+ include Validation
187
+
188
+ attr_accessor :name, :email
189
+
190
+ def initialize(name, email)
191
+ @name = name
192
+ @email = email
193
+ end
194
+
195
+ # Method to create a new user with validation and logging
196
+ def create
197
+ validate_presence(:name, @name)
198
+ validate_format(:email, /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z\d]([a-z\d\-.]*){2,})\z/)
199
+
200
+ log_info("Created new user: #{@name}")
201
+ end
202
+ end
203
+ ```
204
+
205
+ In this example, we define two simple modules (Logging and Validation) with their respective methods. We then include these modules in a User class, which includes both logging and validation functionality. By documenting each module clearly and encapsulating related functionality within the same module, we can minimize complexity and potential for conflicts. Additionally, by declaring dependencies explicitly at the beginning of our class definition, we make it easier for other developers to understand the flow of our code.
206
+ ### Q: A possible follow-up question could be: "Can you explain how the order of inclusion matters when dealing with dependencies in Ruby using `include` and `prepend`, and provide an example of unexpected behavior that might occur due to inconsistent ordering?"
207
+ #### A: Absolutely! When managing dependencies in Ruby with `include` and `prepend`, the order in which you include or prepend modules is crucial. This is because the order determines the method chain for each class or module, and can impact the behavior of your code.\
208
+ \
209
+ Let's consider an example where we have two modules, `ModuleA` and `ModuleB`, with each defining a method named `method_x`. If we include or prepend these modules in different orders, it can lead to unexpected behavior:\
210
+ ```ruby\n\n# Define ModuleA with method x\nmodule ModuleA\n def method_x\n puts "Method X from Module A"\n end\nend\n\n# Define ModuleB with method x\nmodule ModuleB\n def method_x\n puts "Method X from Module B"\n end\nend\n\nclass MyClass\n # Inconsistent ordering: include ModuleA, then include ModuleB\n include ModuleA\n include ModuleB\n\n # Expected output: "Method X from Module A" when calling method_x\nend\n\n# Output: "Method X from Module B" instead of "Method X from Module A", due to inconsistent ordering\nMyClass.new.method_x\n```
211
+ In the example above, we define two modules, `ModuleA` and `ModuleB`, each with a method named `method_x`. We then create a class called `MyClass`, which includes both `ModuleA` and `ModuleB` in an inconsistent order. This results in the `method_x` from `ModuleB` being called instead of `ModuleA` when we call `my_class.new.method_x`.
212
+ \
213
+ The inconsistent ordering can cause unexpected behavior because each module extends the previous one, creating a chain of inheritance that determines which method is actually called when you invoke a method with that name. In our example, because we included `ModuleB` after `ModuleA`, Ruby uses the definition of `method_x` from `ModuleB` instead of `ModuleA`.
214
+ \
215
+ To avoid unexpected behavior due to inconsistent ordering, make sure to declare all dependencies at the beginning of your class definition, preferably in the correct order. In our example above, we should have included `ModuleA` before `ModuleB`:
216
+ ```ruby\nclass MyClass\n include ModuleA\n include ModuleB\n # Expected output: "Method X from Module A" when calling method_x\nend\n```
217
+ This way, we ensure that the definition of `method_x` from `ModuleA` is used instead of `ModuleB`, as intended.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
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 "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,10 @@
1
+ class Base
2
+ attr_accessor :uri
3
+
4
+ def initialize
5
+ end
6
+
7
+ def prompt(question)
8
+ raise NotImplementedError
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+ require_relative 'base'
5
+
6
+ class Ollama < Base
7
+ def initialize
8
+ @uri = URI('http://localhost:11434/api/chat')
9
+ end
10
+
11
+ def prompt(question)
12
+ response = Net::HTTP.start(@uri.hostname, @uri.port, use_ssl: @uri.scheme == 'https') do |http|
13
+ http.post(@uri, JSON.dump({
14
+ messages: [{ role: 'user', content: question }],
15
+ model: 'mistral',
16
+ stream: false
17
+ }), 'Content-Type' => 'application/json')
18
+ end
19
+
20
+ (JSON.parse(response.body) || {}).dig('message', 'content')
21
+ end
22
+ end
@@ -0,0 +1,67 @@
1
+ class Conversation
2
+ attr_accessor :max_responses, :conversation_context, :client
3
+
4
+ def initialize(client, max_responses = 5, &configuration)
5
+ @client = client
6
+ @max_responses = max_responses
7
+ @stop_condition_block = nil
8
+ @follow_up_block = nil
9
+ @conversation_context = []
10
+ instance_eval(&configuration) if block_given?
11
+ end
12
+
13
+ def stop_condition(&block)
14
+ @stop_condition_block = block
15
+ end
16
+
17
+ def follow_up_on(&block)
18
+ @follow_up_block = block
19
+ end
20
+
21
+ def start(initial_question)
22
+ depth = 0
23
+ conversation_context.clear
24
+ current_question = initial_question
25
+ previous_response = ""
26
+
27
+ while continue_conversation?(depth, previous_response)
28
+ response = @client.prompt(current_question_with_previous_context(current_question, conversation_context))
29
+ puts "###Q: #{current_question}"
30
+ puts "####A: #{response}"
31
+ conversation_context << { role: 'system', content: response }
32
+
33
+ previous_response = response
34
+ depth += 1
35
+
36
+ break unless @follow_up_block
37
+
38
+ current_question = instance_exec(response, &@follow_up_block)
39
+ end
40
+
41
+ current_conversation
42
+ end
43
+
44
+ private
45
+
46
+ def current_question_with_previous_context(current_question, conversation_context)
47
+ "#{current_conversation}#{current_question}"
48
+ end
49
+
50
+ def current_conversation
51
+ conversation_context.join("\n")
52
+ end
53
+
54
+ def previous_context
55
+ conversation_context.join("\n")
56
+ end
57
+
58
+ def continue_conversation?(depth, previous_response)
59
+ return !@stop_condition_block.call(depth, previous_response) if @stop_condition_block
60
+
61
+ depth < @max_responses
62
+ end
63
+
64
+ def prompt(question)
65
+ client.prompt(question)
66
+ end
67
+ end
@@ -0,0 +1,14 @@
1
+ require_relative '../clients/ollama'
2
+
3
+ class Base
4
+ attr_accessor :client, :conversation, :max_responses
5
+
6
+ def initialize(max_responses = 5)
7
+ @client = Ollama.new
8
+ @max_responses = max_responses
9
+ end
10
+
11
+ def prompt(question)
12
+ raise NotImplementedError, "Each template should implement it's own conversation."
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'base'
2
+
3
+ class FiveWhys < Base
4
+ def prompt(question)
5
+ @conversation = Conversation.new(client, max_responses) do
6
+ stop_condition do |depth, response|
7
+ response.include?("i do not know") || depth >= @max_responses
8
+ end
9
+
10
+ follow_up_on do |_response|
11
+ ['Why is that?',
12
+ 'What do you mean by that?',
13
+ 'Are there other approaches?',
14
+ 'Can you clarify?'].shuffle.first
15
+ end
16
+ end
17
+
18
+ conversation.start(question)
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'base'
2
+
3
+ class TechnicalOutline < Base
4
+ def prompt(question)
5
+ @conversation = Conversation.new(client, max_responses) do
6
+ stop_condition do |depth, response|
7
+ response.include?("we are done") || depth >= max_responses
8
+ end
9
+
10
+ follow_up_on do |response|
11
+ prompt "What is a good follow up question for #{response}? No compliments, no commentary, just a short follow up question. Or are we done?"
12
+ end
13
+ end
14
+
15
+ conversation.start(question)
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Reprompt
4
+ VERSION = "0.1.0"
5
+ end
data/lib/reprompt.rb ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "reprompt/version"
4
+ require_relative 'reprompt/conversation'
5
+
6
+ require_relative 'reprompt/clients/base'
7
+ require_relative 'reprompt/clients/ollama'
8
+
9
+ require_relative 'reprompt/templates/base'
10
+ require_relative 'reprompt/templates/five_whys'
11
+ require_relative 'reprompt/templates/technical_outline'
12
+
13
+ module Reprompt
14
+ class Error < StandardError; end
15
+ # Your code goes here...
16
+ end
data/reprompt.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/reprompt/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "reprompt"
7
+ spec.version = Reprompt::VERSION
8
+ spec.authors = ["Jim Jones"]
9
+ spec.email = ["jim.jones1@gmail.com"]
10
+
11
+ spec.summary = "Create Ruby classes that iteratively solve problems or create content."
12
+ spec.homepage = "https://www.github.com/aantix/reprompter"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 2.6.0"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://www.github.com/aantix/reprompter"
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(__dir__) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (File.expand_path(f) == __FILE__) ||
24
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
25
+ end
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ # Uncomment to register a new dependency of your gem
32
+ # spec.add_dependency "example-gem", "~> 1.0"
33
+
34
+ # For more information and examples about making a new gem, check out our
35
+ # guide at: https://bundler.io/guides/creating_gem.html
36
+ end
data/sig/reprompt.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Reprompt
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reprompt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jim Jones
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-03-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - jim.jones1@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - ".rubocop.yml"
22
+ - LICENSE.txt
23
+ - README.md
24
+ - Rakefile
25
+ - lib/reprompt.rb
26
+ - lib/reprompt/clients/base.rb
27
+ - lib/reprompt/clients/ollama.rb
28
+ - lib/reprompt/conversation.rb
29
+ - lib/reprompt/templates/base.rb
30
+ - lib/reprompt/templates/five_whys.rb
31
+ - lib/reprompt/templates/technical_outline.rb
32
+ - lib/reprompt/version.rb
33
+ - reprompt.gemspec
34
+ - sig/reprompt.rbs
35
+ homepage: https://www.github.com/aantix/reprompter
36
+ licenses:
37
+ - MIT
38
+ metadata:
39
+ homepage_uri: https://www.github.com/aantix/reprompter
40
+ source_code_uri: https://www.github.com/aantix/reprompter
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 2.6.0
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubygems_version: 3.2.3
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Create Ruby classes that iteratively solve problems or create content.
60
+ test_files: []