turul_mcp_builders/traits/sampling_traits.rs
1//! Framework traits for MCP sampling construction
2//!
3//! **IMPORTANT**: These are framework features, NOT part of the MCP specification.
4
5use turul_mcp_protocol::sampling::{CreateMessageParams, SamplingMessage, ModelPreferences, Role};
6use turul_mcp_protocol::prompts::ContentBlock;
7use serde_json::Value;
8
9pub trait HasSamplingMessageMetadata {
10 /// Role of the message (from spec)
11 fn role(&self) -> &Role;
12
13 /// Content of the message (from spec)
14 fn content(&self) -> &ContentBlock;
15}
16
17/// Trait for sampling configuration (from CreateMessageRequest spec)
18pub trait HasSamplingConfig {
19 /// Maximum tokens to generate (required field from spec)
20 fn max_tokens(&self) -> u32;
21
22 /// Temperature for sampling (optional from spec)
23 fn temperature(&self) -> Option<f64> {
24 None
25 }
26
27 /// Stop sequences (optional from spec)
28 fn stop_sequences(&self) -> Option<&Vec<String>> {
29 None
30 }
31}
32
33/// Trait for sampling context (from CreateMessageRequest spec)
34pub trait HasSamplingContext {
35 /// Messages for context (required from spec)
36 fn messages(&self) -> &[SamplingMessage];
37
38 /// System prompt (optional from spec)
39 fn system_prompt(&self) -> Option<&str> {
40 None
41 }
42
43 /// Include context setting (optional from spec)
44 fn include_context(&self) -> Option<&str> {
45 None
46 }
47}
48
49/// Trait for model preferences (from CreateMessageRequest spec)
50pub trait HasModelPreferences {
51 /// Model preferences (optional from spec)
52 fn model_preferences(&self) -> Option<&ModelPreferences> {
53 None
54 }
55
56 /// Metadata (optional from spec)
57 fn metadata(&self) -> Option<&Value> {
58 None
59 }
60}
61
62/// **Complete MCP Sampling Creation** - Build AI model interaction and completion systems.
63///
64/// This trait represents a **complete, working MCP sampling configuration** that controls
65/// how AI models generate completions with precise parameter control, context management,
66/// and model preferences. When you implement the required metadata traits, you automatically
67/// get `SamplingDefinition` for free via blanket implementation.
68///
69/// # What You're Building
70///
71/// A sampling configuration is an AI interaction system that:
72/// - Controls model generation parameters (temperature, tokens, etc.)
73/// - Manages conversation context and system prompts
74/// - Specifies model preferences and capabilities
75/// - Handles structured completion requests
76///
77/// # How to Create a Sampling Configuration
78///
79/// Implement these three traits on your struct:
80///
81/// ```rust
82/// # use turul_mcp_protocol::sampling::*;
83/// # use turul_mcp_builders::prelude::*;
84/// # use serde_json::{Value, json};
85/// # use std::collections::HashMap;
86///
87/// // This struct will automatically implement SamplingDefinition!
88/// struct CodeReviewSampling {
89/// review_type: String,
90/// language: String,
91/// }
92///
93/// impl HasSamplingConfig for CodeReviewSampling {
94/// fn max_tokens(&self) -> u32 {
95/// 2000 // Enough for detailed code reviews
96/// }
97///
98/// fn temperature(&self) -> Option<f64> {
99/// Some(0.3) // Lower temperature for consistent code analysis
100/// }
101///
102/// fn stop_sequences(&self) -> Option<&Vec<String>> {
103/// None // No special stop sequences needed
104/// }
105/// }
106///
107/// impl HasSamplingContext for CodeReviewSampling {
108/// fn messages(&self) -> &[SamplingMessage] {
109/// // Static messages for this example
110/// &[]
111/// }
112///
113/// fn system_prompt(&self) -> Option<&str> {
114/// Some("You are an expert code reviewer. Analyze the provided code for bugs, performance issues, and best practices.")
115/// }
116///
117/// fn include_context(&self) -> Option<&str> {
118/// Some(&self.language) // Include programming language context
119/// }
120/// }
121///
122/// impl HasModelPreferences for CodeReviewSampling {
123/// fn model_preferences(&self) -> Option<&ModelPreferences> {
124/// None // Use default model
125/// }
126/// }
127///
128/// // Now you can use it with the server:
129/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
130/// let sampling = CodeReviewSampling {
131/// review_type: "security".to_string(),
132/// language: "rust".to_string(),
133/// };
134///
135/// // The sampling automatically implements SamplingDefinition
136/// let create_params = sampling.to_create_params();
137/// # Ok(())
138/// # }
139/// ```
140///
141/// # Key Benefits
142///
143/// - **Precise Control**: Fine-tune model behavior for specific tasks
144/// - **Context Management**: Rich conversation and system prompt support
145/// - **Model Flexibility**: Support for different AI models and capabilities
146/// - **MCP Compliant**: Fully compatible with MCP 2025-06-18 specification
147///
148/// # Common Use Cases
149///
150/// - Code review and analysis systems
151/// - Creative writing assistance
152/// - Technical documentation generation
153/// - Question-answering with domain context
154/// - Conversational AI with specific personalities
155pub trait SamplingDefinition: HasSamplingConfig + HasSamplingContext + HasModelPreferences {
156 /// Convert to CreateMessageParams
157 fn to_create_params(&self) -> CreateMessageParams {
158 CreateMessageParams {
159 messages: self.messages().to_vec(),
160 model_preferences: self.model_preferences().cloned(),
161 system_prompt: self.system_prompt().map(|s| s.to_string()),
162 include_context: self.include_context().map(|s| s.to_string()),
163 temperature: self.temperature(),
164 max_tokens: self.max_tokens(),
165 stop_sequences: self.stop_sequences().cloned(),
166 metadata: self.metadata().cloned(),
167 meta: None,
168 }
169 }
170}
171
172// Blanket implementation: any type implementing the fine-grained traits automatically gets SamplingDefinition
173impl<T> SamplingDefinition for T where
174 T: HasSamplingConfig + HasSamplingContext + HasModelPreferences
175{
176}