diff --git a/kai/ai-test.ipynb b/kai/ai-test.ipynb index 59bf0e303..0c49eaf84 100644 --- a/kai/ai-test.ipynb +++ b/kai/ai-test.ipynb @@ -7,20 +7,182 @@ "outputs": [], "source": [ "from langchain import PromptTemplate\n", - "from langchain.chat_models import ChatOpenAI\n", "from langchain.chains import LLMChain\n", + "from langchain.chat_models import ChatOpenAI\n", "from langchain.callbacks import FileCallbackHandler\n", "\n", - "import os\n", "\n", - "prompt = \"\"\"\n", - "say this is a test\n", + "template = \"\"\"\n", + "You are an excellent enterprise architect who has an extensive\n", + "background in helping companies rewrite their legacy Java EE applications to Quarkus.\n", + "\n", + "You will read a user's problem along with examples of how they have solved a problem in the past.\n", + "The past examples will be presented in format of a summary of the issue along with source code of \n", + "that point in time along with the updated source code when the problem is fixed\n", + "\n", + "You will then write Quarkus code to solve their current problem.\n", + "You will output the results in the form a diff which can be applied via 'git apply'.\n", + "\n", + "Your job is to look at the 'Current Issue' and the 'Current Issue Original Source Code' \n", + "and rewrite the 'Current Issue Original Source Code' so the 'Current Issue' is solved \n", + "in a manner similar to how 'Example #1 Original Source Code' was rewritten to \n", + "'Example #1 Solved Source Code' \n", + "\n", + "Think through the changes you will make and explain each step of the process.\n", + "If you are unsure of what changes is needed please state you are unsure and ask \n", + "for clarification to help you.\n", + "\n", + "When you are done explaining the reasoning for each change, write the updated \n", + "Quarkus source code in the form of a diff which can be applied via 'git apply' \n", + "in Markdown format, e.g.:\n", + "\n", + "```diff\n", + "....\n", + "```\n", + "\n", + "### Input:\n", + "\n", + "Example #1 Issue: {example1_issue}\n", + "\n", + "Example #1 Original Source Code:\n", + "```java\n", + "{example1_original_code}\n", + "```\n", + "\n", + "Example #1 Solved Source Code:\n", + "```java\n", + "{example1_solved_code}\n", + "```\n", + "\n", + "Current Issue: \n", + "{current_issue}\n", + "\n", + "Current Issue Original Source Code: \n", + "```java\n", + "{current_issue_original_code}\n", + "```\n", "\"\"\"\n", "\n", - " streaming=True)\n", + "example1_original_code = \"\"\"import java.util.HashMap;\n", + "import java.util.Map;\n", + "\n", + "public class OldStyleRouter {\n", + " interface RequestHandler {\n", + " void handle(String requestData);\n", + " }\n", + "\n", + " private Map routes;\n", + "\n", + " public OldStyleRouter() {\n", + " routes = new HashMap<>();\n", + " }\n", + "\n", + " public void addRoute(String path, RequestHandler handler) {\n", + " routes.put(path, handler);\n", + " }\n", + "\n", + " public void handleRequest(String path, String requestData) {\n", + " if (routes.containsKey(path)) {\n", + " routes.get(path).handle(requestData);\n", + " } else {\n", + " System.out.println(\"No handler for path: \" + path);\n", + " }\n", + " }\n", + "\n", + " public static void main(String[] args) {\n", + " OldStyleRouter router = new OldStyleRouter();\n", + "\n", + " // Adding routes using anonymous classes\n", + " router.addRoute(\"/home\", new RequestHandler() {\n", + " @Override\n", + " public void handle(String data) {\n", + " System.out.println(\"Home Page Requested: \" + data);\n", + " }\n", + " });\n", + " router.addRoute(\"/about\", new RequestHandler() {\n", + " @Override\n", + " public void handle(String data) {\n", + " System.out.println(\"About Page Requested: \" + data);\n", + " }\n", + " });\n", + "\n", + " // Handling requests\n", + " router.handleRequest(\"/home\", \"User data for home\");\n", + " router.handleRequest(\"/about\", \"User data for about\");\n", + " }\n", + "}\n", + "\"\"\"\n", + "\n", + "example1_solved_code = \"\"\"import java.util.HashMap;\n", + "import java.util.Map;\n", + "import java.util.function.Consumer;\n", + "\n", + "public class ModernRouter {\n", + " private Map> routes;\n", + "\n", + " public ModernRouter() {\n", + " routes = new HashMap<>();\n", + " }\n", + "\n", + " public void addRoute(String path, Consumer handler) {\n", + " routes.put(path, handler);\n", + " }\n", + "\n", + " public void handleRequest(String path, String requestData) {\n", + " if (routes.containsKey(path)) {\n", + " routes.get(path).accept(requestData);\n", + " } else {\n", + " System.out.println(\"No handler for path: \" + path);\n", + " }\n", + " }\n", + "\n", + " public static void main(String[] args) {\n", + " ModernRouter router = new ModernRouter();\n", + "\n", + " // Adding routes with lambda expressions\n", + " router.addRoute(\"/home\", data -> System.out.println(\"Home Page Requested: \" + data));\n", + " router.addRoute(\"/about\", data -> System.out.println(\"About Page Requested: \" + data));\n", + "\n", + " // Handling requests\n", + " router.handleRequest(\"/home\", \"User data for home\");\n", + " router.handleRequest(\"/about\", \"User data for about\");\n", + " }\n", + "}\n", + "\"\"\"\n", + "\n", + "current_issue_original_code = \"\"\"import java.util.Comparator;\n", + "\n", + "public class OldStyleJavaExample {\n", + " public static void main(String[] args) {\n", + " // Using an anonymous class to implement a comparator\n", + " Comparator compareIntegers = new Comparator() {\n", + " @Override\n", + " public int compare(Integer x, Integer y) {\n", + " return x.compareTo(y);\n", + " }\n", + " };\n", + "\n", + " // Using the comparator\n", + " int comparisonResult = compareIntegers.compare(5, 10);\n", + " System.out.println(\"Result using anonymous class: \" + comparisonResult);\n", + " }\n", + "}\n", + "\"\"\"\n", + "\n", + "template_args = {\n", + " \"example1_issue\": \"The usage of anonymous classes for routes is against our coding conventions. Please use modern Java functional syntax instead\",\n", + " \"example1_original_code\": example1_original_code,\n", + " \"example1_solved_code\": example1_solved_code,\n", + " \"current_issue\": \"The usage of anonymous classes for routes is against our coding conventions. Please use modern Java functional syntax instead\",\n", + " \"current_issue_original_code\": current_issue_original_code,\n", + "}\n", + "\n", + "formatted_prompt = template.format(**template_args)\n", + "\n", + "llm = ChatOpenAI(streaming=True)\n", "\n", - "for chunk in llm.stream(prompt):\n", - " print(chunk.content, end=\"\", flush=True)\n" + "for chunk in llm.stream(formatted_prompt):\n", + " print(chunk.content, end=\"\", flush=True)" ] }, { diff --git a/kai/ai-test.py b/kai/ai-test.py new file mode 100644 index 000000000..f7dd976b3 --- /dev/null +++ b/kai/ai-test.py @@ -0,0 +1,384 @@ +from langchain import PromptTemplate +from langchain.callbacks import FileCallbackHandler +from langchain.chains import LLMChain +from langchain.chat_models import ChatOpenAI + +template = """ +You are an excellent enterprise architect who has an extensive +background in helping companies rewrite their legacy Java EE applications to Quarkus. + +You will read a user's problem along with examples of how they have solved a problem in the past. +The past examples will be presented in format of a summary of the issue along with source code of +that point in time along with the updated source code when the problem is fixed + +You will then write Quarkus code to solve their current problem. +You will output the results in the form a diff which can be applied via 'git apply'. + +Your job is to look at the 'Current Issue' and the 'Current Issue Original Source Code' +and rewrite the 'Current Issue Original Source Code' so the 'Current Issue' is solved +in a manner similar to how the diff for 'Example #1 Diff' was obtained. + +Think through the changes you will make and explain each step of the process. +If you are unsure of what changes is needed please state you are unsure and ask +for clarification to help you. + +When you are done explaining the reasoning for each change, write the updated +Quarkus source code in the form of a diff which can be applied via 'git apply' +in Markdown format, e.g.: + +```diff +.... +``` + +### Input: + +Example #1 Issue: {example1_issue} + +Example #1 Diff: +{example1_diff} + +Current Issue: +{current_issue} + +Current Issue Original Source Code: +```java +{current_issue_original_code} +``` +""" + +# Example #1 Original Source Code: +# ```java +# {example1_original_code} +# ``` + +# Example #1 Solved Source Code: +# ```java +# {example1_solved_code} +# ``` + +example1_original_code = """import java.util.HashMap; +import java.util.Map; + +public class OldStyleRouter { + interface RequestHandler { + void handle(String requestData); + } + + private Map routes; + + public OldStyleRouter() { + routes = new HashMap<>(); + } + + public void addRoute(String path, RequestHandler handler) { + routes.put(path, handler); + } + + public void handleRequest(String path, String requestData) { + if (routes.containsKey(path)) { + routes.get(path).handle(requestData); + } else { + System.out.println("No handler for path: " + path); + } + } + + public static void main(String[] args) { + OldStyleRouter router = new OldStyleRouter(); + + // Adding routes using anonymous classes + router.addRoute("/home", new RequestHandler() { + @Override + public void handle(String data) { + System.out.println("Home Page Requested: " + data); + } + }); + router.addRoute("/about", new RequestHandler() { + @Override + public void handle(String data) { + System.out.println("About Page Requested: " + data); + } + }); + + // Handling requests + router.handleRequest("/home", "User data for home"); + router.handleRequest("/about", "User data for about"); + } +} +""" + +example1_solved_code = """import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +public class ModernRouter { + private Map> routes; + + public ModernRouter() { + routes = new HashMap<>(); + } + + public void addRoute(String path, Consumer handler) { + routes.put(path, handler); + } + + public void handleRequest(String path, String requestData) { + if (routes.containsKey(path)) { + routes.get(path).accept(requestData); + } else { + System.out.println("No handler for path: " + path); + } + } + + public static void main(String[] args) { + ModernRouter router = new ModernRouter(); + + // Adding routes with lambda expressions + router.addRoute("/home", data -> System.out.println("Home Page Requested: " + data)); + router.addRoute("/about", data -> System.out.println("About Page Requested: " + data)); + + // Handling requests + router.handleRequest("/home", "User data for home"); + router.handleRequest("/about", "User data for about"); + } +} +""" + +example1_diff = """diff --git a/a b/b +index e16cb82..df9b214 100644 +--- a/a ++++ b/b +@@ -1,45 +1,32 @@ + import java.util.HashMap; + import java.util.Map; ++import java.util.function.Consumer; + +-public class OldStyleRouter { +- interface RequestHandler { +- void handle(String requestData); +- } +- +- private Map routes; ++public class ModernRouter { ++ private Map> routes; + +- public OldStyleRouter() { ++ public ModernRouter() { + routes = new HashMap<>(); + } + +- public void addRoute(String path, RequestHandler handler) { ++ public void addRoute(String path, Consumer handler) { + routes.put(path, handler); + } + + public void handleRequest(String path, String requestData) { + if (routes.containsKey(path)) { +- routes.get(path).handle(requestData); ++ routes.get(path).accept(requestData); + } else { + System.out.println("No handler for path: " + path); + } + } + + public static void main(String[] args) { +- OldStyleRouter router = new OldStyleRouter(); ++ ModernRouter router = new ModernRouter(); + +- // Adding routes using anonymous classes +- router.addRoute("/home", new RequestHandler() { +- @Override +- public void handle(String data) { +- System.out.println("Home Page Requested: " + data); +- } +- }); +- router.addRoute("/about", new RequestHandler() { +- @Override +- public void handle(String data) { +- System.out.println("About Page Requested: " + data); +- } +- }); ++ // Adding routes with lambda expressions ++ router.addRoute("/home", data -> System.out.println("Home Page Requested: " + data)); ++ router.addRoute("/about", data -> System.out.println("About Page Requested: " + data)); + + // Handling requests + router.handleRequest("/home", "User data for home"); +""" + +current_issue_original_code = """import java.util.Comparator; + +public class OldStyleJavaExample { + public static void main(String[] args) { + // Using an anonymous class to implement a comparator + Comparator compareIntegers = new Comparator() { + @Override + public int compare(Integer x, Integer y) { + return x.compareTo(y); + } + }; + + // Using the comparator + int comparisonResult = compareIntegers.compare(5, 10); + System.out.println("Result using anonymous class: " + comparisonResult); + } +} +""" + +template_args = { + "example1_issue": "The usage of anonymous classes for routes is against our coding conventions. Please use modern Java functional syntax instead", + # "example1_original_code": example1_original_code, + # "example1_solved_code": example1_solved_code, + "example1_diff": example1_diff, + "current_issue": "The usage of anonymous classes for routes is against our coding conventions. Please use modern Java functional syntax instead", + "current_issue_original_code": current_issue_original_code, +} + +formatted_prompt = template.format(**template_args) + +complex_prompt = """ +You are an excellent enterprise architect who has an extensive background in +helping companies rewrite their legacy Java EE applications to Quarkus. + +You will read a user's problem along with examples of how they have solved a +problem in the past. The past examples will be presented in format of a summary +of the issue along with source code of that point in time along with the updated +source code when the problem is fixed + +You will then write Quarkus code to solve their current problem. You will output +the results in the form a diff which can be applied via 'git apply'. + +Your job is to look at the 'Current Issue' and the 'Current Issue Original +Source Code' and rewrite the 'Current Issue Original Source Code' so the +'Current Issue' is solved. You will not have an example to go off of, so please +be as accurate as possible. + +Think through the changes you will make and explain each step of the process. If +you are unsure of what changes is needed please state you are unsure and ask for +clarification to help you. + +When you are done explaining the reasoning for each change, write the updated +Quarkus source code in the form of a diff which can be applied via 'git apply' +in Markdown format, e.g.: + +```diff +.... +``` + +Current Issue: +{current_issue} + +Current Issue Original Source Code: +```java +{current_issue_original_code} +``` +""" + +complex_code = """ +package org.jboss.as.quickstarts.servlet; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.jms.Destination; +import javax.jms.JMSContext; +import javax.jms.JMSDestinationDefinition; +import javax.jms.JMSDestinationDefinitions; +import javax.jms.Queue; +import javax.jms.Topic; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Definition of the two JMS destinations used by the quickstart + * (one queue and one topic). + */ +@JMSDestinationDefinitions( + value = { + @JMSDestinationDefinition( + name = "java:/queue/HELLOWORLDMDBQueue", + interfaceName = "javax.jms.Queue", + destinationName = "HelloWorldMDBQueue" + ), + @JMSDestinationDefinition( + name = "java:/topic/HELLOWORLDMDBTopic", + interfaceName = "javax.jms.Topic", + destinationName = "HelloWorldMDBTopic" + ) + } +) + +/** + *

+ * A simple servlet 3 as client that sends several messages to a queue or a topic. + *

+ * + *

+ * The servlet is registered and mapped to /HelloWorldMDBServletClient using the {@linkplain WebServlet + * @HttpServlet}. + *

+ * + * @author Serge Pagop (spagop@redhat.com) + * + */ +@WebServlet("/HelloWorldMDBServletClient") +public class HelloWorldMDBServletClient extends HttpServlet { + + private static final long serialVersionUID = -8314035702649252239L; + + private static final int MSG_COUNT = 5; + + @Inject + private JMSContext context; + + @Resource(lookup = "java:/queue/HELLOWORLDMDBQueue") + private Queue queue; + + @Resource(lookup = "java:/topic/HELLOWORLDMDBTopic") + private Topic topic; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.setContentType("text/html"); + PrintWriter out = resp.getWriter(); + out.write("

Quickstart: Example demonstrates the use of JMS 2.0 and EJB 3.2 Message-Driven Bean in JBoss EAP.

"); + try { + boolean useTopic = req.getParameterMap().keySet().contains("topic"); + final Destination destination = useTopic ? topic : queue; + + out.write("

Sending messages to " + destination + "

"); + out.write("

The following messages will be sent to the destination:

"); + for (int i = 0; i < MSG_COUNT; i++) { + String text = "This is message " + (i + 1); + context.createProducer().send(destination, text); + out.write("Message (" + i + "): " + text + "
"); + } + out.write("

Go to your JBoss EAP server console or server log to see the result of messages processing.

"); + } finally { + if (out != null) { + out.close(); + } + } + } + + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doGet(req, resp); + } +} +""" + +formatted_complex_prompt = complex_prompt.format( + **{ + "current_issue": "MDBs work completely differently in Quarkus. Do not use JMS, use Quarkus reactive messaging. Use JakartaEE 9 instead of javax libraries.", + "current_issue_original_code": complex_code, + } +) + +llm = ChatOpenAI(streaming=True) + +for chunk in llm.stream(formatted_complex_prompt): + print(chunk.content, end="", flush=True)