### Install Dependencies and Run Basic Message Example Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md Install project dependencies using 'shards install' and then run the '01_basic_message.cr' example. This demonstrates basic message generation and multi-turn conversations. ```bash shards install crystal run examples/01_basic_message.cr ``` -------------------------------- ### Run Basic Message Example Source: https://github.com/amscotti/anthropic-cr/blob/main/README.md Execute the basic message creation example from the examples directory. Ensure you have the Crystal environment set up. ```bash crystal run examples/01_basic_message.cr ``` -------------------------------- ### System Prompts and Temperature Control Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example shows how to use system prompts to guide the model's behavior and control the randomness of responses using the temperature parameter. ```crystal require "anthropic" client = Anthropic::Client.new response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, system: "You are a helpful assistant that speaks like a pirate.", temperature: 0.7, messages: [ {"role": "user", "content": "Tell me a joke."} ] ) puts response.content.first.text ``` -------------------------------- ### Install Dependencies with Shards Source: https://github.com/amscotti/anthropic-cr/blob/main/CLAUDE.md Use 'shards install' to fetch and install project dependencies. ```bash shards install ``` -------------------------------- ### Ollama Local Model Integration Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates how to integrate with Ollama for running local models. It requires Ollama to be installed and running, and specifies an Ollama model to use. ```crystal require "anthropic" # Configure the client to use Ollama # Ensure Ollama is running and the model is pulled (e.g., 'ollama pull llama3') client = Anthropic::Client.new(base_url: "http://localhost:11434/v1", api_key: "ollama") response = client.messages.create( model: "llama3", # Or any other model available in your Ollama setup max_tokens: 1024, messages: [ {"role": "user", "content": "Why is the sky blue?"} ] ) puts response.content.first.text ``` -------------------------------- ### Run Basic Message Example Source: https://github.com/amscotti/anthropic-cr/blob/main/CLAUDE.md Execute an example script that sends a basic message. Requires ANTHROPIC_API_KEY to be set in .env or the environment. ```bash crystal run examples/01_basic_message.cr ``` -------------------------------- ### Example: Inline Tool for Weather Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/module-helpers.md Demonstrates creating a 'get_weather' tool with a schema for location and unit, and a handler that returns a weather string. ```crystal weather_tool = Anthropic.tool( name: "get_weather", description: "Get weather for a location", schema: { "location" => Anthropic::Schema.string("City name"), "unit" => Anthropic::Schema.enum("celsius", "fahrenheit") }, required: ["location"] ) do |input| location = input["location"].as_s unit = input["unit"]?.try(&.as_s) || "fahrenheit" "Sunny, 72°#{unit == "celsius" ? "C" : "F"} in #{location}" end ``` -------------------------------- ### List Available Models Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt This example shows how to list all available models using the `client.models.list` method. Auto-pagination is also demonstrated. ```crystal response = client.models.list response.data.each do |model| puts "#{model.display_name} (#{model.id})" end # Auto-pagination all_models = client.models.list.auto_paging_all(client) ``` -------------------------------- ### Example: Create User Profile and Enrollment URL Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/beta-apis.md Demonstrates creating a user profile and then generating an enrollment URL for it. The enrollment URL can be shared with the end-user. ```crystal profile = client.beta.user_profiles.create(external_id: "user-123") enrollment = client.beta.user_profiles.create_enrollment_url(profile.id) puts enrollment.url # Share with end user ``` -------------------------------- ### Web Search Server Tool Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates setting up a web search server tool. This allows the model to perform web searches to gather information. ```crystal require "anthropic" require "json" client = Anthropic::Client.new # This is a simplified representation. A real implementation would involve # setting up a web server to handle search queries from the model. web_search_tool = Anthropic::Tools::Schema.define do name "web_search" description "Searches the web for a given query." input do property "query", type: "string" required "query" end # The output schema would define what the tool returns (e.g., search results) # output do # property "results", type: "array", items: {"type": "string"} # end end # To use this, you would typically run a server that exposes this tool # and then pass the tool definition to the Anthropic API. # Example of how the model might call this tool: # response = client.messages.create( # model: "claude-3-opus-20240229", # max_tokens: 1024, # tools: [web_search_tool], # messages: [ # {"role": "user", "content": "What is the latest news on AI?"} # ] # ) puts "Web search tool definition created. A server implementation is required to use it." ``` -------------------------------- ### Example: Output Schema for Sentiment Analysis Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/module-helpers.md Demonstrates creating an output schema for a 'SentimentResult' struct and using it with the Anthropic client to get structured output. ```crystal struct SentimentResult include JSON::Serializable getter sentiment : String getter confidence : Float64 end schema = Anthropic.output_schema( type: SentimentResult, name: "sentiment_result" ) message = client.beta.messages.create( betas: [Anthropic::STRUCTURED_OUTPUT_BETA], output_schema: schema, messages: [...] ) result = SentimentResult.from_json(message.text) ``` -------------------------------- ### Creating a Message Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Demonstrates how to create a message using the SDK, with examples for NamedTuple, typed MessageParam, and convenience constructors. ```APIDOC ## Creating a Message ```crystal # Simple message with NamedTuple message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 1024, messages: [{role: "user", content: "Hello, Claude!"}] ) # With typed MessageParam message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 1024, messages: [ Anthropic::MessageParam.new(role: "user", content: "Hello!") ] ) # Convenience constructors message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 1024, messages: [Anthropic::MessageParam.user("Hello!")] ) ``` ``` -------------------------------- ### Streaming with Tools Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates how to handle streaming responses when using tools. It allows for real-time updates as the model processes tool calls and their results. ```crystal require "anthropic" client = Anthropic::Client.new # Define a simple tool def multiply(a : Int32, b : Int32) : Int32 a * b end tools = [ { "name": "multiply", "description": "Multiplies two integers.", "input_schema": { "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer"} }, "required": ["a", "b"] } } ] sse_stream = client.messages.create_stream( model: "claude-3-opus-20240229", max_tokens: 1024, tools: tools, messages: [ {"role": "user", "content": "What is 7 times 6?"} ] ) sse_stream.each_content do |content_block| if content_block.type == "tool_use" tool_name = content_block.name tool_input = content_block.input puts "Tool Call: #{tool_name}(#{tool_input})" # In a real scenario, you would execute the tool here and send the result back # For this example, we'll just print the tool call details. elsif content_block.type == "text" puts content_block.text end end ``` -------------------------------- ### Defining and Using Tools in Ruby Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt This Ruby example shows how to define a tool with its schema and then use it in a message creation request. ```ruby weather = Anthropic::Tool.new( name: "get_weather", description: "Get weather", input_schema: { type: "object", properties: { location: {type: "string", description: "City"} }, required: ["location"] } ) do |input| # ... end message = client.messages.create( model: "claude-sonnet-4-6", max_tokens: 1024, messages: [{role: "user", content: "Weather?"}], tools: [weather] ) ``` -------------------------------- ### ToolChoice Configuration Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Examples of configuring `tool_choice` for different behaviors: Auto, Any, and specific Tool selection. ```APIDOC ## ToolChoice Types ```crystal # Auto (default) - Claude decides when to use tools tool_choice: Anthropic::ToolChoiceAuto.new # Any - Claude must use any available tool tool_choice: Anthropic::ToolChoiceAny.new # Tool - Claude must use a specific tool tool_choice: Anthropic::ToolChoiceTool.new(name: "calculator") ``` ``` -------------------------------- ### Automatic Pagination Helpers Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates the use of automatic pagination helpers provided by the SDK. This simplifies iterating over large collections of resources. ```crystal require "anthropic" client = Anthropic::Client.new # Example: Paginate through models client.models.list.each do |model| puts model.id end # Example: Paginate through batches (assuming you have batches) # client.batches.list.each do |batch| # puts batch.id # end ``` -------------------------------- ### Example: Enum Property Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/module-helpers.md Illustrates defining an enum property for color choices with a description. ```crystal Anthropic::Schema.enum("red", "green", "blue", description: "Color choice") ``` -------------------------------- ### Beta Parameters (MCP Servers, Container/Skills, Tool Search) Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example explores beta parameters, potentially including Multi-Channel Processing (MCP) servers, containerized skills, and advanced tool search functionalities. ```crystal require "anthropic" client = Anthropic::Client.new # These parameters are experimental and may change. response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, # mcp_server: "my-mcp-server.example.com", # Hypothetical MCP server parameter # skills: ["calculator", "web_search"], # Hypothetical skills parameter # tool_search: true, # Hypothetical tool search parameter messages: [ {"role": "user", "content": "Perform a calculation and search the web."} ] ) puts response.inspect ``` -------------------------------- ### Get Raw Binary Response Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/client.md Use this method for downloading files. It executes a GET request and returns the raw binary response as an IO::Memory object. ```crystal def get_raw( path : String, extra_headers : Hash(String, String)? = nil ) : IO::Memory ``` -------------------------------- ### Full Batch Workflow Example Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/batches.md Demonstrates the complete lifecycle of a batch operation: creation, polling for completion, processing results, and optional deletion. Suitable for understanding the end-to-end process. ```crystal # 1. Create batch batch = client.messages.batches.create(requests: my_requests) batch_id = batch.id # 2. Poll for completion (in production, use webhook or background job) loop do status = client.messages.batches.retrieve(batch_id) puts "Status: #{status.processing_status}" break if status.processing_status == "ended" sleep(5) end # 3. Process results client.messages.batches.results(batch_id) do |result| if msg = result.result.message save_to_db(result.custom_id, msg.text) end end # 4. Clean up (optional) client.messages.batches.delete(batch_id) ``` -------------------------------- ### Execute GET Request Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/client.md Shows how to perform a low-level GET request to a specified API path. Supports query parameters and additional headers, with automatic retry logic. ```crystal def get( path : String, params : QueryParams? = nil, extra_headers : Hash(String, String)? = nil ) : HTTP::Client::Response ``` -------------------------------- ### Web Search with Streaming Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example shows how to combine web search capabilities with streaming responses. This allows the user to see search results as they are fetched and processed. ```crystal require "anthropic" client = Anthropic::Client.new # Assume a web_search tool is defined and available (similar to the previous example) # For demonstration, we'll simulate the tool call and response. # Define the web_search tool schema web_search_tool = Anthropic::Tools::Schema.define do name "web_search" description "Searches the web for a given query." input do property "query", type: "string" required "query" end end sse_stream = client.messages.create_stream( model: "claude-3-opus-20240229", max_tokens: 1024, tools: [web_search_tool], messages: [ {"role": "user", "content": "What are the latest advancements in quantum computing?"} ] ) sse_stream.each_content do |content_block| if content_block.type == "tool_use" tool_name = content_block.name tool_input = content_block.input puts "Performing web search for: #{tool_input['query']}" # In a real application, you would call your web search service here. # For this example, we'll just acknowledge the tool call. elsif content_block.type == "text" puts content_block.text end end ``` -------------------------------- ### Example: Typed Tool for Weather Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/module-helpers.md Shows creating a 'get_weather' tool using a typed input struct 'WeatherInput'. The handler receives an instance of 'WeatherInput'. ```crystal struct WeatherInput include JSON::Serializable @[JSON::Field(description: "City name")] getter location : String @[JSON::Field(description: "Temperature unit")] getter unit : String? end weather_tool = Anthropic.tool( name: "get_weather", description: "Get weather for a location", input: WeatherInput ) do |input| # input is typed WeatherInput, not JSON::Any unit = input.unit || "fahrenheit" "Sunny, 72° in #{input.location}" end ``` -------------------------------- ### List Models API Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates how to use the Models API to list available models. It's useful for dynamically selecting models for your application. ```crystal require "anthropic" client = Anthropic::Client.new models = client.models.list models.each do |model| puts "ID: #{model.id}, Created: #{model.created_at}, Updated: #{model.updated_at}" end ``` -------------------------------- ### WebFetchTool20260309 with `use_cache: false` Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example shows how to use the `WebFetchTool20260309` and explicitly disable caching by setting `use_cache: false`. This ensures fresh data is fetched on each call. ```crystal require "anthropic" client = Anthropic::Client.new web_fetch_tool = Anthropic::Tools::Schema.define do name "WebFetchTool20260309" description "Fetches content from a URL." input do property "url", type: "string" property "use_cache", type: "boolean", default: true required "url" end end response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, tools: [web_fetch_tool], messages: [ {"role": "user", "content": "Fetch the latest news from example.com, do not use cache."} ] ) puts response.inspect ``` -------------------------------- ### Image Understanding with Vision Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates how to use the Anthropic SDK for image understanding by providing image data in the prompt. It requires base64 encoded image data. ```crystal require "anthropic" require "base64" client = Anthropic::Client.new # Load and encode an image (replace with your image path) image_path = "path/to/your/image.png" image_data = File.read(image_path) base64_image = Base64.strict_encode64(image_data) response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, messages: [ { "role": "user", "content": [ {"type": "text", "text": "What is in this image?"}, { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": base64_image } } ] } ] ) puts response.content.first.text ``` -------------------------------- ### Complete Tool Execution Loop Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example shows a complete tool execution loop, enabling the model to use tools to answer user queries. It requires defining tools and handling their execution. ```crystal require "anthropic" client = Anthropic::Client.new # Define a tool (e.g., a calculator) def add(a : Int32, b : Int32) : Int32 a + b end tools = [ { "name": "add", "description": "Adds two integers.", "input_schema": { "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer"} }, "required": ["a", "b"] } } ] response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, tools: tools, messages: [ {"role": "user", "content": "What is 2 + 2?"} ] ) if response.tool_use? tool_name = response.first_tool_use.name tool_input = response.first_tool_use.input result = case tool_name when "add" add(tool_input["a"].as_i32, tool_input["b"].as_i32) else raise "Unknown tool: #{tool_name}" end response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, messages: [ {"role": "user", "content": "What is 2 + 2?"}, response.to_message, {"role": "user", "content": result.to_s, "tool_result": {"tool_name": tool_name, "content": result.to_s}} ] ) puts response.content.first.text else puts response.content.first.text end ``` -------------------------------- ### Resource Chaining Examples Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/README.md Illustrates how to chain API operations through resource objects accessed from the client. This pattern is used for various operations like listing models or creating batches. ```crystal client.messages.create(...) client.models.list client.messages.batches.create(...) client.beta.messages.create(...) client.beta.files.upload(...) ``` -------------------------------- ### Token Counting for Context Management Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates how to count tokens in a message or conversation. This is essential for managing context length and avoiding exceeding token limits. ```crystal require "anthropic" client = Anthropic::Client.new message = {"role": "user", "content": "This is a sample message to count tokens."} token_count = client.count_tokens(model: "claude-3-opus-20240229", messages: [message]) puts "The message has #{token_count} tokens." conversation = [ {"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi there!"} ] token_count = client.count_tokens(model: "claude-3-opus-20240229", messages: conversation) puts "The conversation has #{token_count} tokens." ``` -------------------------------- ### Skills API (CRUD, Versions, Container Integration) Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates the Skills API for managing skills, including Create, Read, Update, and Delete operations, versioning, and integration with containerized environments. ```crystal require "anthropic" client = Anthropic::Client.new # Example: Creating a skill skill_definition = { "name": "my_calculator_skill", "description": "A skill that performs calculations.", "input_schema": { "type": "object", "properties": { "operation": {"type": "string"}, "a": {"type": "number"}, "b": {"type": "number"} }, "required": ["operation", "a", "b"] } } # skill = client.skills.create(skill_definition) # puts "Skill created: #{skill.id}" # Example: Listing skills # skills = client.skills.list # skills.each { |s| puts s.name } puts "Skills API examples (create, list) are conceptual and require specific implementation." ``` -------------------------------- ### Advisor Tool (`advisor_20260301`) with Typed Result-Block Handling Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates using the `advisor_20260301` tool and handling its typed result-blocks. This allows for structured processing of advice or recommendations provided by the tool. ```crystal require "anthropic" client = Anthropic::Client.new advisor_tool = Anthropic::Tools::Schema.define do name "advisor_20260301" description "Provides advice on a given topic." input do property "topic", type: "string" required "topic" end output do property "advice", type: "string" required "advice" end end response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, tools: [advisor_tool], messages: [ {"role": "user", "content": "What is the best way to learn a new programming language?"} ] ) response.content.each do |content_block| if content_block.type == "tool_use" && content_block.name == "advisor_20260301" advice = content_block.input["advice"] puts "Advisor's advice: #{advice}" elsif content_block.type == "text" puts content_block.text end end ``` -------------------------------- ### Basic Tool Runner Usage Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Initialize a Tool Runner with model, messages, and tools. Iterate through messages to handle tool use or get the final response. ```crystal # Define tools calculator = Anthropic.tool(...) { |input| ... } time_tool = Anthropic.tool(...) { |input| ... } # Create tool runner runner = client.beta.messages.tool_runner( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 1024, messages: [Anthropic::MessageParam.user("What time is it? Also calculate 15 + 27")], tools: [calculator, time_tool] of Anthropic::Tool, max_iterations: 10 ) # Iterate through conversation (tools executed automatically) runner.each_message do |msg| if msg.tool_use? puts "Claude wants to use tools" else puts "Final: #{msg.text}" end end # Or just get the final answer final = runner.final_message puts final.text ``` -------------------------------- ### Document Citations Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates how to handle document citations returned by the model. Citations provide references to the sources used by the model to generate its response. ```crystal require "anthropic" client = Anthropic::Client.new response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, messages: [ {"role": "user", "content": "Explain the theory of relativity and cite your sources."} ] ) response.content.each do |content_block| if content_block.type == "text" puts content_block.text elsif content_block.type == "documentation_source" puts "Source: #{content_block.documentation_source.url}" end end ``` -------------------------------- ### Schema DSL for Tool Definitions Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example showcases the Schema DSL for defining tools in a type-safe manner. It simplifies the process of creating complex tool schemas. ```crystal require "anthropic" client = Anthropic::Client.new # Define a tool using the Schema DSL calculator_tool = Anthropic::Tools::Schema.define do name "calculator" description "Performs arithmetic operations." input do type "object" property "operation", type: "string", enum: ["add", "subtract", "multiply", "divide"] property "a", type: "number" property "b", type: "number" required "operation", "a", "b" end end response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, tools: [calculator_tool], messages: [ {"role": "user", "content": "What is 5 multiplied by 3?"} ] ) puts response.inspect ``` -------------------------------- ### Message Usage Examples Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/types.md Demonstrates different ways to construct message arrays for API requests, including simple tuples, typed structs, and complex content with images. ```crystal # Simple tuple syntax messages = [{role: "user", content: "Hello"}] # Typed structs messages = [MessageParam.user("Hello")] # Complex content with images messages = [ MessageParam.new( role: "user", content: [ Anthropic::TextContent.new("Describe this image"), Anthropic::ImageContent.base64("image/png", base64_string) ] ) ] ``` -------------------------------- ### Define and Use a Tool with Schema DSL Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Define a custom tool using the Schema DSL for simple function definitions. This example shows how to define a weather tool and then call it with user input. ```crystal # Define a tool with Schema DSL weather_tool = Anthropic.tool( name: "get_weather", description: "Get current weather for a location", schema: { "location" => Anthropic::Schema.string("City name, e.g. San Francisco"), "unit" => Anthropic::Schema.enum("celsius", "fahrenheit", description: "Temperature unit"), }, required: ["location"] ) do |input| location = input["location"].as_s unit = input["unit"]?.try(&.as_s) || "fahrenheit" "Sunny, 72°#{unit == "celsius" ? "C" : "F"} in #{location}" end # Use the tool message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 1024, messages: [{role: "user", content: "What's the weather in Tokyo?"}], tools: [weather_tool] ) if message.tool_use? message.tool_use_blocks.each do |tool_use| result = weather_tool.call(tool_use.input) puts result end end ``` -------------------------------- ### Automatic Context Compaction Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example illustrates automatic context compaction. The SDK can help manage long conversations by intelligently shortening the context while preserving key information. ```crystal require "anthropic" client = Anthropic::Client.new # Assume a long conversation history is built up conversation = [ {"role": "user", "content": "Turn 1"}, {"role": "assistant", "content": "Response 1"}, # ... many more turns ... {"role": "user", "content": "Turn N"} ] # The SDK might have a method to automatically compact the context # For example, if the client has a 'compact_context' option or method. # This is a conceptual example, as the exact implementation depends on the SDK's features. # compacted_conversation = client.compact_context(conversation, max_tokens: 4096) # For now, we'll just show how to send a message with a potentially long history # and rely on the API's handling or manual compaction. response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, messages: conversation # In a real scenario, this might be the compacted_conversation ) puts response.content.first.text ``` -------------------------------- ### Typed Tools (BaseTool Pattern) Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates using typed tools with the BaseTool pattern. This approach enhances type safety and code organization when defining and using tools. ```crystal require "anthropic" # Define a tool using the BaseTool pattern class WeatherTool < Anthropic::Tools::BaseTool tool_name "get_weather" description "Gets the current weather for a location." input do property "location", type: "string" required "location" end # Define the output schema output do property "temperature", type: "integer" property "unit", type: "string", enum: ["celsius", "fahrenheit"] required "temperature", "unit" end # Method to execute the tool (simulated) def execute(location : String) : Hash(String, JSON::Any) # In a real app, you'd call a weather API here puts "Fetching weather for #{location}..." if location.downcase.includes?("london") {"temperature": 15, "unit": "celsius"}.to_json else {"temperature": 70, "unit": "fahrenheit"}.to_json end end end client = Anthropic::Client.new response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, tools: [WeatherTool.new], messages: [ {"role": "user", "content": "What's the weather like in London?"} ] ) puts response.inspect ``` -------------------------------- ### Files API: Download File Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example shows how to download a file using the Files API. You need the file ID obtained from a previous upload or API response. ```crystal require "anthropic" client = Anthropic::Client.new file_id = "file-xxxxxxxxxxxxxxxxx" # Replace with your file ID file_content = client.files.download(file_id) # Save the downloaded content to a local file File.write("downloaded_file.txt", file_content) puts "File #{file_id} downloaded successfully to downloaded_file.txt." ``` -------------------------------- ### Agent Tools (Bash, Text Editor, Web Fetch, Memory) Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates the use of various agent tools, including Bash execution, text editor interaction, web fetching, and memory management. These tools enable agents to perform complex tasks. ```crystal require "anthropic" client = Anthropic::Client.new # Define agent tools (simplified definitions) bash_tool = Anthropic::Tools::Schema.define do name "bash_executor" description "Executes bash commands." input { property "command", type: "string"; required "command" } end web_fetch_tool = Anthropic::Tools::Schema.define do name "web_fetcher" description "Fetches content from a URL." input { property "url", type: "string"; required "url" } end # In a real agent, you would orchestrate these tools based on the model's output. # This example just shows the tool definitions. response = client.messages.create( model: "claude-3-opus-20240229", max_tokens: 1024, tools: [bash_tool, web_fetch_tool], # Add other tools like text editor, memory here messages: [ {"role": "user", "content": "Find the current date using bash and then search for 'AI news' online."} ] ) puts response.inspect ``` -------------------------------- ### Initialize Client and Create Message Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/README.md Demonstrates basic client initialization and creating a message with a specified model and content. Use this for simple, single-turn interactions. ```crystal require "anthropic-cr" client = Anthropic::Client.new message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 1024, messages: [{role: "user", content: "Hello, Claude!"}] ) puts message.text ``` -------------------------------- ### GET Stream Request Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/client.md Executes a GET request with a streaming response, yielding the response object to a block. ```APIDOC ## GET Stream Request ### Description Execute a GET request with streaming response. ### Method `get_stream` ### Endpoint API path ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **path** (String) - Required - API path - **extra_headers** (Hash(String, String)?) - Optional - Additional HTTP headers ### Response #### Success Response `Nil` (yields response object to block) ``` -------------------------------- ### Files API: Upload File Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates how to upload a file using the Files API. Uploaded files can be used for various purposes, such as providing context or data for batch operations. ```crystal require "anthropic" client = Anthropic::Client.new # Assume 'my_data.txt' is a file in your project file_path = "my_data.txt" file = client.files.upload( file: File.open(file_path), purpose: "batch" ) puts "File uploaded successfully." puts "File ID: #{file.id}" puts "Filename: #{file.filename}" puts "Purpose: #{file.purpose}" puts "Status: #{file.status}" ``` -------------------------------- ### GET Request Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/client.md Executes a GET request with automatic retry logic for a specified API path and optional query parameters. ```APIDOC ## GET Request ### Description Execute a GET request with automatic retry logic. ### Method `get` ### Endpoint API path (e.g. `/v1/models`) ### Parameters #### Path Parameters None #### Query Parameters - **path** (String) - Required - API path (e.g. `/v1/models`) - **params** (QueryParams?) - Optional - Query parameters as Hash(String, String) or Hash(String, Array(String)) - **extra_headers** (Hash(String, String)?) - Optional - Additional HTTP headers to include in request ### Response #### Success Response (200) `HTTP::Client::Response` ``` -------------------------------- ### Rich Block-Scoped Streaming with `open_stream` Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example showcases richer block-scoped streaming using the `open_stream` method. This allows for more granular control over how different types of content blocks are streamed and processed. ```crystal require "anthropic" client = Anthropic::Client.new # Using open_stream for more control over streaming blocks sse_stream = client.messages.open_stream( model: "claude-3-opus-20240229", max_tokens: 1024, messages: [ {"role": "user", "content": "Generate a short story with a plot twist."} ] ) sse_stream.each do |event| if event.data data = JSON.parse(event.data) content_block = Anthropic::Response::ContentBlock.from_json(data) case content_block.type when "text" print content_block.text when "tool_use" puts "\n[Tool Call: #{content_block.name} with args: #{content_block.input}]\n" else puts "\n[Received block of type: #{content_block.type}]\n" end end end puts "\nStream finished." ``` -------------------------------- ### Stateful Managed Agents API Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example demonstrates the Stateful Managed Agents API, covering environments, memory stores, agents, vaults, and webhooks. This allows for building sophisticated, stateful agent applications. ```crystal require "anthropic" client = Anthropic::Client.new # Conceptual example for Managed Agents API # These operations would typically involve creating/managing resources via API calls. # Example: Creating an environment # env = client.managed_agents.environments.create(name: "my-dev-env") # Example: Creating a memory store # memory = client.managed_agents.memory_stores.create(name: "chat-history", type: "redis") # Example: Creating an agent # agent = client.managed_agents.agents.create( # name: "support-bot", # environment_id: env.id, # memory_store_id: memory.id, # model_id: "claude-3-opus-20240229" # ) puts "Managed Agents API examples are conceptual and require specific resource management." ``` -------------------------------- ### Execute Streaming GET Request Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/client.md Demonstrates performing a GET request with a streaming response. The response object is yielded to a block for processing. ```crystal def get_stream( path : String, extra_headers : Hash(String, String)? = nil, & ) : Nil ``` -------------------------------- ### Client Initialization with Options Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/README.md Initialize the Anthropic client with custom API key, timeout, retry settings, and retry delay. ```crystal Anthropic::Client.new( api_key: "sk-ant-...", timeout: 600.seconds, max_retries: 2, initial_retry_delay: 0.5, max_retry_delay: 8.0 ) ``` -------------------------------- ### Claude Opus 4.8 with `xhigh` effort and `BetaTokenTaskBudget` Source: https://github.com/amscotti/anthropic-cr/blob/main/examples/README.md This example utilizes Claude Opus 4.8, demonstrating the use of the `xhigh` effort parameter and `BetaTokenTaskBudget` for advanced task management and resource allocation. ```crystal require "anthropic" client = Anthropic::Client.new response = client.messages.create( model: "claude-3-opus-20240229", # Assuming this model ID covers Opus 4.8 max_tokens: 1024, effort: "xhigh", # Use 'xhigh' effort # beta_token_task_budget: {"budget_tokens": 1000}, # Example of BetaTokenTaskBudget messages: [ {"role": "user", "content": "Perform a complex analysis requiring high effort."} ] ) puts response.inspect ``` -------------------------------- ### Use ComputerUseTool to List Files Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt This snippet shows how to initialize and use the ComputerUseTool to list files in the current directory. Ensure display dimensions are provided. ```crystal message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 4096, server_tools: [ Anthropic::BashTool.new, Anthropic::TextEditorTool.new, Anthropic::ComputerUseTool.new(display_width_px: 1920, display_height_px: 1080), ] of Anthropic::ServerTool, messages: [{role: "user", content: "List files in the current directory"}] ) ``` -------------------------------- ### AdvisorTool Definition and Example Usage Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/tools.md Defines an AdvisorTool for delegating sub-questions to a secondary model. Includes an example of initializing the tool and using it in a message creation. ```crystal class AdvisorTool < ServerTool def initialize( @model : String, @max_uses : Int32? = nil, @strict : Bool? = nil ) end end # Example: security review with advisor advisor = Anthropic::AdvisorTool.new( model: Anthropic::Model::CLAUDE_OPUS_4_5, max_uses: 3, strict: true ) message = client.beta.messages.create( model: Anthropic::Model::CLAUDE_OPUS_4_8, max_tokens: 2048, server_tools: [advisor] of Anthropic::ServerTool, messages: [{role: "user", content: "Review this code for security issues: ..."}] ) ``` -------------------------------- ### MessageStartEvent Structure Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/streaming.md Represents the start of a streamed message, providing the message ID. ```crystal struct MessageStartEvent getter type : String = "message_start" getter message : Message end ``` -------------------------------- ### Use BashTool to List Files Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/tools.md Demonstrates using the BashTool to execute a command that lists files in the current directory on the server. ```crystal message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 2048, server_tools: [Anthropic::BashTool.new], messages: [{role: "user", content: "List files in the current directory"}] ) ``` -------------------------------- ### Prevent Tool Use Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Example of how to prevent tool use by setting tool_choice to Anthropic::ToolChoiceNone.new. ```crystal tool_choice: Anthropic::ToolChoiceNone.new ``` -------------------------------- ### Configure Server-Side Tools Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/configuration.md Instantiate server-side tools like `WebSearchTool`, `BashTool`, and `ComputerUseTool` to enable their functionality. ```crystal # Server-side tools server_tools: [ Anthropic::WebSearchTool.new, Anthropic::BashTool.new, Anthropic::ComputerUseTool.new ] ``` -------------------------------- ### Initialize Anthropic Client Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/client.md Demonstrates the constructor for the Anthropic::Client. It shows how to set API key, base URL, timeouts, retry configurations, and default headers. ```crystal def initialize( api_key : String? = nil, base_url : String = "https://api.anthropic.com", timeout : Time::Span = 600.seconds, max_retries : Int32 = 2, initial_retry_delay : Float64 = 0.5, max_retry_delay : Float64 = 8.0, default_headers : Hash(String, String) = {} of String => String ) ``` -------------------------------- ### Multi-Turn Conversation Example Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/README.md Accumulate messages in an array and pass each request to maintain conversation history. ```crystal messages = [Anthropic::MessageParam.user("What is AI?")] response = client.messages.create(model: ..., messages: messages) messages << Anthropic::MessageParam.assistant(response.text) messages << Anthropic::MessageParam.user("Explain in simpler terms") response = client.messages.create(model: ..., messages: messages) ``` -------------------------------- ### Handle APIConnectionError Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/errors.md Example of how to rescue and handle APIConnectionError during a client operation. This is useful for diagnosing network issues. ```crystal begin client.messages.create(...) rescue ex : Anthropic::APIConnectionError puts "Connection failed: #{ex.message}" # Check network connectivity end ``` -------------------------------- ### Accessing Message Stop Reason Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Get the reason why message generation stopped, such as 'end_turn', 'max_tokens', or 'tool_use'. ```ruby puts message.stop_reason # "end_turn" | "max_tokens" | "tool_use" | etc. ``` -------------------------------- ### Client Initialization Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Initialize the Anthropic client with required and optional configuration parameters. ```APIDOC ## Client Options ```crystal client = Anthropic::Client.new( api_key: String, # Required base_url: String = "https://api.anthropic.com", # API base URL timeout: Time::Span = 600.seconds, # Request timeout max_retries: Int32 = 2, # Retry attempts initial_retry_delay: Float64 = 0.5, # Initial delay (seconds) max_retry_delay: Float64 = 8.0, # Max delay (seconds) default_headers: Hash(String, String) = {} ) ``` ``` -------------------------------- ### Use WebFetchTool to Read Web Pages Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Demonstrates fetching and reading content from a web page using WebFetchTool. Configuration options like allowed domains and max uses are shown. ```crystal message = client.messages.create( model: Anthropic::Model::CLAUDE_SONNET_4_6, max_tokens: 4096, server_tools: [Anthropic::WebFetchTool.new], messages: [{role: "user", content: "Read the content at https://example.com"}] ) ``` ```crystal fetch = Anthropic::WebFetchTool.new( allowed_domains: ["example.com", "docs.example.com"], max_uses: 5, max_content_tokens: 10_000 ) ``` ```crystal fetch = Anthropic::WebFetchTool.limited_to("example.com", "docs.example.com") ``` ```crystal fetch = Anthropic::WebFetchTool.excluding("spam.com") ``` -------------------------------- ### Handling PermissionDeniedError Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/errors.md Example of catching a PermissionDeniedError, indicating insufficient permissions for the requested action. It prints the error message. ```crystal begin client.beta.files.upload(path) # Feature not enabled rescue ex : Anthropic::PermissionDeniedError puts "Permission denied: #{ex.message}" end ``` -------------------------------- ### Retrieve Skill Details using Beta Skills API Source: https://github.com/amscotti/anthropic-cr/blob/main/_autodocs/beta-apis.md Get the details of a specific skill using its ID. ```crystal def retrieve(skill_id : String) : SkillResponse ``` -------------------------------- ### Define and Use Advisor Tool Source: https://github.com/amscotti/anthropic-cr/blob/main/llms.txt Instantiate and use the `AdvisorTool` for routing specialized reviews. Ensure the `AdvisorTool` is included in `server_tools` to activate the beta header. ```ruby advisor = Anthropic::AdvisorTool.new( model: Anthropic::Model::CLAUDE_OPUS_4_5, # The advisor model max_uses: 3, # Optional cap strict: true, # Enforce schema on advisor calls caching: Anthropic::CacheControl.ephemeral # Optional: cache advisor prompt ) message = client.beta.messages.create( model: Anthropic::Model::CLAUDE_OPUS_4_8, max_tokens: 2048, server_tools: [advisor] of Anthropic::ServerTool, messages: [{role: "user", content: "Review this payload for abuse patterns: ..."}] ) ``` -------------------------------- ### System Prompts and Parameters Source: https://github.com/amscotti/anthropic-cr/blob/main/README.md Configure system prompts and parameters like temperature for message creation. ```Crystal message = client.messages.create( model: Anthropic::Model::CLAUDE_OPUS_4_5, max_tokens: 2048, system: "You are a helpful coding assistant specializing in Crystal.", temperature: 0.7, messages: [{role: "user", content: "How do I create a HTTP server?"}] ) ```