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,500 @@
|
|
1
|
+
# Parameterized Prompts
|
2
|
+
|
3
|
+
Parameterized prompts are the heart of PromptManager. They allow you to create reusable template prompts with placeholders (keywords) that can be filled with different values.
|
4
|
+
|
5
|
+
## Basic Concepts
|
6
|
+
|
7
|
+
### What are Keywords?
|
8
|
+
|
9
|
+
Keywords are placeholders in your prompt text that get replaced with actual values. By default, they follow the pattern `[UPPERCASE_TEXT]`:
|
10
|
+
|
11
|
+
```text
|
12
|
+
Hello [NAME]! Today is [DATE] and you have [COUNT] messages.
|
13
|
+
```
|
14
|
+
|
15
|
+
### Parameter Substitution
|
16
|
+
|
17
|
+
When you provide parameter values, PromptManager replaces keywords with their corresponding values:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
prompt.parameters = {
|
21
|
+
"[NAME]" => "Alice",
|
22
|
+
"[DATE]" => "2024-01-15",
|
23
|
+
"[COUNT]" => "3"
|
24
|
+
}
|
25
|
+
|
26
|
+
puts prompt.to_s
|
27
|
+
# Output: Hello Alice! Today is 2024-01-15 and you have 3 messages.
|
28
|
+
```
|
29
|
+
|
30
|
+
## Keyword Formats
|
31
|
+
|
32
|
+
### Default Format
|
33
|
+
|
34
|
+
The default keyword pattern is `[UPPERCASE_WITH_UNDERSCORES_AND_SPACES]`:
|
35
|
+
|
36
|
+
```text
|
37
|
+
# Valid keywords
|
38
|
+
[NAME]
|
39
|
+
[USER_NAME]
|
40
|
+
[FIRST_NAME]
|
41
|
+
[ORDER NUMBER] # Spaces allowed
|
42
|
+
[API_KEY]
|
43
|
+
```
|
44
|
+
|
45
|
+
### Custom Keyword Patterns
|
46
|
+
|
47
|
+
You can customize the keyword pattern to match your preferences:
|
48
|
+
|
49
|
+
=== "Mustache Style"
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
PromptManager::Prompt.parameter_regex = /(\{\{[a-z_]+\}\})/
|
53
|
+
|
54
|
+
# Now use: {{name}}, {{user_name}}, {{api_key}}
|
55
|
+
prompt_text = "Hello {{name}}, your key is {{api_key}}"
|
56
|
+
```
|
57
|
+
|
58
|
+
=== "Colon Style"
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
PromptManager::Prompt.parameter_regex = /(:[a-z_]+)/
|
62
|
+
|
63
|
+
# Now use: :name, :user_name, :api_key
|
64
|
+
prompt_text = "Hello :name, your key is :api_key"
|
65
|
+
```
|
66
|
+
|
67
|
+
=== "Dollar Style"
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
PromptManager::Prompt.parameter_regex = /(\$[A-Z_]+)/
|
71
|
+
|
72
|
+
# Now use: $NAME, $USER_NAME, $API_KEY
|
73
|
+
prompt_text = "Hello $NAME, your key is $API_KEY"
|
74
|
+
```
|
75
|
+
|
76
|
+
!!! warning "Regex Requirements"
|
77
|
+
Your custom regex must include capturing parentheses `()` to extract the keyword. The capture group should include the delimiter characters.
|
78
|
+
|
79
|
+
## Working with Parameters
|
80
|
+
|
81
|
+
### Setting Parameters
|
82
|
+
|
83
|
+
There are several ways to set parameter values:
|
84
|
+
|
85
|
+
=== "Direct Assignment"
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
prompt.parameters = {
|
89
|
+
"[NAME]" => "Alice",
|
90
|
+
"[EMAIL]" => "alice@example.com"
|
91
|
+
}
|
92
|
+
```
|
93
|
+
|
94
|
+
=== "Individual Assignment"
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
prompt.parameters["[NAME]"] = "Bob"
|
98
|
+
prompt.parameters["[EMAIL]"] = "bob@example.com"
|
99
|
+
```
|
100
|
+
|
101
|
+
=== "Batch Update"
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
new_params = {
|
105
|
+
"[NAME]" => "Charlie",
|
106
|
+
"[ROLE]" => "Administrator"
|
107
|
+
}
|
108
|
+
prompt.parameters.merge!(new_params)
|
109
|
+
```
|
110
|
+
|
111
|
+
### Parameter History (v0.3.0+)
|
112
|
+
|
113
|
+
Since version 0.3.0, parameters maintain a history of values as arrays:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
# Setting a single value
|
117
|
+
prompt.parameters["[NAME]"] = "Alice"
|
118
|
+
|
119
|
+
# Internally stored as: ["Alice"]
|
120
|
+
# The last value is always the most recent
|
121
|
+
|
122
|
+
# Adding more values
|
123
|
+
prompt.parameters["[NAME]"] = ["Alice", "Bob", "Charlie"]
|
124
|
+
|
125
|
+
# Get the current value
|
126
|
+
current_name = prompt.parameters["[NAME]"].last # "Charlie"
|
127
|
+
|
128
|
+
# Get the full history
|
129
|
+
all_names = prompt.parameters["[NAME]"] # ["Alice", "Bob", "Charlie"]
|
130
|
+
```
|
131
|
+
|
132
|
+
This history is useful for:
|
133
|
+
|
134
|
+
- Building dropdown lists in UIs
|
135
|
+
- Providing auto-completion
|
136
|
+
- Tracking parameter usage over time
|
137
|
+
- Implementing "recent values" functionality
|
138
|
+
|
139
|
+
### Getting Available Keywords
|
140
|
+
|
141
|
+
Discover what keywords are available in a prompt:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
prompt = PromptManager::Prompt.new(id: 'email_template')
|
145
|
+
keywords = prompt.keywords
|
146
|
+
puts "Required parameters: #{keywords.join(', ')}"
|
147
|
+
# Output: Required parameters: [TO_NAME], [FROM_NAME], [SUBJECT], [BODY]
|
148
|
+
```
|
149
|
+
|
150
|
+
### Checking for Missing Parameters
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
def check_missing_parameters(prompt)
|
154
|
+
required = prompt.keywords.to_set
|
155
|
+
provided = prompt.parameters.keys.to_set
|
156
|
+
missing = required - provided
|
157
|
+
|
158
|
+
unless missing.empty?
|
159
|
+
puts "⚠️ Missing parameters: #{missing.to_a.join(', ')}"
|
160
|
+
return false
|
161
|
+
end
|
162
|
+
|
163
|
+
puts "✅ All parameters provided"
|
164
|
+
true
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
## Advanced Parameter Techniques
|
169
|
+
|
170
|
+
### Conditional Parameters
|
171
|
+
|
172
|
+
Use ERB to make parameters conditional:
|
173
|
+
|
174
|
+
```text title="conditional_greeting.txt"
|
175
|
+
Hello [NAME]!
|
176
|
+
|
177
|
+
<% if '[ROLE]' == 'admin' %>
|
178
|
+
You have administrative privileges.
|
179
|
+
<% elsif '[ROLE]' == 'user' %>
|
180
|
+
You have standard user access.
|
181
|
+
<% else %>
|
182
|
+
Please contact support to set up your account.
|
183
|
+
<% end %>
|
184
|
+
|
185
|
+
Your last login was [LAST_LOGIN].
|
186
|
+
```
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
prompt = PromptManager::Prompt.new(id: 'conditional_greeting', erb_flag: true)
|
190
|
+
prompt.parameters = {
|
191
|
+
"[NAME]" => "Alice",
|
192
|
+
"[ROLE]" => "admin",
|
193
|
+
"[LAST_LOGIN]" => "2024-01-15 09:30"
|
194
|
+
}
|
195
|
+
```
|
196
|
+
|
197
|
+
### Nested Parameter Substitution
|
198
|
+
|
199
|
+
Parameters can reference other parameters:
|
200
|
+
|
201
|
+
```text title="nested_example.txt"
|
202
|
+
Welcome to [COMPANY_NAME], [USER_NAME]!
|
203
|
+
|
204
|
+
Your profile: [USER_PROFILE_URL]
|
205
|
+
Support email: [SUPPORT_EMAIL]
|
206
|
+
```
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
prompt.parameters = {
|
210
|
+
"[COMPANY_NAME]" => "Acme Corp",
|
211
|
+
"[USER_NAME]" => "alice",
|
212
|
+
"[USER_PROFILE_URL]" => "https://[COMPANY_NAME].com/users/[USER_NAME]".downcase,
|
213
|
+
"[SUPPORT_EMAIL]" => "support@[COMPANY_NAME].com".downcase
|
214
|
+
}
|
215
|
+
|
216
|
+
# First pass replaces top-level parameters
|
217
|
+
# Additional processing may be needed for nested substitution
|
218
|
+
```
|
219
|
+
|
220
|
+
### Dynamic Parameter Generation
|
221
|
+
|
222
|
+
Generate parameters programmatically:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
def generate_user_parameters(user)
|
226
|
+
{
|
227
|
+
"[USER_ID]" => user.id.to_s,
|
228
|
+
"[USER_NAME]" => user.full_name,
|
229
|
+
"[USER_EMAIL]" => user.email,
|
230
|
+
"[USER_ROLE]" => user.role.upcase,
|
231
|
+
"[JOIN_DATE]" => user.created_at.strftime('%B %Y'),
|
232
|
+
"[LAST_ACTIVE]" => time_ago_in_words(user.last_seen_at)
|
233
|
+
}
|
234
|
+
end
|
235
|
+
|
236
|
+
# Usage
|
237
|
+
user = User.find(123)
|
238
|
+
prompt.parameters = generate_user_parameters(user)
|
239
|
+
```
|
240
|
+
|
241
|
+
### Parameter Validation
|
242
|
+
|
243
|
+
Implement custom validation for your parameters:
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
class ParameterValidator
|
247
|
+
def self.validate(prompt)
|
248
|
+
errors = []
|
249
|
+
|
250
|
+
prompt.parameters.each do |key, value|
|
251
|
+
case key
|
252
|
+
when "[EMAIL]"
|
253
|
+
unless value =~ URI::MailTo::EMAIL_REGEXP
|
254
|
+
errors << "#{key} must be a valid email address"
|
255
|
+
end
|
256
|
+
when "[DATE]"
|
257
|
+
begin
|
258
|
+
Date.parse(value)
|
259
|
+
rescue ArgumentError
|
260
|
+
errors << "#{key} must be a valid date"
|
261
|
+
end
|
262
|
+
when "[COUNT]"
|
263
|
+
unless value.to_i.to_s == value && value.to_i >= 0
|
264
|
+
errors << "#{key} must be a non-negative integer"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
errors
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Usage
|
274
|
+
errors = ParameterValidator.validate(prompt)
|
275
|
+
if errors.any?
|
276
|
+
puts "Validation errors:"
|
277
|
+
errors.each { |error| puts " - #{error}" }
|
278
|
+
end
|
279
|
+
```
|
280
|
+
|
281
|
+
## Real-World Examples
|
282
|
+
|
283
|
+
### Email Template
|
284
|
+
|
285
|
+
```text title="welcome_email.txt"
|
286
|
+
Subject: Welcome to [COMPANY_NAME], [FIRST_NAME]!
|
287
|
+
|
288
|
+
Dear [FULL_NAME],
|
289
|
+
|
290
|
+
Welcome to [COMPANY_NAME]! We're excited to have you join our community.
|
291
|
+
|
292
|
+
Here are your account details:
|
293
|
+
- Username: [USERNAME]
|
294
|
+
- Email: [EMAIL]
|
295
|
+
- Account Type: [ACCOUNT_TYPE]
|
296
|
+
- Member Since: [JOIN_DATE]
|
297
|
+
|
298
|
+
Next steps:
|
299
|
+
1. Complete your profile at [PROFILE_URL]
|
300
|
+
2. Download our mobile app: [APP_STORE_URL]
|
301
|
+
3. Join our community forum: [FORUM_URL]
|
302
|
+
|
303
|
+
If you have any questions, contact us at [SUPPORT_EMAIL] or
|
304
|
+
call [SUPPORT_PHONE].
|
305
|
+
|
306
|
+
Best regards,
|
307
|
+
[SENDER_NAME]
|
308
|
+
[SENDER_TITLE]
|
309
|
+
[COMPANY_NAME]
|
310
|
+
```
|
311
|
+
|
312
|
+
### API Documentation Template
|
313
|
+
|
314
|
+
```text title="api_doc_template.txt"
|
315
|
+
# [API_NAME] API Documentation
|
316
|
+
|
317
|
+
## Endpoint: [HTTP_METHOD] [ENDPOINT_URL]
|
318
|
+
|
319
|
+
### Description
|
320
|
+
[DESCRIPTION]
|
321
|
+
|
322
|
+
### Authentication
|
323
|
+
[AUTH_TYPE]: `[AUTH_HEADER]: [AUTH_VALUE]`
|
324
|
+
|
325
|
+
### Parameters
|
326
|
+
|
327
|
+
| Parameter | Type | Required | Description |
|
328
|
+
|-----------|------|----------|-------------|
|
329
|
+
[PARAMETER_TABLE]
|
330
|
+
|
331
|
+
### Example Request
|
332
|
+
|
333
|
+
```[REQUEST_LANGUAGE]
|
334
|
+
[REQUEST_EXAMPLE]
|
335
|
+
```
|
336
|
+
|
337
|
+
### Example Response
|
338
|
+
|
339
|
+
```json
|
340
|
+
[RESPONSE_EXAMPLE]
|
341
|
+
```
|
342
|
+
|
343
|
+
### Error Codes
|
344
|
+
|
345
|
+
[ERROR_TABLE]
|
346
|
+
|
347
|
+
---
|
348
|
+
Last updated: [LAST_UPDATED]
|
349
|
+
API Version: [API_VERSION]
|
350
|
+
```
|
351
|
+
|
352
|
+
### Customer Support Template
|
353
|
+
|
354
|
+
```text title="support_response.txt"
|
355
|
+
//include common/support_header.txt
|
356
|
+
|
357
|
+
Dear [CUSTOMER_NAME],
|
358
|
+
|
359
|
+
Thank you for contacting [COMPANY_NAME] support regarding
|
360
|
+
ticket #[TICKET_ID].
|
361
|
+
|
362
|
+
Issue Summary: [ISSUE_SUMMARY]
|
363
|
+
Priority Level: [PRIORITY]
|
364
|
+
Assigned Agent: [AGENT_NAME]
|
365
|
+
|
366
|
+
<% if '[PRIORITY]' == 'urgent' %>
|
367
|
+
🚨 This is marked as urgent. We're prioritizing your request
|
368
|
+
and aim to resolve it within [URGENT_SLA] hours.
|
369
|
+
<% else %>
|
370
|
+
We aim to resolve your issue within [STANDARD_SLA] business days.
|
371
|
+
<% end %>
|
372
|
+
|
373
|
+
Our preliminary investigation shows:
|
374
|
+
[INVESTIGATION_NOTES]
|
375
|
+
|
376
|
+
Next steps:
|
377
|
+
[NEXT_STEPS]
|
378
|
+
|
379
|
+
You can track your ticket status at: [TICKET_URL]
|
380
|
+
|
381
|
+
Best regards,
|
382
|
+
[AGENT_NAME]
|
383
|
+
[COMPANY_NAME] Support Team
|
384
|
+
|
385
|
+
//include common/support_footer.txt
|
386
|
+
```
|
387
|
+
|
388
|
+
## Best Practices
|
389
|
+
|
390
|
+
### 1. Use Descriptive Keywords
|
391
|
+
|
392
|
+
```ruby
|
393
|
+
# Good - Clear and descriptive
|
394
|
+
"[USER_FIRST_NAME]", "[ORDER_TOTAL_AMOUNT]", "[DELIVERY_DATE]"
|
395
|
+
|
396
|
+
# Avoid - Ambiguous abbreviations
|
397
|
+
"[UFN]", "[OTA]", "[DD]"
|
398
|
+
```
|
399
|
+
|
400
|
+
### 2. Consistent Naming Convention
|
401
|
+
|
402
|
+
```ruby
|
403
|
+
# Choose one style and stick with it
|
404
|
+
"[USER_NAME]" # snake_case
|
405
|
+
"[UserName]" # PascalCase
|
406
|
+
"[user_name]" # lowercase
|
407
|
+
|
408
|
+
# Be consistent with plurality
|
409
|
+
"[ITEM]" + "[ITEM_COUNT]" # Singular + count
|
410
|
+
"[ITEMS]" # Plural when multiple
|
411
|
+
```
|
412
|
+
|
413
|
+
### 3. Document Your Keywords
|
414
|
+
|
415
|
+
```text
|
416
|
+
# Email welcome template
|
417
|
+
# Keywords:
|
418
|
+
# [USER_NAME] - Full display name of the user
|
419
|
+
# [EMAIL] - User's email address
|
420
|
+
# [JOIN_DATE] - Date user created account (YYYY-MM-DD format)
|
421
|
+
# [COMPANY_NAME] - Our company name
|
422
|
+
|
423
|
+
Welcome [USER_NAME]!
|
424
|
+
Your account ([EMAIL]) was created on [JOIN_DATE].
|
425
|
+
```
|
426
|
+
|
427
|
+
### 4. Provide Defaults
|
428
|
+
|
429
|
+
```ruby
|
430
|
+
def apply_defaults(prompt)
|
431
|
+
defaults = {
|
432
|
+
"[DATE]" => Date.today.to_s,
|
433
|
+
"[TIME]" => Time.now.strftime('%H:%M'),
|
434
|
+
"[COMPANY_NAME]" => "Your Company",
|
435
|
+
"[SUPPORT_EMAIL]" => "support@yourcompany.com"
|
436
|
+
}
|
437
|
+
|
438
|
+
defaults.each do |key, value|
|
439
|
+
prompt.parameters[key] ||= value
|
440
|
+
end
|
441
|
+
end
|
442
|
+
```
|
443
|
+
|
444
|
+
### 5. Handle Missing Parameters Gracefully
|
445
|
+
|
446
|
+
```ruby
|
447
|
+
class SafePrompt
|
448
|
+
def initialize(prompt)
|
449
|
+
@prompt = prompt
|
450
|
+
end
|
451
|
+
|
452
|
+
def to_s
|
453
|
+
text = @prompt.to_s
|
454
|
+
|
455
|
+
# Check for unreplaced keywords
|
456
|
+
unreplaced = text.scan(@prompt.class.parameter_regex).flatten
|
457
|
+
|
458
|
+
if unreplaced.any?
|
459
|
+
puts "⚠️ Warning: Unreplaced keywords: #{unreplaced.join(', ')}"
|
460
|
+
|
461
|
+
# Optionally replace with placeholder
|
462
|
+
unreplaced.each do |keyword|
|
463
|
+
text.gsub!(keyword, "[MISSING:#{keyword}]")
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
text
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
# Usage
|
472
|
+
safe_prompt = SafePrompt.new(prompt)
|
473
|
+
puts safe_prompt.to_s
|
474
|
+
```
|
475
|
+
|
476
|
+
## Troubleshooting
|
477
|
+
|
478
|
+
### Keywords Not Being Replaced
|
479
|
+
|
480
|
+
1. **Check keyword format**: Ensure keywords match your regex pattern
|
481
|
+
2. **Verify parameter keys**: Keys must exactly match keywords (case-sensitive)
|
482
|
+
3. **Confirm parameter values**: Make sure values are set and not nil
|
483
|
+
|
484
|
+
### Parameter History Issues
|
485
|
+
|
486
|
+
1. **Array format**: Remember parameters are arrays since v0.3.0
|
487
|
+
2. **Access latest value**: Use `.last` to get the most recent value
|
488
|
+
3. **Backward compatibility**: Single values are automatically converted to arrays
|
489
|
+
|
490
|
+
### Performance with Large Parameter Sets
|
491
|
+
|
492
|
+
1. **Cache keyword extraction**: Don't re-parse keywords unnecessarily
|
493
|
+
2. **Batch parameter updates**: Use `merge!` instead of individual assignments
|
494
|
+
3. **Consider parameter validation**: Validate early to catch errors sooner
|
495
|
+
|
496
|
+
## Next Steps
|
497
|
+
|
498
|
+
- Learn about [Directive Processing](directive-processing.md) for including other files
|
499
|
+
- Explore [ERB Integration](erb-integration.md) for dynamic content generation
|
500
|
+
- See [Advanced Examples](../examples/advanced.md) for complex use cases
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Shell Integration
|
2
|
+
|
3
|
+
PromptManager can automatically substitute environment variables and integrate with shell commands.
|
4
|
+
|
5
|
+
## Environment Variables
|
6
|
+
|
7
|
+
Enable environment variable substitution:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
prompt = PromptManager::Prompt.new(
|
11
|
+
id: 'system_prompt',
|
12
|
+
envar_flag: true
|
13
|
+
)
|
14
|
+
```
|
15
|
+
|
16
|
+
Environment variables in your prompt text will be automatically replaced.
|
17
|
+
|
18
|
+
## Example
|
19
|
+
|
20
|
+
```text title="system_prompt.txt"
|
21
|
+
System: $USER
|
22
|
+
Home: $HOME
|
23
|
+
Path: $PATH
|
24
|
+
|
25
|
+
Working directory: <%= Dir.pwd %>
|
26
|
+
```
|
27
|
+
|
28
|
+
## Shell Command Execution
|
29
|
+
|
30
|
+
PromptManager also supports shell command substitution using `$(command)` syntax:
|
31
|
+
|
32
|
+
```text title="system_info.txt"
|
33
|
+
Current system load: $(uptime)
|
34
|
+
Disk usage: $(df -h / | tail -1)
|
35
|
+
Memory info: $(vm_stat | head -5)
|
36
|
+
```
|
37
|
+
|
38
|
+
Commands are executed when the prompt is processed, with output substituted in place.
|
39
|
+
|
40
|
+
## Advanced Example
|
41
|
+
|
42
|
+
The [advanced_integrations.rb](https://github.com/MadBomber/prompt_manager/blob/main/examples/advanced_integrations.rb) example demonstrates comprehensive shell integration:
|
43
|
+
|
44
|
+
```text
|
45
|
+
### Hardware Platform Details
|
46
|
+
**Architecture**: $HOSTTYPE$MACHTYPE
|
47
|
+
**Hostname**: $HOSTNAME
|
48
|
+
**Operating System**: $OSTYPE
|
49
|
+
**Shell**: $SHELL (version: $BASH_VERSION)
|
50
|
+
**User**: $USER
|
51
|
+
**Home Directory**: $HOME
|
52
|
+
**Current Path**: $PWD
|
53
|
+
**Terminal**: $TERM
|
54
|
+
|
55
|
+
### Environment Configuration
|
56
|
+
**PATH**: $PATH
|
57
|
+
**Language**: $LANG
|
58
|
+
**Editor**: $EDITOR
|
59
|
+
**Pager**: $PAGER
|
60
|
+
|
61
|
+
### Performance Context
|
62
|
+
**Load Average**: <%= `uptime`.strip rescue 'Unable to determine' %>
|
63
|
+
**Memory Info**: <%= `vm_stat | head -5`.strip rescue 'Unable to determine' if RUBY_PLATFORM.include?('darwin') %>
|
64
|
+
**Disk Usage**: <%= `df -h / | tail -1`.strip rescue 'Unable to determine' %>
|
65
|
+
```
|
66
|
+
|
67
|
+
This creates dynamic prompts that capture real-time system information for analysis.
|
68
|
+
|
69
|
+
## Configuration
|
70
|
+
|
71
|
+
Set environment variables that your prompts will use:
|
72
|
+
|
73
|
+
```bash
|
74
|
+
export API_KEY="your-api-key"
|
75
|
+
export ENVIRONMENT="production"
|
76
|
+
export OPENAI_API_KEY="your-openai-key"
|
77
|
+
```
|
78
|
+
|
79
|
+
For more shell integration examples, see the [Examples documentation](../examples.md).
|