deepagents 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/LICENSE +21 -0
- data/README.md +237 -0
- data/Rakefile +17 -0
- data/examples/langchain_integration.rb +58 -0
- data/examples/research_agent.rb +180 -0
- data/lib/deepagents/deepagentsrb/errors.rb +80 -0
- data/lib/deepagents/deepagentsrb/graph.rb +213 -0
- data/lib/deepagents/deepagentsrb/models.rb +167 -0
- data/lib/deepagents/deepagentsrb/state.rb +139 -0
- data/lib/deepagents/deepagentsrb/sub_agent.rb +125 -0
- data/lib/deepagents/deepagentsrb/tools.rb +205 -0
- data/lib/deepagents/deepagentsrb/version.rb +3 -0
- data/lib/deepagents/errors.rb +80 -0
- data/lib/deepagents/graph.rb +207 -0
- data/lib/deepagents/models.rb +217 -0
- data/lib/deepagents/state.rb +139 -0
- data/lib/deepagents/sub_agent.rb +130 -0
- data/lib/deepagents/tools.rb +152 -0
- data/lib/deepagents/version.rb +3 -0
- data/lib/deepagents.rb +61 -0
- metadata +150 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
require_relative 'errors'
|
2
|
+
|
3
|
+
module DeepAgents
|
4
|
+
# Todo class for managing todos
|
5
|
+
class Todo
|
6
|
+
attr_accessor :content, :status
|
7
|
+
|
8
|
+
def initialize(content, status = "pending")
|
9
|
+
raise ArgumentError, "Todo content cannot be nil or empty" if content.nil? || content.empty?
|
10
|
+
@content = content
|
11
|
+
@status = validate_status(status)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_h
|
15
|
+
{
|
16
|
+
content: @content,
|
17
|
+
status: @status
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.from_h(hash)
|
22
|
+
content = hash[:content] || hash["content"]
|
23
|
+
status = hash[:status] || hash["status"] || "pending"
|
24
|
+
|
25
|
+
raise ArgumentError, "Todo hash must contain content" if content.nil?
|
26
|
+
new(content, status)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def validate_status(status)
|
32
|
+
valid_statuses = ["pending", "in_progress", "completed"]
|
33
|
+
status = status.to_s.downcase
|
34
|
+
|
35
|
+
unless valid_statuses.include?(status)
|
36
|
+
raise ArgumentError, "Invalid todo status: #{status}. Must be one of: #{valid_statuses.join(', ')}"
|
37
|
+
end
|
38
|
+
|
39
|
+
status
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Deep agent state class
|
44
|
+
class DeepAgentState
|
45
|
+
attr_reader :todos, :files, :messages
|
46
|
+
|
47
|
+
def initialize
|
48
|
+
@todos = []
|
49
|
+
@files = {}
|
50
|
+
@messages = []
|
51
|
+
end
|
52
|
+
|
53
|
+
def todos=(value)
|
54
|
+
@todos = validate_todos(value)
|
55
|
+
end
|
56
|
+
|
57
|
+
def files=(value)
|
58
|
+
raise ArgumentError, "Files must be a hash" unless value.is_a?(Hash)
|
59
|
+
@files = value
|
60
|
+
end
|
61
|
+
|
62
|
+
def messages=(value)
|
63
|
+
raise ArgumentError, "Messages must be an array" unless value.is_a?(Array)
|
64
|
+
@messages = value
|
65
|
+
end
|
66
|
+
|
67
|
+
def get(key, default = nil)
|
68
|
+
case key.to_s
|
69
|
+
when "todos"
|
70
|
+
@todos
|
71
|
+
when "files"
|
72
|
+
@files
|
73
|
+
when "messages"
|
74
|
+
@messages
|
75
|
+
else
|
76
|
+
default
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def update(todos: nil, files: nil, messages: nil)
|
81
|
+
begin
|
82
|
+
if todos
|
83
|
+
@todos = validate_todos(todos)
|
84
|
+
end
|
85
|
+
|
86
|
+
if files
|
87
|
+
raise ArgumentError, "Files must be a hash" unless files.is_a?(Hash)
|
88
|
+
@files.merge!(files)
|
89
|
+
end
|
90
|
+
|
91
|
+
if messages
|
92
|
+
raise ArgumentError, "Messages must be an array" unless messages.is_a?(Array)
|
93
|
+
@messages += messages
|
94
|
+
end
|
95
|
+
rescue => e
|
96
|
+
raise StateError, "Failed to update state: #{e.message}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def [](key)
|
101
|
+
get(key)
|
102
|
+
end
|
103
|
+
|
104
|
+
def []=(key, value)
|
105
|
+
case key.to_s
|
106
|
+
when "todos"
|
107
|
+
self.todos = value
|
108
|
+
when "files"
|
109
|
+
self.files = value
|
110
|
+
when "messages"
|
111
|
+
self.messages = value
|
112
|
+
else
|
113
|
+
raise ArgumentError, "Unknown state key: #{key}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_h
|
118
|
+
{
|
119
|
+
todos: @todos.map(&:to_h),
|
120
|
+
files: @files,
|
121
|
+
messages: @messages
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def validate_todos(todos)
|
128
|
+
raise ArgumentError, "Todos must be an array" unless todos.is_a?(Array)
|
129
|
+
|
130
|
+
todos.map do |todo|
|
131
|
+
if todo.is_a?(Todo)
|
132
|
+
todo
|
133
|
+
else
|
134
|
+
Todo.from_h(todo)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require_relative 'errors'
|
2
|
+
require_relative 'state'
|
3
|
+
|
4
|
+
module DeepAgents
|
5
|
+
# SubAgent class for creating and managing sub-agents
|
6
|
+
class SubAgent
|
7
|
+
attr_reader :name, :instructions, :tools, :model, :state
|
8
|
+
|
9
|
+
def initialize(name, instructions, tools = [], model = nil)
|
10
|
+
raise ArgumentError, "Sub-agent name cannot be nil or empty" if name.nil? || name.empty?
|
11
|
+
raise ArgumentError, "Sub-agent instructions cannot be nil or empty" if instructions.nil? || instructions.empty?
|
12
|
+
|
13
|
+
@name = name
|
14
|
+
@instructions = instructions
|
15
|
+
@tools = tools
|
16
|
+
@model = model
|
17
|
+
@state = DeepAgentState.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(input, max_iterations = 10)
|
21
|
+
raise ArgumentError, "Model must be provided to run the sub-agent" unless @model
|
22
|
+
|
23
|
+
prompt = build_prompt(input)
|
24
|
+
iterations = 0
|
25
|
+
messages = []
|
26
|
+
|
27
|
+
while iterations < max_iterations
|
28
|
+
iterations += 1
|
29
|
+
|
30
|
+
response = @model.generate(prompt, @tools)
|
31
|
+
|
32
|
+
if response[:tool_calls] && !response[:tool_calls].empty?
|
33
|
+
tool_call = response[:tool_calls].first
|
34
|
+
tool_name = tool_call[:name]
|
35
|
+
tool_args = tool_call[:arguments]
|
36
|
+
|
37
|
+
tool = find_tool(tool_name)
|
38
|
+
result = execute_tool(tool, tool_args)
|
39
|
+
|
40
|
+
messages << { role: "assistant", content: "I'll use the #{tool_name} tool." }
|
41
|
+
messages << { role: "system", content: "Tool result: #{result}" }
|
42
|
+
|
43
|
+
prompt = build_prompt(input, messages)
|
44
|
+
else
|
45
|
+
messages << { role: "assistant", content: response[:content] }
|
46
|
+
break
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if iterations >= max_iterations
|
51
|
+
raise MaxIterationsError.new(max_iterations)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the final response
|
55
|
+
messages.last[:content]
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def build_prompt(input, messages = [])
|
61
|
+
prompt = "You are a sub-agent named #{@name} with the following instructions:\n\n"
|
62
|
+
prompt += "#{@instructions}\n\n"
|
63
|
+
|
64
|
+
if @tools && !@tools.empty?
|
65
|
+
prompt += "You have access to the following tools:\n\n"
|
66
|
+
|
67
|
+
@tools.each do |tool|
|
68
|
+
prompt += "#{tool.name}: #{tool.description}\n"
|
69
|
+
prompt += "Parameters: #{tool.parameters.join(', ')}\n\n"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
prompt += "Input: #{input}\n\n"
|
74
|
+
|
75
|
+
if messages && !messages.empty?
|
76
|
+
prompt += "Previous messages:\n\n"
|
77
|
+
|
78
|
+
messages.each do |message|
|
79
|
+
prompt += "#{message[:role]}: #{message[:content]}\n\n"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
prompt
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_tool(name)
|
87
|
+
tool = @tools.find { |t| t.name == name }
|
88
|
+
raise ToolNotFoundError.new(name) unless tool
|
89
|
+
tool
|
90
|
+
end
|
91
|
+
|
92
|
+
def execute_tool(tool, args)
|
93
|
+
begin
|
94
|
+
if args.is_a?(Hash)
|
95
|
+
tool.call(**args)
|
96
|
+
else
|
97
|
+
tool.call(args)
|
98
|
+
end
|
99
|
+
rescue => e
|
100
|
+
"Error executing tool: #{e.message}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# SubAgentRegistry class for managing sub-agents
|
106
|
+
class SubAgentRegistry
|
107
|
+
def initialize
|
108
|
+
@agents = {}
|
109
|
+
end
|
110
|
+
|
111
|
+
def register(agent)
|
112
|
+
raise ArgumentError, "Agent must be a SubAgent instance" unless agent.is_a?(SubAgent)
|
113
|
+
@agents[agent.name] = agent
|
114
|
+
end
|
115
|
+
|
116
|
+
def get(name)
|
117
|
+
agent = @agents[name]
|
118
|
+
raise SubAgentNotFoundError.new(name) unless agent
|
119
|
+
agent
|
120
|
+
end
|
121
|
+
|
122
|
+
def list
|
123
|
+
@agents.values
|
124
|
+
end
|
125
|
+
|
126
|
+
def names
|
127
|
+
@agents.keys
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require_relative 'errors'
|
2
|
+
|
3
|
+
module DeepAgents
|
4
|
+
# Tool class for defining tools that can be used by the agent
|
5
|
+
class Tool
|
6
|
+
attr_reader :name, :description, :parameters, :function
|
7
|
+
|
8
|
+
def initialize(name, description, parameters = [], &block)
|
9
|
+
raise ArgumentError, "Tool name cannot be nil or empty" if name.nil? || name.empty?
|
10
|
+
raise ArgumentError, "Tool description cannot be nil or empty" if description.nil? || description.empty?
|
11
|
+
raise ArgumentError, "Tool function block must be provided" unless block_given?
|
12
|
+
|
13
|
+
@name = name
|
14
|
+
@description = description
|
15
|
+
@parameters = parameters
|
16
|
+
@function = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(*args, **kwargs)
|
20
|
+
begin
|
21
|
+
@function.call(*args, **kwargs)
|
22
|
+
rescue => e
|
23
|
+
raise ToolError.new(@name, e.message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_h
|
28
|
+
{
|
29
|
+
name: @name,
|
30
|
+
description: @description,
|
31
|
+
parameters: @parameters
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# ToolRegistry class for managing tools
|
37
|
+
class ToolRegistry
|
38
|
+
def initialize
|
39
|
+
@tools = {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def register(tool)
|
43
|
+
raise ArgumentError, "Tool must be a Tool instance" unless tool.is_a?(Tool)
|
44
|
+
@tools[tool.name] = tool
|
45
|
+
end
|
46
|
+
|
47
|
+
def get(name)
|
48
|
+
tool = @tools[name]
|
49
|
+
raise ToolNotFoundError.new(name) unless tool
|
50
|
+
tool
|
51
|
+
end
|
52
|
+
|
53
|
+
def list
|
54
|
+
@tools.values
|
55
|
+
end
|
56
|
+
|
57
|
+
def names
|
58
|
+
@tools.keys
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_h
|
62
|
+
@tools.transform_values(&:to_h)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# FileSystem class for managing virtual files
|
67
|
+
class FileSystem
|
68
|
+
def initialize(initial_files = {})
|
69
|
+
@files = initial_files
|
70
|
+
end
|
71
|
+
|
72
|
+
def read(path)
|
73
|
+
file = @files[path]
|
74
|
+
raise FileNotFoundError.new(path) unless file
|
75
|
+
file
|
76
|
+
end
|
77
|
+
|
78
|
+
def write(path, content)
|
79
|
+
@files[path] = content
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete(path)
|
83
|
+
raise FileNotFoundError.new(path) unless @files.key?(path)
|
84
|
+
@files.delete(path)
|
85
|
+
end
|
86
|
+
|
87
|
+
def list
|
88
|
+
@files.keys
|
89
|
+
end
|
90
|
+
|
91
|
+
def exists?(path)
|
92
|
+
@files.key?(path)
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_h
|
96
|
+
@files
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Standard tools that can be used by the agent
|
101
|
+
module StandardTools
|
102
|
+
def self.file_system_tools(file_system)
|
103
|
+
[
|
104
|
+
Tool.new("read_file", "Read a file from the file system", ["path"]) do |path|
|
105
|
+
file_system.read(path)
|
106
|
+
end,
|
107
|
+
Tool.new("write_file", "Write content to a file in the file system", ["path", "content"]) do |path, content|
|
108
|
+
file_system.write(path, content)
|
109
|
+
"File written to #{path}"
|
110
|
+
end,
|
111
|
+
Tool.new("list_files", "List all files in the file system") do
|
112
|
+
file_system.list
|
113
|
+
end,
|
114
|
+
Tool.new("delete_file", "Delete a file from the file system", ["path"]) do |path|
|
115
|
+
file_system.delete(path)
|
116
|
+
"File deleted: #{path}"
|
117
|
+
end
|
118
|
+
]
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.todo_tools(state)
|
122
|
+
[
|
123
|
+
Tool.new("add_todo", "Add a new todo item", ["content"]) do |content|
|
124
|
+
todo = Todo.new(content)
|
125
|
+
state.todos << todo
|
126
|
+
"Todo added: #{content}"
|
127
|
+
end,
|
128
|
+
Tool.new("list_todos", "List all todo items") do
|
129
|
+
state.todos.map.with_index do |todo, index|
|
130
|
+
"#{index + 1}. [#{todo.status}] #{todo.content}"
|
131
|
+
end
|
132
|
+
end,
|
133
|
+
Tool.new("update_todo", "Update a todo item status", ["index", "status"]) do |index, status|
|
134
|
+
index = index.to_i - 1
|
135
|
+
if index < 0 || index >= state.todos.length
|
136
|
+
raise ArgumentError, "Invalid todo index: #{index + 1}"
|
137
|
+
end
|
138
|
+
|
139
|
+
todo = state.todos[index]
|
140
|
+
todo.status = status
|
141
|
+
"Todo updated: #{todo.content} - #{status}"
|
142
|
+
end
|
143
|
+
]
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.planning_tool
|
147
|
+
Tool.new("plan", "Create a plan for solving a task", ["task"]) do |task|
|
148
|
+
"Plan for #{task}:\n1. Analyze the requirements\n2. Break down into subtasks\n3. Implement each subtask\n4. Test the solution\n5. Refine as needed"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/lib/deepagents.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative "deepagents/version"
|
2
|
+
require_relative "deepagents/errors"
|
3
|
+
require_relative "deepagents/state"
|
4
|
+
require_relative "deepagents/tools"
|
5
|
+
require_relative "deepagents/sub_agent"
|
6
|
+
require_relative "deepagents/models"
|
7
|
+
require_relative "deepagents/graph"
|
8
|
+
|
9
|
+
# External dependencies
|
10
|
+
require "langchainrb"
|
11
|
+
require "langgraph_rb"
|
12
|
+
|
13
|
+
module DeepAgents
|
14
|
+
# Main entry point to create a deep agent
|
15
|
+
def self.create_deep_agent(tools, instructions, model: nil, subagents: nil, state_schema: nil)
|
16
|
+
begin
|
17
|
+
# Validate inputs
|
18
|
+
raise ArgumentError, "Tools must be an array" unless tools.is_a?(Array)
|
19
|
+
raise ArgumentError, "Instructions cannot be nil or empty" if instructions.nil? || instructions.empty?
|
20
|
+
|
21
|
+
# If model is a string, try to create an appropriate model adapter
|
22
|
+
if model.is_a?(String)
|
23
|
+
if model.downcase.include?("claude")
|
24
|
+
model = Models::Claude.new(model: model)
|
25
|
+
elsif model.downcase.include?("gpt") || model.downcase.include?("openai")
|
26
|
+
model = Models::OpenAI.new(model: model)
|
27
|
+
else
|
28
|
+
# Default to Claude if we can't determine the model type
|
29
|
+
model = Models::Claude.new(model: model)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Graph.create_deep_agent(tools, instructions, model: model, subagents: subagents, state_schema: state_schema)
|
34
|
+
rescue => e
|
35
|
+
# Wrap any errors in our own Error class
|
36
|
+
raise Error, "Failed to create deep agent: #{e.message}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convenience method to create a Claude model
|
41
|
+
def self.claude_model(api_key: nil, model: "claude-3-sonnet-20240229")
|
42
|
+
begin
|
43
|
+
Models::Claude.new(api_key: api_key, model: model)
|
44
|
+
rescue LoadError => e
|
45
|
+
raise Error, "Failed to create Claude model: The 'anthropic' gem is not installed. Please run 'gem install anthropic' or add it to your Gemfile."
|
46
|
+
rescue => e
|
47
|
+
raise Error, "Failed to create Claude model: #{e.message}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Convenience method to create an OpenAI model
|
52
|
+
def self.openai_model(api_key: nil, model: "gpt-4o")
|
53
|
+
begin
|
54
|
+
Models::OpenAI.new(api_key: api_key, model: model)
|
55
|
+
rescue LoadError => e
|
56
|
+
raise Error, "Failed to create OpenAI model: The 'openai' gem is not installed. Please run 'gem install openai' or add it to your Gemfile."
|
57
|
+
rescue => e
|
58
|
+
raise Error, "Failed to create OpenAI model: #{e.message}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: deepagents
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Davis
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-08-19 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: langchainrb
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0.6'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0.6'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: langgraph_rb
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.1'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.1'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: anthropic
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.1'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.1'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rake
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '13.0'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '13.0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rspec
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rubocop
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.21'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.21'
|
96
|
+
description: Ruby implementation of deepagents - a library for creating deep agents
|
97
|
+
with planning capabilities, sub-agent spawning, and a mock file system
|
98
|
+
email:
|
99
|
+
- chrisdavis179@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".rspec"
|
105
|
+
- LICENSE
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- examples/langchain_integration.rb
|
109
|
+
- examples/research_agent.rb
|
110
|
+
- lib/deepagents.rb
|
111
|
+
- lib/deepagents/deepagentsrb/errors.rb
|
112
|
+
- lib/deepagents/deepagentsrb/graph.rb
|
113
|
+
- lib/deepagents/deepagentsrb/models.rb
|
114
|
+
- lib/deepagents/deepagentsrb/state.rb
|
115
|
+
- lib/deepagents/deepagentsrb/sub_agent.rb
|
116
|
+
- lib/deepagents/deepagentsrb/tools.rb
|
117
|
+
- lib/deepagents/deepagentsrb/version.rb
|
118
|
+
- lib/deepagents/errors.rb
|
119
|
+
- lib/deepagents/graph.rb
|
120
|
+
- lib/deepagents/models.rb
|
121
|
+
- lib/deepagents/state.rb
|
122
|
+
- lib/deepagents/sub_agent.rb
|
123
|
+
- lib/deepagents/tools.rb
|
124
|
+
- lib/deepagents/version.rb
|
125
|
+
homepage: https://github.com/cdaviis/deepagents
|
126
|
+
licenses:
|
127
|
+
- MIT
|
128
|
+
metadata:
|
129
|
+
homepage_uri: https://github.com/cdaviis/deepagents
|
130
|
+
source_code_uri: https://github.com/cdaviis/deepagents
|
131
|
+
changelog_uri: https://github.com/cdaviis/deepagents/blob/main/CHANGELOG.md
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 2.7.0
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubygems_version: 3.6.2
|
147
|
+
specification_version: 4
|
148
|
+
summary: General purpose 'deep agent' with sub-agent spawning, todo list capabilities,
|
149
|
+
and mock file system for Ruby
|
150
|
+
test_files: []
|