use super::provider::{AgentProvider, ProviderError};
use async_trait::async_trait;
use cc_sdk::llm::{self, LlmOptions};
pub struct ClaudeProvider {
options: Option<LlmOptions>,
}
impl ClaudeProvider {
pub fn new() -> Self {
Self { options: None }
}
#[allow(dead_code)]
pub fn with_options(options: LlmOptions) -> Self {
Self {
options: Some(options),
}
}
}
impl Default for ClaudeProvider {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl AgentProvider for ClaudeProvider {
async fn ask(&self, system: &str, user: &str) -> Result<String, ProviderError> {
let mut builder = LlmOptions::builder().system_prompt(system);
if let Some(pinned) = &self.options {
if let Some(model) = pinned.model.as_ref() {
builder = builder.model(model.clone());
}
}
let opts = builder.build();
let response = llm::query(user, Some(opts))
.await
.map_err(|e| ProviderError::CallFailed(format!("cc-sdk: {e}")))?;
if response.text.trim().is_empty() {
return Err(ProviderError::EmptyResponse);
}
Ok(response.text)
}
fn name(&self) -> &'static str {
"claude"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn claude_provider_name_is_claude() {
let p = ClaudeProvider::new();
assert_eq!(p.name(), "claude");
}
#[test]
fn provider_constructor_does_not_panic() {
let _p = ClaudeProvider::new();
let _p2 = ClaudeProvider::default();
}
}