Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add querying to incident store #23

Merged
merged 14 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
92 changes: 92 additions & 0 deletions kai-service/kai.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""This module is intended to facilitate using Konveyor with LLMs."""

import json
import os
import warnings
from os import listdir
Expand All @@ -11,6 +12,14 @@
import yaml
from aiohttp import web

# TODO: Make openapi spec for everything

# TODO: Repo lives both on client and on server. Determine either A) Best way to
# rectify differences or B) Only have the code on one and pass stuff between
# each other

# TODO: Parameter validation


def load_config():
"""Load the configuration from a yaml conf file."""
Expand Down Expand Up @@ -128,9 +137,92 @@
)


async def run_analysis_report():
pass


async def send_analysis_report():
pass


def prepopulate_incident_store():
"""For demo, populate store with already solved examples"""
pass


def user_gives_which_repo_and_branch(params):
"""
params (json):
- repo: The repo to look at
- program: 'git' | 'svn' | etc... (let's only support git for now)
- branch: Duh
"""

# TODO: Clone the repo locally on the server

pass


def user_gives_service_which_incident_to_solve(params):
# TODO: Make a streaming version

"""
Will need to cache the incident result so that the user, when it accepts
or rejects it knows what the heck the user is referencing

Stateful, stores it

params (json):
- some identifier of the incident that we are looking at

return (json):
- some diff of the code to apply
- id of the associated solved incident
"""

solved_example = try_and_get_the_fricken_solved_example_maybe()

Check failure on line 183 in kai-service/kai.py

View workflow job for this annotation

GitHub Actions / Trunk Check

ruff(F821)

[new] Undefined name `try_and_get_the_fricken_solved_example_maybe`

Check failure on line 183 in kai-service/kai.py

View workflow job for this annotation

GitHub Actions / Trunk Check

ruff(F841)

[new] Local variable `solved_example` is assigned to but never used
prompt = generate_prompt()
llm_result = proxy_handler(prompt) # Maybe?

Check failure on line 185 in kai-service/kai.py

View workflow job for this annotation

GitHub Actions / Trunk Check

ruff(F841)

[new] Local variable `llm_result` is assigned to but never used

diff = get_diff_from_llm_result()

Check failure on line 187 in kai-service/kai.py

View workflow job for this annotation

GitHub Actions / Trunk Check

ruff(F821)

[new] Undefined name `get_diff_from_llm_result`
cache_result_id = cache_the_solution_somehow()

Check failure on line 188 in kai-service/kai.py

View workflow job for this annotation

GitHub Actions / Trunk Check

ruff(F821)

[new] Undefined name `cache_the_solution_somehow`

return json.dumps(
{
"diff": diff,
"id": cache_result_id,
}
)


def accept_or_reject_solution(params):
"""
User says which solution and whether to reject or accept it

params (json):
- id: the id of the incident to accept or reject
- accept: bool to say yes or no

return (json):
- success: duh
"""

id = params["id"]
accept = params["accept"]

if accept:
solution = get_solution_from_id(id)

Check failure on line 214 in kai-service/kai.py

View workflow job for this annotation

GitHub Actions / Trunk Check

ruff(F821)

[new] Undefined name `get_solution_from_id`
put_solution_in_indicent_store(solution)

Check failure on line 215 in kai-service/kai.py

View workflow job for this annotation

GitHub Actions / Trunk Check

ruff(F821)

[new] Undefined name `put_solution_in_indicent_store`

return json.dump({"success": True})


app = web.Application()
app.router.add_post("/generate_prompt", generate_prompt)
app.router.add_route("*", "/proxy", proxy_handler)

if __name__ == "__main__":
# TODO: Remove after demo
prepopulate_incident_store()

web.run_app(app)
45 changes: 37 additions & 8 deletions kai/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
__version__ = "0.0.1"

from typing import List
from typing import Annotated, List

import typer
from typing_extensions import Annotated

from kai.incident_store import IncidentStore
from kai.report import Report
from kai.result import LLMResult

# from typing_extensions import Annotated


app = typer.Typer()

# report_app = typer.Typer()
Expand Down Expand Up @@ -78,14 +80,41 @@ def generate(


@app.command()
def load(applications: str):
def load(folder_path: str):
"""
Load the incident store with the given applications
write the cached_violations to a file for later use
"""
incident_store = IncidentStore()
apps = applications.split(",")
print(f"Loading incident store with {len(apps)} applications\n")
cached_violations = incident_store.load_app_cached_violation(apps)
print("Writing cached_violations")
incident_store.write_cached_violations(cached_violations)
incident_store.load_incident_store(folder_path)


@app.command()
def patch(ruleset: str, violation: str):
"""
Generate patches for a specific violation
"""
print(f"Generating patches for {ruleset} - {violation}")
incident_store = IncidentStore()
patches = incident_store.get_solved_issue(ruleset, violation)
if len(patches) == 0:
print(f"No patches found for {ruleset} - {violation}")
else:
for patch in patches:
print(f"Patch: {patch}")
return patches


@app.command()
def common(ruleset: str, violation: str):
"""
Find common violations for a specific violation
"""
print(f"Finding common violations for {ruleset} - {violation}")
incident_store = IncidentStore()
violations = incident_store.find_common_violations(ruleset, violation)
if violations is None:
print(f"No common violations found for {ruleset} - {violation}")
for violation in violations:
print(f"Violation: {violation}")
return violations
216 changes: 216 additions & 0 deletions kai/ai-test.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain import PromptTemplate\n",
"from langchain.chains import LLMChain\n",
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.callbacks import FileCallbackHandler\n",
"\n",
"\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",
"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<String, RequestHandler> 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<String, Consumer<String>> routes;\n",
"\n",
" public ModernRouter() {\n",
" routes = new HashMap<>();\n",
" }\n",
"\n",
" public void addRoute(String path, Consumer<String> 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<Integer> compareIntegers = new Comparator<Integer>() {\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(formatted_prompt):\n",
" print(chunk.content, end=\"\", flush=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"jhhhhhhhkhhjh"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%pip install langchain\n",
"%pip install openai"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading
Loading