Agent to agent hub communications. Conversation stalls because they ask questions now.
This commit is contained in:
parent
6eadf28c66
commit
fd66c81027
|
@ -52,7 +52,7 @@ public class IoASystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ConversationManager conversationManager(BedrockLanguageModel model, @Lazy WebSocketService webSocketService) {
|
public ConversationManager conversationManager(BedrockLanguageModel model, WebSocketService webSocketService) {
|
||||||
return new ConversationManager(model, webSocketService);
|
return new ConversationManager(model, webSocketService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,36 +122,38 @@ public class IoASystem {
|
||||||
WebSocketService webSocketService = context.getBean(WebSocketService.class);
|
WebSocketService webSocketService = context.getBean(WebSocketService.class);
|
||||||
ToolRegistry toolRegistry = context.getBean(ToolRegistry.class);
|
ToolRegistry toolRegistry = context.getBean(ToolRegistry.class);
|
||||||
ConversationManager conversationManager = context.getBean(ConversationManager.class);
|
ConversationManager conversationManager = context.getBean(ConversationManager.class);
|
||||||
|
BedrockLanguageModel model = context.getBean(BedrockLanguageModel.class);
|
||||||
|
|
||||||
|
|
||||||
// Register all agents
|
// Register all agents
|
||||||
agentRegistry.registerAgent("agent1", new AgentInfo("agent1", "General Assistant",
|
agentRegistry.registerAgent("agent1", new AgentInfo("agent1", "General Assistant",
|
||||||
Arrays.asList("general", "search"),
|
Arrays.asList("general", "search"),
|
||||||
Arrays.asList("webSearch", "getWeather", "setReminder"),
|
Arrays.asList("webSearch", "getWeather", "setReminder"),
|
||||||
treeOfThought, webSocketService, toolRegistry, conversationManager));
|
treeOfThought, webSocketService, toolRegistry, model));
|
||||||
agentRegistry.registerAgent("agent2", new AgentInfo("agent2", "Travel Expert",
|
agentRegistry.registerAgent("agent2", new AgentInfo("agent2", "Travel Expert",
|
||||||
Arrays.asList("travel", "booking"),
|
Arrays.asList("travel", "booking"),
|
||||||
Arrays.asList("bookTravel", "calculateDistance", "findRestaurants"),
|
Arrays.asList("bookTravel", "calculateDistance", "findRestaurants"),
|
||||||
treeOfThought, webSocketService, toolRegistry, conversationManager));
|
treeOfThought, webSocketService, toolRegistry, model));
|
||||||
agentRegistry.registerAgent("agent3", new AgentInfo("agent3", "Event Planner Extraordinaire",
|
agentRegistry.registerAgent("agent3", new AgentInfo("agent3", "Event Planner Extraordinaire",
|
||||||
Arrays.asList("event planning", "team management", "booking"),
|
Arrays.asList("event planning", "team management", "booking"),
|
||||||
Arrays.asList("findRestaurants", "bookTravel", "scheduleAppointment", "getWeather"),
|
Arrays.asList("findRestaurants", "bookTravel", "scheduleAppointment", "getWeather"),
|
||||||
treeOfThought, webSocketService, toolRegistry, conversationManager));
|
treeOfThought, webSocketService, toolRegistry, model));
|
||||||
agentRegistry.registerAgent("agent4", new AgentInfo("agent4", "Fitness Guru",
|
agentRegistry.registerAgent("agent4", new AgentInfo("agent4", "Fitness Guru",
|
||||||
Arrays.asList("health", "nutrition", "motivation"),
|
Arrays.asList("health", "nutrition", "motivation"),
|
||||||
Arrays.asList("findFitnessClasses", "getRecipe", "setReminder", "getWeather"),
|
Arrays.asList("findFitnessClasses", "getRecipe", "setReminder", "getWeather"),
|
||||||
treeOfThought, webSocketService, toolRegistry, conversationManager));
|
treeOfThought, webSocketService, toolRegistry, model));
|
||||||
agentRegistry.registerAgent("agent5", new AgentInfo("agent5", "Research Specialist",
|
agentRegistry.registerAgent("agent5", new AgentInfo("agent5", "Research Specialist",
|
||||||
Arrays.asList("research", "writing", "analysis"),
|
Arrays.asList("research", "writing", "analysis"),
|
||||||
Arrays.asList("webSearch", "getNewsUpdates", "translate", "compareProductPrices"),
|
Arrays.asList("webSearch", "getNewsUpdates", "translate", "compareProductPrices"),
|
||||||
treeOfThought, webSocketService, toolRegistry, conversationManager));
|
treeOfThought, webSocketService, toolRegistry, model));
|
||||||
agentRegistry.registerAgent("agent6", new AgentInfo("agent6", "Digital Marketing Expert",
|
agentRegistry.registerAgent("agent6", new AgentInfo("agent6", "Digital Marketing Expert",
|
||||||
Arrays.asList("marketing", "social media", "content creation"),
|
Arrays.asList("marketing", "social media", "content creation"),
|
||||||
Arrays.asList("webSearch", "getNewsUpdates", "scheduleAppointment", "getMovieRecommendations"),
|
Arrays.asList("webSearch", "getNewsUpdates", "scheduleAppointment", "getMovieRecommendations"),
|
||||||
treeOfThought, webSocketService, toolRegistry, conversationManager));
|
treeOfThought, webSocketService, toolRegistry, model));
|
||||||
agentRegistry.registerAgent("agent7", new AgentInfo("agent7", "Family Travel Coordinator",
|
agentRegistry.registerAgent("agent7", new AgentInfo("agent7", "Family Travel Coordinator",
|
||||||
Arrays.asList("travel", "family planning", "budgeting"),
|
Arrays.asList("travel", "family planning", "budgeting"),
|
||||||
Arrays.asList("bookTravel", "calculateDistance", "getWeather", "findRestaurants", "getFinancialAdvice"),
|
Arrays.asList("bookTravel", "calculateDistance", "getWeather", "findRestaurants", "getFinancialAdvice"),
|
||||||
treeOfThought, webSocketService, toolRegistry, conversationManager));
|
treeOfThought, webSocketService, toolRegistry, model));
|
||||||
|
|
||||||
// Create all tasks
|
// Create all tasks
|
||||||
List<Task> tasks = Arrays.asList(
|
List<Task> tasks = Arrays.asList(
|
||||||
|
@ -196,66 +198,18 @@ public class IoASystem {
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create a thread pool
|
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
|
||||||
|
|
||||||
for (Task task : tasks) {
|
for (Task task : tasks) {
|
||||||
|
taskManager.addTask(task); // Add each task to the TaskManager
|
||||||
System.out.println("\nProcessing task: " + task.getDescription());
|
System.out.println("\nProcessing task: " + task.getDescription());
|
||||||
List<AgentInfo> team = teamFormation.formTeam(task);
|
List<AgentInfo> team = teamFormation.formTeam(task);
|
||||||
System.out.println("Formed team: " + team);
|
System.out.println("Formed team: " + team);
|
||||||
|
|
||||||
if (!team.isEmpty()) {
|
if (!team.isEmpty()) {
|
||||||
// Create a conversation for the team
|
taskManager.executeTask(task.getId(), team);
|
||||||
String conversationId = conversationManager.createConversation();
|
System.out.println("Task result: " + task.getResult());
|
||||||
|
|
||||||
// Add team members to the conversation
|
|
||||||
for (AgentInfo agent : team) {
|
|
||||||
conversationManager.addParticipant(conversationId, agent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a CountDownLatch to wait for all agents to complete their tasks
|
|
||||||
CountDownLatch latch = new CountDownLatch(team.size());
|
|
||||||
|
|
||||||
// Assign the task to all team members and execute in parallel
|
|
||||||
for (AgentInfo agent : team) {
|
|
||||||
executorService.submit(() -> {
|
|
||||||
try {
|
|
||||||
Task agentTask = new Task(task.getId() + "_" + agent.getId(), task.getDescription(), task.getRequiredCapabilities(), task.getRequiredTools());
|
|
||||||
agentTask.setAssignedAgent(agent);
|
|
||||||
taskManager.addTask(agentTask);
|
|
||||||
taskManager.executeTask(agentTask.getId(), conversationId);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the conversation
|
|
||||||
conversationManager.startConversation(conversationId, "Let's work on the task: " + task.getDescription());
|
|
||||||
|
|
||||||
// Wait for all agents to complete their tasks
|
|
||||||
try {
|
|
||||||
latch.await(40, TimeUnit.MINUTES); // Wait for up to 5 minutes
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the result
|
|
||||||
String result = conversationManager.getConversationResult(conversationId);
|
|
||||||
System.out.println("Task result: " + result);
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println("No suitable agents found for this task. Consider updating the agent pool or revising the task requirements.");
|
System.out.println("No suitable agents found for this task. Consider updating the agent pool or revising the task requirements.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown the executor service
|
|
||||||
executorService.shutdown();
|
|
||||||
try {
|
|
||||||
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
|
|
||||||
executorService.shutdownNow();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
executorService.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package com.ioa.agent;
|
package com.ioa.agent;
|
||||||
|
|
||||||
|
import com.ioa.conversation.ConversationFSM;
|
||||||
import com.ioa.conversation.Message;
|
import com.ioa.conversation.Message;
|
||||||
import com.ioa.util.TreeOfThought;
|
import com.ioa.model.BedrockLanguageModel;
|
||||||
import com.ioa.service.WebSocketService;
|
import com.ioa.service.WebSocketService;
|
||||||
import com.ioa.tool.ToolRegistry;
|
import com.ioa.tool.ToolRegistry;
|
||||||
import com.ioa.conversation.ConversationFSM;
|
import com.ioa.util.TreeOfThought;
|
||||||
import com.ioa.conversation.ConversationManager;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -19,11 +18,11 @@ public class AgentInfo {
|
||||||
private TreeOfThought treeOfThought;
|
private TreeOfThought treeOfThought;
|
||||||
private WebSocketService webSocketService;
|
private WebSocketService webSocketService;
|
||||||
private ToolRegistry toolRegistry;
|
private ToolRegistry toolRegistry;
|
||||||
private final ConversationManager conversationManager;
|
private BedrockLanguageModel model;
|
||||||
|
|
||||||
public AgentInfo(String id, String name, List<String> capabilities, List<String> tools,
|
public AgentInfo(String id, String name, List<String> capabilities, List<String> tools,
|
||||||
TreeOfThought treeOfThought, WebSocketService webSocketService,
|
TreeOfThought treeOfThought, WebSocketService webSocketService,
|
||||||
ToolRegistry toolRegistry, ConversationManager conversationManager) {
|
ToolRegistry toolRegistry, BedrockLanguageModel model) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.capabilities = capabilities;
|
this.capabilities = capabilities;
|
||||||
|
@ -31,95 +30,29 @@ public class AgentInfo {
|
||||||
this.treeOfThought = treeOfThought;
|
this.treeOfThought = treeOfThought;
|
||||||
this.webSocketService = webSocketService;
|
this.webSocketService = webSocketService;
|
||||||
this.toolRegistry = toolRegistry;
|
this.toolRegistry = toolRegistry;
|
||||||
this.conversationManager = conversationManager;
|
this.model = model;
|
||||||
}
|
|
||||||
|
|
||||||
public void sendMessage(String conversationId, String content) {
|
|
||||||
conversationManager.postMessage(conversationId, this.id, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveMessage(Message message) {
|
public void receiveMessage(Message message) {
|
||||||
// Process the received message
|
// Process the received message
|
||||||
Map<String, Object> reasoningResult = treeOfThought.reason("Respond to message: " + message.getContent(), 2, 2);
|
String prompt = "You are " + name + " with capabilities: " + capabilities +
|
||||||
String response = (String) reasoningResult.get("response"); // Assuming the response is stored under the key "response"
|
"\nYou received a message: " + message.getContent() +
|
||||||
// Send the response back to the conversation
|
"\nHow would you respond or what actions would you take based on this message?";
|
||||||
sendMessage(message.getConversationId(), response);
|
String response = model.generate(prompt, null);
|
||||||
|
System.out.println("DEBUG: " + name + " processed message: " + message.getContent());
|
||||||
|
System.out.println("DEBUG: " + name + " response: " + response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getCapabilities() {
|
public void notifyTurn(ConversationFSM conversation) {
|
||||||
return this.capabilities;
|
String prompt = "You are " + name + " with capabilities: " + capabilities +
|
||||||
|
"\nIt's your turn to speak in the conversation. What would you like to say or do?";
|
||||||
|
String response = model.generate(prompt, null);
|
||||||
|
conversation.postMessage(new Message(conversation.getConversationId(), id, response));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
// Getters and setters
|
||||||
return this.id;
|
public String getId() { return id; }
|
||||||
}
|
public String getName() { return name; }
|
||||||
|
public List<String> getCapabilities() { return capabilities; }
|
||||||
public List<String> getTools() {
|
public List<String> getTools() { return tools; }
|
||||||
return this.tools;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "AgentInfo{id='" + id + "', name='" + name + "'}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String executeTask(String taskDescription) {
|
|
||||||
System.out.println("DEBUG: Agent " + id + " executing task: " + taskDescription);
|
|
||||||
webSocketService.sendUpdate("agent_task", Map.of("agentId", id, "task", taskDescription));
|
|
||||||
|
|
||||||
// Use Tree of Thought to decide on tools and actions
|
|
||||||
Map<String, Object> reasoning = treeOfThought.reason("Select tools and actions for task: " + taskDescription +
|
|
||||||
"\nAvailable tools: " + tools, 2, 2);
|
|
||||||
String reasoningString = formatReasoning(reasoning);
|
|
||||||
System.out.println("DEBUG: Agent " + id + " reasoning:\n" + reasoningString);
|
|
||||||
webSocketService.sendUpdate("agent_reasoning", Map.of("agentId", id, "reasoning", reasoningString));
|
|
||||||
|
|
||||||
// Extract tool selection from reasoning
|
|
||||||
List<String> selectedTools = extractToolSelection(reasoningString);
|
|
||||||
System.out.println("DEBUG: Agent " + id + " selected tools: " + selectedTools);
|
|
||||||
webSocketService.sendUpdate("agent_tools_selected", Map.of("agentId", id, "tools", selectedTools));
|
|
||||||
|
|
||||||
// Execute actions using selected tools
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
for (String tool : selectedTools) {
|
|
||||||
String actionResult = executeTool(tool, taskDescription);
|
|
||||||
result.append(actionResult).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
String finalResult = result.toString().trim();
|
|
||||||
System.out.println("DEBUG: Agent " + id + " task result: " + finalResult);
|
|
||||||
webSocketService.sendUpdate("agent_task_result", Map.of("agentId", id, "result", finalResult));
|
|
||||||
|
|
||||||
return finalResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatReasoning(Map<String, Object> reasoning) {
|
|
||||||
// Implement a method to format the reasoning tree into a string
|
|
||||||
// This is a placeholder implementation
|
|
||||||
return reasoning.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> extractToolSelection(String reasoning) {
|
|
||||||
// Implement a method to extract tool selection from reasoning
|
|
||||||
// This is a placeholder implementation
|
|
||||||
return new ArrayList<>(tools);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String executeTool(String tool, String context) {
|
|
||||||
System.out.println("DEBUG: Agent " + id + " executing tool: " + tool);
|
|
||||||
webSocketService.sendUpdate("agent_tool_execution", Map.of("agentId", id, "tool", tool));
|
|
||||||
|
|
||||||
// Placeholder for tool execution
|
|
||||||
// In a real implementation, you would call the actual tool method from the ToolRegistry
|
|
||||||
String result = "Simulated result of using " + tool + " for context: " + context;
|
|
||||||
|
|
||||||
System.out.println("DEBUG: Agent " + id + " tool result: " + result);
|
|
||||||
webSocketService.sendUpdate("agent_tool_result", Map.of("agentId", id, "tool", tool, "result", result));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void voteToFinish(String conversationId) {
|
|
||||||
conversationManager.postMessage(conversationId, this.id, "/vote");
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package com.ioa.conversation;
|
package com.ioa.conversation;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import com.ioa.agent.AgentInfo;
|
import com.ioa.agent.AgentInfo;
|
||||||
import com.ioa.model.BedrockLanguageModel;
|
import com.ioa.model.BedrockLanguageModel;
|
||||||
import com.ioa.service.WebSocketService;
|
import com.ioa.service.WebSocketService;
|
||||||
|
@ -8,9 +7,8 @@ import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ConversationFSM {
|
public class ConversationFSM {
|
||||||
|
@ -19,31 +17,42 @@ public class ConversationFSM {
|
||||||
private final WebSocketService webSocketService;
|
private final WebSocketService webSocketService;
|
||||||
private final Queue<Message> messageQueue;
|
private final Queue<Message> messageQueue;
|
||||||
private final List<AgentInfo> participants;
|
private final List<AgentInfo> participants;
|
||||||
|
private final Queue<AgentInfo> speakingQueue;
|
||||||
private final Map<String, Boolean> votes;
|
private final Map<String, Boolean> votes;
|
||||||
private final AtomicBoolean finished;
|
private final AtomicBoolean finished;
|
||||||
private String result;
|
private String result;
|
||||||
private final ScheduledExecutorService executorService;
|
private String conversationId;
|
||||||
|
|
||||||
public ConversationFSM(BedrockLanguageModel model, WebSocketService webSocketService) {
|
public ConversationFSM(BedrockLanguageModel model, WebSocketService webSocketService) {
|
||||||
this.executorService = Executors.newScheduledThreadPool(1);
|
|
||||||
this.currentState = ConversationState.DISCUSSION;
|
this.currentState = ConversationState.DISCUSSION;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.webSocketService = webSocketService;
|
this.webSocketService = webSocketService;
|
||||||
this.messageQueue = new ConcurrentLinkedQueue<>();
|
this.messageQueue = new ConcurrentLinkedQueue<>();
|
||||||
this.participants = new ArrayList<>();
|
this.participants = new ArrayList<>();
|
||||||
|
this.speakingQueue = new ConcurrentLinkedQueue<>();
|
||||||
this.votes = new HashMap<>();
|
this.votes = new HashMap<>();
|
||||||
this.finished = new AtomicBoolean(false);
|
this.finished = new AtomicBoolean(false);
|
||||||
this.result = "";
|
this.result = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initialize(String conversationId) {
|
||||||
|
this.conversationId = conversationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConversationId() {
|
||||||
|
return conversationId;
|
||||||
|
}
|
||||||
|
|
||||||
public void addParticipant(AgentInfo agent) {
|
public void addParticipant(AgentInfo agent) {
|
||||||
participants.add(agent);
|
participants.add(agent);
|
||||||
|
speakingQueue.offer(agent);
|
||||||
votes.put(agent.getId(), false);
|
votes.put(agent.getId(), false);
|
||||||
webSocketService.sendUpdate("conversation_participants", participants);
|
webSocketService.sendUpdate("conversation_participants", participants);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeParticipant(AgentInfo agent) {
|
public void removeParticipant(AgentInfo agent) {
|
||||||
participants.remove(agent);
|
participants.remove(agent);
|
||||||
|
speakingQueue.remove(agent);
|
||||||
votes.remove(agent.getId());
|
votes.remove(agent.getId());
|
||||||
webSocketService.sendUpdate("conversation_participants", participants);
|
webSocketService.sendUpdate("conversation_participants", participants);
|
||||||
}
|
}
|
||||||
|
@ -61,64 +70,53 @@ public class ConversationFSM {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMessage(Message message) {
|
private void handleMessage(Message message) {
|
||||||
if (message == null) {
|
if (message.getContent().startsWith("/vote")) {
|
||||||
System.out.println("DEBUG: Received null message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String content = message.getContent();
|
|
||||||
if (content == null) {
|
|
||||||
System.out.println("DEBUG: Message content is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("DEBUG: Received message: " + content);
|
|
||||||
|
|
||||||
if (content.startsWith("/vote")) {
|
|
||||||
handleVote(message.getSender());
|
handleVote(message.getSender());
|
||||||
} else {
|
} else {
|
||||||
String stateTransitionTask = "Decide the next conversation state based on this message: " + content +
|
broadcastMessage(message);
|
||||||
"\nCurrent state: " + currentState +
|
updateState(message);
|
||||||
"\nParticipants: " + participants +
|
notifyNextSpeaker();
|
||||||
"\nPossible states: " + Arrays.toString(ConversationState.values());
|
|
||||||
|
|
||||||
String reasoning = model.generate(stateTransitionTask, null);
|
|
||||||
|
|
||||||
String decisionPrompt = "Based on this reasoning:\n" + reasoning +
|
|
||||||
"\nProvide the next conversation state. Choose from: " +
|
|
||||||
Arrays.toString(ConversationState.values()) +
|
|
||||||
"\nResponse format: STATE: <state_name>";
|
|
||||||
String response = model.generate(decisionPrompt, null);
|
|
||||||
|
|
||||||
ConversationState newState = parseStateFromResponse(response);
|
|
||||||
transitionTo(newState);
|
|
||||||
|
|
||||||
// Broadcast the message to all participants
|
|
||||||
for (AgentInfo agent : participants) {
|
|
||||||
if (!agent.getId().equals(message.getSender())) {
|
|
||||||
agent.receiveMessage(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
webSocketService.sendUpdate("conversation_message", message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConversationState parseStateFromResponse(String response) {
|
private void broadcastMessage(Message message) {
|
||||||
String[] parts = response.split(":");
|
for (AgentInfo agent : participants) {
|
||||||
if (parts.length > 1) {
|
if (!agent.getId().equals(message.getSender())) {
|
||||||
String stateName = parts[1].trim().toUpperCase();
|
agent.receiveMessage(message);
|
||||||
try {
|
|
||||||
return ConversationState.valueOf(stateName);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
System.out.println("Invalid state name: " + stateName + ". Defaulting to DISCUSSION.");
|
|
||||||
return ConversationState.DISCUSSION;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Could not parse state from response: " + response + ". Defaulting to DISCUSSION.");
|
webSocketService.sendUpdate("conversation_message", message);
|
||||||
return ConversationState.DISCUSSION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateState(Message message) {
|
||||||
|
String stateTransitionTask = "Decide the next conversation state based on this message: " + message.getContent() +
|
||||||
|
"\nCurrent state: " + currentState +
|
||||||
|
"\nParticipants: " + participants;
|
||||||
|
|
||||||
|
String reasoning = model.generate(stateTransitionTask, null);
|
||||||
|
|
||||||
|
String decisionPrompt = "Based on this reasoning:\n" + reasoning +
|
||||||
|
"\nProvide the next conversation state (DISCUSSION,\n" + //
|
||||||
|
" TASK_GATHERING_INFO,\n" + //
|
||||||
|
" TASK,\n" + //
|
||||||
|
" TASK_PLANNING,\n" + //
|
||||||
|
" TASK_ASSIGNMENT,\n" + //
|
||||||
|
" EXECUTION,\n" + //
|
||||||
|
" CONCLUSION). Only give the single word answer in all caps only from the given options.";
|
||||||
|
String response = model.generate(decisionPrompt, null);
|
||||||
|
|
||||||
|
ConversationState newState = ConversationState.valueOf(response.trim());
|
||||||
|
transitionTo(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyNextSpeaker() {
|
||||||
|
AgentInfo nextSpeaker = speakingQueue.poll();
|
||||||
|
if (nextSpeaker != null) {
|
||||||
|
nextSpeaker.notifyTurn(this);
|
||||||
|
speakingQueue.offer(nextSpeaker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleVote(String agentId) {
|
private void handleVote(String agentId) {
|
||||||
votes.put(agentId, true);
|
votes.put(agentId, true);
|
||||||
checkVotes();
|
checkVotes();
|
||||||
|
@ -152,8 +150,7 @@ public class ConversationFSM {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getPossibleTransitions() {
|
private List<String> getPossibleTransitions() {
|
||||||
// This is a simplified version. You might want to implement more complex logic.
|
return Arrays.stream(ConversationState.values())
|
||||||
return Arrays.asList(ConversationState.values()).stream()
|
|
||||||
.map(Enum::name)
|
.map(Enum::name)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,15 @@ public class ConversationManager {
|
||||||
public String createConversation() {
|
public String createConversation() {
|
||||||
String conversationId = UUID.randomUUID().toString();
|
String conversationId = UUID.randomUUID().toString();
|
||||||
ConversationFSM conversation = new ConversationFSM(model, webSocketService);
|
ConversationFSM conversation = new ConversationFSM(model, webSocketService);
|
||||||
|
conversation.initialize(conversationId);
|
||||||
conversations.put(conversationId, conversation);
|
conversations.put(conversationId, conversation);
|
||||||
return conversationId;
|
return conversationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConversationFSM getConversation(String conversationId) {
|
||||||
|
return conversations.get(conversationId);
|
||||||
|
}
|
||||||
|
|
||||||
public void addParticipant(String conversationId, AgentInfo agent) {
|
public void addParticipant(String conversationId, AgentInfo agent) {
|
||||||
ConversationFSM conversation = conversations.get(conversationId);
|
ConversationFSM conversation = conversations.get(conversationId);
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
|
@ -48,6 +53,7 @@ public class ConversationManager {
|
||||||
ConversationFSM conversation = conversations.get(conversationId);
|
ConversationFSM conversation = conversations.get(conversationId);
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
|
Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );
|
||||||
System.out.println("WARNING: Attempting to post null content message");
|
System.out.println("WARNING: Attempting to post null content message");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.ioa.conversation;
|
||||||
public enum ConversationState {
|
public enum ConversationState {
|
||||||
DISCUSSION,
|
DISCUSSION,
|
||||||
TASK_GATHERING_INFO,
|
TASK_GATHERING_INFO,
|
||||||
|
TASK,
|
||||||
|
TASK_PLANNING,
|
||||||
TASK_ASSIGNMENT,
|
TASK_ASSIGNMENT,
|
||||||
EXECUTION,
|
EXECUTION,
|
||||||
CONCLUSION
|
CONCLUSION
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class WebSocketService {
|
||||||
// Create a new Message object
|
// Create a new Message object
|
||||||
Message parsedMessage = new Message(conversationId, sender, content);
|
Message parsedMessage = new Message(conversationId, sender, content);
|
||||||
|
|
||||||
|
System.out.println("DEBUG: WebSocket message: " + payload);
|
||||||
// Process the message
|
// Process the message
|
||||||
conversationManager.postMessage(conversationId, sender, content);
|
conversationManager.postMessage(conversationId, sender, content);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -2,15 +2,19 @@ package com.ioa.task;
|
||||||
|
|
||||||
import com.ioa.agent.AgentInfo;
|
import com.ioa.agent.AgentInfo;
|
||||||
import com.ioa.agent.AgentRegistry;
|
import com.ioa.agent.AgentRegistry;
|
||||||
|
import com.ioa.conversation.ConversationFSM;
|
||||||
|
import com.ioa.conversation.ConversationManager;
|
||||||
import com.ioa.model.BedrockLanguageModel;
|
import com.ioa.model.BedrockLanguageModel;
|
||||||
import com.ioa.service.WebSocketService;
|
import com.ioa.service.WebSocketService;
|
||||||
import com.ioa.tool.ToolRegistry;
|
import com.ioa.tool.ToolRegistry;
|
||||||
import com.ioa.util.TreeOfThought;
|
import com.ioa.util.TreeOfThought;
|
||||||
import com.ioa.conversation.ConversationManager;
|
import com.ioa.conversation.Message;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class TaskManager {
|
public class TaskManager {
|
||||||
|
@ -21,7 +25,8 @@ public class TaskManager {
|
||||||
private TreeOfThought treeOfThought;
|
private TreeOfThought treeOfThought;
|
||||||
private ConversationManager conversationManager;
|
private ConversationManager conversationManager;
|
||||||
|
|
||||||
public TaskManager(AgentRegistry agentRegistry, BedrockLanguageModel model, ToolRegistry toolRegistry, TreeOfThought treeOfThought, ConversationManager conversationManager) {
|
public TaskManager(AgentRegistry agentRegistry, BedrockLanguageModel model, ToolRegistry toolRegistry,
|
||||||
|
TreeOfThought treeOfThought, ConversationManager conversationManager) {
|
||||||
this.agentRegistry = agentRegistry;
|
this.agentRegistry = agentRegistry;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.toolRegistry = toolRegistry;
|
this.toolRegistry = toolRegistry;
|
||||||
|
@ -33,61 +38,43 @@ public class TaskManager {
|
||||||
tasks.put(task.getId(), task);
|
tasks.put(task.getId(), task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeTask(String taskId, String conversationId) {
|
public void executeTask(String taskId, List<AgentInfo> team) {
|
||||||
Task task = tasks.get(taskId);
|
Task task = tasks.get(taskId);
|
||||||
AgentInfo agent = task.getAssignedAgent();
|
if (task == null) {
|
||||||
|
System.out.println("ERROR: Task with ID " + taskId + " not found.");
|
||||||
System.out.println("DEBUG: Executing task: " + taskId + " for agent: " + agent.getId());
|
return;
|
||||||
|
|
||||||
conversationManager.postMessage(conversationId, agent.getId(), "Starting task: " + task.getDescription());
|
|
||||||
|
|
||||||
String executionPlanningTask = "Plan the execution of this task: " + task.getDescription() +
|
|
||||||
"\nAssigned agent capabilities: " + agent.getCapabilities() +
|
|
||||||
"\nAvailable tools: " + agent.getTools();
|
|
||||||
|
|
||||||
System.out.println("DEBUG: Generating execution plan for task: " + taskId);
|
|
||||||
Map<String, Object> reasoningResult = treeOfThought.reason(executionPlanningTask, 3, 2);
|
|
||||||
String reasoning = (String) reasoningResult.get("reasoning");
|
|
||||||
|
|
||||||
System.out.println("DEBUG: Execution plan generated: " + reasoning);
|
|
||||||
|
|
||||||
if (reasoning == null || reasoning.isEmpty()) {
|
|
||||||
System.out.println("WARNING: Empty execution plan generated for task: " + taskId);
|
|
||||||
reasoning = "No execution plan generated. Proceeding with a general approach to organize execution plan.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conversationManager.postMessage(conversationId, agent.getId(), "Task execution plan:\n" + reasoning);
|
String conversationId = conversationManager.createConversation();
|
||||||
|
ConversationFSM conversation = conversationManager.getConversation(conversationId);
|
||||||
String executionPrompt = "Based on this execution plan:\n" + reasoning +
|
|
||||||
"\nExecute the task using the available tools and provide the result.";
|
for (AgentInfo agent : team) {
|
||||||
Map<String, Object> executionResult = treeOfThought.reason(executionPrompt, 1, 1);
|
conversation.addParticipant(agent);
|
||||||
String response = (String) executionResult.get("reasoning");
|
|
||||||
|
|
||||||
if (response == null || response.isEmpty()) {
|
|
||||||
System.out.println("WARNING: Empty response generated for task execution: " + taskId);
|
|
||||||
response = "Unable to execute the task due to technical difficulties. Please try again or seek assistance.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String result = executeToolsFromResponse(response, agent);
|
conversation.postMessage(new Message(conversationId, "SYSTEM", "Let's work on the task: " + task.getDescription()));
|
||||||
|
|
||||||
if (result == null || result.isEmpty()) {
|
// Allow agents to interact for a maximum of 10 minutes
|
||||||
result = "No specific actions were taken based on the execution plan. Please review the plan and provide more detailed instructions if necessary.";
|
long startTime = System.currentTimeMillis();
|
||||||
}
|
//while (!conversation.isFinished() && (System.currentTimeMillis() - startTime) < TimeUnit.MINUTES.toMillis(10)) {
|
||||||
|
while (!conversation.isFinished() && (System.currentTimeMillis() - startTime) < TimeUnit.MINUTES.toMillis(40)) {
|
||||||
task.setResult(result);
|
try {
|
||||||
|
Thread.sleep(1000); // Check every second
|
||||||
conversationManager.postMessage(conversationId, agent.getId(), "Task result: " + result);
|
} catch (InterruptedException e) {
|
||||||
}
|
e.printStackTrace();
|
||||||
|
|
||||||
private String executeToolsFromResponse(String response, AgentInfo agent) {
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
for (String tool : agent.getTools()) {
|
|
||||||
if (response.contains(tool)) {
|
|
||||||
Object toolInstance = toolRegistry.getTool(tool);
|
|
||||||
// Execute the tool (this is a simplified representation)
|
|
||||||
result.append(tool).append(" result: ").append(toolInstance.toString()).append("\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.toString();
|
|
||||||
|
if (!conversation.isFinished()) {
|
||||||
|
conversation.finish("Time limit reached");
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = conversation.getResult();
|
||||||
|
task.setResult(result);
|
||||||
|
System.out.println("Task completed. Result: " + result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task getTask(String taskId) {
|
||||||
|
return tasks.get(taskId);
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,13 +1,26 @@
|
||||||
|
com/ioa/tool/common/TranslationTool.class
|
||||||
|
com/ioa/tool/common/PriceComparisonTool.class
|
||||||
com/ioa/service/WebSocketService.class
|
com/ioa/service/WebSocketService.class
|
||||||
com/ioa/tool/common/WebSearchTool.class
|
com/ioa/tool/common/WebSearchTool.class
|
||||||
com/ioa/conversation/ConversationFSM.class
|
com/ioa/conversation/ConversationFSM.class
|
||||||
com/ioa/conversation/Message.class
|
com/ioa/conversation/Message.class
|
||||||
com/ioa/util/TreeOfThought.class
|
com/ioa/util/TreeOfThought.class
|
||||||
com/ioa/tool/common/NewsUpdateTool.class
|
com/ioa/tool/common/NewsUpdateTool.class
|
||||||
|
com/ioa/tool/common/RestaurantFinderTool.class
|
||||||
com/ioa/conversation/ConversationFSM$ConversationStateUpdate.class
|
com/ioa/conversation/ConversationFSM$ConversationStateUpdate.class
|
||||||
|
com/ioa/IoASystem.class
|
||||||
|
com/ioa/tool/ToolRegistry.class
|
||||||
|
com/ioa/conversation/ConversationState.class
|
||||||
com/ioa/tool/common/FinancialAdviceTool.class
|
com/ioa/tool/common/FinancialAdviceTool.class
|
||||||
|
com/ioa/agent/AgentRegistry.class
|
||||||
com/ioa/team/TeamFormation.class
|
com/ioa/team/TeamFormation.class
|
||||||
|
com/ioa/task/TaskManager.class
|
||||||
|
com/ioa/model/BedrockLanguageModel.class
|
||||||
|
com/ioa/tool/common/DistanceCalculatorTool.class
|
||||||
com/ioa/tool/common/MovieRecommendationTool.class
|
com/ioa/tool/common/MovieRecommendationTool.class
|
||||||
|
com/ioa/tool/common/AppointmentSchedulerTool.class
|
||||||
|
com/ioa/agent/AgentInfo.class
|
||||||
|
com/ioa/task/Task.class
|
||||||
com/ioa/config/WebSocketConfig.class
|
com/ioa/config/WebSocketConfig.class
|
||||||
com/ioa/conversation/ConversationManager.class
|
com/ioa/conversation/ConversationManager.class
|
||||||
com/ioa/tool/common/WeatherTool.class
|
com/ioa/tool/common/WeatherTool.class
|
||||||
|
@ -15,17 +28,4 @@ com/ioa/tool/common/TravelBookingTool.class
|
||||||
com/ioa/tool/common/FitnessClassFinderTool.class
|
com/ioa/tool/common/FitnessClassFinderTool.class
|
||||||
com/ioa/tool/Tool.class
|
com/ioa/tool/Tool.class
|
||||||
com/ioa/tool/common/ReminderTool.class
|
com/ioa/tool/common/ReminderTool.class
|
||||||
com/ioa/tool/common/TranslationTool.class
|
|
||||||
com/ioa/tool/common/PriceComparisonTool.class
|
|
||||||
com/ioa/tool/common/RestaurantFinderTool.class
|
|
||||||
com/ioa/IoASystem.class
|
|
||||||
com/ioa/tool/ToolRegistry.class
|
|
||||||
com/ioa/conversation/ConversationState.class
|
|
||||||
com/ioa/agent/AgentRegistry.class
|
|
||||||
com/ioa/task/TaskManager.class
|
|
||||||
com/ioa/model/BedrockLanguageModel.class
|
|
||||||
com/ioa/tool/common/DistanceCalculatorTool.class
|
|
||||||
com/ioa/tool/common/AppointmentSchedulerTool.class
|
|
||||||
com/ioa/agent/AgentInfo.class
|
|
||||||
com/ioa/task/Task.class
|
|
||||||
com/ioa/tool/common/RecipeTool.class
|
com/ioa/tool/common/RecipeTool.class
|
||||||
|
|
|
@ -1,16 +1,30 @@
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/util/TreeOfThought.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/util/TreeOfThought.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/WeatherTool.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/conversation/ConversationFSM.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/conversation/ConversationFSM.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/model/BedrockLanguageModel.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/model/BedrockLanguageModel.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/conversation/ConversationState.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/conversation/ConversationState.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/task/Task.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/FinancialAdviceTool.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/conversation/Message.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/conversation/Message.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/service/WebSocketService.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/TravelBookingTool.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/agent/AgentInfo.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/agent/AgentInfo.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/DistanceCalculatorTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/TranslationTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/AppointmentSchedulerTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/agent/AgentRegistry.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/task/Task.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/MovieRecommendationTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/RestaurantFinderTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/conversation/ConversationManager.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/RecipeTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/service/WebSocketService.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/PriceComparisonTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/FitnessClassFinderTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/ReminderTool.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/Tool.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/Tool.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/team/TeamFormation.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/team/TeamFormation.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/ToolRegistry.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/ToolRegistry.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/CommonTools.java
|
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/task/TaskManager.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/task/TaskManager.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/IoASystem.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/IoASystem.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/agent/AgentRegistry.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/NewsUpdateTool.java
|
||||||
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/tool/common/WebSearchTool.java
|
||||||
/Users/emkay/Projects/totioa/src/main/java/com/ioa/config/WebSocketConfig.java
|
/Users/emkay/Projects/totioa/src/main/java/com/ioa/config/WebSocketConfig.java
|
||||||
|
|
Loading…
Reference in New Issue
Block a user