reasonkit/thinktool/modules/
mod.rs

1//! ThinkTool Module Type Definitions
2//!
3//! This module provides the core type definitions and traits for ThinkTool modules,
4//! which are structured reasoning components that implement specific analytical strategies.
5//!
6//! ## Architecture Note
7//!
8//! ThinkTool modules can be used in two ways:
9//!
10//! 1. **Direct Module Execution** - Use the module structs directly for local processing
11//! 2. **Protocol Execution** - Use ProtocolExecutor with LLM integration
12//!
13//! ## Direct Module Usage
14//!
15//! ```rust,ignore
16//! use reasonkit::thinktool::modules::{GigaThink, ThinkToolModule, ThinkToolContext};
17//!
18//! let module = GigaThink::new();
19//! let context = ThinkToolContext {
20//!     query: "What are the key factors for success?".to_string(),
21//!     previous_steps: vec![],
22//! };
23//!
24//! // Synchronous execution
25//! let result = module.execute(&context)?;
26//!
27//! // Asynchronous execution (requires AsyncThinkToolModule)
28//! let async_result = module.execute_async(&context).await?;
29//! ```
30//!
31//! ## Protocol Execution (with LLM)
32//!
33//! ```rust,ignore
34//! let executor = ProtocolExecutor::new()?;
35//! let result = executor.execute("gigathink", ProtocolInput::query("question")).await?;
36//! ```
37//!
38//! ## Available Modules
39//!
40//! | Module | Code | Purpose | Key Feature |
41//! |--------|------|---------|-------------|
42//! | `GigaThink` | `gt` | Expansive creative thinking | 10+ perspectives |
43//! | `LaserLogic` | `ll` | Precision deductive reasoning | Fallacy detection |
44//! | `BedRock` | `br` | First principles decomposition | Core axiom extraction |
45//! | `ProofGuard` | `pg` | Multi-source verification | 3+ sources required |
46//! | `BrutalHonesty` | `bh` | Adversarial self-critique | Skeptical scoring |
47//! | `BrutalHonestyEnhanced` | `bhe` | Deep adversarial critique | Cognitive bias detection |
48//!
49//! See `registry.rs` for full protocol definitions.
50
51use crate::error::Result;
52use serde::{Deserialize, Serialize};
53
54// ============================================================================
55// MODULE RE-EXPORTS
56// ============================================================================
57
58pub mod bedrock;
59pub mod brutalhonesty;
60pub mod brutalhonesty_enhanced;
61pub mod gigathink;
62pub mod laserlogic;
63pub mod proofguard;
64
65// Re-export module structs
66pub use bedrock::BedRock;
67pub use brutalhonesty::BrutalHonesty;
68pub use brutalhonesty_enhanced::BrutalHonestyEnhanced;
69pub use gigathink::GigaThink;
70pub use laserlogic::LaserLogic;
71pub use proofguard::ProofGuard;
72
73// Re-export GigaThink types for comprehensive access
74pub use gigathink::{
75    AnalysisDimension, AsyncThinkToolModule, GigaThinkBuilder, GigaThinkConfig, GigaThinkError,
76    GigaThinkMetadata, GigaThinkResult, Perspective, SynthesizedInsight, Theme,
77};
78
79// Re-export LaserLogic types for comprehensive access
80pub use laserlogic::{
81    Argument, ArgumentForm, Contradiction, ContradictionType, DetectedFallacy, Fallacy,
82    LaserLogicConfig, LaserLogicResult, Premise, PremiseType, SoundnessStatus, ValidityStatus,
83};
84
85// Re-export BrutalHonesty types for comprehensive access
86pub use brutalhonesty::{
87    BrutalHonestyBuilder, BrutalHonestyConfig, CritiqueSeverity, CritiqueVerdict, DetectedFlaw,
88    FlawCategory, FlawSeverity, IdentifiedStrength, ImplicitAssumption,
89};
90
91// Re-export BrutalHonestyEnhanced types
92pub use brutalhonesty_enhanced::{
93    ArgumentMap, BiasCategory, CognitiveBias, CognitiveBiasDepth, CulturalAssumption,
94    EnhancedBuilder, EnhancedConfig, SteelmanArgument,
95};
96
97// ============================================================================
98// CORE TYPE DEFINITIONS
99// ============================================================================
100
101/// Configuration for a ThinkTool module
102///
103/// Defines the metadata and behavior parameters for a reasoning module.
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct ThinkToolModuleConfig {
106    /// Module name (e.g., "GigaThink", "LaserLogic")
107    pub name: String,
108
109    /// Semantic version (e.g., "2.1.0")
110    pub version: String,
111
112    /// Human-readable description of module purpose
113    pub description: String,
114
115    /// Weight applied to this module's confidence in composite calculations
116    /// Range: 0.0 - 1.0, typical: 0.10 - 0.30
117    pub confidence_weight: f64,
118}
119
120impl ThinkToolModuleConfig {
121    /// Create a new module configuration
122    pub fn new(
123        name: impl Into<String>,
124        version: impl Into<String>,
125        description: impl Into<String>,
126    ) -> Self {
127        Self {
128            name: name.into(),
129            version: version.into(),
130            description: description.into(),
131            confidence_weight: 0.20, // Default weight
132        }
133    }
134
135    /// Builder: set confidence weight
136    pub fn with_confidence_weight(mut self, weight: f64) -> Self {
137        self.confidence_weight = weight.clamp(0.0, 1.0);
138        self
139    }
140}
141
142/// Context provided to a ThinkTool module for execution
143///
144/// Contains the query to analyze and any context from previous reasoning steps.
145#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct ThinkToolContext {
147    /// The primary query or problem to analyze
148    pub query: String,
149
150    /// Results from previous reasoning steps (for chained execution)
151    pub previous_steps: Vec<String>,
152}
153
154impl ThinkToolContext {
155    /// Create a new context with just a query
156    pub fn new(query: impl Into<String>) -> Self {
157        Self {
158            query: query.into(),
159            previous_steps: Vec::new(),
160        }
161    }
162
163    /// Create a context with previous step results
164    pub fn with_previous_steps(query: impl Into<String>, steps: Vec<String>) -> Self {
165        Self {
166            query: query.into(),
167            previous_steps: steps,
168        }
169    }
170
171    /// Add a previous step result
172    pub fn add_previous_step(&mut self, step: impl Into<String>) {
173        self.previous_steps.push(step.into());
174    }
175
176    /// Check if this context has previous steps
177    pub fn has_previous_steps(&self) -> bool {
178        !self.previous_steps.is_empty()
179    }
180
181    /// Get the number of previous steps
182    pub fn previous_step_count(&self) -> usize {
183        self.previous_steps.len()
184    }
185}
186
187/// Output produced by a ThinkTool module
188///
189/// Contains the module identification, confidence score, and structured output data.
190#[derive(Debug, Clone, Serialize, Deserialize)]
191pub struct ThinkToolOutput {
192    /// Name of the module that produced this output
193    pub module: String,
194
195    /// Confidence score for the output (0.0 - 1.0)
196    pub confidence: f64,
197
198    /// Structured output data (module-specific format)
199    pub output: serde_json::Value,
200}
201
202impl ThinkToolOutput {
203    /// Create a new output
204    pub fn new(module: impl Into<String>, confidence: f64, output: serde_json::Value) -> Self {
205        Self {
206            module: module.into(),
207            confidence: confidence.clamp(0.0, 1.0),
208            output,
209        }
210    }
211
212    /// Get a field from the output
213    pub fn get(&self, field: &str) -> Option<&serde_json::Value> {
214        self.output.get(field)
215    }
216
217    /// Get a string field from the output
218    pub fn get_str(&self, field: &str) -> Option<&str> {
219        self.output.get(field).and_then(|v| v.as_str())
220    }
221
222    /// Get an array field from the output
223    pub fn get_array(&self, field: &str) -> Option<&Vec<serde_json::Value>> {
224        self.output.get(field).and_then(|v| v.as_array())
225    }
226
227    /// Check if the output has high confidence (>= 0.80)
228    pub fn is_high_confidence(&self) -> bool {
229        self.confidence >= 0.80
230    }
231
232    /// Check if the output meets a confidence threshold
233    pub fn meets_threshold(&self, threshold: f64) -> bool {
234        self.confidence >= threshold
235    }
236}
237
238// ============================================================================
239// CORE TRAIT DEFINITIONS
240// ============================================================================
241
242/// Core trait for ThinkTool modules
243///
244/// All ThinkTool modules must implement this trait to provide
245/// synchronous execution capability and configuration access.
246///
247/// For async execution, also implement `AsyncThinkToolModule`.
248pub trait ThinkToolModule: Send + Sync {
249    /// Get the module configuration
250    fn config(&self) -> &ThinkToolModuleConfig;
251
252    /// Execute the module synchronously
253    ///
254    /// # Arguments
255    /// * `context` - The execution context containing query and previous steps
256    ///
257    /// # Returns
258    /// * `Ok(ThinkToolOutput)` - Successful execution with output and confidence
259    /// * `Err(Error)` - Execution failed with error details
260    fn execute(&self, context: &ThinkToolContext) -> Result<ThinkToolOutput>;
261
262    /// Get the module name (convenience method)
263    fn name(&self) -> &str {
264        &self.config().name
265    }
266
267    /// Get the module version (convenience method)
268    fn version(&self) -> &str {
269        &self.config().version
270    }
271
272    /// Get the module description (convenience method)
273    fn description(&self) -> &str {
274        &self.config().description
275    }
276
277    /// Get the confidence weight for this module
278    fn confidence_weight(&self) -> f64 {
279        self.config().confidence_weight
280    }
281}
282
283// ============================================================================
284// TESTS
285// ============================================================================
286
287#[cfg(test)]
288mod tests {
289    use super::*;
290
291    #[test]
292    fn test_module_config_creation() {
293        let config = ThinkToolModuleConfig::new("TestModule", "1.0.0", "A test module");
294        assert_eq!(config.name, "TestModule");
295        assert_eq!(config.version, "1.0.0");
296        assert_eq!(config.confidence_weight, 0.20);
297    }
298
299    #[test]
300    fn test_module_config_with_weight() {
301        let config = ThinkToolModuleConfig::new("TestModule", "1.0.0", "A test module")
302            .with_confidence_weight(0.35);
303        assert_eq!(config.confidence_weight, 0.35);
304    }
305
306    #[test]
307    fn test_context_creation() {
308        let context = ThinkToolContext::new("Test query");
309        assert_eq!(context.query, "Test query");
310        assert!(context.previous_steps.is_empty());
311    }
312
313    #[test]
314    fn test_context_with_previous_steps() {
315        let context =
316            ThinkToolContext::with_previous_steps("Query", vec!["Step 1".into(), "Step 2".into()]);
317        assert!(context.has_previous_steps());
318        assert_eq!(context.previous_step_count(), 2);
319    }
320
321    #[test]
322    fn test_output_creation() {
323        let output =
324            ThinkToolOutput::new("TestModule", 0.85, serde_json::json!({"result": "success"}));
325        assert_eq!(output.module, "TestModule");
326        assert_eq!(output.confidence, 0.85);
327        assert!(output.is_high_confidence());
328    }
329
330    #[test]
331    fn test_output_threshold() {
332        let output =
333            ThinkToolOutput::new("TestModule", 0.75, serde_json::json!({"result": "success"}));
334        assert!(output.meets_threshold(0.70));
335        assert!(!output.meets_threshold(0.80));
336    }
337
338    #[test]
339    fn test_output_field_access() {
340        let output = ThinkToolOutput::new(
341            "TestModule",
342            0.85,
343            serde_json::json!({
344                "name": "test",
345                "values": [1, 2, 3]
346            }),
347        );
348
349        assert_eq!(output.get_str("name"), Some("test"));
350        assert!(output.get_array("values").is_some());
351    }
352
353    #[test]
354    fn test_gigathink_module() {
355        let module = GigaThink::new();
356        assert_eq!(module.name(), "GigaThink");
357        assert_eq!(module.version(), "2.1.0");
358    }
359
360    #[test]
361    fn test_gigathink_execution() {
362        let module = GigaThink::new();
363        let context = ThinkToolContext::new("What are the implications of AI adoption?");
364
365        let result = module.execute(&context).unwrap();
366        assert_eq!(result.module, "GigaThink");
367        assert!(result.confidence > 0.0);
368
369        // Verify 10+ perspectives
370        let perspectives = result.get_array("perspectives").unwrap();
371        assert!(perspectives.len() >= 10);
372    }
373
374    #[test]
375    fn test_laserlogic_module() {
376        let module = LaserLogic::new();
377        assert_eq!(module.name(), "LaserLogic");
378        assert_eq!(module.version(), "3.0.0");
379    }
380
381    #[test]
382    fn test_laserlogic_analyze_argument() {
383        let module = LaserLogic::new();
384        let result = module
385            .analyze_argument(
386                &["All humans are mortal", "Socrates is human"],
387                "Socrates is mortal",
388            )
389            .unwrap();
390
391        // Should detect categorical syllogism
392        assert_eq!(
393            result.argument_form,
394            Some(ArgumentForm::CategoricalSyllogism)
395        );
396        assert!(result.confidence > 0.0);
397    }
398
399    #[test]
400    fn test_laserlogic_fallacy_detection() {
401        let module = LaserLogic::new();
402        let result = module
403            .analyze_argument(
404                &["If it rains, then the ground is wet", "The ground is wet"],
405                "It rained",
406            )
407            .unwrap();
408
409        // Should detect affirming the consequent
410        assert!(result.has_fallacies());
411        assert!(result
412            .fallacies
413            .iter()
414            .any(|f| f.fallacy == Fallacy::AffirmingConsequent));
415    }
416
417    #[test]
418    fn test_brutalhonesty_module() {
419        let module = BrutalHonesty::new();
420        assert_eq!(module.name(), "BrutalHonesty");
421        assert_eq!(module.version(), "3.0.0");
422    }
423
424    #[test]
425    fn test_brutalhonesty_execution() {
426        let module = BrutalHonesty::new();
427        let context =
428            ThinkToolContext::new("Our startup will succeed because we have the best team");
429
430        let result = module.execute(&context).unwrap();
431        assert_eq!(result.module, "BrutalHonesty");
432        assert!(result.confidence > 0.0);
433        assert!(result.confidence <= 0.95);
434
435        // Verify output contains required fields
436        assert!(result.get("verdict").is_some());
437        assert!(result.get("analysis").is_some());
438        assert!(result.get("devils_advocate").is_some());
439    }
440
441    #[test]
442    fn test_brutalhonesty_enhanced_module() {
443        let module = BrutalHonestyEnhanced::new();
444        assert_eq!(module.name(), "BrutalHonestyEnhanced");
445        assert_eq!(module.version(), "3.0.0");
446    }
447
448    #[test]
449    fn test_brutalhonesty_enhanced_execution() {
450        let module = BrutalHonestyEnhanced::new();
451        let context = ThinkToolContext::new(
452            "We're certain this will succeed because everyone agrees it's the best approach.",
453        );
454
455        let result = module.execute(&context).unwrap();
456        assert_eq!(result.module, "BrutalHonestyEnhanced");
457        assert!(result.confidence > 0.0);
458        assert!(result.confidence <= 0.90);
459
460        // Verify output contains enhanced analysis
461        assert!(result.get("enhanced_analysis").is_some());
462        assert!(result.get("base_analysis").is_some());
463    }
464
465    #[test]
466    fn test_brutalhonesty_builder() {
467        let module = BrutalHonesty::builder()
468            .severity(CritiqueSeverity::Ruthless)
469            .enable_devil_advocate(true)
470            .build();
471
472        assert_eq!(module.brutal_config().severity, CritiqueSeverity::Ruthless);
473        assert!(module.brutal_config().enable_devil_advocate);
474    }
475
476    #[test]
477    fn test_brutalhonesty_enhanced_builder() {
478        let module = BrutalHonestyEnhanced::builder()
479            .severity(CritiqueSeverity::Harsh)
480            .cognitive_bias_depth(CognitiveBiasDepth::Deep)
481            .enable_cultural_analysis(true)
482            .build();
483
484        assert_eq!(
485            module.enhanced_config().base_config.severity,
486            CritiqueSeverity::Harsh
487        );
488        assert_eq!(
489            module.enhanced_config().cognitive_bias_depth,
490            CognitiveBiasDepth::Deep
491        );
492    }
493}