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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/COMMITS.md +196 -0
  4. data/README.md +485 -203
  5. data/docs/.keep +0 -0
  6. data/docs/advanced/custom-keywords.md +421 -0
  7. data/docs/advanced/dynamic-directives.md +535 -0
  8. data/docs/advanced/performance.md +612 -0
  9. data/docs/advanced/search-integration.md +635 -0
  10. data/docs/api/configuration.md +355 -0
  11. data/docs/api/directive-processor.md +431 -0
  12. data/docs/api/prompt-class.md +354 -0
  13. data/docs/api/storage-adapters.md +462 -0
  14. data/docs/assets/favicon.ico +1 -0
  15. data/docs/assets/logo.svg +24 -0
  16. data/docs/core-features/comments.md +48 -0
  17. data/docs/core-features/directive-processing.md +38 -0
  18. data/docs/core-features/erb-integration.md +68 -0
  19. data/docs/core-features/error-handling.md +197 -0
  20. data/docs/core-features/parameter-history.md +76 -0
  21. data/docs/core-features/parameterized-prompts.md +500 -0
  22. data/docs/core-features/shell-integration.md +79 -0
  23. data/docs/development/architecture.md +544 -0
  24. data/docs/development/contributing.md +425 -0
  25. data/docs/development/roadmap.md +234 -0
  26. data/docs/development/testing.md +822 -0
  27. data/docs/examples/advanced.md +523 -0
  28. data/docs/examples/basic.md +688 -0
  29. data/docs/examples/real-world.md +776 -0
  30. data/docs/examples.md +337 -0
  31. data/docs/getting-started/basic-concepts.md +318 -0
  32. data/docs/getting-started/installation.md +97 -0
  33. data/docs/getting-started/quick-start.md +256 -0
  34. data/docs/index.md +230 -0
  35. data/docs/migration/v0.9.0.md +459 -0
  36. data/docs/migration/v1.0.0.md +591 -0
  37. data/docs/storage/activerecord-adapter.md +348 -0
  38. data/docs/storage/custom-adapters.md +176 -0
  39. data/docs/storage/filesystem-adapter.md +236 -0
  40. data/docs/storage/overview.md +427 -0
  41. data/examples/advanced_integrations.rb +52 -0
  42. data/examples/prompts_dir/advanced_demo.txt +79 -0
  43. data/examples/prompts_dir/directive_example.json +1 -0
  44. data/examples/prompts_dir/directive_example.txt +8 -0
  45. data/examples/prompts_dir/todo.json +1 -1
  46. data/improvement_plan.md +996 -0
  47. data/lib/prompt_manager/storage/file_system_adapter.rb +8 -2
  48. data/lib/prompt_manager/version.rb +1 -1
  49. data/mkdocs.yml +146 -0
  50. data/prompt_manager_logo.png +0 -0
  51. metadata +46 -3
  52. 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.