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
data/docs/examples.md ADDED
@@ -0,0 +1,337 @@
1
+ # Examples
2
+
3
+ This section provides comprehensive examples demonstrating various features and use cases of PromptManager.
4
+
5
+ ## Basic Usage
6
+
7
+ The simplest way to get started with PromptManager:
8
+
9
+ ```ruby
10
+ # examples/simple.rb
11
+ require 'prompt_manager'
12
+
13
+ # Configure storage adapter
14
+ PromptManager::Prompt.storage_adapter =
15
+ PromptManager::Storage::FileSystemAdapter.config do |config|
16
+ config.prompts_dir = '~/.prompts'
17
+ end.new
18
+
19
+ # Create and use a prompt
20
+ prompt = PromptManager::Prompt.new(id: 'greeting')
21
+ prompt.parameters = {
22
+ "[NAME]" => "Alice",
23
+ "[LANGUAGE]" => "English"
24
+ }
25
+
26
+ # Get the processed prompt text
27
+ puts prompt.to_s
28
+ ```
29
+
30
+ ## Advanced Integration with LLM and Streaming
31
+
32
+ The [advanced_integrations.rb](https://github.com/MadBomber/prompt_manager/blob/main/examples/advanced_integrations.rb) example demonstrates a complete integration with OpenAI's API, showcasing:
33
+
34
+ ### Features Demonstrated
35
+
36
+ - **ERB templating** for dynamic content generation
37
+ - **Shell integration** for environment variable substitution
38
+ - **OpenAI API integration** with streaming responses
39
+ - **Professional UI** with spinner feedback using `tty-spinner`
40
+ - **Real-time streaming** of LLM responses
41
+
42
+ ### Code Overview
43
+
44
+ ```ruby
45
+ #!/usr/bin/env ruby
46
+ # frozen_string_literal: true
47
+
48
+ require 'bundler/inline'
49
+
50
+ gemfile do
51
+ source 'https://rubygems.org'
52
+ gem 'prompt_manager'
53
+ gem 'ruby-openai'
54
+ gem 'tty-spinner'
55
+ end
56
+
57
+ require 'prompt_manager'
58
+ require 'openai'
59
+ require 'erb'
60
+ require 'time'
61
+ require 'tty-spinner'
62
+
63
+ # Configure PromptManager with filesystem adapter
64
+ PromptManager::Prompt.storage_adapter = PromptManager::Storage::FileSystemAdapter.config do |config|
65
+ config.prompts_dir = File.join(__dir__, 'prompts_dir')
66
+ end.new
67
+
68
+ # Configure OpenAI client
69
+ client = OpenAI::Client.new(
70
+ access_token: ENV['OPENAI_API_KEY']
71
+ )
72
+
73
+ # Get prompt instance with advanced features enabled
74
+ prompt = PromptManager::Prompt.new(
75
+ id: 'advanced_demo',
76
+ erb_flag: true, # Enable ERB templating
77
+ envar_flag: true # Enable environment variable substitution
78
+ )
79
+
80
+ # Show spinner while waiting for response
81
+ spinner = TTY::Spinner.new("[:spinner] Waiting for response...")
82
+ spinner.auto_spin
83
+
84
+ # Stream the response from OpenAI
85
+ response = client.chat(
86
+ parameters: {
87
+ model: 'gpt-4o-mini',
88
+ messages: [{ role: 'user', content: prompt.to_s }],
89
+ stream: proc do |chunk, _bytesize|
90
+ spinner.stop
91
+ content = chunk.dig("choices", 0, "delta", "content")
92
+ print content if content
93
+ $stdout.flush
94
+ end
95
+ }
96
+ )
97
+
98
+ puts
99
+ ```
100
+
101
+ ### Prompt Template
102
+
103
+ The example uses a sophisticated prompt template ([advanced_demo.txt](https://github.com/MadBomber/prompt_manager/blob/main/examples/prompts_dir/advanced_demo.txt)) that demonstrates:
104
+
105
+ ```text
106
+ # System Analysis and Historical Comparison Report
107
+ # Generated with PromptManager - ERB + Shell Integration Demo
108
+
109
+ ```markdown
110
+ ## Current System Information
111
+
112
+ **Timestamp**: <%= Time.now.strftime('%A, %B %d, %Y at %I:%M:%S %p %Z') %>
113
+ **Analysis Duration**: <%= Time.now - Time.parse('2024-01-01') %> seconds since 2024 began
114
+
115
+ ### Hardware Platform Details
116
+ **Architecture**: $HOSTTYPE$MACHTYPE
117
+ **Hostname**: $HOSTNAME
118
+ **Operating System**: $OSTYPE
119
+ **Shell**: $SHELL (version: $BASH_VERSION)
120
+ **User**: $USER
121
+ **Home Directory**: $HOME
122
+ **Current Path**: $PWD
123
+ **Terminal**: $TERM
124
+
125
+ ### Detailed System Profile
126
+ <% if RUBY_PLATFORM.include?('darwin') %>
127
+ **Platform**: macOS/Darwin System
128
+ **Ruby Platform**: <%= RUBY_PLATFORM %>
129
+ **Ruby Version**: <%= RUBY_VERSION %>
130
+ **Ruby Engine**: <%= RUBY_ENGINE %>
131
+ <% elsif RUBY_PLATFORM.include?('linux') %>
132
+ **Platform**: Linux System
133
+ **Ruby Platform**: <%= RUBY_PLATFORM %>
134
+ **Ruby Version**: <%= RUBY_VERSION %>
135
+ **Ruby Engine**: <%= RUBY_ENGINE %>
136
+ <% else %>
137
+ **Platform**: Other Unix-like System
138
+ **Ruby Platform**: <%= RUBY_PLATFORM %>
139
+ **Ruby Version**: <%= RUBY_VERSION %>
140
+ **Ruby Engine**: <%= RUBY_ENGINE %>
141
+ <% end %>
142
+
143
+ ### Performance Context
144
+ **Load Average**: <%= `uptime`.strip rescue 'Unable to determine' %>
145
+ **Memory Info**: <%= `vm_stat | head -5`.strip rescue 'Unable to determine' if RUBY_PLATFORM.include?('darwin') %>
146
+ **Disk Usage**: <%= `df -h / | tail -1`.strip rescue 'Unable to determine' %>
147
+
148
+ ## Analysis Request
149
+
150
+ You are a technology historian and systems analyst. Please provide a comprehensive comparison between this current system and **the most powerful Apple computer created in the 20th century** (which would be from the 1990s).
151
+ ```
152
+
153
+ ### Key Benefits
154
+
155
+ 1. **Dynamic Content**: ERB templating allows for real-time system information gathering
156
+ 2. **Environment Awareness**: Shell integration provides current system context
157
+ 3. **Professional UX**: Spinner provides visual feedback during API calls
158
+ 4. **Real-time Streaming**: Users see responses as they're generated
159
+ 5. **Comprehensive Analysis**: The prompt generates detailed technical comparisons
160
+
161
+ ## Search Integration
162
+
163
+ See [using_search_proc.rb](https://github.com/MadBomber/prompt_manager/blob/main/examples/using_search_proc.rb) for advanced search capabilities:
164
+
165
+ ```ruby
166
+ # Configure custom search with ripgrep
167
+ PromptManager::Storage::FileSystemAdapter.config do |config|
168
+ config.prompts_dir = '~/.prompts'
169
+ config.search_proc = ->(query) {
170
+ # Use ripgrep for fast searching
171
+ `rg -l "#{query}" #{config.prompts_dir}`.split("\n")
172
+ .map { |path| File.basename(path, '.txt') }
173
+ }
174
+ end.new
175
+
176
+ # Search for prompts containing specific terms
177
+ results = PromptManager::Prompt.search("database queries")
178
+ puts "Found prompts: #{results.join(', ')}"
179
+ ```
180
+
181
+ ## Parameter Management
182
+
183
+ ### Basic Parameters
184
+
185
+ ```ruby
186
+ prompt = PromptManager::Prompt.new(id: 'template')
187
+ prompt.parameters = {
188
+ "[NAME]" => "John",
189
+ "[ROLE]" => "developer",
190
+ "[PROJECT]" => "web application"
191
+ }
192
+ ```
193
+
194
+ ### Parameter History
195
+
196
+ ```ruby
197
+ # Parameters support history tracking
198
+ prompt.parameters = {
199
+ "[NAME]" => ["Alice", "Bob", "Charlie"] # Charlie is most recent
200
+ }
201
+
202
+ # Access current value
203
+ current_name = prompt.parameters["[NAME]"].last
204
+
205
+ # Access history
206
+ name_history = prompt.parameters["[NAME]"]
207
+ ```
208
+
209
+ ## Custom Storage Adapters
210
+
211
+ ### Redis Storage Example
212
+
213
+ ```ruby
214
+ require 'redis'
215
+ require 'json'
216
+
217
+ class RedisAdapter
218
+ def initialize(redis_client)
219
+ @redis = redis_client
220
+ end
221
+
222
+ def get(id:)
223
+ {
224
+ id: id,
225
+ text: @redis.get("prompt:#{id}:text") || "",
226
+ parameters: JSON.parse(@redis.get("prompt:#{id}:params") || '{}')
227
+ }
228
+ end
229
+
230
+ def save(id:, text:, parameters:)
231
+ @redis.set("prompt:#{id}:text", text)
232
+ @redis.set("prompt:#{id}:params", parameters.to_json)
233
+ end
234
+
235
+ def delete(id:)
236
+ @redis.del("prompt:#{id}:text", "prompt:#{id}:params")
237
+ end
238
+
239
+ def search(query)
240
+ # Simple search implementation
241
+ @redis.keys("prompt:*:text").select do |key|
242
+ content = @redis.get(key)
243
+ content&.include?(query)
244
+ end.map { |key| key.split(':')[1] }
245
+ end
246
+
247
+ def list
248
+ @redis.keys("prompt:*:text").map { |key| key.split(':')[1] }
249
+ end
250
+ end
251
+
252
+ # Usage
253
+ redis = Redis.new
254
+ PromptManager::Prompt.storage_adapter = RedisAdapter.new(redis)
255
+ ```
256
+
257
+ ## Directive Processing
258
+
259
+ ### Custom Directives
260
+
261
+ ```ruby
262
+ class CustomDirectiveProcessor < PromptManager::DirectiveProcessor
263
+ def process_directive(directive, prompt)
264
+ case directive
265
+ when /^\/\/model (.+)$/
266
+ set_model($1)
267
+ when /^\/\/temperature (.+)$/
268
+ set_temperature($1.to_f)
269
+ when /^\/\/max_tokens (\d+)$/
270
+ set_max_tokens($1.to_i)
271
+ else
272
+ super # Handle built-in directives
273
+ end
274
+ end
275
+
276
+ private
277
+
278
+ def set_model(model)
279
+ @model = model
280
+ end
281
+
282
+ def set_temperature(temp)
283
+ @temperature = temp
284
+ end
285
+
286
+ def set_max_tokens(tokens)
287
+ @max_tokens = tokens
288
+ end
289
+ end
290
+
291
+ # Usage
292
+ prompt = PromptManager::Prompt.new(
293
+ id: 'ai_prompt',
294
+ directives_processor: CustomDirectiveProcessor.new
295
+ )
296
+ ```
297
+
298
+ ## Error Handling
299
+
300
+ ```ruby
301
+ begin
302
+ prompt = PromptManager::Prompt.new(id: 'nonexistent')
303
+ result = prompt.to_s
304
+ rescue PromptManager::StorageError => e
305
+ puts "Storage error: #{e.message}"
306
+ rescue PromptManager::ParameterError => e
307
+ puts "Parameter error: #{e.message}"
308
+ rescue PromptManager::ConfigurationError => e
309
+ puts "Configuration error: #{e.message}"
310
+ end
311
+ ```
312
+
313
+ ## Testing Integration
314
+
315
+ ```ruby
316
+ # Test helper for prompt testing
317
+ def test_prompt(id, params = {})
318
+ prompt = PromptManager::Prompt.new(id: id)
319
+ prompt.parameters = params
320
+ prompt.to_s
321
+ end
322
+
323
+ # Example test
324
+ describe "greeting prompt" do
325
+ it "personalizes the greeting" do
326
+ result = test_prompt('greeting', {
327
+ "[NAME]" => "Alice",
328
+ "[TIME]" => "morning"
329
+ })
330
+
331
+ expect(result).to include("Hello Alice")
332
+ expect(result).to include("Good morning")
333
+ end
334
+ end
335
+ ```
336
+
337
+ For more examples and advanced usage patterns, see the complete examples in the [examples/](https://github.com/MadBomber/prompt_manager/tree/main/examples) directory.
@@ -0,0 +1,318 @@
1
+ # Basic Concepts
2
+
3
+ Understanding these core concepts will help you make the most of PromptManager.
4
+
5
+ ## The Prompt Lifecycle
6
+
7
+ Every prompt in PromptManager follows a predictable lifecycle:
8
+
9
+ ```mermaid
10
+ graph TD
11
+ A[Create/Load Prompt] --> B[Parse Keywords]
12
+ B --> C[Set Parameters]
13
+ C --> D[Process Directives]
14
+ D --> E[Apply ERB Templates]
15
+ E --> F[Substitute Variables]
16
+ F --> G[Generate Final Text]
17
+ G --> H[Save Changes]
18
+ ```
19
+
20
+ ## Core Components
21
+
22
+ ### 1. Prompts
23
+
24
+ A **Prompt** is the central entity in PromptManager. It represents a template with:
25
+
26
+ - **Text content** with embedded keywords
27
+ - **Parameters** (values for keywords)
28
+ - **Metadata** (directives, comments, configuration)
29
+
30
+ ```ruby
31
+ prompt = PromptManager::Prompt.new(
32
+ id: 'example', # Unique identifier
33
+ erb_flag: true, # Enable ERB processing
34
+ envar_flag: true # Enable environment variables
35
+ )
36
+ ```
37
+
38
+ ### 2. Keywords
39
+
40
+ **Keywords** are placeholders in your prompt text that get replaced with actual values:
41
+
42
+ ```text
43
+ Hello [NAME], today is [DATE] and the weather is [WEATHER].
44
+ ```
45
+
46
+ Default keyword format: `[UPPERCASE_WITH_UNDERSCORES]`
47
+
48
+ You can customize this pattern:
49
+
50
+ ```ruby
51
+ # Use {{mustache}} style
52
+ PromptManager::Prompt.parameter_regex = /(\{\{[a-z_]+\}\})/
53
+
54
+ # Use :symbol style
55
+ PromptManager::Prompt.parameter_regex = /(:[a-z_]+)/
56
+ ```
57
+
58
+ ### 3. Parameters
59
+
60
+ **Parameters** are the actual values that replace keywords:
61
+
62
+ ```ruby
63
+ prompt.parameters = {
64
+ "[NAME]" => "Alice",
65
+ "[DATE]" => Date.today.to_s,
66
+ "[WEATHER]" => "sunny"
67
+ }
68
+ ```
69
+
70
+ Since v0.3.0, parameters store history as arrays:
71
+
72
+ ```ruby
73
+ prompt.parameters = {
74
+ "[NAME]" => ["Alice", "Bob", "Charlie"] # Charlie is most recent
75
+ }
76
+ ```
77
+
78
+ ### 4. Storage Adapters
79
+
80
+ **Storage Adapters** handle how prompts are persisted:
81
+
82
+ === "FileSystem"
83
+
84
+ ```ruby
85
+ PromptManager::Storage::FileSystemAdapter.config do |config|
86
+ config.prompts_dir = '~/.prompts'
87
+ config.prompt_extension = '.txt'
88
+ config.params_extension = '.json'
89
+ end
90
+ ```
91
+
92
+ === "ActiveRecord"
93
+
94
+ ```ruby
95
+ PromptManager::Storage::ActiveRecordAdapter.config do |config|
96
+ config.model = PromptModel
97
+ config.id_column = :name
98
+ config.text_column = :content
99
+ config.parameters_column = :params
100
+ end
101
+ ```
102
+
103
+ ### 5. Directives
104
+
105
+ **Directives** are special instructions that start with `//`:
106
+
107
+ ```text
108
+ //include common/header.txt
109
+ //import templates/[TEMPLATE_TYPE].txt
110
+
111
+ Your main prompt content here...
112
+ ```
113
+
114
+ ## File Structure (FileSystem Adapter)
115
+
116
+ When using the FileSystem adapter, your prompts are organized like this:
117
+
118
+ ```
119
+ ~/.prompts/
120
+ ├── greeting.txt # Prompt text
121
+ ├── greeting.json # Parameters
122
+ ├── translation.txt
123
+ ├── translation.json
124
+ └── common/
125
+ ├── header.txt # Shared components
126
+ └── footer.txt
127
+ ```
128
+
129
+ ### Prompt Files (`.txt`)
130
+
131
+ ```text title="greeting.txt"
132
+ # Description: Friendly greeting prompt
133
+ # Tags: customer-service, greeting
134
+ # Version: 1.2
135
+
136
+ //include common/header.txt
137
+
138
+ Hello [CUSTOMER_NAME]!
139
+
140
+ Thank you for contacting [COMPANY_NAME]. I'm here to help you with
141
+ [REQUEST_TYPE]. Let me know how I can assist you today.
142
+
143
+ Best regards,
144
+ [AGENT_NAME]
145
+
146
+ __END__
147
+ Internal notes: This prompt is used for all initial customer contacts.
148
+ Update the company name parameter when client changes.
149
+ ```
150
+
151
+ ### Parameter Files (`.json`)
152
+
153
+ ```json title="greeting.json"
154
+ {
155
+ "[CUSTOMER_NAME]": ["Alice Johnson", "Bob Smith"],
156
+ "[COMPANY_NAME]": ["Acme Corp"],
157
+ "[REQUEST_TYPE]": ["general inquiry", "technical support", "billing"],
158
+ "[AGENT_NAME]": ["Sarah", "Mike", "Jennifer"]
159
+ }
160
+ ```
161
+
162
+ ## Processing Pipeline
163
+
164
+ PromptManager processes prompts through several stages:
165
+
166
+ ### 1. Text Loading
167
+ - Load raw prompt text from storage
168
+ - Parse out comments and `__END__` sections
169
+
170
+ ### 2. Keyword Extraction
171
+ - Scan text for keyword patterns
172
+ - Build list of required parameters
173
+
174
+ ### 3. Directive Processing
175
+ - Process `//include` and `//import` directives
176
+ - Handle loop protection for circular includes
177
+ - Substitute keywords in directive paths
178
+
179
+ ### 4. Template Processing
180
+ - Apply ERB templates if `erb_flag` is true
181
+ - Substitute environment variables if `envar_flag` is true
182
+
183
+ ### 5. Parameter Substitution
184
+ - Replace keywords with parameter values
185
+ - Handle missing parameters (error or warning)
186
+
187
+ ### 6. Final Assembly
188
+ - Combine processed components
189
+ - Return final prompt text
190
+
191
+ ## Error Handling
192
+
193
+ PromptManager provides specific error types:
194
+
195
+ ```ruby
196
+ begin
197
+ prompt = PromptManager::Prompt.new(id: 'example')
198
+ puts prompt.to_s
199
+ rescue PromptManager::StorageError => e
200
+ puts "Storage problem: #{e.message}"
201
+ rescue PromptManager::ParameterError => e
202
+ puts "Parameter issue: #{e.message}"
203
+ rescue PromptManager::ConfigurationError => e
204
+ puts "Config problem: #{e.message}"
205
+ end
206
+ ```
207
+
208
+ ### Common Error Scenarios
209
+
210
+ | Error Type | Common Cause | Solution |
211
+ |------------|--------------|----------|
212
+ | `StorageError` | File not found, permission denied | Check file paths and permissions |
213
+ | `ParameterError` | Missing parameter value | Set all required parameters |
214
+ | `ConfigurationError` | Invalid adapter config | Review adapter configuration |
215
+
216
+ ## Best Practices
217
+
218
+ ### 1. Organize Your Prompts
219
+
220
+ ```
221
+ prompts/
222
+ ├── common/ # Shared components
223
+ │ ├── headers/
224
+ │ ├── footers/
225
+ │ └── signatures/
226
+ ├── customer-service/ # Domain-specific prompts
227
+ ├── technical/
228
+ └── templates/ # Reusable templates
229
+ ```
230
+
231
+ ### 2. Use Meaningful Keywords
232
+
233
+ ```text
234
+ # Good - descriptive and clear
235
+ [CUSTOMER_NAME], [ORDER_NUMBER], [DELIVERY_DATE]
236
+
237
+ # Avoid - unclear abbreviations
238
+ [CN], [ON], [DD]
239
+ ```
240
+
241
+ ### 3. Document Your Prompts
242
+
243
+ ```text
244
+ # Description: What this prompt does
245
+ # Tags: classification, tags
246
+ # Version: 1.0
247
+ # Author: Your Name
248
+ # Last Updated: 2024-01-15
249
+
250
+ //include common/disclaimer.txt
251
+
252
+ Your prompt content...
253
+
254
+ __END__
255
+ Internal notes, change history, and documentation go here.
256
+ This section is ignored by the processor.
257
+ ```
258
+
259
+ ### 4. Version Your Parameters
260
+
261
+ ```json
262
+ {
263
+ "_meta": {
264
+ "version": "1.0",
265
+ "updated": "2024-01-15",
266
+ "notes": "Added new product categories"
267
+ },
268
+ "[CATEGORY]": ["electronics", "books", "clothing"]
269
+ }
270
+ ```
271
+
272
+ ## Advanced Concepts
273
+
274
+ ### Parameter Validation
275
+
276
+ ```ruby
277
+ # Custom validation in your application
278
+ def validate_parameters(prompt)
279
+ required = prompt.keywords
280
+ provided = prompt.parameters.keys
281
+ missing = required - provided
282
+
283
+ raise "Missing parameters: #{missing.join(', ')}" unless missing.empty?
284
+ end
285
+ ```
286
+
287
+ ### Dynamic Prompts
288
+
289
+ ```text
290
+ # Template selection based on parameters
291
+ //include templates/[TEMPLATE_TYPE].txt
292
+
293
+ # Conditional content using ERB
294
+ <% if '[URGENCY]' == 'high' %>
295
+ 🚨 URGENT: Immediate attention required
296
+ <% end %>
297
+ ```
298
+
299
+ ### Search Integration
300
+
301
+ ```ruby
302
+ # Configure custom search
303
+ adapter.search_proc = ->(query) {
304
+ # Use ripgrep for fast search
305
+ `rg -l "#{query}" #{prompts_dir}`.split("\n").map { |f|
306
+ File.basename(f, '.txt')
307
+ }
308
+ }
309
+ ```
310
+
311
+ ## Next Steps
312
+
313
+ Now that you understand the basics:
314
+
315
+ 1. **Try the examples** in [Core Features](../core-features/parameterized-prompts.md)
316
+ 2. **Choose a storage adapter** in [Storage Adapters](../storage/overview.md)
317
+ 3. **Explore advanced features** in [Advanced Usage](../advanced/custom-keywords.md)
318
+ 4. **See real applications** in [Examples](../examples/basic.md)