claudius 0.15.0

SDK for the Anthropic API
Documentation
use std::sync::Arc;

use utf8path::Path;

use claudius::{
    Agent, Anthropic, Budget, FileSystem, KnownModel, Message, MessageCreateParams, Model,
    StopReason, SystemPrompt, Tool, ToolTextEditor20250429,
};

pub struct AgentKB {
    tools: Vec<Arc<dyn Tool<Self>>>,
    filesystem: Path<'static>,
}

impl AgentKB {
    pub fn new(filesystem: Path) -> Self {
        let tools = vec![Arc::new(ToolTextEditor20250429::new()) as _];
        let filesystem = filesystem.into_owned();
        Self { tools, filesystem }
    }
}

#[async_trait::async_trait]
impl Agent for AgentKB {
    async fn model(&self) -> Model {
        Model::Known(KnownModel::ClaudeOpus40)
    }

    async fn max_tokens(&self) -> u32 {
        1024
    }

    async fn hook_message_create_params(
        &self,
        params: &MessageCreateParams,
    ) -> Result<(), claudius::Error> {
        eprintln!("{params:#?}");
        Ok(())
    }

    async fn hook_message(&self, msg: &Message) -> Result<(), claudius::Error> {
        eprintln!("{msg:#?}");
        Ok(())
    }

    async fn tools(&self) -> Vec<Arc<dyn Tool<Self>>> {
        self.tools.clone()
    }

    async fn system(&self) -> Option<SystemPrompt> {
        Some("You are chrooted in an extensive, cross-linked, markdown-based Wiki in /.  You are a proof-reading agent.  Accomplish the user's task".into())
    }

    async fn filesystem(&self) -> Option<&dyn FileSystem> {
        Some(&self.filesystem)
    }
}

#[tokio::main]
async fn main() {
    let client = Anthropic::new(None).unwrap();
    let mut agent = AgentKB::new("kb".into());
    let budget = Arc::new(Budget::new(10_000));
    let mut messages = vec![claudius::MessageParam {
        role: claudius::MessageRole::User,
        content: claudius::MessageParamContent::String(
            "Change all references to \"Alice\" to \"Alyssa\"".to_string(),
        ),
    }];
    loop {
        match agent
            .take_turn(&client, &mut messages, &budget)
            .await
            .unwrap()
        {
            StopReason::MaxTokens | StopReason::EndTurn => {
                break;
            }
            StopReason::Refusal => {
                todo!();
            }
            StopReason::StopSequence => {
                todo!();
            }
            StopReason::ToolUse => {
                todo!();
            }
            StopReason::PauseTurn => {
                todo!();
            }
        }
    }
}