agentf 0.3.0 → 0.4.1

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.
data/lib/agentf/packs.rb CHANGED
@@ -14,11 +14,11 @@ module Agentf
14
14
  "description" => "Thin models/controllers with services, queries, presenters, and policy reviews.",
15
15
  "keywords" => %w[rails activerecord rspec pundit viewcomponent hotwire turbo stimulus],
16
16
  "workflow_templates" => {
17
- "feature" => %w[ARCHITECT EXPLORER SPECIALIST TESTER SECURITY REVIEWER DOCUMENTER],
18
- "bugfix" => %w[ARCHITECT DEBUGGER SPECIALIST TESTER SECURITY REVIEWER],
19
- "refactor" => %w[ARCHITECT EXPLORER SPECIALIST TESTER REVIEWER],
20
- "quick_fix" => %w[SPECIALIST TESTER REVIEWER],
21
- "exploration" => %w[EXPLORER]
17
+ "feature" => %w[PLANNER RESEARCHER ENGINEER QA_TESTER SECURITY_REVIEWER REVIEWER KNOWLEDGE_MANAGER],
18
+ "bugfix" => %w[PLANNER INCIDENT_RESPONDER ENGINEER QA_TESTER SECURITY_REVIEWER REVIEWER],
19
+ "refactor" => %w[PLANNER RESEARCHER ENGINEER QA_TESTER REVIEWER],
20
+ "quick_fix" => %w[ENGINEER QA_TESTER REVIEWER],
21
+ "exploration" => %w[RESEARCHER]
22
22
  }
23
23
  },
24
24
  "rails_37signals" => {
@@ -26,11 +26,11 @@ module Agentf
26
26
  "description" => "Resource-centric workflows favoring concerns, CRUD and model-rich patterns.",
27
27
  "keywords" => %w[rails concern crud closure model minitest hotwire],
28
28
  "workflow_templates" => {
29
- "feature" => %w[ARCHITECT EXPLORER SPECIALIST TESTER REVIEWER DOCUMENTER],
30
- "bugfix" => %w[ARCHITECT DEBUGGER SPECIALIST TESTER REVIEWER],
31
- "refactor" => %w[ARCHITECT SPECIALIST TESTER REVIEWER],
32
- "quick_fix" => %w[SPECIALIST REVIEWER],
33
- "exploration" => %w[EXPLORER]
29
+ "feature" => %w[PLANNER RESEARCHER ENGINEER QA_TESTER REVIEWER KNOWLEDGE_MANAGER],
30
+ "bugfix" => %w[PLANNER INCIDENT_RESPONDER ENGINEER QA_TESTER REVIEWER],
31
+ "refactor" => %w[PLANNER ENGINEER QA_TESTER REVIEWER],
32
+ "quick_fix" => %w[ENGINEER REVIEWER],
33
+ "exploration" => %w[RESEARCHER]
34
34
  }
35
35
  },
36
36
  "rails_feature_spec" => {
@@ -38,11 +38,11 @@ module Agentf
38
38
  "description" => "Feature-spec-first orchestration with planning and review emphasis.",
39
39
  "keywords" => %w[rails feature specification acceptance criteria],
40
40
  "workflow_templates" => {
41
- "feature" => %w[ARCHITECT EXPLORER DESIGNER SPECIALIST TESTER REVIEWER DOCUMENTER],
42
- "bugfix" => %w[ARCHITECT DEBUGGER SPECIALIST TESTER REVIEWER],
43
- "refactor" => %w[ARCHITECT EXPLORER SPECIALIST TESTER REVIEWER],
44
- "quick_fix" => %w[SPECIALIST REVIEWER],
45
- "exploration" => %w[EXPLORER]
41
+ "feature" => %w[PLANNER RESEARCHER UI_ENGINEER ENGINEER QA_TESTER REVIEWER KNOWLEDGE_MANAGER],
42
+ "bugfix" => %w[PLANNER INCIDENT_RESPONDER ENGINEER QA_TESTER REVIEWER],
43
+ "refactor" => %w[PLANNER RESEARCHER ENGINEER QA_TESTER REVIEWER],
44
+ "quick_fix" => %w[ENGINEER REVIEWER],
45
+ "exploration" => %w[RESEARCHER]
46
46
  }
47
47
  }
48
48
  }.freeze
@@ -61,18 +61,18 @@ module Agentf
61
61
  return { "error" => "Agent #{agent_name} not found" } unless agent
62
62
 
63
63
  result = case agent_name
64
- when "ARCHITECT"
65
- agent.plan_task(task)
66
- when "EXPLORER"
67
- query = context["explore_query"] || "*.rb"
68
- files = commands.fetch("explorer").glob(query)
69
- response = agent.explore(query)
70
- response["files"] = files
71
- response
72
- when "TESTER"
73
- source_file = context["source_file"] || "app/models/application_record.rb"
74
- tester_commands = commands.fetch("tester")
75
- tdd_phase = context["tdd_phase"] || "normal"
64
+ when Agentf::AgentRoles::PLANNER
65
+ agent.plan_task(task)
66
+ when Agentf::AgentRoles::RESEARCHER
67
+ query = context["explore_query"] || "*.rb"
68
+ files = commands.fetch("explorer").glob(query)
69
+ response = agent.explore(query)
70
+ response["files"] = files
71
+ response
72
+ when Agentf::AgentRoles::QA_TESTER
73
+ source_file = context["source_file"] || "app/models/application_record.rb"
74
+ tester_commands = commands.fetch("tester")
75
+ tdd_phase = context["tdd_phase"] || "normal"
76
76
 
77
77
  if tdd_phase == "red"
78
78
  failure_signature = "expected-failure:#{File.basename(source_file)}:#{Time.now.to_i}"
@@ -92,32 +92,32 @@ module Agentf
92
92
  response["failure_signature"] = context["tdd_failure_signature"]
93
93
  response
94
94
  end
95
- when "DEBUGGER"
96
- error = context["error"] || "No error provided"
97
- analysis = commands.fetch("debugger").parse_error(error)
98
- response = agent.diagnose(error, context: context["error_context"])
95
+ when Agentf::AgentRoles::INCIDENT_RESPONDER
96
+ error = context["error"] || "No error provided"
97
+ analysis = commands.fetch("debugger").parse_error(error)
98
+ response = agent.diagnose(error, context: context["error_context"])
99
99
  response["analysis"] = {
100
100
  "error_type" => analysis.error_type,
101
101
  "root_cause" => analysis.possible_causes,
102
102
  "suggested_fix" => analysis.suggested_fix
103
103
  }
104
104
  response
105
- when "DESIGNER"
106
- design_spec = context["design_spec"] || "Create a card component"
107
- spec = commands.fetch("designer").generate_component("GeneratedComponent", design_spec)
108
- response = agent.implement_design(design_spec)
109
- response["generated_code"] = spec.code
110
- response
111
- when "SPECIALIST"
112
- subtask = context["current_subtask"] || { "description" => task }
113
- agent.execute(subtask)
114
- when "SECURITY"
115
- agent.assess(task: task, context: context)
116
- when "REVIEWER"
117
- last_result = context["execution"] || {}
118
- agent.review(last_result)
119
- when "DOCUMENTER"
120
- agent.sync_docs("project")
105
+ when Agentf::AgentRoles::UI_ENGINEER
106
+ design_spec = context["design_spec"] || "Create a card component"
107
+ spec = commands.fetch("designer").generate_component("GeneratedComponent", design_spec)
108
+ response = agent.implement_design(design_spec)
109
+ response["generated_code"] = spec.code
110
+ response
111
+ when Agentf::AgentRoles::ENGINEER
112
+ subtask = context["current_subtask"] || { "description" => task }
113
+ agent.execute(subtask)
114
+ when Agentf::AgentRoles::SECURITY_REVIEWER
115
+ agent.assess(task: task, context: context)
116
+ when Agentf::AgentRoles::REVIEWER
117
+ last_result = context["execution"] || {}
118
+ agent.review(last_result)
119
+ when Agentf::AgentRoles::KNOWLEDGE_MANAGER
120
+ agent.sync_docs("project")
121
121
  else
122
122
  { "status" => "not_implemented" }
123
123
  end
@@ -133,11 +133,11 @@ module Agentf
133
133
  class OpenCode < Base
134
134
  def workflow_templates
135
135
  {
136
- "feature" => %w[ARCHITECT EXPLORER DESIGNER SPECIALIST TESTER SECURITY REVIEWER DOCUMENTER],
137
- "bugfix" => %w[ARCHITECT DEBUGGER SPECIALIST TESTER SECURITY REVIEWER],
138
- "quick_fix" => %w[SPECIALIST SECURITY REVIEWER],
139
- "exploration" => %w[EXPLORER],
140
- "refactor" => %w[ARCHITECT EXPLORER SPECIALIST TESTER SECURITY REVIEWER]
136
+ "feature" => %w[PLANNER RESEARCHER UI_ENGINEER ENGINEER QA_TESTER SECURITY_REVIEWER REVIEWER KNOWLEDGE_MANAGER],
137
+ "bugfix" => %w[PLANNER INCIDENT_RESPONDER ENGINEER QA_TESTER SECURITY_REVIEWER REVIEWER],
138
+ "quick_fix" => %w[ENGINEER SECURITY_REVIEWER REVIEWER],
139
+ "exploration" => %w[RESEARCHER],
140
+ "refactor" => %w[PLANNER RESEARCHER ENGINEER QA_TESTER SECURITY_REVIEWER REVIEWER]
141
141
  }
142
142
  end
143
143
  end
@@ -145,11 +145,11 @@ module Agentf
145
145
  class Copilot < Base
146
146
  def workflow_templates
147
147
  {
148
- "feature" => %w[ARCHITECT SPECIALIST TESTER SECURITY REVIEWER DOCUMENTER],
149
- "bugfix" => %w[DEBUGGER SPECIALIST TESTER SECURITY REVIEWER],
150
- "quick_fix" => %w[SPECIALIST REVIEWER],
151
- "exploration" => %w[EXPLORER],
152
- "refactor" => %w[ARCHITECT SPECIALIST TESTER REVIEWER]
148
+ "feature" => %w[PLANNER ENGINEER QA_TESTER SECURITY_REVIEWER REVIEWER KNOWLEDGE_MANAGER],
149
+ "bugfix" => %w[INCIDENT_RESPONDER ENGINEER QA_TESTER SECURITY_REVIEWER REVIEWER],
150
+ "quick_fix" => %w[ENGINEER REVIEWER],
151
+ "exploration" => %w[RESEARCHER],
152
+ "refactor" => %w[PLANNER ENGINEER QA_TESTER REVIEWER]
153
153
  }
154
154
  end
155
155
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Agentf
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.1"
5
5
  end
@@ -18,7 +18,7 @@ module Agentf
18
18
  def initialize(memory: nil, base_path: nil, provider: :opencode)
19
19
  @memory = memory || Agentf::Memory::RedisMemory.new
20
20
  @base_path = base_path || Agentf.config.base_path
21
- @name = "WORKFLOW_ENGINE"
21
+ @name = Agentf::AgentRoles::ORCHESTRATOR
22
22
  @provider_ref = provider
23
23
  @provider = build_provider(@provider_ref, pack: Agentf.config.default_pack)
24
24
 
@@ -37,15 +37,15 @@ module Agentf
37
37
  )
38
38
 
39
39
  @agents = {
40
- "ARCHITECT" => Agents::Architect.new(@memory),
41
- "SPECIALIST" => Agents::Specialist.new(@memory),
42
- "REVIEWER" => Agents::Reviewer.new(@memory),
43
- "DOCUMENTER" => Agents::Documenter.new(@memory),
44
- "EXPLORER" => Agents::Explorer.new(@memory, commands: @explorer_commands),
45
- "TESTER" => Agents::Tester.new(@memory, commands: @tester_commands),
46
- "DEBUGGER" => Agents::Debugger.new(@memory, commands: @debugger_commands),
47
- "DESIGNER" => Agents::Designer.new(@memory, commands: @designer_commands),
48
- "SECURITY" => Agents::Security.new(@memory, commands: @security_commands)
40
+ Agentf::AgentRoles::PLANNER => Agents::Architect.new(@memory),
41
+ Agentf::AgentRoles::ENGINEER => Agents::Specialist.new(@memory),
42
+ Agentf::AgentRoles::REVIEWER => Agents::Reviewer.new(@memory),
43
+ Agentf::AgentRoles::KNOWLEDGE_MANAGER => Agents::Documenter.new(@memory),
44
+ Agentf::AgentRoles::RESEARCHER => Agents::Explorer.new(@memory, commands: @explorer_commands),
45
+ Agentf::AgentRoles::QA_TESTER => Agents::Tester.new(@memory, commands: @tester_commands),
46
+ Agentf::AgentRoles::INCIDENT_RESPONDER => Agents::Debugger.new(@memory, commands: @debugger_commands),
47
+ Agentf::AgentRoles::UI_ENGINEER => Agents::Designer.new(@memory, commands: @designer_commands),
48
+ Agentf::AgentRoles::SECURITY_REVIEWER => Agents::Security.new(@memory, commands: @security_commands)
49
49
  }
50
50
 
51
51
  @workflow_state = {}
@@ -91,7 +91,7 @@ module Agentf
91
91
  persist_feature_intent(task: task, workflow_type: plan["workflow_type"], context: @workflow_state["context"])
92
92
 
93
93
  plan["agents_needed"].each do |agent_name|
94
- run_pre_specialist_tdd_cycle if agent_name == "SPECIALIST"
94
+ run_pre_specialist_tdd_cycle if agent_name == Agentf::AgentRoles::ENGINEER
95
95
  agent_result = execute_agent(agent_name)
96
96
  @workflow_state["results"] << { "agent" => agent_name, "result" => agent_result }
97
97
  @workflow_state["completed_agents"] << agent_name
@@ -156,12 +156,12 @@ module Agentf
156
156
  )
157
157
  )
158
158
 
159
- if agent_name == "TESTER"
159
+ if agent_name == Agentf::AgentRoles::QA_TESTER
160
160
  enriched_context["tdd_phase"] = @workflow_state.dig("tdd", "phase")
161
161
  enriched_context["tdd_failure_signature"] = @workflow_state.dig("tdd", "failure_signature")
162
162
  end
163
163
 
164
- if agent_name == "SPECIALIST"
164
+ if agent_name == Agentf::AgentRoles::ENGINEER
165
165
  enriched_context["tdd_phase"] = "green"
166
166
  enriched_context["expected_test_fix"] = @workflow_state.dig("tdd", "failure_signature")
167
167
  end
@@ -241,7 +241,7 @@ module Agentf
241
241
  return
242
242
  end
243
243
 
244
- if agent_name == "TESTER" && result["tdd_phase"] == "red" && result["passed"] == false
244
+ if agent_name == Agentf::AgentRoles::QA_TESTER && result["tdd_phase"] == "red" && result["passed"] == false
245
245
  @memory.store_pitfall(
246
246
  title: "TDD red phase captured",
247
247
  description: result["failure_signature"] || "Intentional failing test captured",
@@ -253,7 +253,7 @@ module Agentf
253
253
  return
254
254
  end
255
255
 
256
- if agent_name == "TESTER" && result["tdd_phase"] == "green" && result["passed"] == true
256
+ if agent_name == Agentf::AgentRoles::QA_TESTER && result["tdd_phase"] == "green" && result["passed"] == true
257
257
  @memory.store_success(
258
258
  title: "TDD green phase passed",
259
259
  description: "Resolved failing test signature: #{result['failure_signature']}",
@@ -280,7 +280,7 @@ module Agentf
280
280
  def summarize_workflow
281
281
  results = @workflow_state["results"]
282
282
  errors = results.select { |r| r["result"]["error"] }
283
- reviews = results.select { |r| r["agent"] == "REVIEWER" }
283
+ reviews = results.select { |r| r["agent"] == Agentf::AgentRoles::REVIEWER }
284
284
  approved = reviews.any? { |r| r["result"]["approved"] }
285
285
  contract_blocked = @workflow_state.dig("workflow_contract", "blocked") == true
286
286
 
@@ -312,11 +312,11 @@ module Agentf
312
312
 
313
313
  red_context = @workflow_state["context"].merge(
314
314
  "tdd_phase" => "red",
315
- "brain" => @context_builder.build(agent: "TESTER", workflow_state: @workflow_state, limit: 8)
315
+ "brain" => @context_builder.build(agent: Agentf::AgentRoles::QA_TESTER, workflow_state: @workflow_state, limit: 8)
316
316
  )
317
317
 
318
318
  red_result = @provider.execute_agent(
319
- agent_name: "TESTER",
319
+ agent_name: Agentf::AgentRoles::QA_TESTER,
320
320
  task: @workflow_state["task"],
321
321
  context: red_context,
322
322
  agents: @agents,
@@ -326,8 +326,8 @@ module Agentf
326
326
 
327
327
  tdd["red_executed"] = true
328
328
  tdd["failure_signature"] = red_result["failure_signature"]
329
- @workflow_state["results"] << { "agent" => "TESTER_TDD_RED", "result" => red_result }
330
- persist_agent_learning(agent_name: "TESTER", result: red_result)
329
+ @workflow_state["results"] << { "agent" => "QA_TESTER_TDD_RED", "result" => red_result }
330
+ persist_agent_learning(agent_name: Agentf::AgentRoles::QA_TESTER, result: red_result)
331
331
  rescue StandardError => e
332
332
  log "TDD red phase skipped: #{e.message}"
333
333
  end
@@ -336,13 +336,13 @@ module Agentf
336
336
  tdd = @workflow_state["tdd"]
337
337
  return unless tdd["enabled"]
338
338
 
339
- if agent_name == "SPECIALIST"
339
+ if agent_name == Agentf::AgentRoles::ENGINEER
340
340
  tdd["phase"] = "green"
341
- elsif agent_name == "TESTER" && tdd["phase"] == "green"
341
+ elsif agent_name == Agentf::AgentRoles::QA_TESTER && tdd["phase"] == "green"
342
342
  tdd["green_executed"] = true
343
343
  end
344
344
 
345
- return unless agent_name == "TESTER" && result["tdd_phase"] == "green"
345
+ return unless agent_name == Agentf::AgentRoles::QA_TESTER && result["tdd_phase"] == "green"
346
346
 
347
347
  tdd["failure_signature"] ||= result["failure_signature"]
348
348
  end
data/lib/agentf.rb CHANGED
@@ -6,6 +6,7 @@ require "time"
6
6
  require "securerandom"
7
7
  require "pathname"
8
8
  require_relative "agentf/version"
9
+ require_relative "agentf/agent_roles"
9
10
 
10
11
  module Agentf
11
12
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agentf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neal Deters
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-07 00:00:00.000000000 Z
11
+ date: 2026-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -81,9 +81,11 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.9.0
83
83
  description: |2
84
- A multi-agent system with Redis-backed memory for code execution,
85
- testing, debugging, and design implementation. Designed for
86
- frontend, backend, and API development workflows.
84
+ Agentf is a Ruby-native multi-agent workflow engine with an ORCHESTRATOR,
85
+ role-specialized agents, provider adapters (OpenCode/Copilot), and
86
+ Redis-backed semantic, episodic, and graph-style memory. It includes a
87
+ unified CLI, MCP server tools, and install/update workflows for generated
88
+ agent/command manifests.
87
89
  email:
88
90
  executables:
89
91
  - agentf
@@ -93,6 +95,7 @@ files:
93
95
  - bin/agentf
94
96
  - lib/agentf.rb
95
97
  - lib/agentf/agent_policy.rb
98
+ - lib/agentf/agent_roles.rb
96
99
  - lib/agentf/agents.rb
97
100
  - lib/agentf/agents/architect.rb
98
101
  - lib/agentf/agents/base.rb
@@ -124,6 +127,7 @@ files:
124
127
  - lib/agentf/context_builder.rb
125
128
  - lib/agentf/installer.rb
126
129
  - lib/agentf/mcp/server.rb
130
+ - lib/agentf/mcp/stub.rb
127
131
  - lib/agentf/memory.rb
128
132
  - lib/agentf/packs.rb
129
133
  - lib/agentf/service/providers.rb
@@ -160,5 +164,5 @@ requirements: []
160
164
  rubygems_version: 3.0.3.1
161
165
  signing_key:
162
166
  specification_version: 4
163
- summary: A self-learning swarm of agents with shared memory
167
+ summary: Ruby multi-agent workflow engine with Redis memory
164
168
  test_files: []