ai-agents 0.1.2 → 0.2.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 +4 -4
- data/.claude/commands/bump-version.md +44 -0
- data/CHANGELOG.md +35 -0
- data/CLAUDE.md +59 -15
- data/README.md +29 -106
- data/docs/Gemfile +14 -0
- data/docs/Gemfile.lock +183 -0
- data/docs/_config.yml +53 -0
- data/docs/_sass/color_schemes/ruby.scss +72 -0
- data/docs/_sass/custom/custom.scss +93 -0
- data/docs/architecture.md +353 -0
- data/docs/assets/fonts/InterVariable.woff2 +0 -0
- data/docs/concepts/agent-tool.md +166 -0
- data/docs/concepts/agents.md +43 -0
- data/docs/concepts/callbacks.md +42 -0
- data/docs/concepts/context.md +110 -0
- data/docs/concepts/handoffs.md +81 -0
- data/docs/concepts/runner.md +87 -0
- data/docs/concepts/tools.md +62 -0
- data/docs/concepts.md +22 -0
- data/docs/guides/agent-as-tool-pattern.md +242 -0
- data/docs/guides/multi-agent-systems.md +261 -0
- data/docs/guides/rails-integration.md +440 -0
- data/docs/guides/state-persistence.md +451 -0
- data/docs/guides.md +18 -0
- data/docs/index.md +97 -0
- data/examples/collaborative-copilot/README.md +169 -0
- data/examples/collaborative-copilot/agents/analysis_agent.rb +48 -0
- data/examples/collaborative-copilot/agents/answer_suggestion_agent.rb +50 -0
- data/examples/collaborative-copilot/agents/copilot_orchestrator.rb +85 -0
- data/examples/collaborative-copilot/agents/integrations_agent.rb +58 -0
- data/examples/collaborative-copilot/agents/research_agent.rb +52 -0
- data/examples/collaborative-copilot/data/contacts.json +47 -0
- data/examples/collaborative-copilot/data/conversations.json +170 -0
- data/examples/collaborative-copilot/data/knowledge_base.json +58 -0
- data/examples/collaborative-copilot/data/linear_issues.json +83 -0
- data/examples/collaborative-copilot/data/stripe_billing.json +71 -0
- data/examples/collaborative-copilot/interactive.rb +90 -0
- data/examples/collaborative-copilot/tools/create_linear_ticket_tool.rb +58 -0
- data/examples/collaborative-copilot/tools/get_article_tool.rb +41 -0
- data/examples/collaborative-copilot/tools/get_contact_tool.rb +51 -0
- data/examples/collaborative-copilot/tools/get_conversation_tool.rb +53 -0
- data/examples/collaborative-copilot/tools/get_stripe_billing_tool.rb +44 -0
- data/examples/collaborative-copilot/tools/search_contacts_tool.rb +57 -0
- data/examples/collaborative-copilot/tools/search_conversations_tool.rb +54 -0
- data/examples/collaborative-copilot/tools/search_knowledge_base_tool.rb +55 -0
- data/examples/collaborative-copilot/tools/search_linear_issues_tool.rb +60 -0
- data/examples/isp-support/interactive.rb +43 -4
- data/lib/agents/agent.rb +34 -0
- data/lib/agents/agent_runner.rb +66 -1
- data/lib/agents/agent_tool.rb +113 -0
- data/lib/agents/callback_manager.rb +54 -0
- data/lib/agents/handoff.rb +8 -34
- data/lib/agents/message_extractor.rb +82 -0
- data/lib/agents/run_context.rb +5 -2
- data/lib/agents/runner.rb +16 -27
- data/lib/agents/tool_wrapper.rb +11 -1
- data/lib/agents/version.rb +1 -1
- data/lib/agents.rb +3 -0
- metadata +48 -1
data/lib/agents/runner.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "message_extractor"
|
4
|
+
|
3
5
|
module Agents
|
4
6
|
# The execution engine that orchestrates conversations between users and agents.
|
5
7
|
# Runner manages the conversation flow, handles tool execution through RubyLLM,
|
@@ -77,14 +79,15 @@ module Agents
|
|
77
79
|
# @param context [Hash] Shared context data accessible to all tools
|
78
80
|
# @param registry [Hash] Registry of agents for handoff resolution
|
79
81
|
# @param max_turns [Integer] Maximum conversation turns before stopping
|
82
|
+
# @param callbacks [Hash] Optional callbacks for real-time event notifications
|
80
83
|
# @return [RunResult] The result containing output, messages, and usage
|
81
|
-
def run(starting_agent, input, context: {}, registry: {}, max_turns: DEFAULT_MAX_TURNS)
|
84
|
+
def run(starting_agent, input, context: {}, registry: {}, max_turns: DEFAULT_MAX_TURNS, callbacks: {})
|
82
85
|
# The starting_agent is already determined by AgentRunner based on conversation history
|
83
86
|
current_agent = starting_agent
|
84
87
|
|
85
88
|
# Create context wrapper with deep copy for thread safety
|
86
89
|
context_copy = deep_copy_context(context)
|
87
|
-
context_wrapper = RunContext.new(context_copy)
|
90
|
+
context_wrapper = RunContext.new(context_copy, callbacks: callbacks)
|
88
91
|
current_turn = 0
|
89
92
|
|
90
93
|
# Create chat and restore conversation history
|
@@ -97,8 +100,12 @@ module Agents
|
|
97
100
|
|
98
101
|
# Get response from LLM (Extended Chat handles tool execution with handoff detection)
|
99
102
|
result = if current_turn == 1
|
103
|
+
# Emit agent thinking event for initial message
|
104
|
+
context_wrapper.callback_manager.emit_agent_thinking(current_agent.name, input)
|
100
105
|
chat.ask(input)
|
101
106
|
else
|
107
|
+
# Emit agent thinking event for continuation
|
108
|
+
context_wrapper.callback_manager.emit_agent_thinking(current_agent.name, "(continuing conversation)")
|
102
109
|
chat.complete
|
103
110
|
end
|
104
111
|
response = result
|
@@ -119,6 +126,9 @@ module Agents
|
|
119
126
|
# Save current conversation state before switching
|
120
127
|
save_conversation_state(chat, context_wrapper, current_agent)
|
121
128
|
|
129
|
+
# Emit agent handoff event
|
130
|
+
context_wrapper.callback_manager.emit_agent_handoff(current_agent.name, next_agent.name, "handoff")
|
131
|
+
|
122
132
|
# Switch to new agent - store agent name for persistence
|
123
133
|
current_agent = next_agent
|
124
134
|
context_wrapper.context[:current_agent] = next_agent.name
|
@@ -143,7 +153,7 @@ module Agents
|
|
143
153
|
|
144
154
|
return RunResult.new(
|
145
155
|
output: response.content,
|
146
|
-
messages: extract_messages(chat, current_agent),
|
156
|
+
messages: MessageExtractor.extract_messages(chat, current_agent),
|
147
157
|
usage: context_wrapper.usage,
|
148
158
|
context: context_wrapper.context
|
149
159
|
)
|
@@ -154,7 +164,7 @@ module Agents
|
|
154
164
|
|
155
165
|
RunResult.new(
|
156
166
|
output: "Conversation ended: #{e.message}",
|
157
|
-
messages: chat ? extract_messages(chat, current_agent) : [],
|
167
|
+
messages: chat ? MessageExtractor.extract_messages(chat, current_agent) : [],
|
158
168
|
usage: context_wrapper.usage,
|
159
169
|
error: e,
|
160
170
|
context: context_wrapper.context
|
@@ -165,7 +175,7 @@ module Agents
|
|
165
175
|
|
166
176
|
RunResult.new(
|
167
177
|
output: nil,
|
168
|
-
messages: chat ? extract_messages(chat, current_agent) : [],
|
178
|
+
messages: chat ? MessageExtractor.extract_messages(chat, current_agent) : [],
|
169
179
|
usage: context_wrapper.usage,
|
170
180
|
error: e,
|
171
181
|
context: context_wrapper.context
|
@@ -208,7 +218,7 @@ module Agents
|
|
208
218
|
|
209
219
|
def save_conversation_state(chat, context_wrapper, current_agent)
|
210
220
|
# Extract messages from chat
|
211
|
-
messages = extract_messages(chat, current_agent)
|
221
|
+
messages = MessageExtractor.extract_messages(chat, current_agent)
|
212
222
|
|
213
223
|
# Update context with latest state
|
214
224
|
context_wrapper.context[:conversation_history] = messages
|
@@ -244,26 +254,5 @@ module Agents
|
|
244
254
|
chat.with_tools(*wrapped_regular_tools) if wrapped_regular_tools.any?
|
245
255
|
chat
|
246
256
|
end
|
247
|
-
|
248
|
-
def extract_messages(chat, current_agent)
|
249
|
-
return [] unless chat.respond_to?(:messages)
|
250
|
-
|
251
|
-
chat.messages.filter_map do |msg|
|
252
|
-
# Only include user and assistant messages with content
|
253
|
-
next unless %i[user assistant].include?(msg.role)
|
254
|
-
next unless msg.content && !msg.content.strip.empty?
|
255
|
-
|
256
|
-
message = {
|
257
|
-
role: msg.role,
|
258
|
-
content: msg.content
|
259
|
-
}
|
260
|
-
|
261
|
-
# Add agent attribution for assistant messages to enable conversation continuity
|
262
|
-
# This allows AgentRunner to determine which agent should continue the conversation
|
263
|
-
message[:agent_name] = current_agent.name if msg.role == :assistant && current_agent
|
264
|
-
|
265
|
-
message
|
266
|
-
end
|
267
|
-
end
|
268
257
|
end
|
269
258
|
end
|
data/lib/agents/tool_wrapper.rb
CHANGED
@@ -46,7 +46,17 @@ module Agents
|
|
46
46
|
# RubyLLM calls this method (follows RubyLLM::Tool pattern)
|
47
47
|
def call(args)
|
48
48
|
tool_context = ToolContext.new(run_context: @context_wrapper)
|
49
|
-
|
49
|
+
|
50
|
+
@context_wrapper.callback_manager.emit_tool_start(@tool.name, args)
|
51
|
+
|
52
|
+
begin
|
53
|
+
result = @tool.execute(tool_context, **args.transform_keys(&:to_sym))
|
54
|
+
@context_wrapper.callback_manager.emit_tool_complete(@tool.name, result)
|
55
|
+
result
|
56
|
+
rescue StandardError => e
|
57
|
+
@context_wrapper.callback_manager.emit_tool_complete(@tool.name, "ERROR: #{e.message}")
|
58
|
+
raise
|
59
|
+
end
|
50
60
|
end
|
51
61
|
|
52
62
|
# Delegate metadata methods to the tool
|
data/lib/agents/version.rb
CHANGED
data/lib/agents.rb
CHANGED
@@ -80,5 +80,8 @@ require_relative "agents/agent"
|
|
80
80
|
# Execution components
|
81
81
|
require_relative "agents/chat"
|
82
82
|
require_relative "agents/tool_wrapper"
|
83
|
+
require_relative "agents/message_extractor"
|
84
|
+
require_relative "agents/callback_manager"
|
83
85
|
require_relative "agents/agent_runner"
|
84
86
|
require_relative "agents/runner"
|
87
|
+
require_relative "agents/agent_tool"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ai-agents
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shivam Mishra
|
@@ -31,13 +31,57 @@ executables: []
|
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
|
+
- ".claude/commands/bump-version.md"
|
34
35
|
- ".rspec"
|
35
36
|
- ".rubocop.yml"
|
37
|
+
- CHANGELOG.md
|
36
38
|
- CLAUDE.md
|
37
39
|
- LICENSE
|
38
40
|
- README.md
|
39
41
|
- Rakefile
|
42
|
+
- docs/Gemfile
|
43
|
+
- docs/Gemfile.lock
|
44
|
+
- docs/_config.yml
|
45
|
+
- docs/_sass/color_schemes/ruby.scss
|
46
|
+
- docs/_sass/custom/custom.scss
|
47
|
+
- docs/architecture.md
|
48
|
+
- docs/assets/fonts/InterVariable.woff2
|
49
|
+
- docs/concepts.md
|
50
|
+
- docs/concepts/agent-tool.md
|
51
|
+
- docs/concepts/agents.md
|
52
|
+
- docs/concepts/callbacks.md
|
53
|
+
- docs/concepts/context.md
|
54
|
+
- docs/concepts/handoffs.md
|
55
|
+
- docs/concepts/runner.md
|
56
|
+
- docs/concepts/tools.md
|
57
|
+
- docs/guides.md
|
58
|
+
- docs/guides/agent-as-tool-pattern.md
|
59
|
+
- docs/guides/multi-agent-systems.md
|
60
|
+
- docs/guides/rails-integration.md
|
61
|
+
- docs/guides/state-persistence.md
|
62
|
+
- docs/index.md
|
40
63
|
- examples/README.md
|
64
|
+
- examples/collaborative-copilot/README.md
|
65
|
+
- examples/collaborative-copilot/agents/analysis_agent.rb
|
66
|
+
- examples/collaborative-copilot/agents/answer_suggestion_agent.rb
|
67
|
+
- examples/collaborative-copilot/agents/copilot_orchestrator.rb
|
68
|
+
- examples/collaborative-copilot/agents/integrations_agent.rb
|
69
|
+
- examples/collaborative-copilot/agents/research_agent.rb
|
70
|
+
- examples/collaborative-copilot/data/contacts.json
|
71
|
+
- examples/collaborative-copilot/data/conversations.json
|
72
|
+
- examples/collaborative-copilot/data/knowledge_base.json
|
73
|
+
- examples/collaborative-copilot/data/linear_issues.json
|
74
|
+
- examples/collaborative-copilot/data/stripe_billing.json
|
75
|
+
- examples/collaborative-copilot/interactive.rb
|
76
|
+
- examples/collaborative-copilot/tools/create_linear_ticket_tool.rb
|
77
|
+
- examples/collaborative-copilot/tools/get_article_tool.rb
|
78
|
+
- examples/collaborative-copilot/tools/get_contact_tool.rb
|
79
|
+
- examples/collaborative-copilot/tools/get_conversation_tool.rb
|
80
|
+
- examples/collaborative-copilot/tools/get_stripe_billing_tool.rb
|
81
|
+
- examples/collaborative-copilot/tools/search_contacts_tool.rb
|
82
|
+
- examples/collaborative-copilot/tools/search_conversations_tool.rb
|
83
|
+
- examples/collaborative-copilot/tools/search_knowledge_base_tool.rb
|
84
|
+
- examples/collaborative-copilot/tools/search_linear_issues_tool.rb
|
41
85
|
- examples/isp-support/README.md
|
42
86
|
- examples/isp-support/agents_factory.rb
|
43
87
|
- examples/isp-support/data/customers.json
|
@@ -52,8 +96,11 @@ files:
|
|
52
96
|
- lib/agents.rb
|
53
97
|
- lib/agents/agent.rb
|
54
98
|
- lib/agents/agent_runner.rb
|
99
|
+
- lib/agents/agent_tool.rb
|
100
|
+
- lib/agents/callback_manager.rb
|
55
101
|
- lib/agents/chat.rb
|
56
102
|
- lib/agents/handoff.rb
|
103
|
+
- lib/agents/message_extractor.rb
|
57
104
|
- lib/agents/result.rb
|
58
105
|
- lib/agents/run_context.rb
|
59
106
|
- lib/agents/runner.rb
|