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,523 @@
|
|
1
|
+
# Advanced Examples
|
2
|
+
|
3
|
+
This section demonstrates advanced usage patterns and real-world scenarios with PromptManager.
|
4
|
+
|
5
|
+
## Complex Parameter Structures
|
6
|
+
|
7
|
+
### Nested Object Rendering
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
# prompts/user_profile.txt
|
11
|
+
User Profile Report
|
12
|
+
===================
|
13
|
+
|
14
|
+
Name: [USER.PERSONAL.FIRST_NAME] [USER.PERSONAL.LAST_NAME]
|
15
|
+
Email: [USER.CONTACT.EMAIL]
|
16
|
+
Phone: [USER.CONTACT.PHONE]
|
17
|
+
|
18
|
+
Address:
|
19
|
+
[USER.ADDRESS.STREET]
|
20
|
+
[USER.ADDRESS.CITY], [USER.ADDRESS.STATE] [USER.ADDRESS.ZIP]
|
21
|
+
|
22
|
+
Account Status: [USER.ACCOUNT.STATUS]
|
23
|
+
Member Since: [USER.ACCOUNT.CREATED_DATE]
|
24
|
+
Last Login: [USER.ACCOUNT.LAST_LOGIN]
|
25
|
+
|
26
|
+
Preferences:
|
27
|
+
- Newsletter: [USER.PREFERENCES.NEWSLETTER]
|
28
|
+
- Notifications: [USER.PREFERENCES.NOTIFICATIONS]
|
29
|
+
```
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
# Usage
|
33
|
+
prompt = PromptManager::Prompt.new(id: 'user_profile')
|
34
|
+
|
35
|
+
user_data = {
|
36
|
+
user: {
|
37
|
+
personal: {
|
38
|
+
first_name: 'John',
|
39
|
+
last_name: 'Doe'
|
40
|
+
},
|
41
|
+
contact: {
|
42
|
+
email: 'john@example.com',
|
43
|
+
phone: '555-0123'
|
44
|
+
},
|
45
|
+
address: {
|
46
|
+
street: '123 Main St',
|
47
|
+
city: 'Springfield',
|
48
|
+
state: 'IL',
|
49
|
+
zip: '62701'
|
50
|
+
},
|
51
|
+
account: {
|
52
|
+
status: 'Active',
|
53
|
+
created_date: '2023-01-15',
|
54
|
+
last_login: '2024-01-20'
|
55
|
+
},
|
56
|
+
preferences: {
|
57
|
+
newsletter: 'Enabled',
|
58
|
+
notifications: 'Email + SMS'
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
report = prompt.render(user_data)
|
64
|
+
```
|
65
|
+
|
66
|
+
## Dynamic Content with ERB
|
67
|
+
|
68
|
+
### Conditional Content Generation
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
# prompts/order_confirmation.txt
|
72
|
+
<%= erb_flag = true %>
|
73
|
+
|
74
|
+
Order Confirmation #[ORDER_ID]
|
75
|
+
==============================
|
76
|
+
|
77
|
+
Dear [CUSTOMER_NAME],
|
78
|
+
|
79
|
+
<% if '[ORDER_STATUS]' == 'express' %>
|
80
|
+
🚀 EXPRESS ORDER - Expected delivery: <%= Date.parse('[ORDER_DATE]') + 1 %>
|
81
|
+
<% elsif '[ORDER_STATUS]' == 'standard' %>
|
82
|
+
📦 STANDARD ORDER - Expected delivery: <%= Date.parse('[ORDER_DATE]') + 5 %>
|
83
|
+
<% else %>
|
84
|
+
📬 ECONOMY ORDER - Expected delivery: <%= Date.parse('[ORDER_DATE]') + 10 %>
|
85
|
+
<% end %>
|
86
|
+
|
87
|
+
Items Ordered:
|
88
|
+
<% '[ITEMS]'.split(',').each_with_index do |item, index| %>
|
89
|
+
<%= index + 1 %>. <%= item.strip %>
|
90
|
+
<% end %>
|
91
|
+
|
92
|
+
<% total = '[TOTAL]'.to_f %>
|
93
|
+
Subtotal: $<%= sprintf('%.2f', total * 0.9) %>
|
94
|
+
Tax: $<%= sprintf('%.2f', total * 0.1) %>
|
95
|
+
Total: $<%= sprintf('%.2f', total) %>
|
96
|
+
|
97
|
+
<% if total > 100 %>
|
98
|
+
🎉 You saved $<%= sprintf('%.2f', total * 0.05) %> with free shipping!
|
99
|
+
<% end %>
|
100
|
+
|
101
|
+
Track your order: [TRACKING_URL]
|
102
|
+
|
103
|
+
Thank you for your business!
|
104
|
+
```
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
prompt = PromptManager::Prompt.new(id: 'order_confirmation', erb_flag: true)
|
108
|
+
|
109
|
+
confirmation = prompt.render(
|
110
|
+
order_id: 'ORD-2024-001',
|
111
|
+
customer_name: 'Alice Johnson',
|
112
|
+
order_status: 'express',
|
113
|
+
order_date: '2024-01-15',
|
114
|
+
items: 'Laptop Pro, Wireless Mouse, USB-C Hub',
|
115
|
+
total: 1299.99,
|
116
|
+
tracking_url: 'https://track.example.com/ORD-2024-001'
|
117
|
+
)
|
118
|
+
```
|
119
|
+
|
120
|
+
### Dynamic Loop Generation
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
# prompts/product_catalog.txt
|
124
|
+
<%= erb_flag = true %>
|
125
|
+
|
126
|
+
Product Catalog - [CATEGORY]
|
127
|
+
============================
|
128
|
+
|
129
|
+
<% products = JSON.parse('[PRODUCTS_JSON]') %>
|
130
|
+
<% products.each do |product| %>
|
131
|
+
**<%= product['name'] %>**
|
132
|
+
Price: $<%= product['price'] %>
|
133
|
+
<% if product['sale_price'] %>
|
134
|
+
🏷️ SALE PRICE: $<%= product['sale_price'] %> (Save $<%= product['price'] - product['sale_price'] %>)
|
135
|
+
<% end %>
|
136
|
+
Rating: <%= '⭐' * product['rating'] %>
|
137
|
+
<%= product['description'] %>
|
138
|
+
|
139
|
+
---
|
140
|
+
<% end %>
|
141
|
+
|
142
|
+
Total Products: <%= products.length %>
|
143
|
+
Average Price: $<%= sprintf('%.2f', products.sum { |p| p['sale_price'] || p['price'] } / products.length) %>
|
144
|
+
```
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
products_data = [
|
148
|
+
{ name: 'Laptop Pro', price: 1299.99, sale_price: 999.99, rating: 5, description: 'High-performance laptop' },
|
149
|
+
{ name: 'Wireless Mouse', price: 49.99, rating: 4, description: 'Ergonomic wireless mouse' },
|
150
|
+
{ name: 'USB-C Hub', price: 79.99, sale_price: 59.99, rating: 4, description: '7-in-1 connectivity hub' }
|
151
|
+
]
|
152
|
+
|
153
|
+
prompt = PromptManager::Prompt.new(id: 'product_catalog', erb_flag: true)
|
154
|
+
catalog = prompt.render(
|
155
|
+
category: 'Electronics',
|
156
|
+
products_json: products_data.to_json
|
157
|
+
)
|
158
|
+
```
|
159
|
+
|
160
|
+
## Advanced Directive Usage
|
161
|
+
|
162
|
+
### Hierarchical Template System
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
# prompts/layouts/base.txt
|
166
|
+
//include headers/company_header.txt
|
167
|
+
|
168
|
+
[CONTENT]
|
169
|
+
|
170
|
+
//include footers/standard_footer.txt
|
171
|
+
|
172
|
+
# prompts/layouts/email.txt
|
173
|
+
//include layouts/base.txt
|
174
|
+
|
175
|
+
Email Settings:
|
176
|
+
- Unsubscribe: [UNSUBSCRIBE_URL]
|
177
|
+
- Update Preferences: [PREFERENCES_URL]
|
178
|
+
|
179
|
+
# prompts/headers/company_header.txt
|
180
|
+
[COMPANY_NAME] - [DEPARTMENT]
|
181
|
+
Customer Service Portal
|
182
|
+
Generated: <%= Date.today.strftime('%B %d, %Y') %>
|
183
|
+
|
184
|
+
# prompts/footers/standard_footer.txt
|
185
|
+
--
|
186
|
+
This message was generated automatically.
|
187
|
+
For assistance, contact support@[COMPANY_DOMAIN]
|
188
|
+
```
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
# prompts/customer_notification.txt
|
192
|
+
//include layouts/email.txt
|
193
|
+
|
194
|
+
Dear [CUSTOMER_NAME],
|
195
|
+
|
196
|
+
Your account status has been updated to: [STATUS]
|
197
|
+
|
198
|
+
<% if '[STATUS]' == 'premium' %>
|
199
|
+
🌟 Welcome to Premium! You now have access to:
|
200
|
+
- Priority support
|
201
|
+
- Advanced features
|
202
|
+
- Exclusive content
|
203
|
+
<% end %>
|
204
|
+
|
205
|
+
Best regards,
|
206
|
+
The [COMPANY_NAME] Team
|
207
|
+
```
|
208
|
+
|
209
|
+
### Dynamic Template Selection
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
# prompts/invoice_template.txt
|
213
|
+
<%= erb_flag = true %>
|
214
|
+
|
215
|
+
<% template_type = '[TEMPLATE_TYPE]' || 'standard' %>
|
216
|
+
//include templates/invoice_<%= template_type %>.txt
|
217
|
+
|
218
|
+
Invoice #[INVOICE_ID]
|
219
|
+
Amount: $[AMOUNT]
|
220
|
+
Due Date: [DUE_DATE]
|
221
|
+
|
222
|
+
# prompts/templates/invoice_standard.txt
|
223
|
+
Standard Invoice Template
|
224
|
+
=========================
|
225
|
+
Payment terms: Net 30
|
226
|
+
|
227
|
+
# prompts/templates/invoice_premium.txt
|
228
|
+
Premium Invoice Template
|
229
|
+
========================
|
230
|
+
⭐ Priority Processing
|
231
|
+
Payment terms: Net 15
|
232
|
+
```
|
233
|
+
|
234
|
+
## Environment Integration
|
235
|
+
|
236
|
+
### System Information Prompts
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
# prompts/system_report.txt
|
240
|
+
<%= envar_flag = true %>
|
241
|
+
<%= erb_flag = true %>
|
242
|
+
|
243
|
+
System Status Report
|
244
|
+
===================
|
245
|
+
Generated: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
|
246
|
+
|
247
|
+
Environment: $RAILS_ENV
|
248
|
+
Version: $APP_VERSION
|
249
|
+
Server: $HOSTNAME
|
250
|
+
User: $USER
|
251
|
+
|
252
|
+
Database Status: [DB_STATUS]
|
253
|
+
Cache Status: [CACHE_STATUS]
|
254
|
+
Queue Status: [QUEUE_STATUS]
|
255
|
+
|
256
|
+
<% if ENV['RAILS_ENV'] == 'production' %>
|
257
|
+
🔴 PRODUCTION ENVIRONMENT - Handle with care!
|
258
|
+
<% else %>
|
259
|
+
🟡 Development Environment
|
260
|
+
<% end %>
|
261
|
+
|
262
|
+
Memory Usage: <%= `ps -o pid,ppid,pmem,comm -p #{Process.pid}`.split("\n").last %>
|
263
|
+
```
|
264
|
+
|
265
|
+
### Configuration-Driven Prompts
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
# config/prompt_config.yml
|
269
|
+
development:
|
270
|
+
api_endpoints:
|
271
|
+
user_service: "http://localhost:3001"
|
272
|
+
payment_service: "http://localhost:3002"
|
273
|
+
debug_mode: true
|
274
|
+
|
275
|
+
production:
|
276
|
+
api_endpoints:
|
277
|
+
user_service: "https://api.example.com/users"
|
278
|
+
payment_service: "https://api.example.com/payments"
|
279
|
+
debug_mode: false
|
280
|
+
|
281
|
+
# prompts/api_integration.txt
|
282
|
+
<%= erb_flag = true %>
|
283
|
+
<%= envar_flag = true %>
|
284
|
+
|
285
|
+
<% config = YAML.load_file("config/prompt_config.yml")[ENV['RAILS_ENV']] %>
|
286
|
+
|
287
|
+
API Integration Guide
|
288
|
+
====================
|
289
|
+
|
290
|
+
User Service: <%= config['api_endpoints']['user_service'] %>
|
291
|
+
Payment Service: <%= config['api_endpoints']['payment_service'] %>
|
292
|
+
|
293
|
+
<% if config['debug_mode'] %>
|
294
|
+
Debug Mode: Enabled
|
295
|
+
- Verbose logging active
|
296
|
+
- Request/response tracing enabled
|
297
|
+
<% end %>
|
298
|
+
|
299
|
+
Request Headers:
|
300
|
+
- Authorization: Bearer $API_TOKEN
|
301
|
+
- Content-Type: application/json
|
302
|
+
- X-Client-Version: $APP_VERSION
|
303
|
+
```
|
304
|
+
|
305
|
+
## Error Handling and Fallbacks
|
306
|
+
|
307
|
+
### Graceful Degradation System
|
308
|
+
|
309
|
+
```ruby
|
310
|
+
class RobustPromptRenderer
|
311
|
+
def initialize(primary_prompt_id, fallback_prompt_id = nil)
|
312
|
+
@primary_prompt_id = primary_prompt_id
|
313
|
+
@fallback_prompt_id = fallback_prompt_id
|
314
|
+
end
|
315
|
+
|
316
|
+
def render(parameters = {})
|
317
|
+
render_primary(parameters)
|
318
|
+
rescue PromptManager::PromptNotFoundError
|
319
|
+
render_fallback(parameters)
|
320
|
+
rescue PromptManager::MissingParametersError => e
|
321
|
+
render_with_defaults(parameters, e.missing_parameters)
|
322
|
+
rescue => e
|
323
|
+
render_error_response(e, parameters)
|
324
|
+
end
|
325
|
+
|
326
|
+
private
|
327
|
+
|
328
|
+
def render_primary(parameters)
|
329
|
+
prompt = PromptManager::Prompt.new(id: @primary_prompt_id)
|
330
|
+
prompt.render(parameters)
|
331
|
+
end
|
332
|
+
|
333
|
+
def render_fallback(parameters)
|
334
|
+
return "Service temporarily unavailable" unless @fallback_prompt_id
|
335
|
+
|
336
|
+
prompt = PromptManager::Prompt.new(id: @fallback_prompt_id)
|
337
|
+
prompt.render(parameters)
|
338
|
+
rescue
|
339
|
+
"Default response: Thank you for your request."
|
340
|
+
end
|
341
|
+
|
342
|
+
def render_with_defaults(parameters, missing_params)
|
343
|
+
# Provide default values for missing parameters
|
344
|
+
defaults = {
|
345
|
+
'customer_name' => 'Valued Customer',
|
346
|
+
'order_id' => 'N/A',
|
347
|
+
'date' => Date.today.to_s
|
348
|
+
}
|
349
|
+
|
350
|
+
filled_params = parameters.dup
|
351
|
+
missing_params.each do |param|
|
352
|
+
filled_params[param.downcase.to_sym] = defaults[param] || "[#{param}]"
|
353
|
+
end
|
354
|
+
|
355
|
+
render_primary(filled_params)
|
356
|
+
end
|
357
|
+
|
358
|
+
def render_error_response(error, parameters)
|
359
|
+
Rails.logger.error "Prompt rendering failed: #{error.message}"
|
360
|
+
Rails.logger.error "Parameters: #{parameters.inspect}"
|
361
|
+
|
362
|
+
"We're sorry, but we encountered an error processing your request. Please try again later."
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
# Usage
|
367
|
+
renderer = RobustPromptRenderer.new('customer_welcome', 'generic_welcome')
|
368
|
+
message = renderer.render(customer_name: 'John Doe')
|
369
|
+
```
|
370
|
+
|
371
|
+
## Performance Optimization
|
372
|
+
|
373
|
+
### Prompt Caching Strategy
|
374
|
+
|
375
|
+
```ruby
|
376
|
+
class CachedPromptRenderer
|
377
|
+
include ActiveSupport::Benchmarkable
|
378
|
+
|
379
|
+
def initialize(cache_store = Rails.cache)
|
380
|
+
@cache = cache_store
|
381
|
+
end
|
382
|
+
|
383
|
+
def render(prompt_id, parameters = {}, cache_options = {})
|
384
|
+
cache_key = generate_cache_key(prompt_id, parameters)
|
385
|
+
|
386
|
+
@cache.fetch(cache_key, cache_options) do
|
387
|
+
benchmark "Rendering prompt #{prompt_id}" do
|
388
|
+
prompt = PromptManager::Prompt.new(id: prompt_id)
|
389
|
+
prompt.render(parameters)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
def warm_cache(prompt_configs)
|
395
|
+
prompt_configs.each do |config|
|
396
|
+
render(config[:prompt_id], config[:parameters], expires_in: 1.hour)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
def invalidate_cache(prompt_id, parameters = nil)
|
401
|
+
if parameters
|
402
|
+
cache_key = generate_cache_key(prompt_id, parameters)
|
403
|
+
@cache.delete(cache_key)
|
404
|
+
else
|
405
|
+
# Invalidate all cached versions of this prompt
|
406
|
+
pattern = "prompt:#{prompt_id}:*"
|
407
|
+
@cache.delete_matched(pattern)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
private
|
412
|
+
|
413
|
+
def generate_cache_key(prompt_id, parameters)
|
414
|
+
param_hash = Digest::MD5.hexdigest(parameters.to_json)
|
415
|
+
"prompt:#{prompt_id}:#{param_hash}"
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
# Usage
|
420
|
+
cache_renderer = CachedPromptRenderer.new
|
421
|
+
result = cache_renderer.render('welcome_email', { name: 'Alice' }, expires_in: 30.minutes)
|
422
|
+
|
423
|
+
# Warm frequently used prompts
|
424
|
+
cache_renderer.warm_cache([
|
425
|
+
{ prompt_id: 'welcome_email', parameters: { name: 'Default User' } },
|
426
|
+
{ prompt_id: 'order_confirmation', parameters: { status: 'pending' } }
|
427
|
+
])
|
428
|
+
```
|
429
|
+
|
430
|
+
## Integration Patterns
|
431
|
+
|
432
|
+
### Background Job Processing
|
433
|
+
|
434
|
+
```ruby
|
435
|
+
class PromptProcessingJob < ApplicationJob
|
436
|
+
queue_as :default
|
437
|
+
|
438
|
+
def perform(prompt_id, parameters, notification_settings = {})
|
439
|
+
prompt = PromptManager::Prompt.new(id: prompt_id)
|
440
|
+
content = prompt.render(parameters)
|
441
|
+
|
442
|
+
case notification_settings[:delivery_method]
|
443
|
+
when 'email'
|
444
|
+
send_email_notification(content, notification_settings)
|
445
|
+
when 'sms'
|
446
|
+
send_sms_notification(content, notification_settings)
|
447
|
+
when 'push'
|
448
|
+
send_push_notification(content, notification_settings)
|
449
|
+
when 'webhook'
|
450
|
+
send_webhook_notification(content, notification_settings)
|
451
|
+
end
|
452
|
+
|
453
|
+
log_notification_sent(prompt_id, parameters, notification_settings)
|
454
|
+
|
455
|
+
rescue => e
|
456
|
+
handle_processing_error(e, prompt_id, parameters, notification_settings)
|
457
|
+
end
|
458
|
+
|
459
|
+
private
|
460
|
+
|
461
|
+
def send_email_notification(content, settings)
|
462
|
+
NotificationMailer.custom_message(
|
463
|
+
to: settings[:email],
|
464
|
+
subject: settings[:subject],
|
465
|
+
content: content
|
466
|
+
).deliver_now
|
467
|
+
end
|
468
|
+
|
469
|
+
def send_webhook_notification(content, settings)
|
470
|
+
HTTParty.post(settings[:webhook_url], {
|
471
|
+
body: {
|
472
|
+
content: content,
|
473
|
+
timestamp: Time.current,
|
474
|
+
metadata: settings[:metadata]
|
475
|
+
}.to_json,
|
476
|
+
headers: {
|
477
|
+
'Content-Type' => 'application/json',
|
478
|
+
'Authorization' => "Bearer #{settings[:api_token]}"
|
479
|
+
}
|
480
|
+
})
|
481
|
+
end
|
482
|
+
|
483
|
+
def handle_processing_error(error, prompt_id, parameters, settings)
|
484
|
+
Rails.logger.error "Prompt processing failed: #{error.message}"
|
485
|
+
|
486
|
+
# Send error notification
|
487
|
+
AdminMailer.prompt_processing_error(
|
488
|
+
error: error,
|
489
|
+
prompt_id: prompt_id,
|
490
|
+
parameters: parameters,
|
491
|
+
settings: settings
|
492
|
+
).deliver_now
|
493
|
+
|
494
|
+
# Retry with fallback prompt if available
|
495
|
+
if settings[:fallback_prompt_id]
|
496
|
+
PromptProcessingJob.perform_later(
|
497
|
+
settings[:fallback_prompt_id],
|
498
|
+
parameters,
|
499
|
+
settings.merge(retry_count: (settings[:retry_count] || 0) + 1)
|
500
|
+
)
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
# Usage
|
506
|
+
PromptProcessingJob.perform_later(
|
507
|
+
'order_shipped',
|
508
|
+
{
|
509
|
+
customer_name: 'John Doe',
|
510
|
+
order_id: 'ORD-123',
|
511
|
+
tracking_number: 'TRK-456',
|
512
|
+
estimated_delivery: Date.tomorrow
|
513
|
+
},
|
514
|
+
{
|
515
|
+
delivery_method: 'email',
|
516
|
+
email: 'customer@example.com',
|
517
|
+
subject: 'Your Order Has Shipped!',
|
518
|
+
fallback_prompt_id: 'generic_shipping_notification'
|
519
|
+
}
|
520
|
+
)
|
521
|
+
```
|
522
|
+
|
523
|
+
These advanced examples demonstrate the full power and flexibility of PromptManager for complex, real-world applications. They show how to handle nested data structures, implement sophisticated error handling, optimize performance, and integrate with background processing systems.
|