Files
windmill/llm/src/gen_samples.py
HugoCasa d4345fb02c feat(frontend): generate scripts in the flow and app builders (#1886)
* feat: add inline code gen flow

* feat(frontend): add script gen to flow and app builders

* fix(backend): allow all users to use openai

* Fix build

* Fix build

* Fix build

---------

Co-authored-by: Faton Ramadani <faton.ramadani14@gmail.com>
2023-07-18 12:55:35 +02:00

185 lines
5.1 KiB
Python

import argparse
import yaml
from dotenv import load_dotenv
from tqdm import tqdm
from resources import RESOURCE_TYPES
load_dotenv()
import openai
import re
from typing import TypedDict, Tuple
class Literal(str):
pass
def literal_presenter(dumper, data):
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
yaml.add_representer(Literal, literal_presenter)
class GenPrompt(TypedDict):
prompt: str
class GenConfig(TypedDict):
prompts: dict[str, GenPrompt]
system: str
class CommonConfig(TypedDict):
system: str
prompt: str
class Query(TypedDict):
description: str
type: str
lang: str
code: str
error: str
def scriptLangToCodeLang(lang: str):
if lang in ["deno", "bun", "nativets"]:
return "typescript"
elif lang in ["postgresql", "mysql"]:
return "sql"
elif lang == "python3":
return "python"
elif lang == "bash":
return "shell"
elif lang == "frontend":
return "javascript"
else:
return lang
def scriptLangToEnvironment(lang: str):
if lang == "deno":
return "typescript in a deno running environment"
elif lang == "bun":
return "typescript in a node.js running environment"
elif lang == "nativets":
return "typescript where you should use fetch and are not allowed to import any libraries"
elif lang == "frontend":
return "client-side javascript"
else:
return lang
def get_prompts(prompts_path: str) -> Tuple[GenConfig, CommonConfig, CommonConfig]:
GEN_CONFIG = None
EDIT_CONFIG = None
FIX_CONFIG = None
with open(prompts_path + "/gen.yaml") as f:
GEN_CONFIG = yaml.safe_load(f)
with open(prompts_path + "/edit.yaml") as f:
EDIT_CONFIG = yaml.safe_load(f)
with open(prompts_path + "/fix.yaml") as f:
FIX_CONFIG = yaml.safe_load(f)
return GEN_CONFIG, EDIT_CONFIG, FIX_CONFIG
def get_queries(queries_path: str) -> list[Query]:
with open(queries_path) as f:
return yaml.safe_load(f)
def prepare_prompt(
query: Query,
GEN_CONFIG: GenConfig,
EDIT_CONFIG: CommonConfig,
FIX_CONFIG: CommonConfig,
):
system = ""
prompt = ""
if query["type"] == "gen":
system = GEN_CONFIG["system"]
prompt = GEN_CONFIG["prompts"][query["lang"]]["prompt"]
prompt = prompt.replace("{description}", query["description"])
if query["lang"] in ["deno", "bun", "nativets"]:
prompt = prompt.replace("{resourceTypes}", RESOURCE_TYPES["typescript"])
elif query["lang"] in ["python3"]:
prompt = prompt.replace("{resourceTypes}", RESOURCE_TYPES["python"])
elif query["type"] == "edit":
system = EDIT_CONFIG["system"]
prompt = EDIT_CONFIG["prompt"]
lang = scriptLangToCodeLang(query["lang"])
environment = scriptLangToEnvironment(query["lang"])
prompt = (
prompt.replace("{description}", query["description"])
.replace("{lang}", lang)
.replace("{environment}", environment)
.replace("{code}", query["code"])
)
elif query["type"] == "fix":
system = FIX_CONFIG["system"]
prompt = FIX_CONFIG["prompt"]
lang = scriptLangToCodeLang(query["lang"])
environment = scriptLangToEnvironment(query["lang"])
prompt = (
prompt.replace("{lang}", lang)
.replace("{environment}", environment)
.replace("{error}", query["error"])
.replace("{code}", query["code"])
)
return system, prompt
def format_answer(answer: str):
return re.sub("[^\\S\n]+\n", "\n", answer).replace("\t", " ")
def gen_samples(queries_path: str, answers_path: str, prompts_path: str):
GEN_CONFIG, EDIT_CONFIG, FIX_CONFIG = get_prompts(prompts_path)
queries = get_queries(queries_path)
answers = []
for query in tqdm(queries):
system, prompt = prepare_prompt(query, GEN_CONFIG, EDIT_CONFIG, FIX_CONFIG)
chat_completion = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": prompt},
],
temperature=0.5,
max_tokens=2048,
)
answer = {
**query,
"answer": Literal(format_answer(chat_completion["choices"][0]["message"]["content"])), # type: ignore
}
if "code" in query:
answer["code"] = Literal(query["code"])
answers.append(answer)
with open(answers_path, "w") as f:
yaml.dump(answers, f)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Process some integers.")
parser.add_argument("--queries_path", type=str, default="./sample_queries.yaml")
parser.add_argument("--answers_path", type=str, default="./sample_answers.yaml")
parser.add_argument(
"--prompts_path",
type=str,
default="../frontend/src/lib/components/codeGen/prompts",
)
args = parser.parse_args()
gen_samples(args.queries_path, args.answers_path, args.prompts_path)