From 1634dfcdc5ce66e84d005afdf5301ff9f58a1d4e Mon Sep 17 00:00:00 2001 From: Mahesh Kommareddi Date: Wed, 17 Jul 2024 05:14:00 -0400 Subject: [PATCH] Was using wrong field in BedrockAPI to retrieve generated results. Working finally. --- src/main/java/com/ioa/IoASystem.java | 26 ++++++++-------- .../ioa/conversation/ConversationManager.java | 7 +++++ .../com/ioa/model/BedrockLanguageModel.java | 29 +++++++++++++++--- src/main/java/com/ioa/task/TaskManager.java | 27 +++++++++++++--- src/main/java/com/ioa/util/TreeOfThought.java | 29 ++++++++++++++++++ target/classes/com/ioa/IoASystem.class | Bin 13447 -> 12332 bytes .../conversation/ConversationManager.class | Bin 4009 -> 4700 bytes .../com/ioa/model/BedrockLanguageModel.class | Bin 5823 -> 7103 bytes target/classes/com/ioa/task/TaskManager.class | Bin 4546 -> 5390 bytes .../classes/com/ioa/util/TreeOfThought.class | Bin 4404 -> 5760 bytes 10 files changed, 97 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/ioa/IoASystem.java b/src/main/java/com/ioa/IoASystem.java index e8aa11b..5d7bee4 100644 --- a/src/main/java/com/ioa/IoASystem.java +++ b/src/main/java/com/ioa/IoASystem.java @@ -176,23 +176,23 @@ public class IoASystem { new Task("task7", "Organize an international tech conference with virtual and in-person components", Arrays.asList("event planning", "tech expertise", "marketing", "travel coordination", "content creation"), - Arrays.asList("scheduleAppointment", "webSearch", "bookTravel", "getWeather", "findRestaurants", "getNewsUpdates")), + Arrays.asList("scheduleAppointment", "webSearch", "bookTravel", "getWeather", "findRestaurants", "getNewsUpdates"))//, - new Task("task8", "Develop and launch a multi-lingual mobile app for sustainable tourism", - Arrays.asList("software development", "travel", "language expertise", "environmental science", "user experience design"), - Arrays.asList("webSearch", "translate", "getWeather", "findRestaurants", "getNewsUpdates", "compareProductPrices")), + // new Task("task8", "Develop and launch a multi-lingual mobile app for sustainable tourism", + // Arrays.asList("software development", "travel", "language expertise", "environmental science", "user experience design"), + // Arrays.asList("webSearch", "translate", "getWeather", "findRestaurants", "getNewsUpdates", "compareProductPrices")), - new Task("task9", "Create a comprehensive health and wellness program for a large corporation, including mental health support", - Arrays.asList("health", "nutrition", "psychology", "corporate wellness", "data analysis"), - Arrays.asList("findFitnessClasses", "getRecipe", "setReminder", "getWeather", "scheduleAppointment", "getFinancialAdvice")), + // new Task("task9", "Create a comprehensive health and wellness program for a large corporation, including mental health support", + // Arrays.asList("health", "nutrition", "psychology", "corporate wellness", "data analysis"), + // Arrays.asList("findFitnessClasses", "getRecipe", "setReminder", "getWeather", "scheduleAppointment", "getFinancialAdvice")), - new Task("task10", "Plan and execute a global product launch campaign for a revolutionary eco-friendly technology", - Arrays.asList("marketing", "environmental science", "international business", "public relations", "social media"), - Arrays.asList("webSearch", "getNewsUpdates", "scheduleAppointment", "translate", "compareProductPrices", "bookTravel")), + // new Task("task10", "Plan and execute a global product launch campaign for a revolutionary eco-friendly technology", + // Arrays.asList("marketing", "environmental science", "international business", "public relations", "social media"), + // Arrays.asList("webSearch", "getNewsUpdates", "scheduleAppointment", "translate", "compareProductPrices", "bookTravel")), - new Task("task11", "Design and implement a smart city initiative focusing on transportation, energy, and public safety", - Arrays.asList("urban planning", "environmental science", "data analysis", "public policy", "technology integration"), - Arrays.asList("webSearch", "getWeather", "calculateDistance", "getNewsUpdates", "getFinancialAdvice", "findHomeServices")) + // new Task("task11", "Design and implement a smart city initiative focusing on transportation, energy, and public safety", + // Arrays.asList("urban planning", "environmental science", "data analysis", "public policy", "technology integration"), + // Arrays.asList("webSearch", "getWeather", "calculateDistance", "getNewsUpdates", "getFinancialAdvice", "findHomeServices")) ); diff --git a/src/main/java/com/ioa/conversation/ConversationManager.java b/src/main/java/com/ioa/conversation/ConversationManager.java index 421e38f..7228efe 100644 --- a/src/main/java/com/ioa/conversation/ConversationManager.java +++ b/src/main/java/com/ioa/conversation/ConversationManager.java @@ -44,9 +44,16 @@ public class ConversationManager { } public void postMessage(String conversationId, String senderId, String content) { + System.out.println("DEBUG: Posting message - ConversationId: " + conversationId + ", SenderId: " + senderId + ", Content: " + content); ConversationFSM conversation = conversations.get(conversationId); if (conversation != null) { + if (content == null) { + System.out.println("WARNING: Attempting to post null content message"); + return; + } conversation.postMessage(new Message(conversationId, senderId, content)); + } else { + System.out.println("WARNING: Conversation not found for id: " + conversationId); } } diff --git a/src/main/java/com/ioa/model/BedrockLanguageModel.java b/src/main/java/com/ioa/model/BedrockLanguageModel.java index f85bab5..3b3fc30 100644 --- a/src/main/java/com/ioa/model/BedrockLanguageModel.java +++ b/src/main/java/com/ioa/model/BedrockLanguageModel.java @@ -10,6 +10,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.JsonNode; + import org.springframework.stereotype.Component; import java.nio.file.Files; @@ -32,6 +34,7 @@ public class BedrockLanguageModel { } public String generate(String prompt, String imagePath) { + System.out.println("DEBUG: Generating response for prompt: " + prompt); try { ObjectNode requestBody = objectMapper.createObjectNode(); requestBody.put("anthropic_version", "bedrock-2023-05-31"); @@ -39,7 +42,7 @@ public class BedrockLanguageModel { ObjectNode message = messages.addObject(); message.put("role", "user"); requestBody.put("max_tokens", 20000); - requestBody.put("temperature", 0.4); + requestBody.put("temperature", 0.7); requestBody.put("top_p", 0.9); ArrayNode content = message.putArray("content"); @@ -71,12 +74,30 @@ public class BedrockLanguageModel { InvokeModelResponse response = bedrockClient.invokeModel(invokeRequest); String responseBody = response.body().asUtf8String(); + System.out.println("DEBUG: Raw response from Bedrock: " + responseBody); - ObjectNode responseJson = (ObjectNode) objectMapper.readTree(responseBody); - return responseJson.path("content").get(0).path("text").asText(); + JsonNode responseJson = objectMapper.readTree(responseBody); + JsonNode contentArray = responseJson.path("content"); + + if (contentArray.isArray() && contentArray.size() > 0) { + JsonNode firstContent = contentArray.get(0); + String generatedText = firstContent.path("text").asText(); + if (generatedText.isEmpty()) { + System.out.println("WARNING: Generated text is empty. Full response: " + responseBody); + return "No response generated"; + } + + System.out.println("DEBUG: Generated text: " + generatedText); + return generatedText; + } else { + System.out.println("WARNING: Unexpected response format. Full response: " + responseBody); + return "Unexpected response format"; + } } catch (Exception e) { - throw new RuntimeException("Error generating text with Bedrock", e); + System.out.println("ERROR: Failed to generate text with Bedrock: " + e.getMessage()); + e.printStackTrace(); + return "Error: " + e.getMessage(); } } } \ No newline at end of file diff --git a/src/main/java/com/ioa/task/TaskManager.java b/src/main/java/com/ioa/task/TaskManager.java index f4b7d07..705ccd4 100644 --- a/src/main/java/com/ioa/task/TaskManager.java +++ b/src/main/java/com/ioa/task/TaskManager.java @@ -37,29 +37,48 @@ public class TaskManager { Task task = tasks.get(taskId); AgentInfo agent = task.getAssignedAgent(); + System.out.println("DEBUG: Executing task: " + taskId + " for agent: " + agent.getId()); + 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 reasoningResult = treeOfThought.reason(executionPlanningTask, 3, 2); - String reasoning = (String) reasoningResult.get("reasoning"); // Assuming the reasoning is stored under the key "reasoning" + 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."; + } conversationManager.postMessage(conversationId, agent.getId(), "Task execution plan:\n" + reasoning); String executionPrompt = "Based on this execution plan:\n" + reasoning + "\nExecute the task using the available tools and provide the result."; Map executionResult = treeOfThought.reason(executionPrompt, 1, 1); - String response = (String) executionResult.get("response"); // Assuming the response is stored under the key "response" + String response = (String) executionResult.get("response"); + + if (response == null || response.isEmpty()) { + System.out.println("WARNING: Empty response generated for task execution: " + taskId); + response = "No response generated."; + } String result = executeToolsFromResponse(response, agent); task.setResult(result); - conversationManager.postMessage(conversationId, agent.getId(), "Task result: " + result); + if (result != null && !result.isEmpty()) { + conversationManager.postMessage(conversationId, agent.getId(), "Task result: " + result); + } else { + conversationManager.postMessage(conversationId, agent.getId(), "Task completed, but no result was generated."); + } } - + private String executeToolsFromResponse(String response, AgentInfo agent) { StringBuilder result = new StringBuilder(); for (String tool : agent.getTools()) { diff --git a/src/main/java/com/ioa/util/TreeOfThought.java b/src/main/java/com/ioa/util/TreeOfThought.java index bc137e4..b9be837 100644 --- a/src/main/java/com/ioa/util/TreeOfThought.java +++ b/src/main/java/com/ioa/util/TreeOfThought.java @@ -17,8 +17,11 @@ public class TreeOfThought { } public Map reason(String task, int depth, int branches) { + System.out.println("DEBUG: Starting reasoning process for task: " + task); Map treeData = exploreThought(task, depth, branches, "Root"); webSocketService.sendUpdate("tree_of_thought", treeData); + String reasoning = formatReasoning(treeData); + System.out.println("DEBUG: Reasoning result: " + reasoning); return treeData; } @@ -67,4 +70,30 @@ public class TreeOfThought { "\nPath: " + path + "\nEvaluations:\n" + childEvaluations; return model.generate(prompt, null); } + + private String formatReasoning(Map treeData) { + StringBuilder sb = new StringBuilder(); + formatNode(treeData, sb, 0); + return sb.toString(); + } + + private void formatNode(Map node, StringBuilder sb, int depth) { + String indent = " ".repeat(depth); + sb.append(indent).append(node.get("name")).append("\n"); + + if (node.containsKey("evaluation")) { + sb.append(indent).append("Evaluation: ").append(node.get("evaluation")).append("\n"); + } + + if (node.containsKey("conclusion")) { + sb.append(indent).append("Conclusion: ").append(node.get("conclusion")).append("\n"); + } + + if (node.containsKey("children")) { + List> children = (List>) node.get("children"); + for (Map child : children) { + formatNode(child, sb, depth + 1); + } + } + } } \ No newline at end of file diff --git a/target/classes/com/ioa/IoASystem.class b/target/classes/com/ioa/IoASystem.class index 2a4f41c6719f5f0fef562ad73b6ba1e07e6e646c..6a0836cc5dcb82a84184cb2a1419cbb7c5a6ccef 100644 GIT binary patch delta 2903 zcmb7G33yaj6+Zvm$-J32cQTX7`q)efNl4hC4LB{3vJ^3~jjTnhFioZ~EJ>Id2(8u_ zY)b{P=o8!0O%$7Ii!=d;Bq&Qotxzo37E+~Es+5*0luAJmNYA|qB<-i4pYwh1zH`q# z_dol2vnu-BJagZbww*+DGu~@5i&A|iy-g7Vn5 zXAJs4(m&~}y)La%(m6VB(7z;Ipo?}#T8X4fblIRQk~%>4&A|c>U4lbGz-iY8bGob=;i{^Na4Zq6jMj#$69xu>^6b*gOnY92e<))Qkr+y+K+bsdo`{KJ440IG5zH7k zwP;q592h0(UR=+9+UwFY?52zcZwW>l7$fm%gzT}I3%voQaje8RjJKOJr>0KCBmEkeX5W!D9G|n-X5~#P$88c7D zfFSFNcWA`xNMY~+?bBBMmYi!mb+kQUZ@4&nEp8WA>uu+gzxRNvC;(8_; zhHvmHHJyU{a6j*W2e68@HQ3_{de7>X9i?S+NwAFBC99|h@lAc-#A>YJdi@rkGdk8X z)VG=TI5g-(dR>im8hXpepvU|d=W>L!hZD%%OvIe6n>X!ym1^EBHy*>`LF?xX%~HL z$KzVs$MLsylzlp)PQESh1fJx2?-5(p_7r}gv@zl$GBmP(2j$KgGh#zWij}Gkj#coYAwWjMy^?pxJ zuWI_wo+|CmPx!Y1KhpR!iwU06J2gsRpoZRPGRAKcW^8N-j=^sjB+U6Bf}P+MkAja6vQ+52}dNI=h#oV9~?}tq6ZZgmvuAuN{~og z-r8qSg@eB~ONPv@Z=v-ePYWGS(t9m*I%Ha&R{9VW@>07FmT5^VjjJZr^0#3mQ7dk6 z(Co&JS2Sp+xi>1aZnFFtC~d}sBtA2{k<3t_Ug^A5$tCgmP(Zm6Xu}NcLnA47(=n6% zY`k*TGFvg5ho6~&FErzhR?Ky>e_qAD6ReJW9JH=Y6FJ0su~BS7xi}(Diw{uF1;VLB zFS>7+zXrX(9 z#?WDLBfT!l=%`poZ-@puA?~A-Vm+M_8|jSLM5o2m^uBnO&WdgHq1Z#`#9lft4$uX0 zkS>WMbVZz?4sjZSErK`;hqwf1y{@Hwl)*|ocoxr5fZ?+>mBxT6*o>bsFF;M$g6Aof z4OosQG?Smz_^_3E0XFzeY{SpV$1a>h65C0Nv*gxyy{hW2_AOJLRVu|9-NE$^$`Qx0 z5iLA8@qH@us8^)kH99z}aZpUU+pp6xK94(lP9ry*0 z^Q;IR=V(caet8HBj!lKsgu4eUTjfCh*o1Fx5x0v)}k{p^JNxsB8zd&nZsg zu0cse+pv&`H(q|0@Kd{;-U_8yDSQ?mY^5YoH`p4%ue*jM@fFLN#Me||xin?Dc5z`b z;utFBwUj34x8V7*ZPcK8HDA<>?oV0x6~|xAuri$qCYVy0Ro~4r9bko1rt_($Wtq;W zQwPUGj`LJ%V6TU3_BVX!z;CY&s2910f5*IH9x?6g=svx^gg2>3;P-f$AI1KIUSHMg QVI1cRCUf7$J2*+!M|N3jLI3~& delta 3971 zcmb7G3v?9a6~5o>%#mnsYMyKkohR zcfbF?cjo@~t;(wY-yFrU*TBea@a(XnCNLyyNnasp`OugGQ;#p3Gvs!A# z<4H4<(bHBc-(?vICkunKwU|*fWu;S=k&UI24SFmYjpsT!ZN0>(1e3|7*@%ZshqqN^vvB zA~V~oLIqXitPa*9&4MHuL4}v)E19KJOp?tsPUmQP95`$8Sqc?YRB$$nV#&_4Qwg)h zw0dGuGvh@7l^z5&gir;lyxiz98sm0T#iYr+GepBs3Yl6NY&6*~2TnacQqHl@)$ldcgFLa!>_j@->m?26YnaE7lPbd_F4WLM zceA8MXXiXVrdTwVHj-HnE&`3>9IEYaRr<#>&H@cz7YfLk*cGN1t+-et1()!`xTd=K zL6UH(Mpxo8yHI(1MLP@+Iy6Ml394n7TKlTt%<_l`-ld@%G5hIYQ$+$v4^kS^SOOa1 zM2m!`sIACo$RcMi3!R9i_I;sIwLR$7a0T%t^QSF7%a*JWUEFFJQBy#EOT(3{%dXII zazw>dcAzS~pdH`Q@Ll1dX1a6P&eYPR!hKErO)EnJ%Qajp!g^X}&piLUSuN#g$MqU+ zK#nhmvDAoVTTLs$ZA)AkvH5)sKfnt6#j3IT%^GgORPHNXX11x*OE=)=Ad7LUIG!JY zrrKu)LiT_!XtxHc%4j=o*Kh~BwpZ7T`mu(eUs#eI*4pW_$yj_R?;-K$|0VxaO;-M4bZi37M#!>`xrLvAa>M|R)w*U#9)*V9|N zmZGjiWkz(amwkM^b5d5q?Bs$s61)~5x8IF}URsJn8s5iF6`$Kz>opAnY%1`%$}`;4 zg}Vg4;8+O1TXK0NSyDWbn-i5h_7?pKzf|Uxyi&PG(lp5@RjgZiLJ*2n2^wv`HnPTB zdu}SVIG6TFA$!Nj8Piv@`iF5 z?TbeZpMTW$WXDz~7u$GCwqmpv>l}YC9>nh%y--BQdWP!bahc?RZg8FtqThku@&)Lr z{{?y@{!oH`01y2y=uLQ-O;+2}YKNbEl=bPyWLRQ-EJM!r5j^VnU0*wV?oq$9{(nl0 z^%x#^uy)qgV=Pi{KU{ zkyo14TS6hSXc%RVIrlLBifz2_p&>w*}t}zO6n)E81MacU#)z;JqzvO7Q)bHh1uYmNrlDqn19pHQ+89 zOb`Z9VK7A)oFfb_YiU!1-NI@;y}?@!=EuQLOPB@W(kEQ@2$y}r<$!|;w|!;Z(CIus zUqD!c5N-$JQ1J5-#AX4(WR&0lLxcctxQaTrA%R4o5x~tu$Ff zlDt#iFCRjWGEteMG@*yRFL-2deVQVzn#iO1s~~5JStYarkw5cD2awC)360^aAzK^ zG;;6#C-;t%l#xz%RA`1$?euLoovWx$@9|I@>n%E_D$D!<_%9AzCi^iPZ{jU}Z@$e5 zan~x63gaDSRWy5-GklLXmy>Tm9%i>stWlwR(C)z)`6u!gLJ~@ zG|Yomo*ksdg&y>{574j!q#h)x<}99;1-#ZeRPHgAC~cL-Nl;{ zJ|67opYZMdl-KIXEpb1_Zs)mIQmM{`{WyUA&cbKT^RReIB>CCF%cFo4l&UEFZx|oC ABLDyZ diff --git a/target/classes/com/ioa/conversation/ConversationManager.class b/target/classes/com/ioa/conversation/ConversationManager.class index b45cbcb33a47ac2acae01b198e0031e1a22c39c8..4de5c4ecfd84c39a11ae9d4e7ec1e20edc27b767 100644 GIT binary patch delta 1728 zcmbtVSyLQU6#nkaFx}JB43j}t18KI%KG`ZzWRqQXWC(H7-G8)EJfsf>oAJTBT)`&z3*JN6U)K>1JfG$~Panr|&)YeBXDzb9(yvj$ewU z@Bdu?8bCeP7p0%=stb*163{H81+5I;6T#V_KOEF1{DHZsp-wZ{^_ans(P>3Oy1zFP z(u{x+QG?S5e1y~{qa7U#S<}HOwNckbgT`RUn53tu5!8$*Lpwhxmhc`ionIAwaS2`M z7SJQ37xyxx{|7FEFk`ZWH6kwEVBXMV(DuZEvH=kRhFyd8ecf%{t#wMhK~iT7iYbP! z%;-@=(PH7SGOBBasu{|(8jS`gQ~^hs4cqxmX9oYv?h^YkC?f^OxYu#F^SF#*+{XtT zdn6wi9x%%q;pfG&Oc6l_XJ9DM-`wSc4Wlx~pznt{8VegD9%0BN$7axwom9uDFQsM2MV#V?ojGYw%6Q5&(>ZR1mrpspHohwU z5Et2({T*6H(2w0S{gyrRVS2}a7Fwn$F zd7fx-r>;-Ms25){fV)8N|hG{4JT#Ln;z_g;3E$K5;9o}qmOcDfhh9G>Mj z+&RK?sGxZ`!+&(|Z#_#99~^Ygg@8Meh3zOp9+G(_W*)@_MwURc!sylh zhodllWRZe)B&kX%v5ct7iK_B{Qw`&oSq^dh1Sh>oK=%?FDk`hiaSyP9cxU-7NEK_S zvEdt3);V$<-=eVUJIHj**SCVs#T>_1=pUk#RSc|P=o->Ygmv6+=65FL?}Urs{Um=E z`MsO`+Jl|gi)!qn-ThQ`E&Z|7Stae;kb-k9Rx3!=rhVObm6~ERm4efg-2yY)RO3Uy9T;E2SHDrl7CL67--E3{`rnXvKw6uBXjHzf#Yik7A>g^jCu>{R~3gX6s@8Jak+}hp_ zqU3^X3Z?%DPO_dWw^?HPf$-2Wu7Ez z50QhuAOf0@N?#DOKADouh*<$FPwil-Wbb8K+VB?Mre7x=dWU|m(3MRf*J%B&b$=f> UXnhs)blsw;M3FDBiZ$f?4a_281^@s6 delta 1197 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