This commit is contained in:
461
examples/director_demo.exs
Normal file
461
examples/director_demo.exs
Normal file
@@ -0,0 +1,461 @@
|
||||
#!/usr/bin/env elixir
|
||||
|
||||
# Director Management Demo Script
|
||||
#
|
||||
# This script demonstrates the director role functionality:
|
||||
# 1. Register a director agent with oversight capabilities
|
||||
# 2. Register multiple standard agents for the director to manage
|
||||
# 3. Show director observing and managing other agents
|
||||
# 4. Demonstrate task assignment, feedback, and redundancy detection
|
||||
# 5. Show autonomous workflow coordination
|
||||
|
||||
Mix.install([
|
||||
{:agent_coordinator, path: "."}
|
||||
])
|
||||
|
||||
defmodule DirectorDemo do
|
||||
alias AgentCoordinator.{TaskRegistry, Inbox, Agent, Task}
|
||||
|
||||
def run do
|
||||
IO.puts("\n🎬 Director Management Demo Starting...")
|
||||
IO.puts("=" <> String.duplicate("=", 50))
|
||||
|
||||
# Start the Agent Coordinator application
|
||||
{:ok, _} = AgentCoordinator.Application.start(:normal, [])
|
||||
:timer.sleep(2000) # Give more time for startup
|
||||
|
||||
# Setup demo scenario
|
||||
setup_demo_scenario()
|
||||
|
||||
# Demonstrate director capabilities
|
||||
demo_director_observations()
|
||||
demo_task_management()
|
||||
demo_redundancy_detection()
|
||||
demo_autonomous_workflow()
|
||||
|
||||
IO.puts("\n✅ Director Management Demo Complete!")
|
||||
IO.puts("=" <> String.duplicate("=", 50))
|
||||
end
|
||||
|
||||
defp setup_demo_scenario do
|
||||
IO.puts("\n📋 Setting up demo scenario...")
|
||||
|
||||
# Register a global director
|
||||
director_opts = %{
|
||||
role: :director,
|
||||
oversight_scope: :global,
|
||||
capabilities: ["management", "coordination", "oversight", "coding"],
|
||||
workspace_path: "/home/ra/agent_coordinator",
|
||||
codebase_id: "agent_coordinator"
|
||||
}
|
||||
|
||||
{:ok, director_id} = TaskRegistry.register_agent("Director Phoenix Eagle", director_opts)
|
||||
IO.puts("✅ Registered Director: #{director_id}")
|
||||
|
||||
# Register several standard agents for the director to manage
|
||||
agents = [
|
||||
{"Frontend Developer Ruby Shark", %{capabilities: ["coding", "testing"], role: :standard}},
|
||||
{"Backend Engineer Silver Wolf", %{capabilities: ["coding", "analysis"], role: :standard}},
|
||||
{"QA Tester Golden Panda", %{capabilities: ["testing", "documentation"], role: :standard}},
|
||||
{"DevOps Engineer Blue Tiger", %{capabilities: ["coding", "review"], role: :standard}}
|
||||
]
|
||||
|
||||
agent_ids = Enum.map(agents, fn {name, opts} ->
|
||||
base_opts = Map.merge(opts, %{
|
||||
workspace_path: "/home/ra/agent_coordinator",
|
||||
codebase_id: "agent_coordinator"
|
||||
})
|
||||
{:ok, agent_id} = TaskRegistry.register_agent(name, base_opts)
|
||||
IO.puts("✅ Registered Agent: #{name} (#{agent_id})")
|
||||
|
||||
# Add some initial tasks to create realistic scenario
|
||||
add_demo_tasks(agent_id, name)
|
||||
|
||||
agent_id
|
||||
end)
|
||||
|
||||
%{director_id: director_id, agent_ids: agent_ids}
|
||||
end
|
||||
|
||||
defp add_demo_tasks(agent_id, agent_name) do
|
||||
tasks = case agent_name do
|
||||
"Frontend Developer" <> _ -> [
|
||||
{"Implement User Dashboard", "Create responsive dashboard with user stats and activity feed"},
|
||||
{"Fix CSS Layout Issues", "Resolve responsive design problems on mobile devices"},
|
||||
{"Add Dark Mode Support", "Implement theme switching with proper contrast ratios"}
|
||||
]
|
||||
"Backend Engineer" <> _ -> [
|
||||
{"Optimize Database Queries", "Review and optimize slow queries in user management system"},
|
||||
{"Implement API Rate Limiting", "Add rate limiting to prevent API abuse"},
|
||||
{"Fix Authentication Bug", "Resolve JWT token refresh issue causing user logouts"}
|
||||
]
|
||||
"QA Tester" <> _ -> [
|
||||
{"Write End-to-End Tests", "Create comprehensive test suite for user authentication flow"},
|
||||
{"Performance Testing", "Conduct load testing on API endpoints"},
|
||||
{"Fix Authentication Bug", "Validate JWT token refresh fix from backend team"} # Intentional duplicate
|
||||
]
|
||||
"DevOps Engineer" <> _ -> [
|
||||
{"Setup CI/CD Pipeline", "Configure automated testing and deployment pipeline"},
|
||||
{"Monitor System Performance", "Setup monitoring dashboards and alerting"},
|
||||
{"Optimize Database Queries", "Database performance tuning and indexing"} # Intentional duplicate
|
||||
]
|
||||
end
|
||||
|
||||
Enum.each(tasks, fn {title, description} ->
|
||||
task = Task.new(title, description, %{
|
||||
priority: Enum.random([:low, :normal, :high]),
|
||||
codebase_id: "agent_coordinator"
|
||||
})
|
||||
Inbox.add_task(agent_id, task)
|
||||
end)
|
||||
end
|
||||
|
||||
defp demo_director_observations do
|
||||
IO.puts("\n👁️ Director Observation Capabilities")
|
||||
IO.puts("-" <> String.duplicate("-", 40))
|
||||
|
||||
# Get the director agent
|
||||
agents = TaskRegistry.list_agents()
|
||||
director = Enum.find(agents, fn agent -> Agent.is_director?(agent) end)
|
||||
|
||||
if director do
|
||||
IO.puts("🔍 Director '#{director.name}' observing all agents...")
|
||||
|
||||
# Simulate director observing agents
|
||||
args = %{
|
||||
"agent_id" => director.id,
|
||||
"scope" => "codebase",
|
||||
"include_activity_history" => true
|
||||
}
|
||||
|
||||
# This would normally be called through MCP, but we'll call directly for demo
|
||||
result = observe_all_agents_demo(director, args)
|
||||
|
||||
case result do
|
||||
{:ok, observation} ->
|
||||
IO.puts("📊 Observation Results:")
|
||||
IO.puts(" - Total Agents: #{observation.total_agents}")
|
||||
IO.puts(" - Oversight Scope: #{observation.oversight_capability}")
|
||||
|
||||
Enum.each(observation.agents, fn agent_info ->
|
||||
task_count = %{
|
||||
pending: length(agent_info.tasks.pending),
|
||||
in_progress: if(agent_info.tasks.in_progress, do: 1, else: 0),
|
||||
completed: length(agent_info.tasks.completed)
|
||||
}
|
||||
|
||||
IO.puts(" 📋 #{agent_info.name}:")
|
||||
IO.puts(" Role: #{agent_info.role} | Status: #{agent_info.status}")
|
||||
IO.puts(" Tasks: #{task_count.pending} pending, #{task_count.in_progress} active, #{task_count.completed} done")
|
||||
IO.puts(" Capabilities: #{Enum.join(agent_info.capabilities, ", ")}")
|
||||
end)
|
||||
|
||||
{:error, reason} ->
|
||||
IO.puts("❌ Observation failed: #{reason}")
|
||||
end
|
||||
else
|
||||
IO.puts("❌ No director found in system")
|
||||
end
|
||||
end
|
||||
|
||||
defp observe_all_agents_demo(director, args) do
|
||||
# Simplified version of the actual function for demo
|
||||
all_agents = TaskRegistry.list_agents()
|
||||
|> Enum.filter(fn a -> a.codebase_id == director.codebase_id end)
|
||||
|
||||
detailed_agents = Enum.map(all_agents, fn target_agent ->
|
||||
task_info = case Inbox.list_tasks(target_agent.id) do
|
||||
{:error, _} -> %{pending: [], in_progress: nil, completed: []}
|
||||
tasks -> tasks
|
||||
end
|
||||
|
||||
%{
|
||||
agent_id: target_agent.id,
|
||||
name: target_agent.name,
|
||||
role: target_agent.role,
|
||||
capabilities: target_agent.capabilities,
|
||||
status: target_agent.status,
|
||||
codebase_id: target_agent.codebase_id,
|
||||
managed_by_director: target_agent.id in (director.managed_agents || []),
|
||||
tasks: task_info
|
||||
}
|
||||
end)
|
||||
|
||||
{:ok, %{
|
||||
director_id: director.id,
|
||||
scope: "codebase",
|
||||
oversight_capability: director.oversight_scope,
|
||||
agents: detailed_agents,
|
||||
total_agents: length(detailed_agents),
|
||||
timestamp: DateTime.utc_now()
|
||||
}}
|
||||
end
|
||||
|
||||
defp demo_task_management do
|
||||
IO.puts("\n📝 Director Task Management")
|
||||
IO.puts("-" <> String.duplicate("-", 40))
|
||||
|
||||
agents = TaskRegistry.list_agents()
|
||||
director = Enum.find(agents, fn agent -> Agent.is_director?(agent) end)
|
||||
standard_agents = Enum.filter(agents, fn agent -> !Agent.is_director?(agent) end)
|
||||
|
||||
if director && length(standard_agents) > 0 do
|
||||
target_agent = Enum.random(standard_agents)
|
||||
|
||||
IO.puts("🎯 Director assigning new task to #{target_agent.name}...")
|
||||
|
||||
# Create a high-priority coordination task
|
||||
new_task = %{
|
||||
"title" => "Team Coordination Meeting",
|
||||
"description" => "Organize cross-functional team sync to align on project priorities and resolve blockers. Focus on identifying dependencies between frontend, backend, and QA work streams.",
|
||||
"priority" => "high",
|
||||
"file_paths" => []
|
||||
}
|
||||
|
||||
# Director assigns the task
|
||||
task = Task.new(new_task["title"], new_task["description"], %{
|
||||
priority: :high,
|
||||
codebase_id: target_agent.codebase_id,
|
||||
assignment_reason: "Director identified need for team alignment",
|
||||
metadata: %{
|
||||
director_assigned: true,
|
||||
director_id: director.id
|
||||
}
|
||||
})
|
||||
|
||||
case Inbox.add_task(target_agent.id, task) do
|
||||
:ok ->
|
||||
IO.puts("✅ Task assigned successfully!")
|
||||
IO.puts(" Task: #{task.title}")
|
||||
IO.puts(" Assigned to: #{target_agent.name}")
|
||||
IO.puts(" Priority: #{task.priority}")
|
||||
IO.puts(" Reason: #{task.assignment_reason}")
|
||||
|
||||
# Update director's managed agents list
|
||||
updated_director = Agent.add_managed_agent(director, target_agent.id)
|
||||
TaskRegistry.update_agent(director.id, updated_director)
|
||||
|
||||
{:error, reason} ->
|
||||
IO.puts("❌ Task assignment failed: #{reason}")
|
||||
end
|
||||
|
||||
IO.puts("\n💬 Director providing task feedback...")
|
||||
|
||||
# Simulate director providing feedback on existing tasks
|
||||
{:ok, tasks} = Inbox.list_tasks(target_agent.id)
|
||||
if length(tasks.pending) > 0 do
|
||||
sample_task = Enum.random(tasks.pending)
|
||||
|
||||
feedback_examples = [
|
||||
"Consider breaking this task into smaller, more manageable subtasks for better tracking.",
|
||||
"This aligns well with the current sprint goals. Prioritize integration with the new API endpoints.",
|
||||
"Coordinate with the QA team before implementation to ensure test coverage is adequate.",
|
||||
"This task may have dependencies on the backend authentication work. Check with the backend team first."
|
||||
]
|
||||
|
||||
feedback = Enum.random(feedback_examples)
|
||||
|
||||
IO.puts("📋 Feedback for task '#{sample_task.title}':")
|
||||
IO.puts(" 💡 #{feedback}")
|
||||
IO.puts(" ⏰ Timestamp: #{DateTime.utc_now()}")
|
||||
end
|
||||
|
||||
else
|
||||
IO.puts("❌ No director or standard agents found for task management demo")
|
||||
end
|
||||
end
|
||||
|
||||
defp demo_redundancy_detection do
|
||||
IO.puts("\n🔍 Director Redundancy Detection")
|
||||
IO.puts("-" <> String.duplicate("-", 40))
|
||||
|
||||
agents = TaskRegistry.list_agents()
|
||||
director = Enum.find(agents, fn agent -> Agent.is_director?(agent) end)
|
||||
|
||||
if director do
|
||||
IO.puts("🔎 Analyzing tasks across all agents for redundancy...")
|
||||
|
||||
# Collect all tasks from all agents
|
||||
all_agents = Enum.filter(agents, fn a -> a.codebase_id == director.codebase_id end)
|
||||
all_tasks = Enum.flat_map(all_agents, fn agent ->
|
||||
case Inbox.list_tasks(agent.id) do
|
||||
{:error, _} -> []
|
||||
tasks ->
|
||||
(tasks.pending ++ (if tasks.in_progress, do: [tasks.in_progress], else: []))
|
||||
|> Enum.map(fn task -> Map.put(task, :agent_id, agent.id) end)
|
||||
end
|
||||
end)
|
||||
|
||||
IO.puts("📊 Total tasks analyzed: #{length(all_tasks)}")
|
||||
|
||||
# Detect redundant tasks (simplified similarity detection)
|
||||
redundant_groups = detect_similar_tasks_demo(all_tasks)
|
||||
|
||||
if length(redundant_groups) > 0 do
|
||||
IO.puts("⚠️ Found #{length(redundant_groups)} groups of potentially redundant tasks:")
|
||||
|
||||
Enum.each(redundant_groups, fn group ->
|
||||
IO.puts("\n 🔄 Redundant Group: '#{group.similarity_key}'")
|
||||
IO.puts(" Task count: #{group.task_count}")
|
||||
|
||||
Enum.each(group.tasks, fn task ->
|
||||
agent = Enum.find(agents, fn a -> a.id == task.agent_id end)
|
||||
agent_name = if agent, do: agent.name, else: "Unknown Agent"
|
||||
IO.puts(" - #{task.title} (#{agent_name})")
|
||||
end)
|
||||
|
||||
IO.puts(" 🎯 Recommendation: Consider consolidating these similar tasks or clearly define distinct responsibilities.")
|
||||
end)
|
||||
|
||||
total_redundant = Enum.sum(Enum.map(redundant_groups, fn g -> g.task_count end))
|
||||
IO.puts("\n📈 Impact Analysis:")
|
||||
IO.puts(" - Total redundant tasks: #{total_redundant}")
|
||||
IO.puts(" - Potential efficiency gain: #{round(total_redundant / length(all_tasks) * 100)}%")
|
||||
|
||||
else
|
||||
IO.puts("✅ No redundant tasks detected. Teams are well-coordinated!")
|
||||
end
|
||||
|
||||
else
|
||||
IO.puts("❌ No director found for redundancy detection")
|
||||
end
|
||||
end
|
||||
|
||||
defp detect_similar_tasks_demo(tasks) do
|
||||
# Group tasks by normalized title keywords
|
||||
tasks
|
||||
|> Enum.group_by(fn task ->
|
||||
# Normalize title for comparison
|
||||
String.downcase(task.title)
|
||||
|> String.replace(~r/[^\w\s]/, "")
|
||||
|> String.split()
|
||||
|> Enum.take(3)
|
||||
|> Enum.join(" ")
|
||||
end)
|
||||
|> Enum.filter(fn {_key, group_tasks} -> length(group_tasks) > 1 end)
|
||||
|> Enum.map(fn {key, group_tasks} ->
|
||||
%{
|
||||
similarity_key: key,
|
||||
tasks: Enum.map(group_tasks, fn task ->
|
||||
%{
|
||||
task_id: task.id,
|
||||
title: task.title,
|
||||
agent_id: task.agent_id,
|
||||
codebase_id: task.codebase_id
|
||||
}
|
||||
end),
|
||||
task_count: length(group_tasks)
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
defp demo_autonomous_workflow do
|
||||
IO.puts("\n🤖 Director Autonomous Workflow Coordination")
|
||||
IO.puts("-" <> String.duplicate("-", 50))
|
||||
|
||||
agents = TaskRegistry.list_agents()
|
||||
director = Enum.find(agents, fn agent -> Agent.is_director?(agent) end)
|
||||
standard_agents = Enum.filter(agents, fn agent -> !Agent.is_director?(agent) end)
|
||||
|
||||
if director && length(standard_agents) >= 2 do
|
||||
IO.puts("🎭 Simulating autonomous workflow coordination scenario...")
|
||||
IO.puts("\nScenario: Director detects that authentication bug fixes require coordination")
|
||||
IO.puts("between Backend Engineer and QA Tester.")
|
||||
|
||||
# Find agents working on authentication
|
||||
backend_agent = Enum.find(standard_agents, fn agent ->
|
||||
String.contains?(agent.name, "Backend")
|
||||
end)
|
||||
|
||||
qa_agent = Enum.find(standard_agents, fn agent ->
|
||||
String.contains?(agent.name, "QA")
|
||||
end)
|
||||
|
||||
if backend_agent && qa_agent do
|
||||
IO.puts("\n1️⃣ Director sending coordination input to Backend Engineer...")
|
||||
|
||||
coordination_message = """
|
||||
🤖 Director Coordination:
|
||||
|
||||
I've identified that your JWT authentication fix needs to be coordinated with QA testing.
|
||||
|
||||
Action Required:
|
||||
- Notify QA team when your fix is ready for testing
|
||||
- Provide test credentials and reproduction steps
|
||||
- Schedule knowledge transfer session if needed
|
||||
|
||||
This will help avoid testing delays and ensure comprehensive coverage.
|
||||
"""
|
||||
|
||||
# Simulate sending input to backend agent
|
||||
IO.puts("📤 Sending message to #{backend_agent.name}:")
|
||||
IO.puts(" Input Type: chat_message")
|
||||
IO.puts(" Content: [Coordination message about JWT fix coordination]")
|
||||
IO.puts(" Context: authentication_workflow_coordination")
|
||||
|
||||
IO.puts("\n2️⃣ Director sending parallel input to QA Tester...")
|
||||
|
||||
qa_message = """
|
||||
🤖 Director Coordination:
|
||||
|
||||
Backend team is working on JWT authentication fix. Please prepare for coordinated testing.
|
||||
|
||||
Action Required:
|
||||
- Review current authentication test cases
|
||||
- Prepare test environment for JWT token scenarios
|
||||
- Block time for testing once backend fix is ready
|
||||
|
||||
I'll facilitate the handoff between teams when implementation is complete.
|
||||
"""
|
||||
|
||||
IO.puts("📤 Sending message to #{qa_agent.name}:")
|
||||
IO.puts(" Input Type: chat_message")
|
||||
IO.puts(" Content: [Coordination message about authentication testing prep]")
|
||||
IO.puts(" Context: authentication_workflow_coordination")
|
||||
|
||||
IO.puts("\n3️⃣ Director scheduling follow-up coordination...")
|
||||
|
||||
# Create coordination task
|
||||
coordination_task = Task.new(
|
||||
"Authentication Fix Coordination Follow-up",
|
||||
"Check progress on JWT fix coordination between backend and QA teams. Ensure handoff is smooth and testing is proceeding without blockers.",
|
||||
%{
|
||||
priority: :normal,
|
||||
codebase_id: director.codebase_id,
|
||||
assignment_reason: "Autonomous workflow coordination",
|
||||
metadata: %{
|
||||
workflow_type: "authentication_coordination",
|
||||
involves_agents: [backend_agent.id, qa_agent.id],
|
||||
coordination_phase: "follow_up"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Inbox.add_task(director.id, coordination_task)
|
||||
IO.puts("✅ Created follow-up coordination task for director")
|
||||
|
||||
IO.puts("\n🎯 Autonomous Workflow Benefits Demonstrated:")
|
||||
IO.puts(" ✅ Proactive cross-team coordination")
|
||||
IO.puts(" ✅ Parallel communication to reduce delays")
|
||||
IO.puts(" ✅ Automated follow-up task creation")
|
||||
IO.puts(" ✅ Context-aware workflow management")
|
||||
IO.puts(" ✅ Human-out-of-the-loop efficiency")
|
||||
|
||||
IO.puts("\n🔮 Next Steps in Full Implementation:")
|
||||
IO.puts(" - VSCode integration for real agent messaging")
|
||||
IO.puts(" - Workflow templates for common coordination patterns")
|
||||
IO.puts(" - ML-based task dependency detection")
|
||||
IO.puts(" - Automated testing trigger coordination")
|
||||
IO.puts(" - Cross-codebase workflow orchestration")
|
||||
|
||||
else
|
||||
IO.puts("❌ Could not find Backend and QA agents for workflow demo")
|
||||
end
|
||||
else
|
||||
IO.puts("❌ Insufficient agents for autonomous workflow demonstration")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Run the demo
|
||||
DirectorDemo.run()
|
||||
Reference in New Issue
Block a user