prompt_manager 0.5.7 → 0.5.8
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 +4 -0
- data/COMMITS.md +196 -0
- data/README.md +485 -203
- data/docs/.keep +0 -0
- data/docs/advanced/custom-keywords.md +421 -0
- data/docs/advanced/dynamic-directives.md +535 -0
- data/docs/advanced/performance.md +612 -0
- data/docs/advanced/search-integration.md +635 -0
- data/docs/api/configuration.md +355 -0
- data/docs/api/directive-processor.md +431 -0
- data/docs/api/prompt-class.md +354 -0
- data/docs/api/storage-adapters.md +462 -0
- data/docs/assets/favicon.ico +1 -0
- data/docs/assets/logo.svg +24 -0
- data/docs/core-features/comments.md +48 -0
- data/docs/core-features/directive-processing.md +38 -0
- data/docs/core-features/erb-integration.md +68 -0
- data/docs/core-features/error-handling.md +197 -0
- data/docs/core-features/parameter-history.md +76 -0
- data/docs/core-features/parameterized-prompts.md +500 -0
- data/docs/core-features/shell-integration.md +79 -0
- data/docs/development/architecture.md +544 -0
- data/docs/development/contributing.md +425 -0
- data/docs/development/roadmap.md +234 -0
- data/docs/development/testing.md +822 -0
- data/docs/examples/advanced.md +523 -0
- data/docs/examples/basic.md +688 -0
- data/docs/examples/real-world.md +776 -0
- data/docs/examples.md +337 -0
- data/docs/getting-started/basic-concepts.md +318 -0
- data/docs/getting-started/installation.md +97 -0
- data/docs/getting-started/quick-start.md +256 -0
- data/docs/index.md +230 -0
- data/docs/migration/v0.9.0.md +459 -0
- data/docs/migration/v1.0.0.md +591 -0
- data/docs/storage/activerecord-adapter.md +348 -0
- data/docs/storage/custom-adapters.md +176 -0
- data/docs/storage/filesystem-adapter.md +236 -0
- data/docs/storage/overview.md +427 -0
- data/examples/advanced_integrations.rb +52 -0
- data/examples/prompts_dir/advanced_demo.txt +79 -0
- data/examples/prompts_dir/directive_example.json +1 -0
- data/examples/prompts_dir/directive_example.txt +8 -0
- data/examples/prompts_dir/todo.json +1 -1
- data/improvement_plan.md +996 -0
- data/lib/prompt_manager/storage/file_system_adapter.rb +8 -2
- data/lib/prompt_manager/version.rb +1 -1
- data/mkdocs.yml +146 -0
- data/prompt_manager_logo.png +0 -0
- metadata +46 -3
- data/LICENSE.txt +0 -21
data/README.md
CHANGED
@@ -1,58 +1,92 @@
|
|
1
1
|
# PromptManager
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
> [!CAUTION]
|
4
|
+
> ## ⚠️ Breaking Changes are Coming ⚠️
|
5
|
+
> See [Roadmap](#roadmap) for details about upcoming changes.
|
6
|
+
<br />
|
7
|
+
<div align="center">
|
8
|
+
<table>
|
9
|
+
<tr>
|
10
|
+
<td width="40%" align="center" valign="top">
|
11
|
+
<a href="https://madbomber.github.io/blog/" target="_blank">
|
12
|
+
<img src="prompt_manager_logo.png" alt="PromptManager - The Enchanted Librarian of AI Prompts" width="800">
|
13
|
+
</a>
|
14
|
+
<br /><br />
|
15
|
+
[Comprehensive Documentation Website](https://madbomber.github.io/prompt_manager/)
|
16
|
+
</td>
|
17
|
+
<td width="60%" align="left" valign="top">
|
18
|
+
Like an enchanted librarian organizing floating books of knowledge, PromptManager helps you masterfully orchestrate and organize your AI prompts through wisdom and experience. Each prompt becomes a living entity that can be categorized, parameterized, and interconnected with golden threads of relationships.
|
19
|
+
<br/><br/>
|
20
|
+
<h3>Key Features</h3>
|
21
|
+
<ul>
|
22
|
+
<li><strong>📚 <a href="#storage-adapters">Multiple Storage Adapters</a></strong>
|
23
|
+
<li><strong>🔧 <a href="#parameterized-prompts">Parameterized Prompts</a></strong>
|
24
|
+
<li><strong>📋 <a href="#directive-processing">Directive Processing</a></strong>
|
25
|
+
<li><strong>🎨 <a href="#erb-and-shell-integration">ERB Integration</a></strong>
|
26
|
+
<li><strong>🌍 <a href="#erb-and-shell-integration">Shell Integration</a></strong>
|
27
|
+
<li><strong>📖 <a href="#comments-and-documentation">Inline Documentation</a></strong>
|
28
|
+
<li><strong>📊 <a href="#parameter-history">Parameter History</a></strong>
|
29
|
+
<li><strong>⚡ <a href="#error-handling">Error Handling</a></strong>
|
30
|
+
<li><strong>🔌 <a href="#extensible-architecture">Extensible Architecture</a></strong>
|
31
|
+
</ul>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
</table>
|
35
|
+
</div>
|
10
36
|
|
11
37
|
## Table of Contents
|
12
38
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
39
|
+
* [Installation](#installation)
|
40
|
+
* [Quick Start](#quick-start)
|
41
|
+
* [Core Features](#core-features)
|
42
|
+
* [Parameterized Prompts](#parameterized-prompts)
|
43
|
+
* [Keyword Syntax](#keyword-syntax)
|
44
|
+
* [Custom Patterns](#custom-patterns)
|
45
|
+
* [Working with Parameters](#working-with-parameters)
|
46
|
+
* [Directive Processing](#directive-processing)
|
47
|
+
* [Built\-in Directives](#built-in-directives)
|
48
|
+
* [Directive Syntax](#directive-syntax)
|
49
|
+
* [Custom Directive Processors](#custom-directive-processors)
|
50
|
+
* [ERB and Shell Integration](#erb-and-shell-integration)
|
51
|
+
* [ERB Templates](#erb-templates)
|
52
|
+
* [Environment Variables](#environment-variables)
|
53
|
+
* [Comments and Documentation](#comments-and-documentation)
|
54
|
+
* [Line Comments](#line-comments)
|
55
|
+
* [Block Comments](#block-comments)
|
56
|
+
* [Blank Lines](#blank-lines)
|
57
|
+
* [Parameter History](#parameter-history)
|
58
|
+
* [Error Handling](#error-handling)
|
59
|
+
* [Storage Adapters](#storage-adapters)
|
60
|
+
* [FileSystemAdapter](#filesystemadapter)
|
61
|
+
* [Configuration](#configuration)
|
62
|
+
* [File Structure](#file-structure)
|
63
|
+
* [Custom Search](#custom-search)
|
64
|
+
* [Extra Methods](#extra-methods)
|
65
|
+
* [ActiveRecordAdapter](#activerecordadapter)
|
66
|
+
* [Configuration](#configuration-1)
|
67
|
+
* [Database Setup](#database-setup)
|
68
|
+
* [Custom Adapters](#custom-adapters)
|
69
|
+
* [Configuration](#configuration-2)
|
70
|
+
* [Initialization Options](#initialization-options)
|
71
|
+
* [Global Configuration](#global-configuration)
|
72
|
+
* [Advanced Usage](#advanced-usage)
|
73
|
+
* [Custom Keyword Patterns](#custom-keyword-patterns)
|
74
|
+
* [Dynamic Directives](#dynamic-directives)
|
75
|
+
* [Search Capabilities](#search-capabilities)
|
76
|
+
* [Examples](#examples)
|
77
|
+
* [Basic Usage](#basic-usage)
|
78
|
+
* [With Search](#with-search)
|
79
|
+
* [Custom Storage](#custom-storage)
|
80
|
+
* [Extensible Architecture](#extensible-architecture)
|
81
|
+
* [Extension Points](#extension-points)
|
82
|
+
* [Potential Extensions](#potential-extensions)
|
83
|
+
* [Roadmap](#roadmap)
|
84
|
+
* [v0\.9\.0 \- Modern Prompt Format (Breaking Changes)](#v090---modern-prompt-format-breaking-changes)
|
85
|
+
* [v1\.0\.0 \- Stability Release](#v100---stability-release)
|
86
|
+
* [Future Enhancements](#future-enhancements)
|
87
|
+
* [Development](#development)
|
88
|
+
* [Contributing](#contributing)
|
89
|
+
* [License](#license)
|
56
90
|
|
57
91
|
## Installation
|
58
92
|
|
@@ -64,271 +98,519 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
64
98
|
|
65
99
|
gem install prompt_manager
|
66
100
|
|
67
|
-
##
|
101
|
+
## Quick Start
|
68
102
|
|
69
|
-
|
103
|
+
```ruby
|
104
|
+
require 'prompt_manager'
|
70
105
|
|
71
|
-
|
106
|
+
# Configure storage adapter
|
107
|
+
PromptManager::Prompt.storage_adapter =
|
108
|
+
PromptManager::Storage::FileSystemAdapter.config do |config|
|
109
|
+
config.prompts_dir = '~/.prompts'
|
110
|
+
end.new
|
72
111
|
|
73
|
-
|
112
|
+
# Load and use a prompt
|
113
|
+
prompt = PromptManager::Prompt.new(id: 'greeting')
|
114
|
+
prompt.parameters = {
|
115
|
+
"[NAME]" => "Alice",
|
116
|
+
"[LANGUAGE]" => "English"
|
117
|
+
}
|
74
118
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
- `directives_processor`: An instance of PromptManager::DirectiveProcessor (default), can be customized.
|
79
|
-
- `external_binding`: A Ruby binding to be used for ERB processing.
|
80
|
-
- `erb_flag`: Boolean flag to enable ERB processing in the prompt text.
|
81
|
-
- `envar_flag`: Boolean flag to enable environment variable substitution in the prompt text.
|
119
|
+
# Get the processed prompt text
|
120
|
+
result = prompt.to_s
|
121
|
+
```
|
82
122
|
|
83
|
-
|
123
|
+
## Core Features
|
84
124
|
|
85
|
-
###
|
125
|
+
### Parameterized Prompts
|
86
126
|
|
87
|
-
|
127
|
+
The heart of PromptManager is its ability to manage parameterized prompts - text templates with embedded keywords that can be replaced with dynamic values.
|
88
128
|
|
89
|
-
|
129
|
+
#### Keyword Syntax
|
90
130
|
|
91
|
-
|
131
|
+
By default, keywords are enclosed in square brackets: `[KEYWORD]`, `[MULTIPLE WORDS]`, or `[WITH_UNDERSCORES]`.
|
92
132
|
|
93
|
-
|
133
|
+
```ruby
|
134
|
+
prompt_text = "Hello [NAME], please translate this to [LANGUAGE]"
|
135
|
+
```
|
94
136
|
|
95
|
-
|
137
|
+
#### Custom Patterns
|
138
|
+
|
139
|
+
You can customize the keyword pattern to match your preferences:
|
96
140
|
|
97
141
|
```ruby
|
98
|
-
# Use {{
|
142
|
+
# Use {{mustache}} style
|
99
143
|
PromptManager::Prompt.parameter_regex = /(\{\{[A-Za-z_]+\}\})/
|
144
|
+
|
145
|
+
# Use :colon style
|
146
|
+
PromptManager::Prompt.parameter_regex = /(:[a-z_]+)/
|
100
147
|
```
|
101
148
|
|
102
|
-
The regex must include capturing parentheses () to extract the keyword.
|
103
|
-
#### All about directives
|
149
|
+
The regex must include capturing parentheses `()` to extract the keyword.
|
104
150
|
|
105
|
-
|
151
|
+
#### Working with Parameters
|
106
152
|
|
107
|
-
|
153
|
+
```ruby
|
154
|
+
prompt = PromptManager::Prompt.new(id: 'example')
|
108
155
|
|
109
|
-
|
156
|
+
# Get all keywords found in the prompt
|
157
|
+
keywords = prompt.keywords #=> ["[NAME]", "[LANGUAGE]"]
|
110
158
|
|
111
|
-
|
159
|
+
# Set parameter values
|
160
|
+
prompt.parameters = {
|
161
|
+
"[NAME]" => "Alice",
|
162
|
+
"[LANGUAGE]" => "French"
|
163
|
+
}
|
164
|
+
|
165
|
+
# Get processed text with substitutions
|
166
|
+
final_text = prompt.to_s
|
167
|
+
|
168
|
+
# Save changes
|
169
|
+
prompt.save
|
170
|
+
```
|
171
|
+
|
172
|
+
### Directive Processing
|
173
|
+
|
174
|
+
Directives are special line oriented instructions in your prompts that begin with `//` starting in column 1. They're inspired by IBM JCL and provide powerful prompt composition capabilities. A character string that begins with `//` but is not at the very beginning of the line will NOT be processed as a directive.
|
175
|
+
|
176
|
+
#### Built-in Directives
|
177
|
+
|
178
|
+
**`//include` (alias: `//import`)** - Include content from other files:
|
112
179
|
|
113
180
|
```text
|
114
|
-
|
115
|
-
|
181
|
+
//include common/header.txt
|
182
|
+
//import [TEMPLATE_NAME].txt
|
116
183
|
|
117
|
-
|
184
|
+
Main prompt content here...
|
185
|
+
```
|
118
186
|
|
119
|
-
|
187
|
+
Features:
|
188
|
+
- Loop protection prevents circular includes
|
189
|
+
- Supports keyword substitution in file paths
|
190
|
+
- Processes included files recursively
|
120
191
|
|
121
|
-
|
122
|
-
|
192
|
+
#### Directive Syntax
|
193
|
+
|
194
|
+
```text
|
195
|
+
//directive_name [PARAM1] [PARAM2] options
|
196
|
+
|
197
|
+
# Dynamic directives using keywords
|
198
|
+
//[COMMAND] [OPTIONS]
|
199
|
+
```
|
200
|
+
|
201
|
+
#### Custom Directive Processors
|
202
|
+
|
203
|
+
You can create custom directive processors:
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
class MyDirectiveProcessor < PromptManager::DirectiveProcessor
|
207
|
+
def process_directive(directive, prompt)
|
208
|
+
case directive
|
209
|
+
when /^\/\/model (.+)$/
|
210
|
+
set_model($1)
|
211
|
+
when /^\/\/temperature (.+)$/
|
212
|
+
set_temperature($1.to_f)
|
213
|
+
else
|
214
|
+
super
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
prompt = PromptManager::Prompt.new(
|
220
|
+
id: 'example',
|
221
|
+
directives_processor: MyDirectiveProcessor.new
|
222
|
+
)
|
123
223
|
```
|
124
224
|
|
125
|
-
|
225
|
+
### ERB and Shell Integration
|
126
226
|
|
127
|
-
|
227
|
+
#### ERB Templates
|
228
|
+
|
229
|
+
Enable ERB processing for dynamic content generation:
|
128
230
|
|
129
231
|
```ruby
|
130
|
-
prompt = PromptManager::Prompt.new(
|
131
|
-
|
232
|
+
prompt = PromptManager::Prompt.new(
|
233
|
+
id: 'dynamic',
|
234
|
+
erb_flag: true
|
235
|
+
)
|
236
|
+
```
|
132
237
|
|
133
|
-
|
134
|
-
prompt.parameters = {
|
135
|
-
"[KEYWORD1]" => "value1",
|
136
|
-
"[KEYWORD2]" => "value2"
|
137
|
-
}
|
238
|
+
Example prompt with ERB:
|
138
239
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
240
|
+
```text
|
241
|
+
Today's date is <%= Date.today %>
|
242
|
+
<% 5.times do |i| %>
|
243
|
+
Item <%= i + 1 %>
|
244
|
+
<% end %>
|
245
|
+
```
|
143
246
|
|
144
|
-
|
145
|
-
|
247
|
+
#### Environment Variables
|
248
|
+
|
249
|
+
Enable automatic environment variable substitution:
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
prompt = PromptManager::Prompt.new(
|
253
|
+
id: 'with_env',
|
254
|
+
envar_flag: true
|
255
|
+
)
|
146
256
|
```
|
147
257
|
|
148
|
-
|
258
|
+
Environment variables are automatically replaced in the prompt text.
|
259
|
+
|
260
|
+
### Comments and Documentation
|
261
|
+
|
262
|
+
PromptManager supports comprehensive inline documentation:
|
149
263
|
|
150
|
-
|
264
|
+
#### Line Comments
|
151
265
|
|
152
|
-
|
266
|
+
Lines beginning with `#` are treated as comments:
|
153
267
|
|
154
268
|
```text
|
155
|
-
|
156
|
-
#
|
157
|
-
|
269
|
+
# This is a comment
|
270
|
+
# Description: This prompt does something useful
|
271
|
+
|
272
|
+
Actual prompt text here...
|
158
273
|
```
|
159
|
-
... where [COMMAND] gets replaced by some directive name. [SOMETHING] could be replaced by "//directive options"
|
160
274
|
|
161
|
-
|
275
|
+
#### Block Comments
|
162
276
|
|
163
|
-
|
277
|
+
Everything after `__END__` is ignored:
|
164
278
|
|
165
|
-
|
279
|
+
```text
|
280
|
+
Main prompt content...
|
166
281
|
|
167
|
-
|
168
|
-
|
169
|
-
-
|
282
|
+
__END__
|
283
|
+
Development notes:
|
284
|
+
- This section is completely ignored
|
285
|
+
- Great for documentation
|
286
|
+
- TODO items
|
287
|
+
```
|
170
288
|
|
171
|
-
|
289
|
+
#### Blank Lines
|
172
290
|
|
291
|
+
Blank lines are automatically removed from the final output.
|
173
292
|
|
174
|
-
|
293
|
+
### Parameter History
|
175
294
|
|
176
|
-
|
295
|
+
PromptManager maintains a history of parameter values (since v0.3.0):
|
177
296
|
|
178
|
-
|
297
|
+
```ruby
|
298
|
+
# Parameters are stored as arrays
|
299
|
+
prompt.parameters = {
|
300
|
+
"[NAME]" => ["Alice", "Bob", "Charlie"] # Charlie is most recent
|
301
|
+
}
|
179
302
|
|
180
|
-
|
303
|
+
# The last value is always the most recent
|
304
|
+
current_name = prompt.parameters["[NAME]"].last
|
181
305
|
|
182
|
-
|
306
|
+
# Useful for:
|
307
|
+
# - Implementing value history in UIs
|
308
|
+
# - Providing dropdown selections
|
309
|
+
# - Tracking parameter usage over time
|
310
|
+
```
|
183
311
|
|
184
|
-
|
312
|
+
### Error Handling
|
313
|
+
|
314
|
+
PromptManager provides specific error classes for better debugging:
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
begin
|
318
|
+
prompt = PromptManager::Prompt.new(id: 'missing')
|
319
|
+
rescue PromptManager::StorageError => e
|
320
|
+
# Handle storage-related errors
|
321
|
+
puts "Storage error: #{e.message}"
|
322
|
+
rescue PromptManager::ParameterError => e
|
323
|
+
# Handle parameter substitution errors
|
324
|
+
puts "Parameter error: #{e.message}"
|
325
|
+
rescue PromptManager::ConfigurationError => e
|
326
|
+
# Handle configuration errors
|
327
|
+
puts "Configuration error: #{e.message}"
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
## Storage Adapters
|
332
|
+
|
333
|
+
Storage adapters provide the persistence layer for prompts. PromptManager includes two built-in adapters and supports custom implementations.
|
185
334
|
|
186
335
|
### FileSystemAdapter
|
187
336
|
|
188
|
-
|
337
|
+
Stores prompts as text files in a directory structure.
|
189
338
|
|
190
|
-
|
339
|
+
#### Configuration
|
191
340
|
|
192
|
-
|
341
|
+
```ruby
|
342
|
+
PromptManager::Storage::FileSystemAdapter.config do |config|
|
343
|
+
config.prompts_dir = "~/.prompts" # Required
|
344
|
+
config.search_proc = nil # Optional custom search
|
345
|
+
config.prompt_extension = '.txt' # Default
|
346
|
+
config.params_extension = '.json' # Default
|
347
|
+
end
|
348
|
+
```
|
349
|
+
|
350
|
+
#### File Structure
|
351
|
+
|
352
|
+
```
|
353
|
+
~/.prompts/
|
354
|
+
├── greeting.txt # Prompt text
|
355
|
+
├── greeting.json # Parameters
|
356
|
+
├── email/
|
357
|
+
│ ├── welcome.txt
|
358
|
+
│ └── welcome.json
|
359
|
+
```
|
360
|
+
|
361
|
+
#### Custom Search
|
362
|
+
|
363
|
+
Integrate with external search tools:
|
364
|
+
|
365
|
+
```ruby
|
366
|
+
config.search_proc = ->(query) {
|
367
|
+
# Use ripgrep for fast searching
|
368
|
+
`rg -l "#{query}" #{config.prompts_dir}`.split("\n")
|
369
|
+
}
|
370
|
+
```
|
371
|
+
|
372
|
+
#### Extra Methods
|
373
|
+
|
374
|
+
- `list` - Returns array of all prompt IDs
|
375
|
+
- `path(id)` - Returns Pathname to prompt file
|
376
|
+
|
377
|
+
### ActiveRecordAdapter
|
378
|
+
|
379
|
+
Stores prompts in a database using ActiveRecord.
|
193
380
|
|
194
381
|
#### Configuration
|
195
382
|
|
196
|
-
|
383
|
+
```ruby
|
384
|
+
PromptManager::Storage::ActiveRecordAdapter.config do |config|
|
385
|
+
config.model = PromptModel # Your AR model
|
386
|
+
config.id_column = :prompt_id # Column for ID
|
387
|
+
config.text_column = :content # Column for text
|
388
|
+
config.parameters_column = :params # Column for parameters
|
389
|
+
end
|
390
|
+
```
|
391
|
+
|
392
|
+
#### Database Setup
|
393
|
+
|
394
|
+
```ruby
|
395
|
+
class CreatePrompts < ActiveRecord::Migration[7.0]
|
396
|
+
def change
|
397
|
+
create_table :prompts do |t|
|
398
|
+
t.string :prompt_id, null: false, index: { unique: true }
|
399
|
+
t.text :content
|
400
|
+
t.json :params
|
401
|
+
t.timestamps
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
```
|
406
|
+
|
407
|
+
### Custom Adapters
|
408
|
+
|
409
|
+
Create your own storage adapter:
|
197
410
|
|
198
411
|
```ruby
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
412
|
+
class RedisAdapter
|
413
|
+
def initialize(redis_client)
|
414
|
+
@redis = redis_client
|
415
|
+
end
|
416
|
+
|
417
|
+
def get(id)
|
418
|
+
prompt_text = @redis.get("prompt:#{id}:text")
|
419
|
+
parameters = JSON.parse(@redis.get("prompt:#{id}:params") || '{}')
|
420
|
+
[prompt_text, parameters]
|
421
|
+
end
|
422
|
+
|
423
|
+
def save(id, text, parameters)
|
424
|
+
@redis.set("prompt:#{id}:text", text)
|
425
|
+
@redis.set("prompt:#{id}:params", parameters.to_json)
|
426
|
+
end
|
427
|
+
|
428
|
+
def delete(id)
|
429
|
+
@redis.del("prompt:#{id}:text", "prompt:#{id}:params")
|
430
|
+
end
|
431
|
+
|
432
|
+
def list
|
433
|
+
@redis.keys("prompt:*:text").map { |k| k.split(':')[1] }
|
434
|
+
end
|
204
435
|
end
|
205
436
|
```
|
206
437
|
|
207
|
-
|
438
|
+
## Configuration
|
439
|
+
|
440
|
+
### Initialization Options
|
441
|
+
|
442
|
+
When creating a prompt instance:
|
208
443
|
|
209
444
|
```ruby
|
210
|
-
PromptManager::Prompt
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
445
|
+
prompt = PromptManager::Prompt.new(
|
446
|
+
id: 'example',
|
447
|
+
context: ['additional', 'context'],
|
448
|
+
directives_processor: CustomProcessor.new,
|
449
|
+
external_binding: binding,
|
450
|
+
erb_flag: true,
|
451
|
+
envar_flag: true
|
452
|
+
)
|
216
453
|
```
|
217
454
|
|
218
|
-
|
455
|
+
Options:
|
456
|
+
- `id` - Unique identifier for the prompt
|
457
|
+
- `context` - Additional context array
|
458
|
+
- `directives_processor` - Custom directive processor
|
459
|
+
- `external_binding` - Ruby binding for ERB
|
460
|
+
- `erb_flag` - Enable ERB processing
|
461
|
+
- `envar_flag` - Enable environment variable substitution
|
219
462
|
|
220
|
-
|
463
|
+
### Global Configuration
|
221
464
|
|
222
|
-
|
465
|
+
Set the storage adapter globally:
|
223
466
|
|
224
|
-
|
467
|
+
```ruby
|
468
|
+
PromptManager::Prompt.storage_adapter = adapter_instance
|
469
|
+
```
|
225
470
|
|
226
|
-
|
471
|
+
## Advanced Usage
|
227
472
|
|
228
|
-
|
473
|
+
### Custom Keyword Patterns
|
229
474
|
|
230
|
-
|
475
|
+
Examples of different keyword patterns:
|
231
476
|
|
232
|
-
|
477
|
+
```ruby
|
478
|
+
# Handlebars style: {{name}}
|
479
|
+
PromptManager::Prompt.parameter_regex = /(\{\{[a-z_]+\}\})/
|
233
480
|
|
234
|
-
|
481
|
+
# Colon prefix: :name
|
482
|
+
PromptManager::Prompt.parameter_regex = /(:[a-z_]+)/
|
235
483
|
|
236
|
-
|
237
|
-
|
484
|
+
# Dollar sign: $NAME
|
485
|
+
PromptManager::Prompt.parameter_regex = /(\$[A-Z_]+)/
|
238
486
|
|
239
|
-
|
487
|
+
# Percentage: %name%
|
488
|
+
PromptManager::Prompt.parameter_regex = /(%[a-z_]+%)/
|
489
|
+
```
|
240
490
|
|
241
|
-
|
491
|
+
### Dynamic Directives
|
242
492
|
|
243
|
-
|
493
|
+
Create directives that change based on parameters:
|
244
494
|
|
245
495
|
```text
|
246
|
-
#
|
247
|
-
|
496
|
+
# Set directive name via parameter
|
497
|
+
//[DIRECTIVE_TYPE] [OPTIONS]
|
248
498
|
|
249
|
-
|
499
|
+
# Conditional directives
|
500
|
+
//include templates/[TEMPLATE_TYPE].txt
|
250
501
|
```
|
251
502
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
```
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
503
|
+
### Search Capabilities
|
504
|
+
|
505
|
+
Implement powerful search across prompts:
|
506
|
+
|
507
|
+
```ruby
|
508
|
+
# With FileSystemAdapter
|
509
|
+
adapter.search_proc = ->(query) {
|
510
|
+
# Custom search implementation
|
511
|
+
results = []
|
512
|
+
Dir.glob("#{prompts_dir}/**/*.txt").each do |file|
|
513
|
+
content = File.read(file)
|
514
|
+
if content.include?(query)
|
515
|
+
results << File.basename(file, '.txt')
|
516
|
+
end
|
517
|
+
end
|
518
|
+
results
|
268
519
|
}
|
520
|
+
|
521
|
+
# With ActiveRecordAdapter
|
522
|
+
PromptModel.where("content LIKE ?", "%#{query}%").pluck(:prompt_id)
|
269
523
|
```
|
270
524
|
|
271
|
-
|
525
|
+
## Examples
|
272
526
|
|
273
|
-
|
527
|
+
### Basic Usage
|
274
528
|
|
275
|
-
|
529
|
+
```ruby
|
530
|
+
# examples/simple.rb
|
531
|
+
require 'prompt_manager'
|
276
532
|
|
277
|
-
|
278
|
-
|
533
|
+
# Setup
|
534
|
+
PromptManager::Prompt.storage_adapter =
|
535
|
+
PromptManager::Storage::FileSystemAdapter.config do |c|
|
536
|
+
c.prompts_dir = '~/.prompts'
|
537
|
+
end.new
|
279
538
|
|
280
|
-
|
281
|
-
|
539
|
+
# Create and use a prompt
|
540
|
+
prompt = PromptManager::Prompt.new(id: 'story')
|
541
|
+
prompt.parameters = {
|
542
|
+
"[GENRE]" => "fantasy",
|
543
|
+
"[CHARACTER]" => "wizard"
|
544
|
+
}
|
282
545
|
|
283
|
-
|
546
|
+
puts prompt.to_s
|
547
|
+
```
|
284
548
|
|
285
|
-
|
549
|
+
### Advanced Integration with LLM and Streaming
|
286
550
|
|
287
|
-
|
288
|
-
- prompt text
|
289
|
-
- prompt parameters
|
551
|
+
See [examples/advanced_integrations.rb](examples/advanced_integrations.rb) for a complete example that demonstrates:
|
290
552
|
|
291
|
-
|
553
|
+
- **ERB templating** for dynamic content generation
|
554
|
+
- **Shell integration** for environment variable substitution
|
555
|
+
- **OpenAI API integration** with streaming responses
|
556
|
+
- **Professional UI** with spinner feedback using `tty-spinner`
|
292
557
|
|
558
|
+
This example shows how to create sophisticated AI prompts that adapt to your system environment and stream responses in real-time.
|
293
559
|
|
294
|
-
|
560
|
+
### With Search
|
295
561
|
|
296
|
-
|
562
|
+
See [examples/using_search_proc.rb](examples/using_search_proc.rb) for advanced search integration.
|
297
563
|
|
298
|
-
|
564
|
+
### Custom Storage
|
299
565
|
|
300
566
|
```ruby
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
config.parameters_column = :prompt_params
|
308
|
-
end.new # adapters an instances of the adapter class
|
567
|
+
# examples/redis_storage.rb
|
568
|
+
class RedisStorage
|
569
|
+
# ... implementation
|
570
|
+
end
|
571
|
+
|
572
|
+
PromptManager::Prompt.storage_adapter = RedisStorage.new(Redis.new)
|
309
573
|
```
|
310
574
|
|
311
|
-
|
312
|
-
|
575
|
+
## Extensible Architecture
|
576
|
+
|
577
|
+
PromptManager is designed to be extended:
|
578
|
+
|
579
|
+
### Extension Points
|
313
580
|
|
314
|
-
|
315
|
-
|
581
|
+
1. **Storage Adapters** - Implement your own persistence layer
|
582
|
+
2. **Directive Processors** - Add custom directives
|
583
|
+
3. **Search Processors** - Integrate external search tools
|
584
|
+
4. **Serializers** - Support different parameter formats
|
316
585
|
|
317
|
-
|
318
|
-
The `text_column` contains name of the column that contains the actual raw text of the prompt. This raw text can include the keywords which will be replaced by values from the parameters Hash. The column name value can be either a `String` or a `Symbol`.
|
586
|
+
### Potential Extensions
|
319
587
|
|
320
|
-
|
321
|
-
|
588
|
+
- **CloudStorageAdapter** - S3, Google Cloud Storage
|
589
|
+
- **RedisAdapter** - For caching and fast access
|
590
|
+
- **ApiAdapter** - REST API backend
|
591
|
+
- **GraphQLAdapter** - GraphQL endpoint storage
|
592
|
+
- **GitAdapter** - Version controlled prompts
|
322
593
|
|
323
|
-
|
594
|
+
## Roadmap
|
324
595
|
|
325
|
-
###
|
596
|
+
### v0.9.0 - Modern Prompt Format (Breaking Changes)
|
597
|
+
- **Markdown Support**: Full `.md` file support with YAML front matter
|
598
|
+
- **Modern Parameter Syntax**: Support for `{{keyword}}` format
|
599
|
+
- **Enhanced API**: New `set_parameter()` and `get_parameter()` methods
|
600
|
+
- **Parameter Validation**: Built-in validation based on specifications
|
601
|
+
- **HTML Comments**: Support for `<!-- comments -->`
|
602
|
+
- **Migration Tools**: Automated conversion utilities
|
326
603
|
|
327
|
-
|
604
|
+
### v1.0.0 - Stability Release
|
605
|
+
- Performance optimizations
|
606
|
+
- Complete documentation
|
607
|
+
- Production hardening
|
328
608
|
|
329
|
-
|
330
|
-
-
|
331
|
-
-
|
609
|
+
### Future Enhancements
|
610
|
+
- Additional storage adapters
|
611
|
+
- Enhanced directive system with plugins
|
612
|
+
- Prompt versioning and inheritance
|
613
|
+
- Performance optimizations for large collections
|
332
614
|
|
333
615
|
## Development
|
334
616
|
|