claudius/
lib.rs

1#![deny(missing_docs)]
2
3//! Claudius: A Rust client for the Anthropic API.
4//!
5//! This crate provides a comprehensive client implementation for interacting with
6//! Anthropic's Claude AI models, including support for streaming responses, tool use,
7//! and agent-based interactions.
8
9mod agent;
10mod backoff;
11mod client;
12mod error;
13mod json_schema;
14mod sse;
15mod types;
16
17pub use agent::{
18    Agent, Budget, FileSystem, IntermediateToolResult, Mount, MountHierarchy, Tool, ToolCallback,
19    ToolResult, ToolSearchFileSystem,
20};
21pub use client::Anthropic;
22pub use error::{Error, Result};
23pub use json_schema::JsonSchema;
24pub use types::*;
25
26/// Pushes a message to the messages vector, or merges it with the last message if they have the same role.
27///
28/// This function helps maintain a clean message history by combining consecutive messages
29/// from the same role into a single message entry.
30pub fn push_or_merge_message(messages: &mut Vec<MessageParam>, to_push: MessageParam) {
31    if let Some(last) = messages.last_mut() {
32        if last.role != to_push.role {
33            messages.push(to_push);
34        } else {
35            merge_message_content(&mut last.content, to_push.content);
36        }
37    } else {
38        messages.push(to_push);
39    }
40}
41
42/// Merges new message content into existing message content.
43///
44/// Handles all combinations of string and array content types, converting between
45/// them as necessary to produce a unified message content.
46pub fn merge_message_content(existing: &mut MessageParamContent, new: MessageParamContent) {
47    match (&mut *existing, new) {
48        (MessageParamContent::Array(existing_blocks), MessageParamContent::Array(new_blocks)) => {
49            existing_blocks.extend(new_blocks);
50        }
51        (MessageParamContent::Array(existing_blocks), MessageParamContent::String(new_string)) => {
52            existing_blocks.push(ContentBlock::Text(crate::TextBlock::new(new_string)));
53        }
54        (MessageParamContent::String(existing_string), MessageParamContent::Array(new_blocks)) => {
55            let mut combined = vec![ContentBlock::Text(crate::TextBlock::new(
56                existing_string.clone(),
57            ))];
58            combined.extend(new_blocks);
59            *existing = MessageParamContent::Array(combined);
60        }
61        (MessageParamContent::String(existing_string), MessageParamContent::String(new_string)) => {
62            existing_string.push_str(&new_string);
63        }
64    }
65}