rosetta_aisp_llm/lib.rs
1//! Rosetta AISP LLM Fallback
2//!
3//! Provides LLM-powered fallback for AISP conversion when deterministic
4//! Rosetta mappings have low confidence. Uses Claude SDK for intelligent
5//! prose-to-symbol translation.
6//!
7//! # Example
8//!
9//! ```no_run
10//! use rosetta_aisp_llm::{convert_with_fallback, ConversionOptionsExt};
11//!
12//! # async fn example() {
13//! let prose = "Define a type User with valid credentials";
14//! let result = convert_with_fallback(prose, None).await;
15//! println!("Output: {}", result.output);
16//! println!("Used LLM: {}", result.used_fallback);
17//! # }
18//! ```
19
20mod claude;
21mod provider;
22
23pub use claude::ClaudeFallback;
24pub use provider::{LlmProvider, LlmResult};
25
26// Re-export rosetta-aisp types for convenience
27pub use rosetta_aisp::{
28 AispConverter, ConversionOptions, ConversionResult, ConversionTier, RosettaStone, TokenStats,
29};
30
31/// Extended conversion options with LLM fallback support
32#[derive(Debug, Clone, Default)]
33pub struct ConversionOptionsExt {
34 /// Force specific tier (auto-detect if None)
35 pub tier: Option<ConversionTier>,
36 /// Confidence threshold for LLM fallback (default: 0.8)
37 pub confidence_threshold: Option<f64>,
38 /// Enable LLM fallback
39 pub enable_llm_fallback: bool,
40 /// LLM model to use (default: sonnet)
41 pub llm_model: Option<String>,
42}
43
44/// Convert prose to AISP with optional LLM fallback
45///
46/// This function first attempts deterministic conversion using rosetta-aisp.
47/// If the confidence is below the threshold and LLM fallback is enabled,
48/// it uses Claude to improve the conversion.
49///
50/// # Arguments
51///
52/// * `prose` - The natural language text to convert
53/// * `options` - Optional configuration for conversion behavior
54///
55/// # Returns
56///
57/// A `ConversionResult` containing the AISP output and metadata
58pub async fn convert_with_fallback(
59 prose: &str,
60 options: Option<ConversionOptionsExt>,
61) -> ConversionResult {
62 let opts = options.unwrap_or_default();
63
64 // Convert using rosetta-aisp's ConversionOptions
65 let base_options = ConversionOptions {
66 tier: opts.tier,
67 confidence_threshold: opts.confidence_threshold,
68 };
69
70 let result = AispConverter::convert(prose, Some(base_options));
71 let threshold = opts.confidence_threshold.unwrap_or(0.8);
72
73 // Check if LLM fallback is needed
74 if opts.enable_llm_fallback && result.confidence < threshold {
75 let provider = if let Some(model) = &opts.llm_model {
76 ClaudeFallback::with_model(model)
77 } else {
78 ClaudeFallback::new()
79 };
80
81 if provider.is_available().await {
82 if let Ok(llm_result) = provider
83 .convert(prose, result.tier, &result.unmapped, Some(&result.output))
84 .await
85 {
86 return llm_result.to_conversion_result(result.tier, prose.len());
87 }
88 }
89 }
90
91 result
92}