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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/bump-version.md +44 -0
  3. data/CHANGELOG.md +35 -0
  4. data/CLAUDE.md +59 -15
  5. data/README.md +29 -106
  6. data/docs/Gemfile +14 -0
  7. data/docs/Gemfile.lock +183 -0
  8. data/docs/_config.yml +53 -0
  9. data/docs/_sass/color_schemes/ruby.scss +72 -0
  10. data/docs/_sass/custom/custom.scss +93 -0
  11. data/docs/architecture.md +353 -0
  12. data/docs/assets/fonts/InterVariable.woff2 +0 -0
  13. data/docs/concepts/agent-tool.md +166 -0
  14. data/docs/concepts/agents.md +43 -0
  15. data/docs/concepts/callbacks.md +42 -0
  16. data/docs/concepts/context.md +110 -0
  17. data/docs/concepts/handoffs.md +81 -0
  18. data/docs/concepts/runner.md +87 -0
  19. data/docs/concepts/tools.md +62 -0
  20. data/docs/concepts.md +22 -0
  21. data/docs/guides/agent-as-tool-pattern.md +242 -0
  22. data/docs/guides/multi-agent-systems.md +261 -0
  23. data/docs/guides/rails-integration.md +440 -0
  24. data/docs/guides/state-persistence.md +451 -0
  25. data/docs/guides.md +18 -0
  26. data/docs/index.md +97 -0
  27. data/examples/collaborative-copilot/README.md +169 -0
  28. data/examples/collaborative-copilot/agents/analysis_agent.rb +48 -0
  29. data/examples/collaborative-copilot/agents/answer_suggestion_agent.rb +50 -0
  30. data/examples/collaborative-copilot/agents/copilot_orchestrator.rb +85 -0
  31. data/examples/collaborative-copilot/agents/integrations_agent.rb +58 -0
  32. data/examples/collaborative-copilot/agents/research_agent.rb +52 -0
  33. data/examples/collaborative-copilot/data/contacts.json +47 -0
  34. data/examples/collaborative-copilot/data/conversations.json +170 -0
  35. data/examples/collaborative-copilot/data/knowledge_base.json +58 -0
  36. data/examples/collaborative-copilot/data/linear_issues.json +83 -0
  37. data/examples/collaborative-copilot/data/stripe_billing.json +71 -0
  38. data/examples/collaborative-copilot/interactive.rb +90 -0
  39. data/examples/collaborative-copilot/tools/create_linear_ticket_tool.rb +58 -0
  40. data/examples/collaborative-copilot/tools/get_article_tool.rb +41 -0
  41. data/examples/collaborative-copilot/tools/get_contact_tool.rb +51 -0
  42. data/examples/collaborative-copilot/tools/get_conversation_tool.rb +53 -0
  43. data/examples/collaborative-copilot/tools/get_stripe_billing_tool.rb +44 -0
  44. data/examples/collaborative-copilot/tools/search_contacts_tool.rb +57 -0
  45. data/examples/collaborative-copilot/tools/search_conversations_tool.rb +54 -0
  46. data/examples/collaborative-copilot/tools/search_knowledge_base_tool.rb +55 -0
  47. data/examples/collaborative-copilot/tools/search_linear_issues_tool.rb +60 -0
  48. data/examples/isp-support/interactive.rb +43 -4
  49. data/lib/agents/agent.rb +34 -0
  50. data/lib/agents/agent_runner.rb +66 -1
  51. data/lib/agents/agent_tool.rb +113 -0
  52. data/lib/agents/callback_manager.rb +54 -0
  53. data/lib/agents/handoff.rb +8 -34
  54. data/lib/agents/message_extractor.rb +82 -0
  55. data/lib/agents/run_context.rb +5 -2
  56. data/lib/agents/runner.rb +16 -27
  57. data/lib/agents/tool_wrapper.rb +11 -1
  58. data/lib/agents/version.rb +1 -1
  59. data/lib/agents.rb +3 -0
  60. 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
@@ -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
- @tool.execute(tool_context, **args.transform_keys(&:to_sym))
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Agents
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
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.1.2
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