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
@@ -0,0 +1,462 @@
|
|
1
|
+
# Storage Adapters API Reference
|
2
|
+
|
3
|
+
PromptManager uses a storage adapter pattern to provide flexible backends for prompt storage and retrieval.
|
4
|
+
|
5
|
+
## Base Storage Adapter
|
6
|
+
|
7
|
+
All storage adapters inherit from `PromptManager::Storage::Base` and must implement the core interface.
|
8
|
+
|
9
|
+
### `PromptManager::Storage::Base`
|
10
|
+
|
11
|
+
The abstract base class that defines the storage adapter interface.
|
12
|
+
|
13
|
+
#### Required Methods
|
14
|
+
|
15
|
+
##### `read(prompt_id)`
|
16
|
+
|
17
|
+
Reads prompt content from storage.
|
18
|
+
|
19
|
+
**Parameters:**
|
20
|
+
- `prompt_id` (String): Unique identifier for the prompt
|
21
|
+
|
22
|
+
**Returns:** String - The prompt content
|
23
|
+
|
24
|
+
**Raises:**
|
25
|
+
- `PromptManager::PromptNotFoundError` - If prompt doesn't exist
|
26
|
+
- `PromptManager::StorageError` - For storage-related errors
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
def read(prompt_id)
|
30
|
+
# Implementation must return prompt content as string
|
31
|
+
# or raise PromptNotFoundError if not found
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
##### `write(prompt_id, content)`
|
36
|
+
|
37
|
+
Writes prompt content to storage.
|
38
|
+
|
39
|
+
**Parameters:**
|
40
|
+
- `prompt_id` (String): Unique identifier for the prompt
|
41
|
+
- `content` (String): The prompt content to store
|
42
|
+
|
43
|
+
**Returns:** Boolean - True on success
|
44
|
+
|
45
|
+
**Raises:**
|
46
|
+
- `PromptManager::StorageError` - For storage-related errors
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
def write(prompt_id, content)
|
50
|
+
# Implementation must store content and return true
|
51
|
+
# or raise StorageError on failure
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
##### `exist?(prompt_id)`
|
56
|
+
|
57
|
+
Checks if a prompt exists in storage.
|
58
|
+
|
59
|
+
**Parameters:**
|
60
|
+
- `prompt_id` (String): Unique identifier for the prompt
|
61
|
+
|
62
|
+
**Returns:** Boolean - True if prompt exists
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
def exist?(prompt_id)
|
66
|
+
# Implementation must return boolean
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
##### `delete(prompt_id)`
|
71
|
+
|
72
|
+
Removes a prompt from storage.
|
73
|
+
|
74
|
+
**Parameters:**
|
75
|
+
- `prompt_id` (String): Unique identifier for the prompt
|
76
|
+
|
77
|
+
**Returns:** Boolean - True if successfully deleted
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
def delete(prompt_id)
|
81
|
+
# Implementation must remove prompt and return success status
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
##### `list`
|
86
|
+
|
87
|
+
Returns all available prompt identifiers.
|
88
|
+
|
89
|
+
**Returns:** Array<String> - Array of prompt IDs
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
def list
|
93
|
+
# Implementation must return array of all prompt IDs
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
#### Optional Methods
|
98
|
+
|
99
|
+
##### `initialize(**options)`
|
100
|
+
|
101
|
+
Constructor for storage adapter configuration.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
def initialize(**options)
|
105
|
+
super
|
106
|
+
# Custom initialization logic
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
##### `clear`
|
111
|
+
|
112
|
+
Removes all prompts from storage (optional).
|
113
|
+
|
114
|
+
**Returns:** Boolean - True on success
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
def clear
|
118
|
+
# Optional: implement to support clearing all prompts
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
## Built-in Storage Adapters
|
123
|
+
|
124
|
+
### FileSystemAdapter
|
125
|
+
|
126
|
+
Stores prompts as files in a directory structure.
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
adapter = PromptManager::Storage::FileSystemAdapter.new(
|
130
|
+
prompts_dir: '/path/to/prompts',
|
131
|
+
file_extensions: ['.txt', '.md', '.prompt'],
|
132
|
+
create_directories: true
|
133
|
+
)
|
134
|
+
```
|
135
|
+
|
136
|
+
**Configuration Options:**
|
137
|
+
|
138
|
+
- `prompts_dir` (String|Array): Directory path(s) to search
|
139
|
+
- `file_extensions` (Array): File extensions to recognize (default: `['.txt', '.md']`)
|
140
|
+
- `create_directories` (Boolean): Create directories if they don't exist (default: `true`)
|
141
|
+
|
142
|
+
**Features:**
|
143
|
+
- Hierarchical prompt organization with subdirectories
|
144
|
+
- Multiple search paths with fallback
|
145
|
+
- Automatic file extension detection
|
146
|
+
- Thread-safe file operations
|
147
|
+
|
148
|
+
### ActiveRecordAdapter
|
149
|
+
|
150
|
+
Stores prompts in a database using ActiveRecord.
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
adapter = PromptManager::Storage::ActiveRecordAdapter.new(
|
154
|
+
model_class: Prompt,
|
155
|
+
id_column: :prompt_id,
|
156
|
+
content_column: :content,
|
157
|
+
scope: -> { where(active: true) }
|
158
|
+
)
|
159
|
+
```
|
160
|
+
|
161
|
+
**Configuration Options:**
|
162
|
+
|
163
|
+
- `model_class` (Class): ActiveRecord model class
|
164
|
+
- `id_column` (Symbol): Column containing prompt ID (default: `:prompt_id`)
|
165
|
+
- `content_column` (Symbol): Column containing prompt content (default: `:content`)
|
166
|
+
- `scope` (Proc): Additional query scope (optional)
|
167
|
+
|
168
|
+
**Features:**
|
169
|
+
- Full database integration with Rails
|
170
|
+
- Transaction support
|
171
|
+
- Query optimization
|
172
|
+
- Multi-tenancy support
|
173
|
+
|
174
|
+
## Custom Adapter Implementation
|
175
|
+
|
176
|
+
### Example: MemoryAdapter
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class MemoryAdapter < PromptManager::Storage::Base
|
180
|
+
def initialize(**options)
|
181
|
+
super
|
182
|
+
@prompts = {}
|
183
|
+
@mutex = Mutex.new
|
184
|
+
end
|
185
|
+
|
186
|
+
def read(prompt_id)
|
187
|
+
@mutex.synchronize do
|
188
|
+
content = @prompts[prompt_id]
|
189
|
+
raise PromptManager::PromptNotFoundError.new("Prompt '#{prompt_id}' not found") unless content
|
190
|
+
content
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def write(prompt_id, content)
|
195
|
+
@mutex.synchronize do
|
196
|
+
@prompts[prompt_id] = content
|
197
|
+
end
|
198
|
+
true
|
199
|
+
end
|
200
|
+
|
201
|
+
def exist?(prompt_id)
|
202
|
+
@mutex.synchronize { @prompts.key?(prompt_id) }
|
203
|
+
end
|
204
|
+
|
205
|
+
def delete(prompt_id)
|
206
|
+
@mutex.synchronize do
|
207
|
+
@prompts.delete(prompt_id) ? true : false
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def list
|
212
|
+
@mutex.synchronize { @prompts.keys }
|
213
|
+
end
|
214
|
+
|
215
|
+
def clear
|
216
|
+
@mutex.synchronize { @prompts.clear }
|
217
|
+
true
|
218
|
+
end
|
219
|
+
end
|
220
|
+
```
|
221
|
+
|
222
|
+
### Example: HTTPAdapter
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
require 'net/http'
|
226
|
+
require 'json'
|
227
|
+
|
228
|
+
class HTTPAdapter < PromptManager::Storage::Base
|
229
|
+
def initialize(base_url:, api_token: nil, **options)
|
230
|
+
super(**options)
|
231
|
+
@base_url = base_url.chomp('/')
|
232
|
+
@api_token = api_token
|
233
|
+
end
|
234
|
+
|
235
|
+
def read(prompt_id)
|
236
|
+
response = http_get("/prompts/#{prompt_id}")
|
237
|
+
|
238
|
+
case response.code
|
239
|
+
when '200'
|
240
|
+
JSON.parse(response.body)['content']
|
241
|
+
when '404'
|
242
|
+
raise PromptManager::PromptNotFoundError.new("Prompt '#{prompt_id}' not found")
|
243
|
+
else
|
244
|
+
raise PromptManager::StorageError.new("HTTP error: #{response.code}")
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def write(prompt_id, content)
|
249
|
+
body = { content: content }.to_json
|
250
|
+
response = http_post("/prompts/#{prompt_id}", body)
|
251
|
+
|
252
|
+
response.code == '200' || response.code == '201'
|
253
|
+
end
|
254
|
+
|
255
|
+
def exist?(prompt_id)
|
256
|
+
response = http_head("/prompts/#{prompt_id}")
|
257
|
+
response.code == '200'
|
258
|
+
rescue
|
259
|
+
false
|
260
|
+
end
|
261
|
+
|
262
|
+
def delete(prompt_id)
|
263
|
+
response = http_delete("/prompts/#{prompt_id}")
|
264
|
+
response.code == '200' || response.code == '204'
|
265
|
+
end
|
266
|
+
|
267
|
+
def list
|
268
|
+
response = http_get("/prompts")
|
269
|
+
return [] unless response.code == '200'
|
270
|
+
|
271
|
+
JSON.parse(response.body)['prompt_ids']
|
272
|
+
end
|
273
|
+
|
274
|
+
private
|
275
|
+
|
276
|
+
def http_get(path)
|
277
|
+
uri = URI("#{@base_url}#{path}")
|
278
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
279
|
+
http.use_ssl = uri.scheme == 'https'
|
280
|
+
|
281
|
+
request = Net::HTTP::Get.new(uri)
|
282
|
+
add_auth_header(request)
|
283
|
+
|
284
|
+
http.request(request)
|
285
|
+
end
|
286
|
+
|
287
|
+
def http_post(path, body)
|
288
|
+
uri = URI("#{@base_url}#{path}")
|
289
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
290
|
+
http.use_ssl = uri.scheme == 'https'
|
291
|
+
|
292
|
+
request = Net::HTTP::Post.new(uri)
|
293
|
+
request['Content-Type'] = 'application/json'
|
294
|
+
request.body = body
|
295
|
+
add_auth_header(request)
|
296
|
+
|
297
|
+
http.request(request)
|
298
|
+
end
|
299
|
+
|
300
|
+
def add_auth_header(request)
|
301
|
+
return unless @api_token
|
302
|
+
request['Authorization'] = "Bearer #{@api_token}"
|
303
|
+
end
|
304
|
+
end
|
305
|
+
```
|
306
|
+
|
307
|
+
## Adapter Registration
|
308
|
+
|
309
|
+
Register your custom adapter:
|
310
|
+
|
311
|
+
```ruby
|
312
|
+
# Global configuration
|
313
|
+
PromptManager.configure do |config|
|
314
|
+
config.storage = CustomAdapter.new(option: 'value')
|
315
|
+
end
|
316
|
+
|
317
|
+
# Per-prompt configuration
|
318
|
+
prompt = PromptManager::Prompt.new(
|
319
|
+
id: 'special_prompt',
|
320
|
+
storage: CustomAdapter.new
|
321
|
+
)
|
322
|
+
```
|
323
|
+
|
324
|
+
## Error Handling
|
325
|
+
|
326
|
+
### Standard Exceptions
|
327
|
+
|
328
|
+
All adapters should raise these standard exceptions:
|
329
|
+
|
330
|
+
```ruby
|
331
|
+
# Prompt not found
|
332
|
+
raise PromptManager::PromptNotFoundError.new("Prompt 'xyz' not found")
|
333
|
+
|
334
|
+
# Storage operation failed
|
335
|
+
raise PromptManager::StorageError.new("Connection timeout")
|
336
|
+
|
337
|
+
# Configuration error
|
338
|
+
raise PromptManager::ConfigurationError.new("Invalid database URL")
|
339
|
+
```
|
340
|
+
|
341
|
+
### Error Context
|
342
|
+
|
343
|
+
Provide context in error messages:
|
344
|
+
|
345
|
+
```ruby
|
346
|
+
begin
|
347
|
+
content = storage.read(prompt_id)
|
348
|
+
rescue => e
|
349
|
+
raise PromptManager::StorageError.new(
|
350
|
+
"Failed to read prompt '#{prompt_id}': #{e.message}"
|
351
|
+
)
|
352
|
+
end
|
353
|
+
```
|
354
|
+
|
355
|
+
## Performance Considerations
|
356
|
+
|
357
|
+
### Connection Pooling
|
358
|
+
|
359
|
+
```ruby
|
360
|
+
class PooledAdapter < PromptManager::Storage::Base
|
361
|
+
def initialize(pool_size: 10, **options)
|
362
|
+
super(**options)
|
363
|
+
@pool = ConnectionPool.new(size: pool_size) do
|
364
|
+
create_connection
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def read(prompt_id)
|
369
|
+
@pool.with { |conn| conn.read(prompt_id) }
|
370
|
+
end
|
371
|
+
end
|
372
|
+
```
|
373
|
+
|
374
|
+
### Caching
|
375
|
+
|
376
|
+
```ruby
|
377
|
+
class CachedAdapter < PromptManager::Storage::Base
|
378
|
+
def initialize(cache_ttl: 300, **options)
|
379
|
+
super(**options)
|
380
|
+
@cache = {}
|
381
|
+
@cache_ttl = cache_ttl
|
382
|
+
end
|
383
|
+
|
384
|
+
def read(prompt_id)
|
385
|
+
cached = @cache[prompt_id]
|
386
|
+
if cached && (Time.current - cached[:timestamp]) < @cache_ttl
|
387
|
+
return cached[:content]
|
388
|
+
end
|
389
|
+
|
390
|
+
content = super(prompt_id)
|
391
|
+
@cache[prompt_id] = {
|
392
|
+
content: content,
|
393
|
+
timestamp: Time.current
|
394
|
+
}
|
395
|
+
content
|
396
|
+
end
|
397
|
+
end
|
398
|
+
```
|
399
|
+
|
400
|
+
## Testing Adapters
|
401
|
+
|
402
|
+
### RSpec Shared Examples
|
403
|
+
|
404
|
+
```ruby
|
405
|
+
# spec/support/shared_examples/storage_adapter.rb
|
406
|
+
RSpec.shared_examples 'a storage adapter' do
|
407
|
+
let(:prompt_id) { 'test_prompt' }
|
408
|
+
let(:content) { 'Hello [NAME]!' }
|
409
|
+
|
410
|
+
describe '#write and #read' do
|
411
|
+
it 'stores and retrieves content' do
|
412
|
+
expect(adapter.write(prompt_id, content)).to be true
|
413
|
+
expect(adapter.read(prompt_id)).to eq content
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe '#exist?' do
|
418
|
+
it 'returns false for non-existent prompts' do
|
419
|
+
expect(adapter.exist?('non_existent')).to be false
|
420
|
+
end
|
421
|
+
|
422
|
+
it 'returns true for existing prompts' do
|
423
|
+
adapter.write(prompt_id, content)
|
424
|
+
expect(adapter.exist?(prompt_id)).to be true
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
describe '#delete' do
|
429
|
+
it 'removes prompts' do
|
430
|
+
adapter.write(prompt_id, content)
|
431
|
+
expect(adapter.delete(prompt_id)).to be true
|
432
|
+
expect(adapter.exist?(prompt_id)).to be false
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
describe '#list' do
|
437
|
+
it 'returns all prompt IDs' do
|
438
|
+
adapter.write('prompt1', 'content1')
|
439
|
+
adapter.write('prompt2', 'content2')
|
440
|
+
|
441
|
+
expect(adapter.list).to contain_exactly('prompt1', 'prompt2')
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
# Usage in adapter specs
|
447
|
+
describe CustomAdapter do
|
448
|
+
let(:adapter) { described_class.new(options) }
|
449
|
+
|
450
|
+
include_examples 'a storage adapter'
|
451
|
+
end
|
452
|
+
```
|
453
|
+
|
454
|
+
## Best Practices
|
455
|
+
|
456
|
+
1. **Thread Safety**: Ensure adapter operations are thread-safe
|
457
|
+
2. **Error Handling**: Use standard PromptManager exceptions
|
458
|
+
3. **Resource Management**: Properly close connections and clean up resources
|
459
|
+
4. **Configuration Validation**: Validate configuration parameters in constructor
|
460
|
+
5. **Documentation**: Document all configuration options and behavior
|
461
|
+
6. **Testing**: Use shared examples to ensure consistent behavior
|
462
|
+
7. **Performance**: Consider caching and connection pooling for remote storage
|
@@ -0,0 +1 @@
|
|
1
|
+
data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A4uLiDOHh4Rjh4eEY4eHhGOHh4Rjh4eEY4eHhGOHh4Rji4uIM////AP///wD///8A////AP///wDY2NgspqamjJmZmbeZmZm3mZmZt5mZmbeZmZm3mZmZt5mZmbeZmZm3pqamjNjY2Cz///8A////AP///wCfn5+MZGRk/1FRUX9RUVF/UVFRX1FRUX9RUVF/UVFRX1FRUX9RUVF/UVFRX2RkZP+fn5+M////AP///wCWlpa3UFBQ/4CAgP+BgYH/gYGB/4GBgf+BgYH/gYGB/4GBgf+BgYH/gYGB/4CAgP9QUFD/lpaWt////wCWlpa3UFBQ/4CAgP//////////////////////////////////////////////////////////////////////////////////////gICA/1BQUP+Wlpa3////AJaWlrdQUFD/gICA//////////////////////////////////////////////////7+/v/+/v7//v7+/v+AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID///////////////////////X19f/Ozs7/zs7O/87Ozv/Ozs7/9fX1///////////////////////AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID///////////////////////X19f/Ozs7/////////////////zs7O/87Ozv/19fX///////////////////////+AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID///////////////////////X19f/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/19fX///////////////////////+AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID///////////////////////X19f/Ozs7/////////////////zs7O/87Ozv/19fX///////////////////////+AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID///////////////////////X19f/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/19fX///////////////////////+AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID///////////////////////////////////////7+/v/+/v7//v7+/v////////////////////////////////+AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID///////////////////////////////////////////////////////////////////////////////////////+AgID/UFBQ/5aWlrf///8AlpaWt1BQUP+AgID/gYGB/4GBgf+BgYH/gYGB/4GBgf+BgYH/gYGB/4GBgf+BgYH/gICA/1BQUP+Wlpa3////AJ+fn4xkZGT/UVFRX1FRUX9RUVF/UVFRX1FRUX9RUVF/UVFRX1FRUX9RUVF/UVFRX2RkZP+fn5+M////AP///wDY2NgspqamjJmZmbeZmZm3mZmZt5mZmbeZmZm3mZmZt5mZmbeZmZm3pqamjNjY2Cz///8A////AP///wD///8A////AP///wDi4uIM4eHhGOHh4Rjh4eEY4eHhGOHh4Rjh4eEY4eHhGOLi4gz///8A////AP///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA=
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
3
|
+
<!-- Background circle -->
|
4
|
+
<circle cx="32" cy="32" r="30" fill="#4F46E5" stroke="#3730A3" stroke-width="2"/>
|
5
|
+
|
6
|
+
<!-- Librarian figure (simplified) -->
|
7
|
+
<circle cx="32" cy="22" r="6" fill="#F3F4F6"/>
|
8
|
+
<path d="M20 50 Q32 45 44 50" stroke="#F3F4F6" stroke-width="3" fill="none"/>
|
9
|
+
|
10
|
+
<!-- Floating books -->
|
11
|
+
<rect x="12" y="18" width="8" height="6" rx="1" fill="#FBBF24" transform="rotate(-15 16 21)"/>
|
12
|
+
<rect x="18" y="12" width="8" height="6" rx="1" fill="#EF4444" transform="rotate(25 22 15)"/>
|
13
|
+
<rect x="44" y="16" width="8" height="6" rx="1" fill="#10B981" transform="rotate(15 48 19)"/>
|
14
|
+
<rect x="38" y="10" width="8" height="6" rx="1" fill="#8B5CF6" transform="rotate(-25 42 13)"/>
|
15
|
+
|
16
|
+
<!-- Golden threads (simplified) -->
|
17
|
+
<path d="M16 21 Q32 28 48 19" stroke="#FBBF24" stroke-width="1" fill="none" opacity="0.6"/>
|
18
|
+
<path d="M22 15 Q32 25 42 13" stroke="#FBBF24" stroke-width="1" fill="none" opacity="0.6"/>
|
19
|
+
|
20
|
+
<!-- Sparkles -->
|
21
|
+
<circle cx="24" cy="35" r="1" fill="#FBBF24"/>
|
22
|
+
<circle cx="40" cy="33" r="1" fill="#FBBF24"/>
|
23
|
+
<circle cx="28" cy="40" r="1" fill="#FBBF24"/>
|
24
|
+
</svg>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Comments and Documentation
|
2
|
+
|
3
|
+
PromptManager supports comprehensive inline documentation through comments and special sections.
|
4
|
+
|
5
|
+
## Line Comments
|
6
|
+
|
7
|
+
Lines beginning with `#` are treated as comments and ignored during processing:
|
8
|
+
|
9
|
+
```text
|
10
|
+
# This is a comment describing the prompt
|
11
|
+
# Author: Your Name
|
12
|
+
# Version: 1.0
|
13
|
+
|
14
|
+
Hello [NAME]! This text will be processed.
|
15
|
+
```
|
16
|
+
|
17
|
+
## Block Comments
|
18
|
+
|
19
|
+
Everything after `__END__` is ignored, creating a documentation section:
|
20
|
+
|
21
|
+
```text
|
22
|
+
Your prompt content here...
|
23
|
+
|
24
|
+
__END__
|
25
|
+
This section is completely ignored by PromptManager.
|
26
|
+
|
27
|
+
Development notes:
|
28
|
+
- TODO: Add more parameters
|
29
|
+
- Version history
|
30
|
+
- Usage examples
|
31
|
+
```
|
32
|
+
|
33
|
+
## Documentation Best Practices
|
34
|
+
|
35
|
+
```text
|
36
|
+
# Description: Customer service greeting template
|
37
|
+
# Tags: customer-service, greeting
|
38
|
+
# Version: 1.2
|
39
|
+
# Author: Support Team
|
40
|
+
# Last Updated: 2024-01-15
|
41
|
+
|
42
|
+
//include common/header.txt
|
43
|
+
|
44
|
+
Your prompt content...
|
45
|
+
|
46
|
+
__END__
|
47
|
+
Internal notes and documentation go here.
|
48
|
+
```
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Directive Processing
|
2
|
+
|
3
|
+
Directives are special instructions in your prompts that begin with `//` and provide powerful prompt composition capabilities.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
Directives allow you to:
|
8
|
+
- Include content from other files
|
9
|
+
- Create modular, reusable prompt components
|
10
|
+
- Build dynamic prompt structures
|
11
|
+
- Process commands during prompt generation
|
12
|
+
|
13
|
+
## Built-in Directives
|
14
|
+
|
15
|
+
### `//include` (alias: `//import`)
|
16
|
+
|
17
|
+
Include content from other files:
|
18
|
+
|
19
|
+
```text
|
20
|
+
//include common/header.txt
|
21
|
+
//import templates/[TEMPLATE_TYPE].txt
|
22
|
+
|
23
|
+
Your main prompt content here...
|
24
|
+
```
|
25
|
+
|
26
|
+
## Example
|
27
|
+
|
28
|
+
```text title="customer_response.txt"
|
29
|
+
//include common/header.txt
|
30
|
+
|
31
|
+
Dear [CUSTOMER_NAME],
|
32
|
+
|
33
|
+
Thank you for your inquiry about [TOPIC].
|
34
|
+
|
35
|
+
//include common/footer.txt
|
36
|
+
```
|
37
|
+
|
38
|
+
For detailed examples and advanced usage, see the [Basic Examples](../examples/basic.md).
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# ERB Integration
|
2
|
+
|
3
|
+
PromptManager supports ERB (Embedded Ruby) templating for dynamic content generation.
|
4
|
+
|
5
|
+
## Enabling ERB
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
prompt = PromptManager::Prompt.new(
|
9
|
+
id: 'dynamic_prompt',
|
10
|
+
erb_flag: true
|
11
|
+
)
|
12
|
+
```
|
13
|
+
|
14
|
+
## Basic Usage
|
15
|
+
|
16
|
+
```text title="dynamic_prompt.txt"
|
17
|
+
Current date: <%= Date.today.strftime('%B %d, %Y') %>
|
18
|
+
|
19
|
+
<% if '[PRIORITY]' == 'high' %>
|
20
|
+
🚨 URGENT: This requires immediate attention!
|
21
|
+
<% else %>
|
22
|
+
📋 Standard processing request.
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
Generated at: <%= Time.now %>
|
26
|
+
```
|
27
|
+
|
28
|
+
## Advanced Examples
|
29
|
+
|
30
|
+
### System Information Template
|
31
|
+
|
32
|
+
```text
|
33
|
+
**Timestamp**: <%= Time.now.strftime('%A, %B %d, %Y at %I:%M:%S %p %Z') %>
|
34
|
+
**Analysis Duration**: <%= Time.now - Time.parse('2024-01-01') %> seconds since 2024 began
|
35
|
+
|
36
|
+
<% if RUBY_PLATFORM.include?('darwin') %>
|
37
|
+
**Platform**: macOS/Darwin System
|
38
|
+
**Ruby Platform**: <%= RUBY_PLATFORM %>
|
39
|
+
**Ruby Version**: <%= RUBY_VERSION %>
|
40
|
+
**Ruby Engine**: <%= RUBY_ENGINE %>
|
41
|
+
<% elsif RUBY_PLATFORM.include?('linux') %>
|
42
|
+
**Platform**: Linux System
|
43
|
+
**Ruby Platform**: <%= RUBY_PLATFORM %>
|
44
|
+
**Ruby Version**: <%= RUBY_VERSION %>
|
45
|
+
**Ruby Engine**: <%= RUBY_ENGINE %>
|
46
|
+
<% else %>
|
47
|
+
**Platform**: Other Unix-like System
|
48
|
+
**Ruby Platform**: <%= RUBY_PLATFORM %>
|
49
|
+
**Ruby Version**: <%= RUBY_VERSION %>
|
50
|
+
**Ruby Engine**: <%= RUBY_ENGINE %>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
**Performance Context**: <%= `uptime`.strip rescue 'Unable to determine' %>
|
54
|
+
```
|
55
|
+
|
56
|
+
### Complete Integration Example
|
57
|
+
|
58
|
+
See the complete [advanced_integrations.rb](https://github.com/MadBomber/prompt_manager/blob/main/examples/advanced_integrations.rb) example that demonstrates:
|
59
|
+
|
60
|
+
- ERB templating with system information
|
61
|
+
- Dynamic timestamp generation
|
62
|
+
- Platform-specific content rendering
|
63
|
+
- Integration with OpenAI API streaming
|
64
|
+
- Professional UI with `tty-spinner`
|
65
|
+
|
66
|
+
This example shows how to create sophisticated prompts that adapt to your system environment and generate technical analysis reports.
|
67
|
+
|
68
|
+
For more comprehensive ERB examples, see the [Examples documentation](../examples.md).
|