prompt_manager 0.1.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b3b9572e08d0f90b7857d9451a13e0ed5d3b089761a1ce820d3b4cf9a47b805
4
- data.tar.gz: aa374359e5200177d631ce9607bac8559529bdc968a661820110017021414605
3
+ metadata.gz: 6c96927dad3be1d7e793e3edd5d3df3e3a12999fcec57ad01d3d773d9b40e674
4
+ data.tar.gz: 4aa47ce704540fa933dbdf30d3afddbb3704bd541b4dab1f7a751e0e461f3c1e
5
5
  SHA512:
6
- metadata.gz: 992bc7f9e337d3fadbc99d0d192a325640bc113f244dd0bf448273398717e9e0d60d0e2a2ee02d18f617e3c9687efaee8fc36c6594f0a3819ca9e877140d6164
7
- data.tar.gz: a7d7891c715aa4beea562a82135e2f945d36d4e2132eb39efaf71a8795572dc804ef55bd253a34734a4d84bfb1e516fd6f973dc0c62da0b63fb4ad59cd18f5c2
6
+ metadata.gz: '0857d6d0532c0c1293799e760933e5bf2ee1a82f8cfdce6dd649b187f724e31935bf959b04c8058a90877525751cf99deaa4fd51a9cc64d0259a3d4b1e40de38'
7
+ data.tar.gz: 59d2e1cabed3a87766092f56eae6ed7e7d30a2c0d0b3e3dc2efd93fe9ce79d97ce7ee5af3d1beae6896aed3a1754649dc7a7f3bbdec1e0566015640d8f7f2128
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2023-11-21
4
+
5
+ - **Breaking change to FileSystemAdapter config process**
6
+ - added list and path as extra methods in FileSystemAdapter
7
+
3
8
  ## [0.1.0] - 2023-11-16
4
9
 
5
10
  - Initial release using the FileSystemAdapter
data/README.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  Manage the parameterized prompts (text) used in generative AI (aka chatGPT, OpenAI, _et.al._) using storage adapters such as FileSystemAdapter, SqliteAdapter and ActiveRecordAdapter.
4
4
 
5
+ **Breaking Change** in version 0.2.0 for `FileSystemAdapter` configuration. See [Configuration](#configuration) to see how the new `config` block works.
6
+
7
+ <!-- Tocer[start]: Auto-generated, don't remove. -->
8
+
9
+ ## Table of Contents
10
+
11
+ - [Installation](#installation)
12
+ - [Usage](#usage)
13
+ - [Overview](#overview)
14
+ - [Generative AI (gen-AI)](#generative-ai-gen-ai)
15
+ - [What does a keyword look like?](#what-does-a-keyword-look-like)
16
+ - [Storage Adapters](#storage-adapters)
17
+ - [FileSystemAdapter](#filesystemadapter)
18
+ - [Configuration](#configuration)
19
+ - [prompts_dir](#prompts_dir)
20
+ - [search_proc](#search_proc)
21
+ - [File Extensions](#file-extensions)
22
+ - [Extra Functionality](#extra-functionality)
23
+ - [SqliteAdapter](#sqliteadapter)
24
+ - [ActiveRecordAdapter](#activerecordadapter)
25
+ - [Other Potential Storage Adapters](#other-potential-storage-adapters)
26
+ - [Development](#development)
27
+ - [Contributing](#contributing)
28
+ - [License](#license)
29
+
30
+ <!-- Tocer[finish]: Auto-generated, don't remove. -->
31
+
5
32
  ## Installation
6
33
 
7
34
  Install the gem and add to the application's Gemfile by executing:
@@ -34,6 +61,8 @@ This is just the initial convention adopted by prompt_manager. It is intended th
34
61
 
35
62
  A storage adapter is a class instance that ties the `PromptManager::Prompt` class to a storage facility that holds the actual prompts. Currently there are 3 storage adapters planned for implementation.
36
63
 
64
+ The `PromptManager::Prompt` to support a small set of methods. A storage adapter can provide "extra" class or instance methods that can be used through the Prompt class. See the `test/prompt_manager/prompt_test.rb` for guidance on creating a new storage adapter.
65
+
37
66
  #### FileSystemAdapter
38
67
 
39
68
  This is the first storage adapter developed. It saves prompts as text files within the file system inside a designated `prompts_dir` (directory) such as `~/.prompts` or where it makes the most sense to you. Another example would be to have your directory on a shared file system so that others can use the same prompts.
@@ -42,6 +71,62 @@ The `prompt ID` is the basename of the text file. For example `todo.txt` is the
42
71
 
43
72
  The parameters for the `todo` prompt ID are saved in the same directory as `todo.txt` in a JSON file named `todo.json` (also in the examples directory.)
44
73
 
74
+ ##### Configuration
75
+
76
+ Use a `config` block to establish the configuration for the class.
77
+
78
+ ```ruby
79
+ PromptManager::Storage::FileSystemAdapter.config do |o|
80
+ o.prompts_dir = "path/to/prompts_directory"
81
+ o.search_proc = -> (q) { "ag -l #{q} #{prompts_dir} | reformat" }
82
+ o.prompt_extension = '.txt' # default
83
+ o.params_extension = '.json' # the default
84
+ end
85
+ ```
86
+
87
+ The `config` block returns `self` so that means you can do this to setup the storage adapter with the Prompt class:
88
+
89
+ ```ruby
90
+ PromptManager::Prompt
91
+ .storage_adapter =
92
+ PromptManager::Storage::FileSystemAdapter
93
+ .config do |config|
94
+ config.prompts_dir = 'path/to/prompts_dir'
95
+ end.new
96
+ ```
97
+
98
+ ###### prompts_dir
99
+
100
+ This is either a `String` or a `Pathname` object. All file paths are maintained in the class as `Pathname` objects. If you provide a `String` it will be converted. Relative paths will be converted to absolute paths.
101
+
102
+ An `ArgumentError` will be raised when `prompts_dir` does not exist or if it is not a directory.
103
+
104
+ ###### search_proc
105
+
106
+ The default for `search_proc` is nil. In this case the search will be preformed by a default `search` method which is basically reading all the prompt files to see which ones contain the search term. There are faster ways to do this kind of thing using CLI=based utilities.
107
+
108
+ TODO: add a example to the examples directory on how to integrate with command line utilities.
109
+
110
+ ###### File Extensions
111
+
112
+ These two configuration options are `String` objects that must start with a period "." utherwise an `ArgumentError` will be raised.
113
+
114
+ * prompt_extension - default: '.txt'
115
+ * params_extension - default: '.json'
116
+
117
+ Currently the `FileSystemAdapter` only supports a JSON serializer for its parameters Hash. Using any other values for these extensions will cause problems.
118
+
119
+ They exist so that there is a platform on to which other storage adapters can be built or serializers added. This is not currently on the roadmap.
120
+
121
+ ##### Extra Functionality
122
+
123
+ The `FileSystemAdapter` adds two new methods for use by the `Prompt` class:
124
+ * list - returns an Array of prompt IDs
125
+ * path and path(prompt_id) - returns a `Pathname` object to the prompt file
126
+
127
+ Use the `path(prompt_id)` form against the `Prompt` class
128
+ Use `prompt.path` when you have an instance of a `Prompt`
129
+
45
130
  #### SqliteAdapter
46
131
 
47
132
  TODO: This may be the next adapter to be implemented.
data/Rakefile CHANGED
@@ -1,5 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ begin
4
+ require "tocer/rake/register"
5
+ rescue LoadError => error
6
+ puts error.message
7
+ end
8
+
9
+ Tocer::Rake::Register.call
10
+
11
+
3
12
  require "bundler/gem_tasks"
4
13
  require "rake/testtask"
5
14
 
@@ -0,0 +1,4 @@
1
+ # prompt_manager/examples/prompts_dir/toy/8-ball.txt
2
+ # Desc: In the late 1940s the toy "Magic 8 Ball" came to market
3
+
4
+ As a magic 8-ball, provide me with a terse answer to what you suspect that I am thinking about.
data/examples/simple.rb CHANGED
@@ -9,7 +9,9 @@
9
9
  ## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
10
10
  ##
11
11
  #
12
-
12
+ # TODO: Add `list` to get an Array of prompt IDs
13
+ # TODO: Add `path` to get a path to the prompt file
14
+ #
13
15
 
14
16
  require 'prompt_manager'
15
17
  require 'prompt_manager/storage/file_system_adapter'
@@ -31,11 +33,14 @@ at_exit do
31
33
  end
32
34
 
33
35
  # Configure the Storage Adapter to use
36
+ PromptManager::Storage::FileSystemAdapter.config do |config|
37
+ config.prompts_dir = PROMPTS_DIR
38
+ # config.search_proc = nil # default
39
+ # config.prompt_extension = '.txt' # default
40
+ # config.parms+_extension = '.json' # default
41
+ end
34
42
 
35
- PromptManager::Prompt.storage_adapter =
36
- PromptManager::Storage::FileSystemAdapter.new(
37
- prompts_dir: PROMPTS_DIR
38
- )
43
+ PromptManager::Prompt.storage_adapter = PromptManager::Storage::FileSystemAdapter.new
39
44
 
40
45
  # Get a prompt
41
46
 
@@ -87,3 +92,51 @@ EOS
87
92
 
88
93
  puts todo.to_s
89
94
 
95
+ puts <<~EOS
96
+
97
+ When using the FileSystemAdapter for prompt storage you can have within
98
+ the prompts_dir you can have many sub-directories. These sub-directories
99
+ act like categories. The prompt ID is composed for the sub-directory name,
100
+ a "/" character and then the normal prompt ID. For example "toy/8-ball"
101
+
102
+ EOS
103
+
104
+ magic = PromptManager::Prompt.get( id: 'toy/8-ball' )
105
+
106
+ puts "The magic PROMPT is:"
107
+ puts magic
108
+ puts
109
+ puts "Remember if you want to see the full text of the prompt file:"
110
+ puts magic.text
111
+
112
+ puts "="*64
113
+
114
+ puts <<~EOS
115
+
116
+ The FileSystemAdapter also adds two new methods to the Prompt class:
117
+
118
+ list - provides an Array of pompt IDs
119
+ path(prompt_id) - Returns a Pathname object to the prompt file
120
+
121
+ EOS
122
+
123
+ puts "List of prompts available"
124
+ puts "========================="
125
+
126
+ puts PromptManager::Prompt.list
127
+
128
+ puts <<~EOS
129
+
130
+ And the path to the "toy/8-ball" prompt file is:
131
+
132
+ #{magic.path}
133
+
134
+ Use "your_prompt.path" for when you want to do something with the
135
+ the prompt file like send it to a text editor.
136
+
137
+ Your can also use the class method if you supply a prompt_id
138
+ like this:
139
+
140
+ EOS
141
+
142
+ puts PromptManager::Prompt.path('toy/8-ball')
@@ -25,9 +25,24 @@ class PromptManager::Prompt
25
25
  new(id: id)
26
26
  end
27
27
 
28
+
28
29
  def search(for_what)
29
30
  storage_adapter.search(for_what)
30
31
  end
32
+
33
+
34
+ def method_missing(method_name, *args, &block)
35
+ if storage_adapter.respond_to?(method_name)
36
+ storage_adapter.send(method_name, *args, &block)
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+
43
+ def respond_to_missing?(method_name, include_private = false)
44
+ storage_adapter.respond_to?(method_name, include_private) || super
45
+ end
31
46
  end
32
47
 
33
48
  # SMELL: Does the db (aka storage adapter) really need
@@ -142,6 +157,23 @@ class PromptManager::Prompt
142
157
  end
143
158
 
144
159
 
160
+ # Let the storage adapter instance take a crake at
161
+ # these unknown methods. Don't care what the args
162
+ # are, just pass the prompt's ID.
163
+ def method_missing(method_name, *args, &block)
164
+ if db.respond_to?(method_name)
165
+ db.send(method_name, id, &block)
166
+ else
167
+ super
168
+ end
169
+ end
170
+
171
+
172
+ def respond_to_missing?(method_name, include_private = false)
173
+ db.respond_to?(method_name, include_private) || super
174
+ end
175
+
176
+
145
177
  # SMELL: should this gem log errors or is that a function of
146
178
  # main program? I believe its the main program's job.
147
179
  def log_error(message)
@@ -1,31 +1,157 @@
1
1
  # prompt_manager/lib/prompt_manager/storage/file_system_adapter.rb
2
2
 
3
-
4
- require 'json'
3
+ # Use the local (or remote) file system as a place to
4
+ # store and access prompts.
5
+ #
6
+ # Adds two additional methods to the Promp class:
7
+ # list - returns Array of prompt IDs
8
+ # path = returns a Pathname object to the prompt's text file
9
+ # path(prompt_id) - same as path on the prompt instance
10
+ #
11
+ # Allows sub-directories of the prompts_dir to be
12
+ # used like categories. For example the prompt_id "toy/magic"
13
+ # is found in the `magic.txt` file inside the `toy` sub-directory
14
+ # of the prompts_dir.
15
+ #
16
+ # There can man be many layers of categories (sub-directories)
17
+ #
18
+
19
+ require 'json' # basic serialization of parameters
20
+ require 'pathname'
5
21
 
6
22
  class PromptManager::Storage::FileSystemAdapter
7
- PARAMS_EXTENSION = '.json'.freeze
8
- PROMPT_EXTENSION = '.txt'.freeze
23
+ SEARCH_PROC = nil # placeholder
24
+ PARAMS_EXTENSION = '.json'.freeze
25
+ PROMPT_EXTENSION = '.txt'.freeze
26
+ PROMPT_ID_FORMAT = /^[a-zA-Z0-9\-\/_]+$/
27
+
28
+ class << self
29
+ attr_accessor :prompts_dir, :search_proc,
30
+ :params_extension, :prompt_extension
31
+
32
+ def config
33
+ if block_given?
34
+ yield self
35
+ validate_configuration
36
+ else
37
+ raise ArgumentError, "No block given to config"
38
+ end
9
39
 
10
- attr_reader :prompts_dir
40
+ self
41
+ end
11
42
 
12
- def initialize(
13
- prompts_dir: '.prompts',
14
- search_proc: nil # Example: ->(q) {`ag -l #{q}`}
15
- )
43
+ # Expansion methods on the Prompt class specific to
44
+ # this storage adapter.
45
+
46
+ # Ignore the incoming prompt_id
47
+ def list(prompt_id = nil)
48
+ new.list
49
+ end
50
+
51
+
52
+ def path(prompt_id)
53
+ new.path(prompt_id)
54
+ end
55
+
56
+ #################################################
57
+ private
58
+
59
+ def validate_configuration
60
+ validate_prompts_dir
61
+ validate_search_proc
62
+ validate_prompt_extension
63
+ validate_params_extension
64
+ end
65
+
66
+
67
+ def validate_prompts_dir
68
+ # This is a work around for a Ruby scope issue where the
69
+ # class getter/setter method is becoming confused with a
70
+ # local variable when anything other than plain 'ol get and
71
+ # set are used.'This error is in both Ruby v3.2.2 and
72
+ # v3.3.0-preview3.
73
+ #
74
+ prompts_dir_local = self.prompts_dir
75
+
76
+ unless prompts_dir_local.is_a?(Pathname)
77
+ prompts_dir_local = Pathname.new(prompts_dir_local) unless prompts_dir_local.nil?
78
+ end
79
+
80
+ prompts_dir_local = prompts_dir_local.expand_path
81
+
82
+ raise(ArgumentError, "prompts_dir: #{prompts_dir_local}") unless prompts_dir_local.exist? && prompts_dir_local.directory?
83
+
84
+ self.prompts_dir = prompts_dir_local
85
+ end
86
+
87
+
88
+ def validate_search_proc
89
+ search_proc_local = self.search_proc
90
+
91
+ if search_proc_local.nil?
92
+ search_proc_local = SEARCH_PROC
93
+ else
94
+ raise(ArgumentError, "search_proc invalid; does not respond to call") unless search_proc_local.respond_to?(:call)
95
+ end
96
+
97
+ self.search_proc = search_proc_local
98
+ end
99
+
100
+
101
+ def validate_prompt_extension
102
+ prompt_extension_local = self.prompt_extension
103
+
104
+ if prompt_extension_local.nil?
105
+ prompt_extension_local = PROMPT_EXTENSION
106
+ else
107
+ unless prompt_extension_local.is_a?(String) &&
108
+ prompt_extension_local.start_with?('.')
109
+ raise(ArgumentError, "Invalid prompt_extension: #{prompt_extension_local}")
110
+ end
111
+ end
112
+
113
+ self.prompt_extension = prompt_extension_local
114
+ end
16
115
 
17
- # validate that prompts_dir exist and is in fact a directory.
18
- unless Dir.exist?(prompts_dir)
19
- raise "Directory #{prompts_dir} does not exist or is not a directory"
116
+
117
+ def validate_params_extension
118
+ params_extension_local = self.params_extension
119
+
120
+ if params_extension_local.nil?
121
+ params_extension_local = PARAMS_EXTENSION
122
+ else
123
+ unless params_extension_local.is_a?(String) &&
124
+ params_extension_local.start_with?('.')
125
+ raise(ArgumentError, "Invalid params_extension: #{params_extension_local}")
126
+ end
127
+ end
128
+
129
+ self.params_extension = params_extension_local
20
130
  end
131
+ end
132
+
133
+
134
+ ##################################################
135
+ ###
136
+ ## Instance
137
+ #
21
138
 
22
- @prompts_dir = prompts_dir
23
- @search_proc = search_proc
139
+ def prompts_dir = self.class.prompts_dir
140
+ def search_proc = self.class.search_proc
141
+ def prompt_extension = self.class.prompt_extension
142
+ def params_extension = self.class.params_extension
143
+
144
+
145
+ def initialize
146
+ # NOTE: validate because main program may have made
147
+ # changes outside of the config block
148
+ self.class.send(:validate_configuration) # send gets around private designations of a method
24
149
  end
25
150
 
26
151
 
27
152
  def get(id:)
28
153
  validate_id(id)
154
+ verify_id(id)
29
155
 
30
156
  {
31
157
  id: id,
@@ -37,14 +163,20 @@ class PromptManager::Storage::FileSystemAdapter
37
163
 
38
164
  # Retrieve prompt text by its id
39
165
  def prompt_text(prompt_id)
40
- read_file(file_path(prompt_id, PROMPT_EXTENSION))
166
+ read_file(file_path(prompt_id, prompt_extension))
41
167
  end
42
168
 
43
169
 
44
170
  # Retrieve parameter values by its id
45
171
  def parameter_values(prompt_id)
46
- json_content = read_file(file_path(prompt_id, PARAMS_EXTENSION))
47
- deserialize(json_content)
172
+ params_path = file_path(prompt_id, params_extension)
173
+
174
+ if params_path.exist?
175
+ parms_content = read_file(params_path)
176
+ deserialize(parms_content)
177
+ else
178
+ {}
179
+ end
48
180
  end
49
181
 
50
182
 
@@ -56,8 +188,8 @@ class PromptManager::Storage::FileSystemAdapter
56
188
  )
57
189
  validate_id(id)
58
190
 
59
- prompt_filepath = file_path(id, PROMPT_EXTENSION)
60
- params_filepath = file_path(id, PARAMS_EXTENSION)
191
+ prompt_filepath = file_path(id, prompt_extension)
192
+ params_filepath = file_path(id, params_extension)
61
193
 
62
194
  write_with_error_handling(prompt_filepath, text)
63
195
  write_with_error_handling(params_filepath, serialize(parameters))
@@ -68,8 +200,8 @@ class PromptManager::Storage::FileSystemAdapter
68
200
  def delete(id:)
69
201
  validate_id(id)
70
202
 
71
- prompt_filepath = file_path(id, PROMPT_EXTENSION)
72
- params_filepath = file_path(id, PARAMS_EXTENSION)
203
+ prompt_filepath = file_path(id, prompt_extension)
204
+ params_filepath = file_path(id, params_extension)
73
205
 
74
206
  delete_with_error_handling(prompt_filepath)
75
207
  delete_with_error_handling(params_filepath)
@@ -77,34 +209,65 @@ class PromptManager::Storage::FileSystemAdapter
77
209
 
78
210
 
79
211
  def search(for_what)
212
+ search_term = for_what.downcase
213
+
80
214
  if @search_proc
81
- @search_proc.call(for_what)
215
+ @search_proc.call(search_term)
82
216
  else
83
- search_prompts(for_what)
217
+ search_prompts(search_term)
218
+ end
219
+ end
220
+
221
+
222
+ # Return an Array of prompt IDs
223
+ def list(*)
224
+ prompt_ids = []
225
+
226
+ Pathname.glob(prompts_dir.join("**/*#{prompt_extension}")).each do |file_path|
227
+ prompt_id = file_path.relative_path_from(prompts_dir).to_s.gsub(prompt_extension, '')
228
+ prompt_ids << prompt_id
84
229
  end
230
+
231
+ prompt_ids
85
232
  end
86
233
 
87
234
 
235
+ # Returns a Pathname object for a prompt ID text file
236
+ # However, it is possible that the file does not exist.
237
+ def path(id)
238
+ validate_id(id)
239
+ file_path(id, prompt_extension)
240
+ end
241
+
88
242
  ##########################################
89
243
  private
90
244
 
245
+ # Validate that the ID contains good characters.
91
246
  def validate_id(id)
92
- raise ArgumentError, 'Invalid ID format' unless id =~ /^[a-zA-Z0-9\-_]+$/
247
+ raise ArgumentError, "Invalid ID format id: #{id}" unless id =~ PROMPT_ID_FORMAT
248
+ end
249
+
250
+
251
+ def verify_id(id)
252
+ unless file_path(id, prompt_extension).exist?
253
+ raise ArgumentError, "Invalid prompt_id: #{id}"
254
+ end
93
255
  end
94
256
 
95
257
 
96
258
  def write_with_error_handling(file_path, content)
97
259
  begin
98
- File.write(file_path, content)
260
+ file_path.write content
99
261
  rescue IOError => e
100
262
  raise "Failed to write to file: #{e.message}"
101
263
  end
102
264
  end
103
265
 
104
266
 
267
+ # file_path (Pathname)
105
268
  def delete_with_error_handling(file_path)
106
269
  begin
107
- FileUtils.rm_f(file_path)
270
+ file_path.delete
108
271
  rescue IOError => e
109
272
  raise "Failed to delete file: #{e.message}"
110
273
  end
@@ -112,7 +275,7 @@ class PromptManager::Storage::FileSystemAdapter
112
275
 
113
276
 
114
277
  def file_path(id, extension)
115
- File.join(@prompts_dir, "#{id}#{extension}")
278
+ prompts_dir + "#{id}#{extension}"
116
279
  end
117
280
 
118
281
 
@@ -123,21 +286,21 @@ class PromptManager::Storage::FileSystemAdapter
123
286
 
124
287
 
125
288
  def search_prompts(search_term)
126
- query_term = search_term.downcase
127
-
128
- Dir.glob(File.join(@prompts_dir, "*#{PROMPT_EXTENSION}")).each_with_object([]) do |file_path, ids|
129
- File.open(file_path) do |file|
130
- file.each_line do |line|
131
- if line.downcase.include?(query_term)
132
- ids << File.basename(file_path, PROMPT_EXTENSION)
133
- next
134
- end
135
- end
289
+ prompt_ids = []
290
+
291
+ Pathname.glob(prompts_dir.join("**/*#{prompt_extension}")).each do |prompt_path|
292
+ if prompt_path.read.downcase.include?(search_term)
293
+ prompt_id = prompt_path.relative_path_from(prompts_dir).to_s.gsub(prompt_extension, '')
294
+ prompt_ids << prompt_id
136
295
  end
137
- end.uniq
296
+ end
297
+
298
+ prompt_ids
138
299
  end
139
300
 
140
301
 
302
+ # TODO: Should the serializer be generic?
303
+
141
304
  def serialize(data)
142
305
  data.to_json
143
306
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PromptManager
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prompt_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-19 00:00:00.000000000 Z
11
+ date: 2023-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amazing_print
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: fakefs
28
+ name: debug_me
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tocer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: "Manage the parameterized prompts (text) used in generative AI (aka chatGPT,
56
70
  \nOpenAI, et.al.) using storage adapters such as FileSystemAdapter, \nSqliteAdapter
57
71
  and ActiveRecordAdapter.\n"
@@ -69,6 +83,7 @@ files:
69
83
  - Rakefile
70
84
  - examples/prompts_dir/todo.json
71
85
  - examples/prompts_dir/todo.txt
86
+ - examples/prompts_dir/toy/8-ball.txt
72
87
  - examples/simple.rb
73
88
  - lib/prompt_manager.rb
74
89
  - lib/prompt_manager/prompt.rb