mirror of https://github.com/0xplaygrounds/rig
Add examples
This commit is contained in:
parent
0a9bbe52b7
commit
1fe55ad1dd
|
@ -8685,6 +8685,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"syn 2.0.100",
|
||||
"tokio",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -17,3 +17,4 @@ schemars = "0.8.22"
|
|||
rig-core = { path = "../rig-core" }
|
||||
serde = "1.0"
|
||||
tokio = { version = "1.44.0", features = ["full"] }
|
||||
tracing-subscriber = "0.3.0"
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
# Rig Tool Macro Examples
|
||||
|
||||
This directory contains examples demonstrating different ways to use the `rig_tool` macro with a rig Agent.
|
||||
|
||||
## Examples
|
||||
|
||||
### 1. Simple Example (`simple.rs`)
|
||||
Demonstrates the most basic usage of the macro without any attributes. Shows how to create a simple tool that adds two numbers and use it with a rig Agent.
|
||||
|
||||
### 2. With Description (`with_description.rs`)
|
||||
Shows how to add a description to your tool using the `description` attribute. Implements a calculator that can perform basic arithmetic operations and uses it with a rig Agent.
|
||||
|
||||
### 3. Full Attributes (`full.rs`)
|
||||
Demonstrates using all available attributes including parameter descriptions. Implements a string processor that can perform various string operations and uses it with a rig Agent.
|
||||
|
||||
### 4. Error Handling (`error_handling.rs`)
|
||||
Shows how to handle errors in your tools, including:
|
||||
- Domain-specific errors (e.g., square root of negative numbers)
|
||||
- Parameter validation errors
|
||||
- Missing parameter errors
|
||||
- Type conversion errors
|
||||
|
||||
### 5. Async Tool (`async_tool.rs`)
|
||||
Demonstrates how to create and use async tools with a rig Agent, including:
|
||||
- Basic async operation
|
||||
- Error handling in async context
|
||||
|
||||
## Running the Examples
|
||||
|
||||
To run any example, use:
|
||||
|
||||
```bash
|
||||
cargo run --example <example_name>
|
||||
```
|
||||
|
||||
For example:
|
||||
```bash
|
||||
cargo run --example simple
|
||||
cargo run --example with_description
|
||||
cargo run --example full
|
||||
cargo run --example error_handling
|
||||
cargo run --example async_tool
|
||||
```
|
||||
|
||||
## Features Demonstrated
|
||||
|
||||
- Basic tool creation
|
||||
- Optional attributes
|
||||
- Parameter descriptions
|
||||
- Error handling
|
||||
- Async support
|
||||
- Static tool instances
|
||||
- Parameter validation
|
||||
- Integration with rig Agent
|
||||
- Natural language interaction with tools
|
||||
- Tool definitions and schemas
|
|
@ -0,0 +1,59 @@
|
|||
use rig::completion::Prompt;
|
||||
use rig::providers;
|
||||
use rig::tool::Tool;
|
||||
use rig_macros::rig_tool;
|
||||
use std::time::Duration;
|
||||
use tracing_subscriber;
|
||||
|
||||
// Example demonstrating async tool usage
|
||||
#[rig_tool(
|
||||
description = "A tool that simulates an async operation",
|
||||
params(
|
||||
input = "Input value to process",
|
||||
delay_ms = "Delay in milliseconds before returning result"
|
||||
)
|
||||
)]
|
||||
async fn async_operation(input: String, delay_ms: u64) -> Result<String, rig::tool::ToolError> {
|
||||
// Simulate some async work
|
||||
tokio::time::sleep(Duration::from_millis(delay_ms)).await;
|
||||
|
||||
// Process the input
|
||||
Ok(format!(
|
||||
"Processed after {}ms: {}",
|
||||
delay_ms,
|
||||
input.to_uppercase()
|
||||
))
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize tracing
|
||||
tracing_subscriber::fmt().pretty().init();
|
||||
|
||||
// Create an agent with the ASYNCOPERATION tool
|
||||
let async_agent = providers::openai::Client::from_env()
|
||||
.agent(providers::openai::GPT_4O)
|
||||
.preamble("You are an agent with tools access, always use the tools")
|
||||
.max_tokens(1024)
|
||||
.tool(AsyncOperation)
|
||||
.build();
|
||||
|
||||
// Print out the tool definition to verify
|
||||
println!("Tool definition:");
|
||||
println!(
|
||||
"ASYNCOPERATION: {}",
|
||||
serde_json::to_string_pretty(&AsyncOperation.definition(String::default()).await).unwrap()
|
||||
);
|
||||
|
||||
// Test prompts
|
||||
for prompt in [
|
||||
"What tools do you have?",
|
||||
"Process the text 'hello world' with a delay of 1000ms",
|
||||
"Process the text 'async operation' with a delay of 500ms",
|
||||
"Process the text 'concurrent calls' with a delay of 200ms",
|
||||
"Process the text 'error handling' with a delay of 'not a number'",
|
||||
] {
|
||||
println!("User: {}", prompt);
|
||||
println!("Agent: {}", async_agent.prompt(prompt).await.unwrap());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
use rig::completion::Prompt;
|
||||
use rig::providers;
|
||||
use rig::tool::Tool;
|
||||
use rig_macros::rig_tool;
|
||||
use tracing_subscriber;
|
||||
|
||||
// Example with full attributes including parameter descriptions
|
||||
#[rig_tool(
|
||||
description = "A tool that performs string operations",
|
||||
params(
|
||||
text = "The input text to process",
|
||||
operation = "The operation to perform (uppercase, lowercase, reverse)",
|
||||
)
|
||||
)]
|
||||
fn string_processor(
|
||||
text: String,
|
||||
operation: String,
|
||||
) -> Result<String, rig::tool::ToolError> {
|
||||
let result = match operation.as_str() {
|
||||
"uppercase" => text.to_uppercase(),
|
||||
"lowercase" => text.to_lowercase(),
|
||||
"reverse" => text.chars().rev().collect(),
|
||||
_ => {
|
||||
return Err(rig::tool::ToolError::ToolCallError(
|
||||
format!("Unknown operation: {}", operation).into(),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize tracing
|
||||
tracing_subscriber::fmt().pretty().init();
|
||||
|
||||
// Create an agent with the STRINGPROCESSOR tool
|
||||
let string_agent = providers::openai::Client::from_env()
|
||||
.agent(providers::openai::GPT_4O)
|
||||
.preamble("You are an agent with tools access, always use the tools")
|
||||
.max_tokens(1024)
|
||||
.tool(StringProcessor)
|
||||
.build();
|
||||
|
||||
// Print out the tool definition to verify
|
||||
println!("Tool definition:");
|
||||
println!(
|
||||
"STRINGPROCESSOR: {}",
|
||||
serde_json::to_string_pretty(&StringProcessor.definition(String::default()).await).unwrap()
|
||||
);
|
||||
|
||||
// Test prompts
|
||||
for prompt in [
|
||||
"What tools do you have?",
|
||||
"Convert 'hello world' to uppercase",
|
||||
"Convert 'HELLO WORLD' to lowercase",
|
||||
"Reverse the string 'hello world'",
|
||||
"Convert 'hello world' to uppercase and repeat it 3 times",
|
||||
"Perform an invalid operation on 'hello world'",
|
||||
] {
|
||||
println!("User: {}", prompt);
|
||||
println!("Agent: {}", string_agent.prompt(prompt).await.unwrap());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
use rig_macros::rig_tool;
|
||||
use rig::completion::Prompt;
|
||||
use rig::providers;
|
||||
use tracing_subscriber;
|
||||
|
||||
// Simple example with no attributes
|
||||
#[rig_tool]
|
||||
fn add(a: i32, b: i32) -> Result<i32, rig::tool::ToolError> {
|
||||
Ok(a + b)
|
||||
}
|
||||
|
||||
#[rig_tool]
|
||||
fn subtract(a: i32, b: i32) -> Result<i32, rig::tool::ToolError> {
|
||||
Ok(a - b)
|
||||
}
|
||||
|
||||
#[rig_tool]
|
||||
fn multiply(a: i32, b: i32) -> Result<i32, rig::tool::ToolError> {
|
||||
Ok(a * b)
|
||||
}
|
||||
|
||||
#[rig_tool]
|
||||
fn divide(a: i32, b: i32) -> Result<i32, rig::tool::ToolError> {
|
||||
if b == 0 {
|
||||
Err(rig::tool::ToolError::ToolCallError("Division by zero".into()))
|
||||
} else {
|
||||
Ok(a / b)
|
||||
}
|
||||
}
|
||||
|
||||
#[rig_tool]
|
||||
fn answer_secret_question() -> Result<(bool, bool, bool, bool, bool), rig::tool::ToolError> {
|
||||
Ok((false, false, true, false, false))
|
||||
}
|
||||
|
||||
#[rig_tool]
|
||||
fn how_many_rs(s: String) -> Result<usize, rig::tool::ToolError> {
|
||||
Ok(s.chars()
|
||||
.filter(|c| *c == 'r' || *c == 'R')
|
||||
.collect::<Vec<_>>()
|
||||
.len())
|
||||
}
|
||||
|
||||
#[rig_tool]
|
||||
fn sum_numbers(numbers: Vec<i64>) -> Result<i64, rig::tool::ToolError> {
|
||||
Ok(numbers.iter().sum())
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize tracing
|
||||
tracing_subscriber::fmt().pretty().init();
|
||||
|
||||
// Create an agent with the ADD tool
|
||||
let calculator_agent = providers::openai::Client::from_env()
|
||||
.agent(providers::openai::GPT_4O)
|
||||
.preamble("You are an agent with tools access, always use the tools")
|
||||
.max_tokens(1024)
|
||||
.tool(Add)
|
||||
.build();
|
||||
|
||||
// Test prompts
|
||||
for prompt in [
|
||||
"What tools do you have?",
|
||||
"Calculate 5 + 3",
|
||||
"What is 10 + 20?",
|
||||
"Add 100 and 200",
|
||||
] {
|
||||
println!("User: {}", prompt);
|
||||
println!("Agent: {}", calculator_agent.prompt(prompt).await.unwrap());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
use rig::completion::Prompt;
|
||||
use rig::providers;
|
||||
use rig::tool::Tool;
|
||||
use rig_macros::rig_tool;
|
||||
use tracing_subscriber;
|
||||
|
||||
// Example with description attribute
|
||||
#[rig_tool(description = "Perform basic arithmetic operations")]
|
||||
fn calculator(x: i32, y: i32, operation: String) -> Result<i32, rig::tool::ToolError> {
|
||||
match operation.as_str() {
|
||||
"add" => Ok(x + y),
|
||||
"subtract" => Ok(x - y),
|
||||
"multiply" => Ok(x * y),
|
||||
"divide" => {
|
||||
if y == 0 {
|
||||
Err(rig::tool::ToolError::ToolCallError(
|
||||
"Division by zero".into(),
|
||||
))
|
||||
} else {
|
||||
Ok(x / y)
|
||||
}
|
||||
}
|
||||
_ => Err(rig::tool::ToolError::ToolCallError(
|
||||
format!("Unknown operation: {}", operation).into(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize tracing
|
||||
tracing_subscriber::fmt().pretty().init();
|
||||
|
||||
// Create an agent with the CALCULATOR tool
|
||||
let calculator_agent = providers::openai::Client::from_env()
|
||||
.agent(providers::openai::GPT_4O)
|
||||
.preamble("You are an agent with tools access, always use the tools")
|
||||
.max_tokens(1024)
|
||||
.tool(Calculator)
|
||||
.build();
|
||||
|
||||
// Print out the tool definition to verify
|
||||
println!("Tool definition:");
|
||||
println!(
|
||||
"CALCULATOR: {}",
|
||||
serde_json::to_string_pretty(&CALCULATOR.definition(String::default()).await).unwrap()
|
||||
);
|
||||
|
||||
// Test prompts
|
||||
for prompt in [
|
||||
"What tools do you have?",
|
||||
"Calculate 5 + 3",
|
||||
"What is 10 - 4?",
|
||||
"Multiply 6 and 7",
|
||||
"Divide 20 by 5",
|
||||
"What is 10 / 0?",
|
||||
] {
|
||||
println!("User: {}", prompt);
|
||||
println!("Agent: {}", calculator_agent.prompt(prompt).await.unwrap());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue