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,688 @@
|
|
1
|
+
# Basic Examples
|
2
|
+
|
3
|
+
This section provides practical, ready-to-use examples that demonstrate PromptManager's core functionality. Each example includes complete code and explanations.
|
4
|
+
|
5
|
+
## Setup
|
6
|
+
|
7
|
+
All examples assume this basic setup:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
require 'prompt_manager'
|
11
|
+
|
12
|
+
# Configure FileSystem adapter
|
13
|
+
PromptManager::Prompt.storage_adapter =
|
14
|
+
PromptManager::Storage::FileSystemAdapter.config do |config|
|
15
|
+
config.prompts_dir = File.expand_path('~/.prompts')
|
16
|
+
end.new
|
17
|
+
```
|
18
|
+
|
19
|
+
## Example 1: Simple Greeting
|
20
|
+
|
21
|
+
The classic "Hello World" example for prompts.
|
22
|
+
|
23
|
+
### Prompt File
|
24
|
+
|
25
|
+
```text title="~/.prompts/greeting.txt"
|
26
|
+
# Simple greeting prompt
|
27
|
+
# Keywords: NAME
|
28
|
+
|
29
|
+
Hello [NAME]! Welcome to PromptManager.
|
30
|
+
|
31
|
+
How can I help you today?
|
32
|
+
```
|
33
|
+
|
34
|
+
### Parameters File
|
35
|
+
|
36
|
+
```json title="~/.prompts/greeting.json"
|
37
|
+
{
|
38
|
+
"[NAME]": ["World", "Alice", "Bob"]
|
39
|
+
}
|
40
|
+
```
|
41
|
+
|
42
|
+
### Ruby Code
|
43
|
+
|
44
|
+
```ruby title="greeting_example.rb"
|
45
|
+
#!/usr/bin/env ruby
|
46
|
+
require 'prompt_manager'
|
47
|
+
|
48
|
+
# Configure storage
|
49
|
+
PromptManager::Prompt.storage_adapter =
|
50
|
+
PromptManager::Storage::FileSystemAdapter.config do |config|
|
51
|
+
config.prompts_dir = File.expand_path('~/.prompts')
|
52
|
+
end.new
|
53
|
+
|
54
|
+
# Load and use the prompt
|
55
|
+
prompt = PromptManager::Prompt.new(id: 'greeting')
|
56
|
+
prompt.parameters['[NAME]'] = 'Alice'
|
57
|
+
|
58
|
+
puts prompt.to_s
|
59
|
+
# Output: Hello Alice! Welcome to PromptManager.\n\nHow can I help you today?
|
60
|
+
```
|
61
|
+
|
62
|
+
**Key Learning Points:**
|
63
|
+
- Basic prompt loading with `new(id: 'greeting')`
|
64
|
+
- Parameter setting with direct assignment
|
65
|
+
- Text generation with `to_s`
|
66
|
+
|
67
|
+
## Example 2: Email Template
|
68
|
+
|
69
|
+
A more realistic example showing email template management.
|
70
|
+
|
71
|
+
### Prompt File
|
72
|
+
|
73
|
+
```text title="~/.prompts/welcome_email.txt"
|
74
|
+
# Welcome email template
|
75
|
+
# Keywords: USER_NAME, COMPANY_NAME, LOGIN_URL, SUPPORT_EMAIL
|
76
|
+
|
77
|
+
Subject: Welcome to [COMPANY_NAME]!
|
78
|
+
|
79
|
+
Dear [USER_NAME],
|
80
|
+
|
81
|
+
Welcome to [COMPANY_NAME]! We're excited to have you join our community.
|
82
|
+
|
83
|
+
To get started:
|
84
|
+
1. Log in to your account: [LOGIN_URL]
|
85
|
+
2. Complete your profile setup
|
86
|
+
3. Explore our features
|
87
|
+
|
88
|
+
If you need any help, don't hesitate to contact us at [SUPPORT_EMAIL].
|
89
|
+
|
90
|
+
Best regards,
|
91
|
+
The [COMPANY_NAME] Team
|
92
|
+
```
|
93
|
+
|
94
|
+
### Ruby Code
|
95
|
+
|
96
|
+
```ruby title="email_example.rb"
|
97
|
+
require 'prompt_manager'
|
98
|
+
|
99
|
+
class WelcomeEmailGenerator
|
100
|
+
def initialize
|
101
|
+
@prompt = PromptManager::Prompt.new(id: 'welcome_email')
|
102
|
+
end
|
103
|
+
|
104
|
+
def generate_for_user(user_data)
|
105
|
+
@prompt.parameters = {
|
106
|
+
'[USER_NAME]' => user_data[:name],
|
107
|
+
'[COMPANY_NAME]' => 'Acme Corp',
|
108
|
+
'[LOGIN_URL]' => 'https://app.acme.com/login',
|
109
|
+
'[SUPPORT_EMAIL]' => 'support@acme.com'
|
110
|
+
}
|
111
|
+
|
112
|
+
@prompt.to_s
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Usage
|
117
|
+
generator = WelcomeEmailGenerator.new
|
118
|
+
user = { name: 'Alice Johnson', email: 'alice@example.com' }
|
119
|
+
|
120
|
+
email_content = generator.generate_for_user(user)
|
121
|
+
puts email_content
|
122
|
+
|
123
|
+
# Save parameters for future use
|
124
|
+
generator.instance_variable_get(:@prompt).save
|
125
|
+
```
|
126
|
+
|
127
|
+
**Key Learning Points:**
|
128
|
+
- Organizing prompt logic in classes
|
129
|
+
- Batch parameter assignment with hash
|
130
|
+
- Saving parameter changes back to storage
|
131
|
+
|
132
|
+
## Example 3: Dynamic Content with ERB
|
133
|
+
|
134
|
+
Using ERB for conditional content and dynamic generation.
|
135
|
+
|
136
|
+
### Prompt File
|
137
|
+
|
138
|
+
```text title="~/.prompts/order_confirmation.txt"
|
139
|
+
# Order confirmation with dynamic content
|
140
|
+
# Keywords: CUSTOMER_NAME, ORDER_NUMBER, ITEM_COUNT, TOTAL_AMOUNT, IS_PREMIUM
|
141
|
+
|
142
|
+
Dear [CUSTOMER_NAME],
|
143
|
+
|
144
|
+
Thank you for your order #[ORDER_NUMBER]!
|
145
|
+
|
146
|
+
<% item_count = '[ITEM_COUNT]'.to_i %>
|
147
|
+
Your order contains <%= item_count %> item<%= 's' if item_count != 1 %>.
|
148
|
+
|
149
|
+
<% if '[IS_PREMIUM]' == 'true' %>
|
150
|
+
🌟 As a premium member, you'll receive:
|
151
|
+
- Free express shipping
|
152
|
+
- Priority customer support
|
153
|
+
- Extended warranty on all items
|
154
|
+
<% else %>
|
155
|
+
Standard shipping will be applied to your order.
|
156
|
+
<% end %>
|
157
|
+
|
158
|
+
Order Total: $[TOTAL_AMOUNT]
|
159
|
+
|
160
|
+
<% if '[TOTAL_AMOUNT]'.to_f > 100 %>
|
161
|
+
🎉 Congratulations! You qualify for free shipping!
|
162
|
+
<% end %>
|
163
|
+
|
164
|
+
Best regards,
|
165
|
+
Customer Service Team
|
166
|
+
```
|
167
|
+
|
168
|
+
### Ruby Code
|
169
|
+
|
170
|
+
```ruby title="order_confirmation_example.rb"
|
171
|
+
require 'prompt_manager'
|
172
|
+
|
173
|
+
class OrderConfirmation
|
174
|
+
def initialize
|
175
|
+
# Enable ERB processing
|
176
|
+
@prompt = PromptManager::Prompt.new(
|
177
|
+
id: 'order_confirmation',
|
178
|
+
erb_flag: true
|
179
|
+
)
|
180
|
+
end
|
181
|
+
|
182
|
+
def generate(order)
|
183
|
+
@prompt.parameters = {
|
184
|
+
'[CUSTOMER_NAME]' => order[:customer_name],
|
185
|
+
'[ORDER_NUMBER]' => order[:order_number],
|
186
|
+
'[ITEM_COUNT]' => order[:items].count.to_s,
|
187
|
+
'[TOTAL_AMOUNT]' => sprintf('%.2f', order[:total]),
|
188
|
+
'[IS_PREMIUM]' => order[:premium_member].to_s
|
189
|
+
}
|
190
|
+
|
191
|
+
@prompt.to_s
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Usage with different order types
|
196
|
+
confirmation = OrderConfirmation.new
|
197
|
+
|
198
|
+
# Regular customer order
|
199
|
+
regular_order = {
|
200
|
+
customer_name: 'John Smith',
|
201
|
+
order_number: 'ORD-12345',
|
202
|
+
items: ['Widget A', 'Widget B'],
|
203
|
+
total: 85.50,
|
204
|
+
premium_member: false
|
205
|
+
}
|
206
|
+
|
207
|
+
puts "=== Regular Order ==="
|
208
|
+
puts confirmation.generate(regular_order)
|
209
|
+
|
210
|
+
# Premium customer order
|
211
|
+
premium_order = {
|
212
|
+
customer_name: 'Jane Doe',
|
213
|
+
order_number: 'ORD-12346',
|
214
|
+
items: ['Premium Widget', 'Deluxe Kit', 'Accessories'],
|
215
|
+
total: 150.00,
|
216
|
+
premium_member: true
|
217
|
+
}
|
218
|
+
|
219
|
+
puts "\n=== Premium Order ==="
|
220
|
+
puts confirmation.generate(premium_order)
|
221
|
+
```
|
222
|
+
|
223
|
+
**Key Learning Points:**
|
224
|
+
- Enabling ERB with `erb_flag: true`
|
225
|
+
- Conditional content using ERB syntax
|
226
|
+
- Dynamic content generation based on parameter values
|
227
|
+
|
228
|
+
## Example 4: Directive Processing
|
229
|
+
|
230
|
+
Using directives to include shared content and build modular prompts.
|
231
|
+
|
232
|
+
### Shared Header File
|
233
|
+
|
234
|
+
```text title="~/.prompts/common/header.txt"
|
235
|
+
=====================================
|
236
|
+
ACME CORPORATION
|
237
|
+
Customer Service Division
|
238
|
+
=====================================
|
239
|
+
|
240
|
+
Date: <%= Date.today.strftime('%B %d, %Y') %>
|
241
|
+
```
|
242
|
+
|
243
|
+
### Shared Footer File
|
244
|
+
|
245
|
+
```text title="~/.prompts/common/footer.txt"
|
246
|
+
=====================================
|
247
|
+
|
248
|
+
For immediate assistance:
|
249
|
+
📞 Call: 1-800-ACME-HELP
|
250
|
+
📧 Email: support@acme.com
|
251
|
+
🌐 Web: https://help.acme.com
|
252
|
+
|
253
|
+
Office Hours: Monday-Friday, 9 AM - 6 PM EST
|
254
|
+
```
|
255
|
+
|
256
|
+
### Main Prompt File
|
257
|
+
|
258
|
+
```text title="~/.prompts/customer_response.txt"
|
259
|
+
# Customer service response template
|
260
|
+
# Keywords: CUSTOMER_NAME, ISSUE_TYPE, RESOLUTION_TIME, AGENT_NAME
|
261
|
+
|
262
|
+
//include common/header.txt
|
263
|
+
|
264
|
+
Dear [CUSTOMER_NAME],
|
265
|
+
|
266
|
+
Thank you for contacting us regarding your [ISSUE_TYPE] issue.
|
267
|
+
|
268
|
+
We understand your concern and want to resolve this as quickly as possible.
|
269
|
+
Based on our initial review, we expect to have this resolved within [RESOLUTION_TIME].
|
270
|
+
|
271
|
+
I'll personally be handling your case and will keep you updated on our progress.
|
272
|
+
|
273
|
+
Best regards,
|
274
|
+
[AGENT_NAME]
|
275
|
+
Customer Service Representative
|
276
|
+
|
277
|
+
//include common/footer.txt
|
278
|
+
```
|
279
|
+
|
280
|
+
### Ruby Code
|
281
|
+
|
282
|
+
```ruby title="customer_response_example.rb"
|
283
|
+
require 'prompt_manager'
|
284
|
+
|
285
|
+
class CustomerServiceResponse
|
286
|
+
def initialize
|
287
|
+
@prompt = PromptManager::Prompt.new(
|
288
|
+
id: 'customer_response',
|
289
|
+
erb_flag: true # Enable ERB for header date processing
|
290
|
+
)
|
291
|
+
end
|
292
|
+
|
293
|
+
def generate_response(case_data)
|
294
|
+
@prompt.parameters = {
|
295
|
+
'[CUSTOMER_NAME]' => case_data[:customer_name],
|
296
|
+
'[ISSUE_TYPE]' => case_data[:issue_type],
|
297
|
+
'[RESOLUTION_TIME]' => case_data[:expected_resolution],
|
298
|
+
'[AGENT_NAME]' => case_data[:agent_name]
|
299
|
+
}
|
300
|
+
|
301
|
+
@prompt.to_s
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# Usage
|
306
|
+
response_generator = CustomerServiceResponse.new
|
307
|
+
|
308
|
+
customer_case = {
|
309
|
+
customer_name: 'Sarah Wilson',
|
310
|
+
issue_type: 'billing discrepancy',
|
311
|
+
expected_resolution: '2-3 business days',
|
312
|
+
agent_name: 'Mike Johnson'
|
313
|
+
}
|
314
|
+
|
315
|
+
puts response_generator.generate_response(customer_case)
|
316
|
+
```
|
317
|
+
|
318
|
+
**Key Learning Points:**
|
319
|
+
- Using `//include` directives for shared content
|
320
|
+
- Combining ERB and directive processing
|
321
|
+
- Building modular, reusable prompt components
|
322
|
+
|
323
|
+
## Example 5: Parameter History and Management
|
324
|
+
|
325
|
+
Leveraging parameter history for better user experience.
|
326
|
+
|
327
|
+
### Ruby Code
|
328
|
+
|
329
|
+
```ruby title="parameter_history_example.rb"
|
330
|
+
require 'prompt_manager'
|
331
|
+
|
332
|
+
class PromptWithHistory
|
333
|
+
def initialize(prompt_id)
|
334
|
+
@prompt = PromptManager::Prompt.new(id: prompt_id)
|
335
|
+
end
|
336
|
+
|
337
|
+
def set_parameter(key, value)
|
338
|
+
# Get current history
|
339
|
+
current_history = @prompt.parameters[key] || []
|
340
|
+
|
341
|
+
# Add new value if it's different from the last one
|
342
|
+
unless current_history.last == value
|
343
|
+
current_history << value
|
344
|
+
# Keep only last 10 values
|
345
|
+
current_history = current_history.last(10)
|
346
|
+
end
|
347
|
+
|
348
|
+
@prompt.parameters[key] = current_history
|
349
|
+
@prompt.save
|
350
|
+
end
|
351
|
+
|
352
|
+
def get_parameter_history(key)
|
353
|
+
@prompt.parameters[key] || []
|
354
|
+
end
|
355
|
+
|
356
|
+
def get_current_parameter(key)
|
357
|
+
history = get_parameter_history(key)
|
358
|
+
history.empty? ? nil : history.last
|
359
|
+
end
|
360
|
+
|
361
|
+
def get_parameter_suggestions(key, limit = 5)
|
362
|
+
history = get_parameter_history(key)
|
363
|
+
history.reverse.take(limit)
|
364
|
+
end
|
365
|
+
|
366
|
+
def generate
|
367
|
+
@prompt.to_s
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
# Usage example
|
372
|
+
class InteractivePromptBuilder
|
373
|
+
def initialize
|
374
|
+
@prompt_manager = PromptWithHistory.new('greeting')
|
375
|
+
end
|
376
|
+
|
377
|
+
def interactive_session
|
378
|
+
puts "=== Interactive Prompt Builder ==="
|
379
|
+
puts "Available keywords: #{@prompt_manager.instance_variable_get(:@prompt).keywords.join(', ')}"
|
380
|
+
|
381
|
+
@prompt_manager.instance_variable_get(:@prompt).keywords.each do |keyword|
|
382
|
+
# Show previous values
|
383
|
+
suggestions = @prompt_manager.get_parameter_suggestions(keyword)
|
384
|
+
|
385
|
+
if suggestions.any?
|
386
|
+
puts "\nPrevious values for #{keyword}:"
|
387
|
+
suggestions.each_with_index do |value, index|
|
388
|
+
puts " #{index + 1}. #{value}"
|
389
|
+
end
|
390
|
+
puts " #{suggestions.length + 1}. Enter new value"
|
391
|
+
|
392
|
+
print "Choose option or enter new value: "
|
393
|
+
input = gets.chomp
|
394
|
+
|
395
|
+
if input.to_i.between?(1, suggestions.length)
|
396
|
+
selected_value = suggestions[input.to_i - 1]
|
397
|
+
@prompt_manager.set_parameter(keyword, selected_value)
|
398
|
+
puts "Selected: #{selected_value}"
|
399
|
+
else
|
400
|
+
@prompt_manager.set_parameter(keyword, input)
|
401
|
+
puts "New value saved: #{input}"
|
402
|
+
end
|
403
|
+
else
|
404
|
+
print "Enter value for #{keyword}: "
|
405
|
+
value = gets.chomp
|
406
|
+
@prompt_manager.set_parameter(keyword, value)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
puts "\n=== Generated Prompt ==="
|
411
|
+
puts @prompt_manager.generate
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
# Run interactive session
|
416
|
+
# InteractivePromptBuilder.new.interactive_session
|
417
|
+
```
|
418
|
+
|
419
|
+
**Key Learning Points:**
|
420
|
+
- Working with parameter history arrays
|
421
|
+
- Building user-friendly parameter selection
|
422
|
+
- Maintaining parameter history across sessions
|
423
|
+
|
424
|
+
## Example 6: Error Handling
|
425
|
+
|
426
|
+
Robust error handling for production use.
|
427
|
+
|
428
|
+
### Ruby Code
|
429
|
+
|
430
|
+
```ruby title="error_handling_example.rb"
|
431
|
+
require 'prompt_manager'
|
432
|
+
|
433
|
+
class RobustPromptProcessor
|
434
|
+
def initialize(prompt_id)
|
435
|
+
@prompt_id = prompt_id
|
436
|
+
@prompt = nil
|
437
|
+
end
|
438
|
+
|
439
|
+
def process_with_fallback(parameters, fallback_text = nil)
|
440
|
+
begin
|
441
|
+
# Attempt to load prompt
|
442
|
+
@prompt = PromptManager::Prompt.new(id: @prompt_id)
|
443
|
+
|
444
|
+
# Validate required parameters
|
445
|
+
validate_parameters(parameters)
|
446
|
+
|
447
|
+
# Set parameters
|
448
|
+
@prompt.parameters = parameters
|
449
|
+
|
450
|
+
# Generate text
|
451
|
+
result = @prompt.to_s
|
452
|
+
|
453
|
+
# Check for unreplaced keywords
|
454
|
+
check_unreplaced_keywords(result)
|
455
|
+
|
456
|
+
{ success: true, text: result }
|
457
|
+
|
458
|
+
rescue PromptManager::StorageError => e
|
459
|
+
handle_storage_error(e, fallback_text)
|
460
|
+
rescue PromptManager::ParameterError => e
|
461
|
+
handle_parameter_error(e)
|
462
|
+
rescue => e
|
463
|
+
handle_unexpected_error(e, fallback_text)
|
464
|
+
ensure
|
465
|
+
# Always try to save any parameter changes
|
466
|
+
save_parameters_safely if @prompt
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
private
|
471
|
+
|
472
|
+
def validate_parameters(parameters)
|
473
|
+
return unless @prompt
|
474
|
+
|
475
|
+
required_keywords = @prompt.keywords
|
476
|
+
provided_keywords = parameters.keys
|
477
|
+
missing = required_keywords - provided_keywords
|
478
|
+
|
479
|
+
unless missing.empty?
|
480
|
+
raise PromptManager::ParameterError, "Missing required parameters: #{missing.join(', ')}"
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
def check_unreplaced_keywords(text)
|
485
|
+
# Look for unreplaced keywords (basic pattern)
|
486
|
+
unreplaced = text.scan(/\[([A-Z_\s]+)\]/).flatten
|
487
|
+
|
488
|
+
if unreplaced.any?
|
489
|
+
puts "⚠️ Warning: Found unreplaced keywords: #{unreplaced.join(', ')}"
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
def handle_storage_error(error, fallback_text)
|
494
|
+
puts "❌ Storage Error: #{error.message}"
|
495
|
+
|
496
|
+
if fallback_text
|
497
|
+
puts "📄 Using fallback text"
|
498
|
+
{ success: false, text: fallback_text, error: :storage_error }
|
499
|
+
else
|
500
|
+
{ success: false, error: :storage_error, message: error.message }
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
def handle_parameter_error(error)
|
505
|
+
puts "❌ Parameter Error: #{error.message}"
|
506
|
+
{ success: false, error: :parameter_error, message: error.message }
|
507
|
+
end
|
508
|
+
|
509
|
+
def handle_unexpected_error(error, fallback_text)
|
510
|
+
puts "❌ Unexpected Error: #{error.class} - #{error.message}"
|
511
|
+
puts error.backtrace.first(3) if ENV['DEBUG']
|
512
|
+
|
513
|
+
if fallback_text
|
514
|
+
{ success: false, text: fallback_text, error: :unexpected_error }
|
515
|
+
else
|
516
|
+
{ success: false, error: :unexpected_error, message: error.message }
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
def save_parameters_safely
|
521
|
+
@prompt.save
|
522
|
+
rescue => e
|
523
|
+
puts "⚠️ Warning: Could not save parameters: #{e.message}"
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
# Usage examples
|
528
|
+
processor = RobustPromptProcessor.new('welcome_email')
|
529
|
+
|
530
|
+
# Successful processing
|
531
|
+
result = processor.process_with_fallback({
|
532
|
+
'[USER_NAME]' => 'Alice',
|
533
|
+
'[COMPANY_NAME]' => 'Acme Corp'
|
534
|
+
})
|
535
|
+
|
536
|
+
puts "Success: #{result[:success]}"
|
537
|
+
puts result[:text] if result[:success]
|
538
|
+
|
539
|
+
# Error handling with fallback
|
540
|
+
fallback = "Welcome! Thank you for joining us."
|
541
|
+
|
542
|
+
result = processor.process_with_fallback(
|
543
|
+
{ '[USER_NAME]' => 'Bob' }, # Missing required parameter
|
544
|
+
fallback
|
545
|
+
)
|
546
|
+
|
547
|
+
puts "Success: #{result[:success]}"
|
548
|
+
puts "Error: #{result[:error]}" unless result[:success]
|
549
|
+
puts "Text: #{result[:text]}" if result[:text]
|
550
|
+
```
|
551
|
+
|
552
|
+
**Key Learning Points:**
|
553
|
+
- Comprehensive error handling for all error types
|
554
|
+
- Graceful fallback strategies
|
555
|
+
- Parameter validation and safety checks
|
556
|
+
- Production-ready error reporting
|
557
|
+
|
558
|
+
## Example 7: Batch Processing
|
559
|
+
|
560
|
+
Processing multiple prompts efficiently.
|
561
|
+
|
562
|
+
### Ruby Code
|
563
|
+
|
564
|
+
```ruby title="batch_processing_example.rb"
|
565
|
+
require 'prompt_manager'
|
566
|
+
|
567
|
+
class BatchPromptProcessor
|
568
|
+
def initialize
|
569
|
+
@results = []
|
570
|
+
@errors = []
|
571
|
+
end
|
572
|
+
|
573
|
+
def process_batch(prompt_configs)
|
574
|
+
prompt_configs.each_with_index do |config, index|
|
575
|
+
begin
|
576
|
+
result = process_single_prompt(config)
|
577
|
+
@results << { index: index, config: config, result: result }
|
578
|
+
puts "✅ Processed #{config[:id]} successfully"
|
579
|
+
rescue => e
|
580
|
+
error = { index: index, config: config, error: e }
|
581
|
+
@errors << error
|
582
|
+
puts "❌ Failed to process #{config[:id]}: #{e.message}"
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
summary
|
587
|
+
end
|
588
|
+
|
589
|
+
def process_single_prompt(config)
|
590
|
+
prompt = PromptManager::Prompt.new(
|
591
|
+
id: config[:id],
|
592
|
+
erb_flag: config[:erb_flag] || false
|
593
|
+
)
|
594
|
+
|
595
|
+
prompt.parameters = config[:parameters]
|
596
|
+
prompt.to_s
|
597
|
+
end
|
598
|
+
|
599
|
+
def summary
|
600
|
+
{
|
601
|
+
total: @results.length + @errors.length,
|
602
|
+
successful: @results.length,
|
603
|
+
failed: @errors.length,
|
604
|
+
results: @results,
|
605
|
+
errors: @errors
|
606
|
+
}
|
607
|
+
end
|
608
|
+
|
609
|
+
def successful_results
|
610
|
+
@results.map { |r| r[:result] }
|
611
|
+
end
|
612
|
+
|
613
|
+
def failed_configs
|
614
|
+
@errors.map { |e| e[:config] }
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
# Usage
|
619
|
+
batch_configs = [
|
620
|
+
{
|
621
|
+
id: 'greeting',
|
622
|
+
parameters: { '[NAME]' => 'Alice' }
|
623
|
+
},
|
624
|
+
{
|
625
|
+
id: 'welcome_email',
|
626
|
+
parameters: {
|
627
|
+
'[USER_NAME]' => 'Bob',
|
628
|
+
'[COMPANY_NAME]' => 'Acme Corp',
|
629
|
+
'[LOGIN_URL]' => 'https://app.acme.com',
|
630
|
+
'[SUPPORT_EMAIL]' => 'support@acme.com'
|
631
|
+
}
|
632
|
+
},
|
633
|
+
{
|
634
|
+
id: 'order_confirmation',
|
635
|
+
erb_flag: true,
|
636
|
+
parameters: {
|
637
|
+
'[CUSTOMER_NAME]' => 'Charlie',
|
638
|
+
'[ORDER_NUMBER]' => 'ORD-789',
|
639
|
+
'[ITEM_COUNT]' => '3',
|
640
|
+
'[TOTAL_AMOUNT]' => '199.99',
|
641
|
+
'[IS_PREMIUM]' => 'true'
|
642
|
+
}
|
643
|
+
}
|
644
|
+
]
|
645
|
+
|
646
|
+
processor = BatchPromptProcessor.new
|
647
|
+
summary = processor.process_batch(batch_configs)
|
648
|
+
|
649
|
+
puts "\n=== Batch Processing Summary ==="
|
650
|
+
puts "Total: #{summary[:total]}"
|
651
|
+
puts "Successful: #{summary[:successful]}"
|
652
|
+
puts "Failed: #{summary[:failed]}"
|
653
|
+
|
654
|
+
if summary[:failed] > 0
|
655
|
+
puts "\nFailed prompts:"
|
656
|
+
processor.failed_configs.each do |config|
|
657
|
+
puts " - #{config[:id]}"
|
658
|
+
end
|
659
|
+
end
|
660
|
+
```
|
661
|
+
|
662
|
+
**Key Learning Points:**
|
663
|
+
- Batch processing patterns
|
664
|
+
- Error collection and reporting
|
665
|
+
- Processing summaries and statistics
|
666
|
+
- Handling mixed success/failure scenarios
|
667
|
+
|
668
|
+
## Running the Examples
|
669
|
+
|
670
|
+
1. **Create the prompts directory:**
|
671
|
+
```bash
|
672
|
+
mkdir -p ~/.prompts/common
|
673
|
+
```
|
674
|
+
|
675
|
+
2. **Create the prompt files** shown in each example
|
676
|
+
|
677
|
+
3. **Run any example:**
|
678
|
+
```bash
|
679
|
+
ruby greeting_example.rb
|
680
|
+
ruby email_example.rb
|
681
|
+
# etc.
|
682
|
+
```
|
683
|
+
|
684
|
+
## Next Steps
|
685
|
+
|
686
|
+
- **Advanced Examples**: See [Advanced Examples](advanced.md) for complex scenarios
|
687
|
+
- **Real World Cases**: Check [Real World Use Cases](real-world.md) for production examples
|
688
|
+
- **Core Features**: Learn more about [Parameterized Prompts](../core-features/parameterized-prompts.md)
|