llm-content-blocks
Typed fluent builder for Anthropic Messages-API content blocks. No SDK requirement, narrow deps (serde, serde_json, base64).
use ;
let content = new
.text
.image_b64.unwrap
.text_with_cache
.build;
// wrap as a full message
let user_msg = new.text.build_message;
// Message { role: "user", content: vec![Text { text: "Hi", ... }] }
// tool result (one-shot, not chained)
use json;
let tr = tool_result_block;
Why
The Anthropic Messages content-block shapes are simple but fiddly when you assemble them programmatically: tool responses, multi-image inputs, cached system prompts, retry-with-correction loops. Blocks is a fluent builder that emits the exact JSON shape the API expects.
No SDK dependency. The crate doesn't talk to the API. It just makes the right shape, so you can use it from any HTTP client (reqwest, ureq, hyper) or pass the output through serde_json to the official SDK.
Supported blocks: text, image (base64 or URL), tool_use, tool_result, document (PDF, plain text).
Install
[]
= "0.1"
API
use ;
use json;
// chained appends, return &mut self
let mut b = new;
b.text;
b.text_with_cache;
b.image_b64.unwrap;
b.image_url;
b.tool_use;
b.tool_result;
b.document_b64.unwrap;
b.document_pdf_b64;
// terminal
let blocks = b.build; // Vec<ContentBlock>
let msg = new.text.build_message; // Message { role, content }
// one-shot helpers
let tr = tool_result_block;
CacheControl::Ephemeral is the only valid value today (Anthropic's prompt cache). The cache_control field is omitted from JSON when unset. The crate rejects unknown image and document media types up front with a typed [BlockError], so you get a build-site error instead of a 400 from the API.
Serialization
ContentBlock derives serde::Serialize with #[serde(tag = "type", rename_all = "snake_case")]. The produced JSON matches the Anthropic dict shape exactly. Pass &content (or the Message envelope) to serde_json::to_value / serde_json::to_string and ship it.
Companion libraries
claude-cost- cache-aware cost calculator for Anthropic + Bedrock model IDs.agentprompt-rs- Jinja-style prompt template render; pair with this builder for final message construction.claude-stream-rs- incremental SSE parser for Anthropic streamed responses.
License
MIT OR Apache-2.0