Function bodies 463 total
long_pause_not_a_break function · rust · L95-L99 (5 LOC)core/src/dsp/voice_breaks.rs
fn long_pause_not_a_break() {
// 600ms gap (60 frames) — intentional pause, not a break
let contour = make_contour(&[(20, true), (60, false), (20, true)], 10.0);
assert_eq!(count_voice_breaks(&contour, 10.0, 250.0), 0);
}multiple_breaks function · rust · L102-L109 (8 LOC)core/src/dsp/voice_breaks.rs
fn multiple_breaks() {
// voiced → 100ms gap → voiced → 200ms gap → voiced
let contour = make_contour(
&[(20, true), (10, false), (20, true), (20, false), (20, true)],
10.0,
);
assert_eq!(count_voice_breaks(&contour, 10.0, 250.0), 2);
}mixed_gaps function · rust · L112-L127 (16 LOC)core/src/dsp/voice_breaks.rs
fn mixed_gaps() {
// Short gap (not a break) + medium gap (break) + long gap (not a break)
let contour = make_contour(
&[
(20, true),
(3, false), // 30ms — too short
(20, true),
(10, false), // 100ms — break
(20, true),
(60, false), // 600ms — too long
(20, true),
],
10.0,
);
assert_eq!(count_voice_breaks(&contour, 10.0, 250.0), 1);
}hanning function · rust · L13-L29 (17 LOC)core/src/dsp/windowing.rs
pub fn hanning(samples: &[f32]) -> Vec<f32> {
let n = samples.len();
if n <= 1 {
return samples.to_vec();
}
let scale = 2.0 * PI / (n - 1) as f32;
samples
.iter()
.enumerate()
.map(|(i, &s)| {
let w = 0.5 * (1.0 - (scale * i as f32).cos());
s * w
})
.collect()
}hanning_edges_are_zero function · rust · L36-L43 (8 LOC)core/src/dsp/windowing.rs
fn hanning_edges_are_zero() {
let samples = vec![1.0; 100];
let windowed = hanning(&samples);
// First and last samples should be (very close to) zero
assert!(windowed[0].abs() < 1e-6);
assert!(windowed[99].abs() < 1e-6);
}hanning_center_is_one function · rust · L46-L53 (8 LOC)core/src/dsp/windowing.rs
fn hanning_center_is_one() {
let n = 101; // odd length so there's an exact center
let samples = vec![1.0; n];
let windowed = hanning(&samples);
// Middle sample should be ~1.0
assert!((windowed[50] - 1.0).abs() < 1e-6);
}hanning_is_symmetric function · rust · L56-L66 (11 LOC)core/src/dsp/windowing.rs
fn hanning_is_symmetric() {
let samples = vec![1.0; 64];
let windowed = hanning(&samples);
for i in 0..32 {
assert!(
(windowed[i] - windowed[63 - i]).abs() < 1e-6,
"Asymmetry at index {i}"
);
}
}Repobility · MCP-ready · https://repobility.com
hanning_preserves_silence function · rust · L69-L73 (5 LOC)core/src/dsp/windowing.rs
fn hanning_preserves_silence() {
let samples = vec![0.0; 50];
let windowed = hanning(&samples);
assert!(windowed.iter().all(|&s| s == 0.0));
}hanning_single_sample function · rust · L76-L79 (4 LOC)core/src/dsp/windowing.rs
fn hanning_single_sample() {
let windowed = hanning(&[0.5]);
assert_eq!(windowed, vec![0.5]);
}hanning_empty function · rust · L82-L85 (4 LOC)core/src/dsp/windowing.rs
fn hanning_empty() {
let windowed = hanning(&[]);
assert!(windowed.is_empty());
}complete_async function · rust · L46-L97 (52 LOC)core/src/llm/anthropic.rs
pub async fn complete_async(
api_key: &str,
model: &str,
system: &str,
user_message: &str,
) -> Result<String> {
let request = Request {
model: model.to_string(),
max_tokens: 1024,
system: system.to_string(),
messages: vec![Message {
role: "user".into(),
content: user_message.into(),
}],
};
let client = reqwest::Client::new();
let response = client
.post(API_URL)
.header("x-api-key", api_key)
.header("anthropic-version", API_VERSION)
.header("content-type", "application/json")
.json(&request)
.send()
.await
.context("Failed to send request to Anthropic API")?;
let status = response.status();
let body = response
.text()
.await
.context("Failed to read Anthropic API response")?;
if !status.is_success() {
if let Ok(err) = serde_json::from_str::<ErrorResponse>(&body) {
anyhocomplete function · rust · L100-L112 (13 LOC)core/src/llm/anthropic.rs
pub fn complete(
api_key: &str,
model: &str,
system: &str,
user_message: &str,
) -> Result<String> {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.context("Failed to create async runtime")?;
rt.block_on(complete_async(api_key, model, system, user_message))
}interpret function · rust · L16-L33 (18 LOC)core/src/llm/mod.rs
pub fn interpret(
provider: &Provider,
model: Option<&str>,
current: &SessionData,
history: &[SessionData],
trend_report: Option<&str>,
) -> Result<String> {
let api_key = provider.api_key()?;
let model = model.unwrap_or_else(|| provider.default_model());
let system = prompt::system_prompt();
let user = prompt::user_prompt(current, history, trend_report);
match provider {
Provider::Anthropic => anthropic::complete(&api_key, model, &system, &user),
Provider::OpenAI => openai::complete(&api_key, model, &system, &user),
}
}simplify function · rust · L37-L51 (15 LOC)core/src/llm/mod.rs
pub fn simplify(
provider: &Provider,
technical_response: &str,
) -> Result<String> {
let api_key = provider.api_key()?;
let model = provider.model_for_tier(provider::ModelTier::Fast);
let system = prompt::plain_language_system_prompt();
let user = format!("Here is the technical voice analysis to translate:\n\n{technical_response}");
match provider {
Provider::Anthropic => anthropic::complete(&api_key, model, &system, &user),
Provider::OpenAI => openai::complete(&api_key, model, &system, &user),
}
}deep_interpret function · rust · L63-L114 (52 LOC)core/src/llm/mod.rs
pub fn deep_interpret(
current: &SessionData,
history: &[SessionData],
tier: provider::ModelTier,
trend_report: Option<&str>,
) -> Result<DeepReport> {
let claude = Provider::Anthropic;
let gpt = Provider::OpenAI;
// Verify both API keys upfront before making any calls
let claude_key = claude.api_key()?;
let gpt_key = gpt.api_key()?;
let system = prompt::system_prompt();
let user = prompt::user_prompt(current, history, trend_report);
let claude_model = claude.model_for_tier(tier);
let gpt_model = gpt.model_for_tier(tier);
// Single runtime for all async work
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.context("Failed to create async runtime")?;
// Step 1: Claude and GPT in parallel
let (claude_response, gpt_response) = rt.block_on(async {
tokio::try_join!(
anthropic::complete_async(&claude_key, claude_model, &system, &user),
Repobility · open methodology · https://repobility.com/research/
complete_async function · rust · L50-L108 (59 LOC)core/src/llm/openai.rs
pub async fn complete_async(
api_key: &str,
model: &str,
system: &str,
user_message: &str,
) -> Result<String> {
let request = Request {
model: model.to_string(),
instructions: system.to_string(),
input: user_message.to_string(),
};
let client = reqwest::Client::new();
let response = client
.post(API_URL)
.header("Authorization", format!("Bearer {api_key}"))
.header("Content-Type", "application/json")
.json(&request)
.send()
.await
.context("Failed to send request to OpenAI API")?;
let status = response.status();
let body = response
.text()
.await
.context("Failed to read OpenAI API response")?;
if !status.is_success() {
if let Ok(err) = serde_json::from_str::<ErrorResponse>(&body) {
anyhow::bail!("OpenAI API error ({}): {}", status, err.error.message);
}
anyhow::bail!("OpenAI API error ({}): {}", statcomplete function · rust · L111-L123 (13 LOC)core/src/llm/openai.rs
pub fn complete(
api_key: &str,
model: &str,
system: &str,
user_message: &str,
) -> Result<String> {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.context("Failed to create async runtime")?;
rt.block_on(complete_async(api_key, model, system, user_message))
}system_prompt function · rust · L5-L105 (101 LOC)core/src/llm/prompt.rs
pub fn system_prompt() -> String {
r#"You are a voice recovery specialist assistant. You interpret objective acoustic measurements from a patient recovering from left vocal cord paralysis caused by radiation therapy.
## Medical context
Left vocal cord paralysis means the left vocal fold cannot adduct (close) fully during phonation. This causes:
- Breathy voice (air escapes through the glottal gap)
- Higher than normal pitch (the cord is thin and stiff)
- Reduced maximum phonation time (air escapes too fast)
- Voice breaks during connected speech
- Low harmonic-to-noise ratio (turbulent airflow adds noise)
Recovery is gradual over months. Signs of improvement include:
- Pitch dropping toward the patient's natural range
- HNR increasing (less breathiness)
- Jitter and shimmer decreasing (more stable vibration)
- MPT increasing (better cord closure retains air)
- Fewer voice breaks in connected speech
- Higher voiced fraction in reading passages
## Metric definitions
### Sustaineuser_prompt function · rust · L110-L275 (166 LOC)core/src/llm/prompt.rs
pub fn user_prompt(current: &SessionData, history: &[SessionData], trend_report: Option<&str>) -> String {
let mut parts = Vec::new();
parts.push(format!("## Current session: {}", current.date));
parts.push(String::new());
if let Some(c) = ¤t.conditions {
parts.push("### Recording conditions".into());
parts.push(format!("- Time of day: {}", c.time_of_day));
parts.push(format!("- Fatigue: {}/10", c.fatigue_level));
parts.push(format!("- Throat cleared: {}", if c.throat_cleared { "yes" } else { "no" }));
parts.push(format!("- Mucus level: {}", c.mucus_level));
parts.push(format!("- Hydration: {}", c.hydration));
if let Some(ref notes) = c.notes {
parts.push(format!("- Notes: {notes}"));
}
parts.push(String::new());
}
if let Some(s) = ¤t.analysis.sustained {
parts.push("### Sustained vowel".into());
push_reliability_header(&mut parts, s.reliability.as_plain_language_system_prompt function · rust · L279-L293 (15 LOC)core/src/llm/prompt.rs
pub fn plain_language_system_prompt() -> String {
r#"You are a kind, clear communicator who translates medical voice analysis into language anyone can understand. You receive a technical interpretation of someone's voice recovery data.
Your job: rewrite the key findings in simple, warm, honest language. Imagine you're explaining this to someone sitting across from you at a kitchen table.
Rules:
- No jargon. Never say "F0", "jitter", "shimmer", "HNR", "CPPS", "semitones", "Hz", "dB", or "phonation". Translate everything into plain descriptions: "how long you can hold a note", "how steady your voice sounds", "how clear vs breathy it is", "your pitch range".
- No numbers unless they're immediately meaningful (like "you held a note for 16 seconds" or "your range covers about 2 octaves").
- Be honest. If things are getting better, say so warmly. If they're stagnating or declining, say that gently but clearly. Don't sugarcoat.
- Be brief. 3-5 sentences. Think of this as the "bottom linsynthesis_system_prompt function · rust · L298-L309 (12 LOC)core/src/llm/prompt.rs
pub fn synthesis_system_prompt() -> String {
r#"You are a medical data analyst reviewing two independent AI interpretations of voice recovery data. You have access to the raw measurements.
Your job:
1. **Consensus**: What do both interpretations agree on? Lead with this.
2. **Disagreements**: Where do they differ? Who's more accurate given the data?
3. **Fact-check**: Verify any specific claims against the raw numbers. Flag anything that's wrong or misleading.
4. **The central question — is the voice improving over time?** End with a clear, honest verdict based on the data trends. If historical data is available, compare key metrics across sessions. If not, state that a single session can't answer this question yet.
Be concise — 2-3 short paragraphs. Use plain language. Don't hedge excessively. If one interpretation is clearly better, say so."#
.to_string()
}synthesis_user_prompt function · rust · L314-L329 (16 LOC)core/src/llm/prompt.rs
pub fn synthesis_user_prompt(
current: &SessionData,
history: &[SessionData],
claude_response: &str,
gpt_response: &str,
) -> String {
let data = user_prompt(current, history, None);
format!(
"## Raw measurement data\n\n{data}\n\n\
---\n\n\
## Interpretation A (Claude)\n\n{claude_response}\n\n\
---\n\n\
## Interpretation B (GPT)\n\n{gpt_response}"
)
}push_reliability_header function · rust · L332-L360 (29 LOC)core/src/llm/prompt.rs
fn push_reliability_header(parts: &mut Vec<String>, rel: Option<&ReliabilityInfo>, dq: Option<&str>) {
if let Some(r) = rel {
let validity_notes: Vec<&str> = [
(!r.metrics_validity.jitter).then_some("jitter unreliable"),
(!r.metrics_validity.shimmer).then_some("shimmer unreliable"),
(!r.metrics_validity.hnr).then_some("HNR unreliable"),
(r.metrics_validity.voice_breaks != "valid").then_some("voice breaks approximate"),
]
.into_iter()
.flatten()
.collect();
let note = if validity_notes.is_empty() {
String::new()
} else {
format!(" ({})", validity_notes.join(", "))
};
parts.push(format!(
"- **Quality: {}** — {:.0}% active, {:.0}% pitched, tier {}{}",
r.analysis_quality,
r.active_fraction * 100.0,
r.pitched_fraction * 100.0,
r.dominant_tier,
note,
));
} else iProvenance: Repobility (https://repobility.com) — every score reproducible from /scan/
jitter_caveat function · rust · L363-L372 (10 LOC)core/src/llm/prompt.rs
fn jitter_caveat(rel: Option<&ReliabilityInfo>, dq: Option<&str>) -> &'static str {
if let Some(r) = rel {
if !r.metrics_validity.jitter {
return " (unreliable — insufficient pitched frames)";
}
} else if dq == Some("energy_fallback") {
return " (zeroed — unreliable with energy fallback)";
}
""
}voice_breaks_caveat function · rust · L375-L386 (12 LOC)core/src/llm/prompt.rs
fn voice_breaks_caveat(rel: Option<&ReliabilityInfo>, dq: Option<&str>) -> &'static str {
if let Some(r) = rel {
match r.metrics_validity.voice_breaks.as_str() {
"trend_only" => return " (approximate — trend only)",
"unavailable" => return " (unavailable — detection too noisy)",
_ => {}
}
} else if dq == Some("energy_fallback") {
return " (zeroed — unreliable with energy fallback)";
}
""
}quality_tag function · rust · L389-L398 (10 LOC)core/src/llm/prompt.rs
fn quality_tag(rel: Option<&ReliabilityInfo>, dq: Option<&str>) -> String {
if let Some(r) = rel {
format!(" [quality: {}]", r.analysis_quality)
} else {
match dq {
Some(dq) => format!(" [detection: {dq}]"),
None => String::new(),
}
}
}sample_session function · rust · L404-L433 (30 LOC)core/src/llm/prompt.rs
fn sample_session(date: &str) -> SessionData {
SessionData {
date: date.into(),
recordings: SessionRecordings {
sustained: Some("test.wav".into()),
scale: None,
reading: None,
},
analysis: SessionAnalysis {
sustained: Some(SustainedAnalysis {
mpt_seconds: 8.0,
mean_f0_hz: 645.0,
f0_std_hz: 11.0,
jitter_local_percent: 0.28,
shimmer_local_percent: 75.0,
hnr_db: -0.9,
cpps_db: None,
periodicity_mean: None,
detection_quality: None,
reliability: None,
}),
scale: None,
reading: None,
sz: None,
fatigue: None,
},
conditions: None,
}
}system_prompt_contains_key_concepts function · rust · L436-L442 (7 LOC)core/src/llm/prompt.rs
fn system_prompt_contains_key_concepts() {
let prompt = system_prompt();
assert!(prompt.contains("vocal cord paralysis"));
assert!(prompt.contains("HNR"));
assert!(prompt.contains("Jitter"));
assert!(prompt.contains("MPT"));
}user_prompt_includes_current_data function · rust · L445-L451 (7 LOC)core/src/llm/prompt.rs
fn user_prompt_includes_current_data() {
let session = sample_session("2026-02-15");
let prompt = user_prompt(&session, &[], None);
assert!(prompt.contains("2026-02-15"));
assert!(prompt.contains("645.0 Hz"));
assert!(prompt.contains("8.0 seconds"));
}user_prompt_includes_history function · rust · L454-L460 (7 LOC)core/src/llm/prompt.rs
fn user_prompt_includes_history() {
let current = sample_session("2026-02-22");
let history = vec![sample_session("2026-02-15")];
let prompt = user_prompt(¤t, &history, None);
assert!(prompt.contains("History (1 prior session)"));
assert!(prompt.contains("2026-02-15"));
}user_prompt_no_history_section_when_empty function · rust · L463-L467 (5 LOC)core/src/llm/prompt.rs
fn user_prompt_no_history_section_when_empty() {
let current = sample_session("2026-02-15");
let prompt = user_prompt(¤t, &[], None);
assert!(!prompt.contains("History"));
}Same scanner, your repo: https://repobility.com — Repobility
user_prompt_includes_trend_report function · rust · L470-L475 (6 LOC)core/src/llm/prompt.rs
fn user_prompt_includes_trend_report() {
let session = sample_session("2026-02-15");
let prompt = user_prompt(&session, &[], Some("MPT improving +2.1s"));
assert!(prompt.contains("Trend Report (pre-computed)"));
assert!(prompt.contains("MPT improving +2.1s"));
}user_prompt_no_trend_section_when_none function · rust · L478-L482 (5 LOC)core/src/llm/prompt.rs
fn user_prompt_no_trend_section_when_none() {
let session = sample_session("2026-02-15");
let prompt = user_prompt(&session, &[], None);
assert!(!prompt.contains("Trend Report"));
}synthesis_prompt_contains_instructions function · rust · L485-L489 (5 LOC)core/src/llm/prompt.rs
fn synthesis_prompt_contains_instructions() {
let prompt = synthesis_system_prompt();
assert!(prompt.contains("Consensus"));
assert!(prompt.contains("Fact-check"));
}synthesis_user_prompt_includes_all_parts function · rust · L492-L506 (15 LOC)core/src/llm/prompt.rs
fn synthesis_user_prompt_includes_all_parts() {
let session = sample_session("2026-02-15");
let prompt = synthesis_user_prompt(
&session,
&[],
"Claude says something",
"GPT says something else",
);
assert!(prompt.contains("Raw measurement data"));
assert!(prompt.contains("645.0 Hz"));
assert!(prompt.contains("Claude says something"));
assert!(prompt.contains("GPT says something else"));
assert!(prompt.contains("Interpretation A"));
assert!(prompt.contains("Interpretation B"));
}user_prompt_includes_conditions_when_present function · rust · L509-L527 (19 LOC)core/src/llm/prompt.rs
fn user_prompt_includes_conditions_when_present() {
let mut session = sample_session("2026-02-15");
session.conditions = Some(RecordingConditions {
time_of_day: "morning".into(),
fatigue_level: 7,
throat_cleared: true,
mucus_level: "high".into(),
hydration: "low".into(),
notes: Some("bad night".into()),
});
let prompt = user_prompt(&session, &[], None);
assert!(prompt.contains("### Recording conditions"));
assert!(prompt.contains("Time of day: morning"));
assert!(prompt.contains("Fatigue: 7/10"));
assert!(prompt.contains("Throat cleared: yes"));
assert!(prompt.contains("Mucus level: high"));
assert!(prompt.contains("Hydration: low"));
assert!(prompt.contains("Notes: bad night"));
}user_prompt_omits_conditions_when_none function · rust · L530-L534 (5 LOC)core/src/llm/prompt.rs
fn user_prompt_omits_conditions_when_none() {
let session = sample_session("2026-02-15");
let prompt = user_prompt(&session, &[], None);
assert!(!prompt.contains("Recording conditions"));
}user_prompt_history_includes_conditions function · rust · L537-L551 (15 LOC)core/src/llm/prompt.rs
fn user_prompt_history_includes_conditions() {
let current = sample_session("2026-02-22");
let mut past = sample_session("2026-02-15");
past.conditions = Some(RecordingConditions {
time_of_day: "evening".into(),
fatigue_level: 3,
throat_cleared: false,
mucus_level: "low".into(),
hydration: "high".into(),
notes: None,
});
let prompt = user_prompt(¤t, &[past], None);
assert!(prompt.contains("Conditions: evening, fatigue=3, mucus=low, hydration=high"));
assert!(!prompt.contains("throat_cleared"));
}plain_language_prompt_no_jargon_instructions function · rust · L554-L559 (6 LOC)core/src/llm/prompt.rs
fn plain_language_prompt_no_jargon_instructions() {
let prompt = plain_language_system_prompt();
assert!(prompt.contains("No jargon"));
assert!(prompt.contains("kitchen table"));
assert!(prompt.contains("second person"));
}Repobility · MCP-ready · https://repobility.com
system_prompt_mentions_conditions function · rust · L562-L567 (6 LOC)core/src/llm/prompt.rs
fn system_prompt_mentions_conditions() {
let prompt = system_prompt();
assert!(prompt.contains("Recording conditions"));
assert!(prompt.contains("fatigue"));
assert!(prompt.contains("hydration"));
}from_str_loose function · rust · L25-L33 (9 LOC)core/src/llm/provider.rs
pub fn from_str_loose(s: &str) -> Result<Self> {
match s.to_lowercase().as_str() {
"claude" | "anthropic" => Ok(Provider::Anthropic),
"gpt" | "openai" => Ok(Provider::OpenAI),
_ => anyhow::bail!(
"Unknown provider: {s}. Use 'claude' or 'gpt'."
),
}
}api_key_env function · rust · L36-L41 (6 LOC)core/src/llm/provider.rs
pub fn api_key_env(&self) -> &'static str {
match self {
Provider::Anthropic => "ANTHROPIC_API_KEY",
Provider::OpenAI => "OPENAI_API_KEY",
}
}api_key function · rust · L44-L51 (8 LOC)core/src/llm/provider.rs
pub fn api_key(&self) -> Result<String> {
let var = self.api_key_env();
std::env::var(var).with_context(|| {
format!(
"{var} not set. Export it in your shell:\n export {var}=sk-..."
)
})
}default_model function · rust · L54-L56 (3 LOC)core/src/llm/provider.rs
pub fn default_model(&self) -> &'static str {
self.model_for_tier(ModelTier::Default)
}model_for_tier function · rust · L59-L69 (11 LOC)core/src/llm/provider.rs
pub fn model_for_tier(&self, tier: ModelTier) -> &'static str {
match (self, tier) {
(Provider::Anthropic, ModelTier::Fast) => "claude-haiku-4-5-20251001",
(Provider::Anthropic, ModelTier::Default) => "claude-sonnet-4-6",
(Provider::Anthropic, ModelTier::Think) => "claude-opus-4-6",
(Provider::OpenAI, ModelTier::Fast) => "gpt-5-mini",
(Provider::OpenAI, ModelTier::Default) => "gpt-5.2",
(Provider::OpenAI, ModelTier::Think) => "gpt-5.2-pro",
}
}from_flags function · rust · L74-L80 (7 LOC)core/src/llm/provider.rs
pub fn from_flags(fast: bool, think: bool) -> Self {
match (fast, think) {
(true, _) => ModelTier::Fast,
(_, true) => ModelTier::Think,
_ => ModelTier::Default,
}
}fmt function · rust · L84-L89 (6 LOC)core/src/llm/provider.rs
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Provider::Anthropic => write!(f, "Claude"),
Provider::OpenAI => write!(f, "GPT"),
}
}Repobility · open methodology · https://repobility.com/research/
fmt function · rust · L93-L99 (7 LOC)core/src/llm/provider.rs
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ModelTier::Fast => write!(f, "fast"),
ModelTier::Default => write!(f, "default"),
ModelTier::Think => write!(f, "think"),
}
}parse_provider_aliases function · rust · L107-L113 (7 LOC)core/src/llm/provider.rs
fn parse_provider_aliases() {
assert!(matches!(Provider::from_str_loose("claude").unwrap(), Provider::Anthropic));
assert!(matches!(Provider::from_str_loose("anthropic").unwrap(), Provider::Anthropic));
assert!(matches!(Provider::from_str_loose("gpt").unwrap(), Provider::OpenAI));
assert!(matches!(Provider::from_str_loose("openai").unwrap(), Provider::OpenAI));
assert!(matches!(Provider::from_str_loose("Claude").unwrap(), Provider::Anthropic));
}parse_unknown_provider function · rust · L116-L118 (3 LOC)core/src/llm/provider.rs
fn parse_unknown_provider() {
assert!(Provider::from_str_loose("gemini").is_err());
}