prompt_manager 0.1.1 → 0.2.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +85 -0
- data/Rakefile +9 -0
- data/examples/prompts_dir/toy/8-ball.txt +4 -0
- data/examples/simple.rb +58 -5
- data/lib/prompt_manager/prompt.rb +32 -0
- data/lib/prompt_manager/storage/file_system_adapter.rb +196 -36
- data/lib/prompt_manager/version.rb +1 -1
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbcdfe0c23335596eaad240b45fdb1451cab1be2569e511d21ddaf58ea986128
|
4
|
+
data.tar.gz: ce09536239ef6d06c8e42a120d0fd6661f3e42b72a4e9bea6dc998be12024956
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a603d11d09c89ba70e4577db65e0feb31246406dadb0b118717a51b1b4831d54dde782e90511a4d2e44733dd255c501296c97639b446d8f458903d391e3aa0a
|
7
|
+
data.tar.gz: bf48bf56a2e28ccde3ec5673ca9d54e5994ca4b7b71b35714177b2fcb8fbe07bf64521e5f4e9d8d1faf0ca4ec86f8ed98c5f879d532245e8978c200b319fee71
|
data/CHANGELOG.md
CHANGED
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 toe 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
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,26 +1,151 @@
|
|
1
1
|
# prompt_manager/lib/prompt_manager/storage/file_system_adapter.rb
|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
-
|
8
|
-
|
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
|
-
|
40
|
+
self
|
41
|
+
end
|
11
42
|
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
16
79
|
|
17
|
-
|
18
|
-
|
19
|
-
raise "
|
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
|
20
114
|
end
|
21
115
|
|
22
|
-
|
23
|
-
|
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
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
##################################################
|
135
|
+
###
|
136
|
+
## Instance
|
137
|
+
#
|
138
|
+
|
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
|
|
@@ -37,14 +162,20 @@ class PromptManager::Storage::FileSystemAdapter
|
|
37
162
|
|
38
163
|
# Retrieve prompt text by its id
|
39
164
|
def prompt_text(prompt_id)
|
40
|
-
read_file(file_path(prompt_id,
|
165
|
+
read_file(file_path(prompt_id, prompt_extension))
|
41
166
|
end
|
42
167
|
|
43
168
|
|
44
169
|
# Retrieve parameter values by its id
|
45
170
|
def parameter_values(prompt_id)
|
46
|
-
|
47
|
-
|
171
|
+
params_path = file_path(prompt_id, params_extension)
|
172
|
+
|
173
|
+
if params_path.exist?
|
174
|
+
parms_content = read_file(params_path)
|
175
|
+
deserialize(parms_content)
|
176
|
+
else
|
177
|
+
{}
|
178
|
+
end
|
48
179
|
end
|
49
180
|
|
50
181
|
|
@@ -56,8 +187,8 @@ class PromptManager::Storage::FileSystemAdapter
|
|
56
187
|
)
|
57
188
|
validate_id(id)
|
58
189
|
|
59
|
-
prompt_filepath = file_path(id,
|
60
|
-
params_filepath = file_path(id,
|
190
|
+
prompt_filepath = file_path(id, prompt_extension)
|
191
|
+
params_filepath = file_path(id, params_extension)
|
61
192
|
|
62
193
|
write_with_error_handling(prompt_filepath, text)
|
63
194
|
write_with_error_handling(params_filepath, serialize(parameters))
|
@@ -68,8 +199,8 @@ class PromptManager::Storage::FileSystemAdapter
|
|
68
199
|
def delete(id:)
|
69
200
|
validate_id(id)
|
70
201
|
|
71
|
-
prompt_filepath = file_path(id,
|
72
|
-
params_filepath = file_path(id,
|
202
|
+
prompt_filepath = file_path(id, prompt_extension)
|
203
|
+
params_filepath = file_path(id, params_extension)
|
73
204
|
|
74
205
|
delete_with_error_handling(prompt_filepath)
|
75
206
|
delete_with_error_handling(params_filepath)
|
@@ -85,26 +216,54 @@ class PromptManager::Storage::FileSystemAdapter
|
|
85
216
|
end
|
86
217
|
|
87
218
|
|
219
|
+
# Return an Array of prompt IDs
|
220
|
+
def list(*)
|
221
|
+
prompt_ids = []
|
222
|
+
|
223
|
+
Pathname.glob(prompts_dir.join("**/*#{prompt_extension}")).each do |file_path|
|
224
|
+
prompt_id = file_path.relative_path_from(prompts_dir).to_s.gsub(prompt_extension, '')
|
225
|
+
prompt_ids << prompt_id
|
226
|
+
end
|
227
|
+
|
228
|
+
prompt_ids
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
# Returns a Pathname object for a prompt ID text file
|
233
|
+
# However, it is possible that the file does not exist.
|
234
|
+
def path(id)
|
235
|
+
validate_id(id)
|
236
|
+
file_path(id, prompt_extension)
|
237
|
+
end
|
238
|
+
|
88
239
|
##########################################
|
89
240
|
private
|
90
241
|
|
242
|
+
# Validate that the ID contains good characters.
|
91
243
|
def validate_id(id)
|
92
|
-
raise ArgumentError,
|
244
|
+
raise ArgumentError, "Invalid ID format id: #{id}" unless id =~ PROMPT_ID_FORMAT
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
# Verify that the ID actually exists
|
249
|
+
def verify_id(id)
|
250
|
+
file_path(id, prompt_extension).exist?
|
93
251
|
end
|
94
252
|
|
95
253
|
|
96
254
|
def write_with_error_handling(file_path, content)
|
97
255
|
begin
|
98
|
-
|
256
|
+
file_path.write content
|
99
257
|
rescue IOError => e
|
100
258
|
raise "Failed to write to file: #{e.message}"
|
101
259
|
end
|
102
260
|
end
|
103
261
|
|
104
262
|
|
263
|
+
# file_path (Pathname)
|
105
264
|
def delete_with_error_handling(file_path)
|
106
265
|
begin
|
107
|
-
|
266
|
+
file_path.delete
|
108
267
|
rescue IOError => e
|
109
268
|
raise "Failed to delete file: #{e.message}"
|
110
269
|
end
|
@@ -112,7 +271,7 @@ class PromptManager::Storage::FileSystemAdapter
|
|
112
271
|
|
113
272
|
|
114
273
|
def file_path(id, extension)
|
115
|
-
|
274
|
+
prompts_dir + "#{id}#{extension}"
|
116
275
|
end
|
117
276
|
|
118
277
|
|
@@ -123,21 +282,22 @@ class PromptManager::Storage::FileSystemAdapter
|
|
123
282
|
|
124
283
|
|
125
284
|
def search_prompts(search_term)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
ids << File.basename(file_path, PROMPT_EXTENSION)
|
133
|
-
next
|
134
|
-
end
|
135
|
-
end
|
285
|
+
prompt_ids = []
|
286
|
+
|
287
|
+
Pathname.glob(prompts_dir.join("**/*#{prompt_extension}")).each do |prompt_path|
|
288
|
+
if prompt_path.read.downcase.include?(search_term)
|
289
|
+
prompt_id = prompt_path.relative_path_from(prompts_dir).to_s.gsub(prompt_extension, '')
|
290
|
+
prompt_ids << prompt_id
|
136
291
|
end
|
137
|
-
end
|
292
|
+
end
|
293
|
+
|
294
|
+
prompt_ids
|
295
|
+
|
138
296
|
end
|
139
297
|
|
140
298
|
|
299
|
+
# TODO: Should the serializer be generic?
|
300
|
+
|
141
301
|
def serialize(data)
|
142
302
|
data.to_json
|
143
303
|
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.
|
4
|
+
version: 0.2.0
|
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-
|
11
|
+
date: 2023-11-22 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:
|
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
|