ai-agents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +26 -0
- data/CLAUDE.md +188 -0
- data/LICENSE +21 -0
- data/README.md +283 -0
- data/Rakefile +12 -0
- data/examples/README.md +64 -0
- data/examples/isp-support/README.md +121 -0
- data/examples/isp-support/agents_factory.rb +142 -0
- data/examples/isp-support/data/customers.json +133 -0
- data/examples/isp-support/data/docs.json +133 -0
- data/examples/isp-support/data/plans.json +86 -0
- data/examples/isp-support/interactive.rb +135 -0
- data/examples/isp-support/tools/create_checkout_tool.rb +16 -0
- data/examples/isp-support/tools/create_lead_tool.rb +15 -0
- data/examples/isp-support/tools/crm_lookup_tool.rb +28 -0
- data/examples/isp-support/tools/escalate_to_human_tool.rb +12 -0
- data/examples/isp-support/tools/search_docs_tool.rb +22 -0
- data/lib/agents/agent.rb +170 -0
- data/lib/agents/handoff.rb +116 -0
- data/lib/agents/result.rb +13 -0
- data/lib/agents/run_context.rb +106 -0
- data/lib/agents/runner.rb +233 -0
- data/lib/agents/tool.rb +153 -0
- data/lib/agents/tool_context.rb +98 -0
- data/lib/agents/tool_wrapper.rb +71 -0
- data/lib/agents/version.rb +5 -0
- data/lib/agents.rb +70 -0
- data/sig/ruby/agents.rbs +6 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3d23007ce65c6dae4c20025ad5cacb683652452a973472fa3c9fba1166606e57
|
4
|
+
data.tar.gz: 39b4522bd4ee7e329285a3806a4e06e5e312526e9139d4369bb7a12f4ede2d06
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc45c4328b0ec188abb77249ee3da9de9515251f2c872b8468c1704d49ea3765cb1dae285cad84c6fd1b644d6adde35073ddf09a6071c82b8ae7671ebbc67d52
|
7
|
+
data.tar.gz: 354a10db6fab8d2885c1bdd6e20e72086a9cd87e1a16b99c1b744f0c35b962b19b07aafcf7c0ca0301f30bccc0a8e3ba00de13807178e7d02ec16466ba002a79
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rspec
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
TargetRubyVersion: 3.1
|
6
|
+
|
7
|
+
Style/StringLiterals:
|
8
|
+
EnforcedStyle: double_quotes
|
9
|
+
|
10
|
+
Style/StringLiteralsInInterpolation:
|
11
|
+
EnforcedStyle: double_quotes
|
12
|
+
|
13
|
+
RSpec/MultipleExpectations:
|
14
|
+
Max: 10
|
15
|
+
|
16
|
+
RSpec/ExampleLength:
|
17
|
+
Max: 20
|
18
|
+
|
19
|
+
RSpec/MultipleMemoizedHelpers:
|
20
|
+
Max: 15
|
21
|
+
|
22
|
+
RSpec/SpecFilePathFormat:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Metrics/MethodLength:
|
26
|
+
Max: 20
|
data/CLAUDE.md
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
# CLAUDE.md
|
2
|
+
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
4
|
+
|
5
|
+
## Repository Overview
|
6
|
+
|
7
|
+
This is a Ruby AI Agents SDK that provides multi-agent orchestration capabilities, similar to OpenAI's Agents SDK but built for Ruby. The SDK enables the creation of sophisticated AI workflows with specialized agents, tool execution, and conversation handoffs.
|
8
|
+
|
9
|
+
**IMPORTANT**: This is a generic agent library. When implementing library code, ensure that:
|
10
|
+
- No domain-specific logic from examples (airline booking, FAQ, seat management, etc.) leaks into the core library
|
11
|
+
- The library remains agnostic to specific use cases
|
12
|
+
- All domain-specific implementations belong in the examples directory only
|
13
|
+
|
14
|
+
## Development Commands
|
15
|
+
|
16
|
+
### Building and Testing
|
17
|
+
```bash
|
18
|
+
# Install dependencies
|
19
|
+
bundle install
|
20
|
+
|
21
|
+
# Run tests with RSpec
|
22
|
+
rake spec
|
23
|
+
# OR
|
24
|
+
bundle exec rspec
|
25
|
+
|
26
|
+
# Run specific spec file
|
27
|
+
bundle exec rspec spec/agents/agent_spec.rb
|
28
|
+
|
29
|
+
# Run tests with coverage report
|
30
|
+
bundle exec rspec # SimpleCov will generate coverage/index.html
|
31
|
+
|
32
|
+
# Lint code (includes RSpec cops)
|
33
|
+
rake rubocop
|
34
|
+
# OR
|
35
|
+
bundle exec rubocop
|
36
|
+
|
37
|
+
# Auto-fix linting issues
|
38
|
+
bundle exec rubocop -a
|
39
|
+
|
40
|
+
# Run all checks (spec + lint)
|
41
|
+
rake
|
42
|
+
```
|
43
|
+
|
44
|
+
### Interactive Development
|
45
|
+
```bash
|
46
|
+
# Start interactive console
|
47
|
+
bin/console
|
48
|
+
|
49
|
+
# Run the airline booking demo
|
50
|
+
ruby examples/booking/interactive.rb
|
51
|
+
|
52
|
+
# Run automatic booking demo
|
53
|
+
ruby examples/booking/automatic.rb
|
54
|
+
```
|
55
|
+
|
56
|
+
## Architecture and Code Structure
|
57
|
+
|
58
|
+
### Core Components (Generic Library)
|
59
|
+
|
60
|
+
**lib/agents.rb** - Main module and configuration entry point. Configures both the Agents SDK and underlying RubyLLM library. Contains the `RECOMMENDED_HANDOFF_PROMPT_PREFIX` for multi-agent workflows.
|
61
|
+
|
62
|
+
**lib/agents/agent.rb** - The core `Agent` class with Ruby-like DSL for defining AI agents. Key features:
|
63
|
+
- Class-level configuration: `name`, `instructions`, `provider`, `model`, `uses`, `handoffs`
|
64
|
+
- Instance execution via `call` method with conversation history management
|
65
|
+
- Tool and handoff tool registration at runtime
|
66
|
+
- Context-aware execution with proper conversation history restoration using `chat.add_message`
|
67
|
+
- **No domain-specific logic** - remains completely generic
|
68
|
+
|
69
|
+
**lib/agents/tool.rb** - Base class for tools that agents can use. Inherits from `RubyLLM::Tool` and adds:
|
70
|
+
- Ruby-style parameter definitions with automatic JSON schema conversion
|
71
|
+
- Context injection through `perform` method (called by `execute`)
|
72
|
+
- Enhanced parameter definition supporting Ruby types (String, Integer, etc.)
|
73
|
+
- **Domain-agnostic** - specific tool implementations belong in user code
|
74
|
+
|
75
|
+
**lib/agents/handoff.rb** - Contains the handoff system classes:
|
76
|
+
- `HandoffResult` - Represents a handoff decision
|
77
|
+
- `AgentResponse` - Wraps agent responses with optional handoff results
|
78
|
+
- `HandoffTool` - Generic tool for transferring between agents using context-based signaling
|
79
|
+
- **Generic handoff mechanism** - no assumptions about specific agent types
|
80
|
+
|
81
|
+
**lib/agents/context.rb** - Base context class for sharing state between agents and tools across handoffs. Must be subclassed for domain-specific context. The base class provides only generic state management capabilities.
|
82
|
+
|
83
|
+
**lib/agents/runner.rb** - Execution engine for orchestrating multi-agent workflows (future implementation).
|
84
|
+
|
85
|
+
### Key Design Patterns
|
86
|
+
|
87
|
+
#### Agent Definition Pattern (Generic)
|
88
|
+
```ruby
|
89
|
+
class MyAgent < Agents::Agent
|
90
|
+
name "Agent Name"
|
91
|
+
instructions "Behavior description" # Can be dynamic via Proc
|
92
|
+
provider :openai # Optional, defaults to configured provider
|
93
|
+
model "gpt-4o" # Optional, defaults to configured model
|
94
|
+
|
95
|
+
uses SomeTool # Register tools by class
|
96
|
+
handoffs OtherAgent, AnotherAgent # Define possible handoff targets
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
#### Tool Definition Pattern (Generic)
|
101
|
+
```ruby
|
102
|
+
class MyTool < Agents::Tool
|
103
|
+
description "What this tool does"
|
104
|
+
param :input_param, String, "Parameter description"
|
105
|
+
param :optional_param, Integer, "Optional param", required: false
|
106
|
+
|
107
|
+
def perform(input_param:, optional_param: nil, context:)
|
108
|
+
# context is always available for state management
|
109
|
+
# Must implement perform, not execute
|
110
|
+
# Tool logic should be domain-specific in user implementations
|
111
|
+
"Tool result"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
#### Context-Based Handoff System
|
117
|
+
The handoff system uses context signaling rather than text parsing:
|
118
|
+
1. `HandoffTool` instances are created automatically from `handoffs` declarations
|
119
|
+
2. When called, `HandoffTool.perform` sets `context[:pending_handoff]`
|
120
|
+
3. `Agent.detect_handoff_from_context` checks for pending handoffs after LLM responses
|
121
|
+
4. Interactive systems handle handoffs by switching to the target agent class
|
122
|
+
|
123
|
+
#### Conversation History Management
|
124
|
+
Critical for multi-turn conversations:
|
125
|
+
- Agents maintain `@conversation_history` as array of `{user:, assistant:, timestamp:}` hashes
|
126
|
+
- `restore_conversation_history(chat)` uses `chat.add_message(role:, content:)` to restore RubyLLM chat state
|
127
|
+
- This prevents agents from "forgetting" previous conversation turns
|
128
|
+
|
129
|
+
### Configuration Rules
|
130
|
+
|
131
|
+
#### Class Naming
|
132
|
+
- Use flat naming like `class Agents::Tool` instead of nested declarations
|
133
|
+
- Follow Ruby naming conventions for agent and tool classes
|
134
|
+
|
135
|
+
#### Documentation
|
136
|
+
- Always write doc strings when writing functions
|
137
|
+
- Use YARD format for documentation
|
138
|
+
- Always write RDoc for new methods
|
139
|
+
- When creating a new file, start the file with a description comment on what the file has and where does it fit in the project
|
140
|
+
|
141
|
+
#### Model Defaults
|
142
|
+
- Default model for OpenAI provider is `gpt-4.1-mini` (configured in lib/agents.rb)
|
143
|
+
- Can be overridden in agent classes or runtime configuration
|
144
|
+
|
145
|
+
### Examples Structure
|
146
|
+
|
147
|
+
**examples/booking/** - Complete airline booking demo showcasing multi-agent workflows. This is just one example of how the SDK can be used. The example demonstrates:
|
148
|
+
- Multi-agent workflow patterns
|
149
|
+
- Context sharing between agents
|
150
|
+
- Tool usage patterns
|
151
|
+
- Interactive CLI and automatic execution modes
|
152
|
+
- Proper handoff handling
|
153
|
+
|
154
|
+
Note: The airline booking scenario is purely demonstrative. The SDK is not limited to or designed specifically for airline systems.
|
155
|
+
|
156
|
+
### Dependencies and Integration
|
157
|
+
|
158
|
+
**RubyLLM Integration** - Built on top of RubyLLM library for LLM communication:
|
159
|
+
- Agents SDK configures RubyLLM automatically via `Agents.configure`
|
160
|
+
- Tools inherit from `RubyLLM::Tool` but use enhanced `perform` method
|
161
|
+
- Conversation history restored using `chat.add_message`
|
162
|
+
- Debug mode available via `ENV["RUBYLLM_DEBUG"] = "true"`
|
163
|
+
|
164
|
+
**Provider Support** - Currently supports OpenAI through RubyLLM, extensible to other providers
|
165
|
+
|
166
|
+
### Important Implementation Details
|
167
|
+
|
168
|
+
1. **Conversation History**: Must call `restore_conversation_history(chat)` before each agent execution to maintain conversation state across turns.
|
169
|
+
|
170
|
+
2. **Tool Context Flow**: `RubyLLM.execute()` → `Agents::Tool.execute()` → `Tool.perform(context:, **args)` - the context injection happens in the base `Tool.execute` method.
|
171
|
+
|
172
|
+
3. **Handoff Detection**: Uses context-based detection (`@context[:pending_handoff]`) rather than parsing LLM responses for tool calls.
|
173
|
+
|
174
|
+
4. **Model Configuration**: Default model is `gpt-4.1-mini` but examples use `gpt-4o` for better performance.
|
175
|
+
|
176
|
+
5. **Thread Safety**: Agents are designed to be stateless with context passed through execution rather than stored in instance variables.
|
177
|
+
|
178
|
+
6. **Library vs Example Code**: The core library (lib/agents/*) must remain completely generic and free of domain-specific logic. All domain-specific implementations (airline booking, FAQ systems, etc.) belong exclusively in the examples directory.
|
179
|
+
|
180
|
+
### Testing Guidelines
|
181
|
+
|
182
|
+
When writing tests, follow the rules:
|
183
|
+
1. Avoid stubbing using allow_any_instance_of`
|
184
|
+
2. Each example block `it ... end` should have less than 20 lines
|
185
|
+
3. Example group should not have more than 10 memoized helpers, not more than 10 except statements
|
186
|
+
4. Never use `receive_message_chain`
|
187
|
+
5. When writing tests, always use verifying doubles and never normal doubles
|
188
|
+
```
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Chatwoot Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
<div align="center">
|
2
|
+
<br>
|
3
|
+
<br>
|
4
|
+
<p>
|
5
|
+
<img src="./.github/ruby-agent.png" width="200px"/>
|
6
|
+
<h1>Ruby Agents</h1>
|
7
|
+
</p>
|
8
|
+
<br>
|
9
|
+
<br>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
A Ruby SDK for building multi-agent AI workflows with seamless handoffs, inspired by OpenAI's Agents SDK but built specifically for Ruby developers.
|
13
|
+
|
14
|
+
## ✨ Features
|
15
|
+
|
16
|
+
- **🤖 Multi-Agent Orchestration**: Create specialized AI agents that work together
|
17
|
+
- **🔄 Seamless Handoffs**: Transparent agent-to-agent transfers (users never know!)
|
18
|
+
- **🛠️ Tool Integration**: Agents can use custom tools and functions
|
19
|
+
- **💾 Shared Context**: State management across agent interactions
|
20
|
+
- **🚀 Simple API**: One method call handles everything including handoffs
|
21
|
+
- **🔌 Provider Agnostic**: Works with OpenAI, Anthropic, and other LLM providers
|
22
|
+
|
23
|
+
## 🚀 Quick Start
|
24
|
+
|
25
|
+
### Installation
|
26
|
+
|
27
|
+
Add to your Gemfile:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem 'ai-agents'
|
31
|
+
```
|
32
|
+
|
33
|
+
### Basic Usage
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'agents'
|
37
|
+
|
38
|
+
# Configure with your API key
|
39
|
+
Agents.configure do |config|
|
40
|
+
config.openai_api_key = ENV['OPENAI_API_KEY']
|
41
|
+
end
|
42
|
+
|
43
|
+
# Create a simple agent
|
44
|
+
agent = Agents::Agent.new(
|
45
|
+
name: "Weather Assistant",
|
46
|
+
instructions: "Help users get weather information",
|
47
|
+
tools: [WeatherTool.new]
|
48
|
+
)
|
49
|
+
|
50
|
+
# Use the agent with the Runner
|
51
|
+
result = Agents::Runner.run(agent, "What's the weather like today?")
|
52
|
+
puts result.output
|
53
|
+
```
|
54
|
+
|
55
|
+
### Multi-Agent Workflows with Handoffs
|
56
|
+
|
57
|
+
The real power comes from multi-agent workflows with automatic handoffs:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# Create specialized agents
|
61
|
+
triage = Agents::Agent.new(
|
62
|
+
name: "Triage Agent",
|
63
|
+
instructions: "Route customers to the right specialist"
|
64
|
+
)
|
65
|
+
|
66
|
+
faq = Agents::Agent.new(
|
67
|
+
name: "FAQ Agent",
|
68
|
+
instructions: "Answer frequently asked questions",
|
69
|
+
tools: [FaqLookupTool.new]
|
70
|
+
)
|
71
|
+
|
72
|
+
support = Agents::Agent.new(
|
73
|
+
name: "Support Agent",
|
74
|
+
instructions: "Handle technical issues",
|
75
|
+
tools: [TicketTool.new]
|
76
|
+
)
|
77
|
+
|
78
|
+
# Wire up handoff relationships - clean and simple!
|
79
|
+
triage.register_handoffs(faq, support)
|
80
|
+
faq.register_handoffs(triage) # Can route back to triage
|
81
|
+
support.register_handoffs(triage) # Hub-and-spoke pattern
|
82
|
+
|
83
|
+
# Run a conversation with automatic handoffs
|
84
|
+
result = Agents::Runner.run(triage, "How many seats are on the plane?")
|
85
|
+
# User gets direct answer from FAQ agent without knowing about the handoff!
|
86
|
+
```
|
87
|
+
|
88
|
+
## 🏗️ Architecture
|
89
|
+
|
90
|
+
### Core Components
|
91
|
+
|
92
|
+
- **Agent**: Individual AI agents with specific roles and capabilities
|
93
|
+
- **Runner**: Orchestrates multi-agent conversations with automatic handoffs
|
94
|
+
- **Context**: Shared state management across agents
|
95
|
+
- **Tools**: Custom functions that agents can use
|
96
|
+
- **Handoffs**: Seamless transfers between specialized agents
|
97
|
+
|
98
|
+
### Agent Definition
|
99
|
+
|
100
|
+
Agents can be created in two ways:
|
101
|
+
|
102
|
+
#### Instance-based (Recommended for dynamic agents)
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
# Create agents as instances
|
106
|
+
agent = Agents::Agent.new(
|
107
|
+
name: "Customer Service",
|
108
|
+
instructions: "You are a helpful customer service agent.",
|
109
|
+
model: "gpt-4o",
|
110
|
+
tools: [EmailTool.new, TicketTool.new]
|
111
|
+
)
|
112
|
+
|
113
|
+
# Register handoffs after creation
|
114
|
+
agent.register_handoffs(technical_support, billing)
|
115
|
+
```
|
116
|
+
|
117
|
+
#### Class-based (Coming soon)
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class CustomerServiceAgent < Agents::Agent
|
121
|
+
name "Customer Service"
|
122
|
+
instructions <<~PROMPT
|
123
|
+
You are a helpful customer service agent.
|
124
|
+
Always be polite and professional.
|
125
|
+
PROMPT
|
126
|
+
|
127
|
+
model "gpt-4o"
|
128
|
+
uses EmailTool, TicketTool
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
### Custom Tools
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
class EmailTool < Agents::Tool
|
136
|
+
description "Send emails to customers"
|
137
|
+
param :to, String, "Email address"
|
138
|
+
param :subject, String, "Email subject"
|
139
|
+
param :body, String, "Email body"
|
140
|
+
|
141
|
+
def perform(to:, subject:, body:, context:)
|
142
|
+
# Send email logic here
|
143
|
+
"Email sent to #{to}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
148
|
+
### Handoff Patterns
|
149
|
+
|
150
|
+
#### Hub-and-Spoke Pattern (Recommended)
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
# Central triage agent routes to specialists
|
154
|
+
triage = Agents::Agent.new(name: "Triage")
|
155
|
+
billing = Agents::Agent.new(name: "Billing")
|
156
|
+
support = Agents::Agent.new(name: "Support")
|
157
|
+
|
158
|
+
# Triage can route to any specialist
|
159
|
+
triage.register_handoffs(billing, support)
|
160
|
+
|
161
|
+
# Specialists only route back to triage
|
162
|
+
billing.register_handoffs(triage)
|
163
|
+
support.register_handoffs(triage)
|
164
|
+
```
|
165
|
+
|
166
|
+
#### Circular Handoffs
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
# Agents can hand off to each other
|
170
|
+
sales = Agents::Agent.new(name: "Sales")
|
171
|
+
customer_info = Agents::Agent.new(name: "Customer Info")
|
172
|
+
|
173
|
+
# Both agents can transfer to each other
|
174
|
+
sales.register_handoffs(customer_info)
|
175
|
+
customer_info.register_handoffs(sales)
|
176
|
+
```
|
177
|
+
|
178
|
+
### Context Management
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
# Context is automatically managed by the Runner
|
182
|
+
context = {}
|
183
|
+
result = Agents::Runner.run(agent, "Hello", context: context)
|
184
|
+
|
185
|
+
# Access conversation history and agent state
|
186
|
+
puts context[:conversation_history]
|
187
|
+
puts context[:current_agent].name
|
188
|
+
```
|
189
|
+
|
190
|
+
## 📋 Examples
|
191
|
+
|
192
|
+
### ISP Customer Support
|
193
|
+
|
194
|
+
See the complete ISP support example in `examples/isp-support/`:
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
# Run the interactive demo
|
198
|
+
ruby examples/isp-support/interactive.rb
|
199
|
+
```
|
200
|
+
|
201
|
+
This showcases:
|
202
|
+
- **Triage Agent**: Routes customers to appropriate specialists
|
203
|
+
- **Customer Info Agent**: Handles account info and billing inquiries
|
204
|
+
- **Sales Agent**: Manages new connections and upgrades
|
205
|
+
- **Support Agent**: Provides technical troubleshooting
|
206
|
+
- **Hub-and-Spoke Handoffs**: Clean architecture pattern
|
207
|
+
|
208
|
+
### Airline Customer Service
|
209
|
+
|
210
|
+
See the airline booking example in `examples/booking/`:
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
# Run the interactive demo
|
214
|
+
ruby examples/booking/interactive.rb
|
215
|
+
```
|
216
|
+
|
217
|
+
This showcases:
|
218
|
+
- **Triage Agent**: Routes questions to specialists
|
219
|
+
- **FAQ Agent**: Answers questions about policies, seats, baggage
|
220
|
+
- **Seat Booking Agent**: Handles seat changes and updates
|
221
|
+
- **Seamless Handoffs**: Users never repeat their questions
|
222
|
+
|
223
|
+
### Sample Conversation
|
224
|
+
|
225
|
+
```
|
226
|
+
You: How many seats are on the plane?
|
227
|
+
|
228
|
+
Agent: The plane has a total of 120 seats, which includes 22 business
|
229
|
+
class seats and 98 economy seats. Exit rows are located at rows 4 and
|
230
|
+
16, and rows 5-8 are designated as Economy Plus, offering extra legroom.
|
231
|
+
```
|
232
|
+
|
233
|
+
Behind the scenes:
|
234
|
+
1. Triage Agent receives question
|
235
|
+
2. Automatically transfers to FAQ Agent
|
236
|
+
3. FAQ Agent processes original question and responds
|
237
|
+
4. User sees seamless experience!
|
238
|
+
|
239
|
+
## 🔧 Configuration
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
Agents.configure do |config|
|
243
|
+
# Provider API keys
|
244
|
+
config.openai_api_key = ENV['OPENAI_API_KEY']
|
245
|
+
config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
|
246
|
+
config.gemini_api_key = ENV['GEMINI_API_KEY']
|
247
|
+
|
248
|
+
# Defaults
|
249
|
+
config.default_provider = :openai
|
250
|
+
config.default_model = 'gpt-4o'
|
251
|
+
|
252
|
+
# Performance
|
253
|
+
config.request_timeout = 120
|
254
|
+
config.max_turns = 10
|
255
|
+
|
256
|
+
# Debugging
|
257
|
+
config.debug = true
|
258
|
+
end
|
259
|
+
```
|
260
|
+
|
261
|
+
## 🤝 Contributing
|
262
|
+
|
263
|
+
1. Fork the repository
|
264
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
265
|
+
3. Run tests (`rake test`)
|
266
|
+
4. Run linter (`rake rubocop`)
|
267
|
+
5. Commit your changes (`git commit -am 'Add amazing feature'`)
|
268
|
+
6. Push to the branch (`git push origin feature/amazing-feature`)
|
269
|
+
7. Open a Pull Request
|
270
|
+
|
271
|
+
## 📝 License
|
272
|
+
|
273
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
274
|
+
|
275
|
+
## 🙏 Acknowledgments
|
276
|
+
|
277
|
+
- Inspired by [OpenAI's Agents SDK](https://github.com/openai/agents)
|
278
|
+
- Built on top of [RubyLLM](https://rubyllm.com) for LLM integration
|
279
|
+
- Thanks to the Ruby community for continuous inspiration
|
280
|
+
|
281
|
+
---
|
282
|
+
|
283
|
+
**Built with ❤️ by the Chatwoot Team**
|
data/Rakefile
ADDED
data/examples/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Examples
|
2
|
+
|
3
|
+
This directory contains examples demonstrating how to use the Ruby Agents SDK.
|
4
|
+
|
5
|
+
## Prerequisites
|
6
|
+
|
7
|
+
1. **Set up your API key:**
|
8
|
+
```bash
|
9
|
+
export OPENAI_API_KEY=your_api_key_here
|
10
|
+
```
|
11
|
+
|
12
|
+
2. **Install dependencies:**
|
13
|
+
```bash
|
14
|
+
bundle install
|
15
|
+
```
|
16
|
+
|
17
|
+
## Running Examples
|
18
|
+
|
19
|
+
### Basic Usage
|
20
|
+
```bash
|
21
|
+
ruby examples/basic_usage.rb
|
22
|
+
```
|
23
|
+
|
24
|
+
This example demonstrates:
|
25
|
+
- Configuring the Agents gem
|
26
|
+
- Creating a simple tool with parameters
|
27
|
+
- Creating an agent that uses the tool
|
28
|
+
- Testing both tool and agent functionality
|
29
|
+
- Viewing conversation history
|
30
|
+
|
31
|
+
### Expected Output
|
32
|
+
|
33
|
+
The example will show:
|
34
|
+
- ✅ Configuration success message
|
35
|
+
- 🔧 Direct tool testing with different greeting styles
|
36
|
+
- 🤖 Agent conversations using the tool
|
37
|
+
- 📝 Conversation history with timestamps
|
38
|
+
|
39
|
+
## What You'll Learn
|
40
|
+
|
41
|
+
- How to configure the gem with `Agents.configure`
|
42
|
+
- How to create tools that extend `Agents::Tool`
|
43
|
+
- How to create agents that extend `Agents::Agent`
|
44
|
+
- How to use tools within agents
|
45
|
+
- How tools and agents integrate with RubyLLM
|
46
|
+
|
47
|
+
## Troubleshooting
|
48
|
+
|
49
|
+
### "No API keys configured" Error
|
50
|
+
Make sure you've set the `OPENAI_API_KEY` environment variable:
|
51
|
+
```bash
|
52
|
+
export OPENAI_API_KEY=sk-your-key-here
|
53
|
+
```
|
54
|
+
|
55
|
+
### Connection Errors
|
56
|
+
- Check your internet connection
|
57
|
+
- Verify your API key is valid
|
58
|
+
- Ensure you have sufficient API credits
|
59
|
+
|
60
|
+
### Ruby Version
|
61
|
+
Make sure you're using Ruby 3.1 or later:
|
62
|
+
```bash
|
63
|
+
ruby --version
|
64
|
+
```
|