Skip to content

Commit ee7326f

Browse files
committed
chore: Remove redundant prompt_examples.md documentation
The examples/prompts/ directory already contains comprehensive examples: - few_shot_prompt.rb: Array format, builder pattern, backward compatibility - prompt_code_review.rb: ERB template usage - inline_prompt.rb: Inline text without templates No need for duplicate documentation in docs/
1 parent ea034eb commit ee7326f

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# Comparison of Prompt Implementations
2+
3+
## Overview
4+
This document compares our comprehensive prompt implementation with mariochavez's simpler alternative approach.
5+
6+
## Key Differences
7+
8+
### 1. Architecture Approach
9+
10+
#### Our Implementation (Comprehensive)
11+
- **Schema Validation**: Uses Dry::Schema for robust argument validation
12+
- **Message Builder**: Fluent API with MessageBuilder class for constructing messages
13+
- **Multiple APIs**: Supports hash, array, and block formats for messages
14+
- **Template Support**: Full ERB template rendering with variable interpolation
15+
- **Base64 Validation**: Ensures image content compliance with MCP spec
16+
- **Authorization**: Authorization blocks for access control
17+
- **Filtering**: Integration with ServerFiltering for dynamic prompt filtering
18+
- **Feature Parity**: Matches tool implementation with tags, metadata, annotations
19+
20+
#### Their Implementation (Simpler)
21+
- **Basic Validation**: Simple hash-based argument validation
22+
- **Direct Messages**: Static `get_messages` class method returns array
23+
- **Singleton Pattern**: Uses Singleton for prompt instances
24+
- **Simple Arguments**: Basic argument definitions with name/description/required
25+
- **No Templates**: No ERB or template support
26+
- **No Authorization**: No authorization mechanism
27+
- **No Filtering**: No filtering support
28+
- **Basic Feature Set**: Minimal feature set focused on core functionality
29+
30+
### 2. Code Complexity
31+
32+
#### Our Implementation
33+
```ruby
34+
# ~655 lines in prompt.rb
35+
class Prompt
36+
- Complex MessageBuilder class
37+
- Multiple validation layers
38+
- Template rendering
39+
- Authorization system
40+
- Extensive metadata support
41+
- Auto-naming from class names
42+
end
43+
```
44+
45+
#### Their Implementation
46+
```ruby
47+
# ~130 lines in prompt.rb
48+
class Prompt
49+
- Simple argument validation
50+
- Direct message generation
51+
- Basic metadata
52+
- Singleton pattern
53+
end
54+
```
55+
56+
### 3. Usage Examples
57+
58+
#### Our Implementation
59+
```ruby
60+
class CodeReviewPrompt < FastMcp::Prompt
61+
arguments do
62+
required(:code).filled(:string)
63+
optional(:language).filled(:string)
64+
end
65+
66+
def call(code:, language: 'ruby')
67+
messages do |b|
68+
b.user("Review this #{language} code: #{code}")
69+
b.assistant("I'll analyze this code for you.")
70+
end
71+
end
72+
end
73+
```
74+
75+
#### Their Implementation
76+
```ruby
77+
class CodeReviewPrompt < FastMcp::Prompt
78+
prompt_name 'code-review'
79+
argument :code, required: true
80+
argument :language, required: false
81+
82+
def self.get_messages(code:, language: 'ruby')
83+
[{
84+
role: 'user',
85+
content: { type: 'text', text: "Review this #{language} code: #{code}" }
86+
}]
87+
end
88+
end
89+
```
90+
91+
### 4. Testing Coverage
92+
93+
#### Our Implementation
94+
- **900+ lines** of tests in prompt_spec.rb
95+
- 71 test cases for messages API alone
96+
- Comprehensive edge case coverage
97+
- Template validation tests
98+
- Authorization tests
99+
- Base64 validation tests
100+
101+
#### Their Implementation
102+
- **450 lines** of tests
103+
- Basic functionality tests
104+
- Argument validation tests
105+
- Simple integration tests
106+
107+
## Potential Improvements from Their Approach
108+
109+
### 1. **Simplicity First**
110+
Their implementation shows that a simpler approach might be sufficient for many use cases. We could consider:
111+
- Adding a "simple mode" that doesn't require Dry::Schema
112+
- Making advanced features opt-in rather than default
113+
114+
### 2. **Class-level Message Generation** ⚠️
115+
Their `get_messages` as a class method is simpler but less flexible. Our instance method approach allows:
116+
- Access to instance variables
117+
- Dynamic message generation based on state
118+
- Better integration with Rails patterns
119+
120+
### 3. **Singleton Pattern**
121+
They use Singleton which we deliberately avoided because:
122+
- Resources moved away from Singleton in main branch
123+
- Stateless pattern is more scalable
124+
- Better for concurrent access
125+
126+
### 4. **Argument Definition Simplicity**
127+
Their simple argument definition is more approachable:
128+
```ruby
129+
# Theirs (simple)
130+
argument :name, required: true
131+
132+
# Ours (powerful but complex)
133+
arguments do
134+
required(:name).filled(:string).description('User name')
135+
end
136+
```
137+
138+
We could add a simpler API alongside our Dry::Schema approach.
139+
140+
## Recommendations
141+
142+
### What We Should Keep from Our Implementation
143+
1. **Dry::Schema validation** - Provides robust type checking and validation
144+
2. **MessageBuilder API** - Clean, fluent interface for building messages
145+
3. **Template support** - Powerful for complex prompts
146+
4. **Authorization blocks** - Essential for production use
147+
5. **Auto-naming convention** - Reduces boilerplate
148+
6. **Feature parity with tools** - Consistent API across MCP types
149+
150+
### What We Could Adopt from Their Approach
151+
1. **Simpler argument API option** - Add convenience methods for simple cases:
152+
```ruby
153+
class SimplePrompt < FastMcp::Prompt
154+
simple_argument :name, required: true
155+
simple_argument :age, type: :integer
156+
end
157+
```
158+
159+
2. **Class-level metadata** - Their metadata method is cleaner for static information
160+
161+
3. **Reduced complexity for basic use cases** - Consider making advanced features opt-in
162+
163+
### What We Should Avoid from Their Approach
164+
1. **Singleton pattern** - Goes against current architecture direction
165+
2. **No template support** - Templates are valuable for complex prompts
166+
3. **Basic validation only** - Type safety is important
167+
4. **No authorization** - Security is critical
168+
169+
## Conclusion
170+
171+
Our implementation is significantly more comprehensive and feature-rich, which aligns with the production-ready goals of FastMCP. The simpler approach shows an alternative philosophy, but lacks critical features needed for production use.
172+
173+
### Decision: Stick with Dry::Schema
174+
175+
After analysis, we've decided to **maintain our Dry::Schema approach** for these reasons:
176+
177+
1. **Consistency** - Matches the Tool implementation pattern already established
178+
2. **Type Safety** - Provides robust validation and clear error messages
179+
3. **Flexibility** - Handles everything from simple to complex validation needs
180+
4. **Philosophy Alignment** - Fits with the project author's preference for robust, type-safe solutions
181+
5. **Maintainability** - One validation approach is better than maintaining two parallel systems
182+
183+
### Recommended Action Items
184+
1.**Keep our current implementation** - It's more complete and production-ready
185+
2. 📝 **Improve documentation** - Created comprehensive examples showing Dry::Schema patterns from simple to complex
186+
3. 🎯 **Focus on developer experience** - Better examples and documentation make Dry::Schema approachable
187+
4. 🚀 **Embrace the power** - Dry::Schema provides features that will be valuable as applications grow
188+
189+
The slight additional complexity of Dry::Schema is worth the benefits it provides. Good documentation and examples make it accessible to developers at all levels.

0 commit comments

Comments
 (0)