Skip to content

Commit f2f195b

Browse files
author
melih-unsal
committed
finalizer module refined, doc_load refined
1 parent 3d84306 commit f2f195b

File tree

7 files changed

+119
-89
lines changed

7 files changed

+119
-89
lines changed

demogpt/chains/prompts/combine_v2.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
system_template = """
2-
Regenerate the code by only combining the input parts into st.form.
2+
Regenerate the code by combining all the user input parts into st.form.
33
It is really important not to change other parts.
44
Copy all the function definitions and library imports as is and don't modify or replace them.
55
Combine input-related parts under the st.form.
66
If a function needs an input from user via st.text_input, put it between st.form and st.form_submit_button so that the state is preserved.
7-
Show the result when the form is submitted.
7+
Show the result when the form is submitted under the if submit_button: statement.
88
Keep in mind that don't miss any function definition.
99
1010
Don't forget to add those functions with their original definitions as is
1111
1212
{function_names}
13+
14+
Always put "if submit_button:" inside of st.form block
1315
"""
1416

1517
human_template = """
1618
=============================================================
1719
DRAFT CODE 1:
1820
# all imports
1921
22+
openai_api_key = st.sidebar.text_input(
23+
"OpenAI API Key",
24+
placeholder="sk-...",
25+
value=os.getenv("OPENAI_API_KEY", ""),
26+
type="password",
27+
)
28+
2029
def foo1():
2130
result = "res"
2231
return result
@@ -43,27 +52,41 @@ def foo2(half_story,user_choice):
4352
FINAL CODE 1:
4453
# all imports
4554
55+
# all functions
56+
57+
openai_api_key = st.sidebar.text_input(
58+
"OpenAI API Key",
59+
placeholder="sk-...",
60+
value=os.getenv("OPENAI_API_KEY", ""),
61+
type="password",
62+
)
63+
4664
def foo1():
4765
result = "res"
4866
return result
4967
50-
half_story = foo1()
51-
52-
if half_story:
53-
st.write(half_story)
54-
5568
def foo2(half_story,user_choice):
5669
result = half_story + user_choice
5770
return result
5871
5972
with st.form(key='story_game'):
73+
# take all user inputs
6074
text_input = st.text_input(label='Enter some text')
6175
user_choice = st.selectbox("What would you like to do next?", ["Choice1", "Choice2"])
6276
submit_button = st.form_submit_button(label='Submit Story')
77+
# run functions if submit button is pressed
6378
if submit_button:
79+
half_story = foo1()
80+
if half_story:
81+
st.write(half_story)
6482
if text_input and user_choice :
6583
continued_story = foo2(text_input,user_choice)
84+
else:
85+
continued_story = ""
86+
if continued_story:
6687
st.markdown(continued_story)
88+
else: # if not submitted yet, we need to initizalize continued_story to get rid of name error
89+
continued_story = ""
6790
#############################################################
6891
6992
Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,49 @@
11
loaders = """
22
For Local TXT file:
3-
from langchain.document_loaders import TextLoader
4-
loader = TextLoader(<local_txt_file_path>)
3+
TextLoader
54
################################
65
For Web Page:
7-
from langchain.document_loaders import WebBaseLoader
8-
loader = WebBaseLoader("<url>")
6+
WebBaseLoader
97
################################
108
For Online PDF:
11-
from langchain.document_loaders import OnlinePDFLoader
12-
loader = OnlinePDFLoader("<online_pdf_url>")
9+
OnlinePDFLoader
1310
################################
1411
For Local PDF:
15-
from langchain.document_loaders import UnstructuredPDFLoader
16-
loader = UnstructuredPDFLoader(
17-
<local_pdf_full_path>, mode="elements", strategy="fast"
18-
)
12+
UnstructuredPDFLoader
1913
################################
2014
For Power Point:
21-
from langchain.document_loaders import UnstructuredPowerPointLoader
22-
loader = UnstructuredPowerPointLoader(
23-
<local_powerpoint_file>, mode="elements", strategy="fast"
24-
)
15+
UnstructuredPowerPointLoader
2516
################################
2617
For CSV:
27-
from langchain.document_loaders.csv_loader import UnstructuredCSVLoader
28-
loader = UnstructuredCSVLoader(<csv_file_path>, mode="elements")
18+
UnstructuredCSVLoader
2919
################################
3020
For Excel:
31-
from langchain.document_loaders.excel import UnstructuredExcelLoader
32-
loader = UnstructuredExcelLoader(<excel_file_path>, mode="elements")
21+
UnstructuredExcelLoader
3322
"""
3423

24+
loader_dict = {
25+
"txt" : "TextLoader",
26+
"web_page" : "WebBaseLoader",
27+
"online_pdf" : "OnlinePDFLoader",
28+
"pdf" :"UnstructuredPDFLoader",
29+
"powerpoint" : "UnstructuredPowerPointLoader",
30+
"csv" : "UnstructuredCSVLoader",
31+
"excel" :"UnstructuredExcelLoader"
32+
}
33+
3534
system_template = f"""
36-
These are the Loader classes that you should select.
37-
Select the loader according to the input type unless the input type is ambiguous.
35+
Based on the provided context in 'Previous Code', choose the most appropriate loader.
36+
37+
These are your loader options:
38+
3839
{loaders}
3940
"""
4041

4142
human_template = """
42-
Write a loader function using langchain.document_loaders
43-
to load the document for the argument name, variable and instruction
44-
below like in the below format:
45-
46-
###
47-
def {function_name}({argument}):
48-
loader = Loader(path) # Select the appropriate Loader
49-
docs = loader.load()
50-
return docs
51-
52-
if {argument}:
53-
{variable} = {function_name}({argument})
54-
else:
55-
{variable} = ''
56-
###
57-
58-
While using the loader, don't change "mode" and "strategy" arguments, they need to be constant as stated.
59-
If there are no such arguments, ignore it.
60-
61-
Instruction:{instruction}
43+
Use the information from 'Previous Code' to determine the loader from one of the 7 loader options.
44+
Don't write any explanation but directly say the loader option
6245
63-
Document Loader Code:
46+
Instruction: {instruction}
47+
Previous Code: {code_snippets}
48+
Loader Option:
6449
"""

demogpt/chains/prompts/task_list/ui_input_file.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
You will basically use file_uploader and get file path from it but nothing else.
1717
Do not loose the file path and check if the file is uploaded. Otherwise, assign empty string to "{variable}"
1818
Don't read the file, only get the file path
19+
In the st.file_uploader, change type parameter compatible with the type of the expected file such as pdf, csv, ...
1920
"""
2021

2122
human_template = """

demogpt/chains/task_chains.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,15 @@ def pathToContent(cls, task, code_snippets):
9393
return utils.refine(code)
9494

9595
@classmethod
96-
def promptTemplate(cls, task, code_snippets):
96+
def promptTemplate(cls, task):
9797
inputs = task["input_key"]
9898
instruction = task["description"]
9999

100100
res = cls.getChain(
101101
system_template=prompts.prompt_template.system_template,
102102
human_template=prompts.prompt_template.human_template,
103103
instruction=instruction,
104-
inputs=inputs,
105-
code_snippets=code_snippets,
104+
inputs=inputs
106105
)
107106
res = res[res.find("{") : res.rfind("}") + 1]
108107
return json.loads(res)
@@ -175,16 +174,34 @@ def docLoad(cls, task, code_snippets):
175174
variable = task["output_key"]
176175
function_name = task["task_name"]
177176

178-
code = cls.getChain(
177+
loader = cls.getChain(
179178
system_template=prompts.doc_load.system_template,
180179
human_template=prompts.doc_load.human_template,
181180
instruction=instruction,
182-
argument=argument,
183-
variable=variable,
184-
function_name=function_name,
185181
code_snippets=code_snippets,
186182
)
187-
return utils.refine(code)
183+
184+
185+
if loader in ["TextLoader", "WebBaseLoader", "OnlinePDFLoader"]:
186+
loader_line = f'loader = {loader}({argument})'
187+
elif loader in ["UnstructuredPDFLoader", "UnstructuredPowerPointLoader"]:
188+
loader_line = f'loader = {loader}({argument}, mode="elements", strategy="fast")'
189+
elif loader in ["UnstructuredCSVLoader", "UnstructuredExcelLoader"]:
190+
loader_line = f'loader = {loader}({argument}, mode="elements")'
191+
else:
192+
loader_line = f'loader = TextLoader({argument})'
193+
194+
code = f"""
195+
def {function_name}({argument}):
196+
{loader_line}
197+
docs = loader.load()
198+
return docs
199+
if {argument}:
200+
{variable} = {function_name}({argument})
201+
else:
202+
{variable} = ''
203+
"""
204+
return code
188205

189206
@classmethod
190207
def stringToDoc(cls, task, code_snippets):

demogpt/controllers.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ def checkDTypes(tasks):
4949
feedback += f"""
5050
{name} expects all inputs as {reference_input} or none but the data type of {input_key} is {input_data_type} not {reference_input}. Please find another way.\n
5151
"""
52-
print("1:",)
5352
else:
5453
for res, data_type in zip(input_key, input_data_type):
5554
if data_type != reference_input:
@@ -75,10 +74,8 @@ def checkDTypes(tasks):
7574
return {"feedback": feedback, "valid": valid}
7675

7776

78-
def checkPromptTemplates(templates, task):
79-
human_template = templates["template"]
80-
system_template = templates["system_template"]
81-
templates = human_template + system_template
77+
def checkPromptTemplates(templates, task, additional_inputs=[]):
78+
templates = " ".join(list(templates.values()))
8279
inputs = task["input_key"]
8380
if inputs == "none":
8481
inputs = []
@@ -87,8 +84,9 @@ def checkPromptTemplates(templates, task):
8784
if inputs.startswith("["):
8885
inputs = inputs[1:-1]
8986
inputs = [var.strip() for var in inputs.split(",")]
87+
template_inputs = inputs + additional_inputs
9088
feedback = ""
91-
for input_key in inputs:
89+
for input_key in template_inputs:
9290
if f"{{{input_key}}}" not in templates:
9391
feedback += f"'{{{input_key}}}' is not included in any of the templates. You must add '{{{input_key}}}' inside of at least one of the templates.\n"
9492

@@ -97,7 +95,7 @@ def checkPromptTemplates(templates, task):
9795
matches = set(re.findall(r"\{([^}]+)\}", templates))
9896

9997
for match in matches:
100-
if match not in inputs:
98+
if match not in template_inputs:
10199
feedback += f"'{{{match}}}' cannot be included nowhere in the templates. You must remove '{{{match}}}'.\n"
102100

103101
valid = len(feedback) == 0

demogpt/utils.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,35 @@ def getFunctionNames(code):
2121
pattern = r"def (\w+)\(.*\):"
2222
return re.findall(pattern, code)
2323

24-
24+
def getGenericPromptTemplateCode(task, iters):
25+
res = ""
26+
is_valid = False
27+
task_type = task["task_type"]
28+
prompt_func = TaskChains.promptTemplate if task_type == "prompt_template" else TaskChains.chat
29+
finalizer_func = getPromptChatTemplateCode if task_type == "prompt_template" else getChatCode
30+
additional_inputs = []
31+
if task_type == "chat":
32+
additional_inputs.append("chat_history")
33+
res = prompt_func(task=task)
34+
templates = {key:res.get(key) for key in res if "template" in key}
35+
function_name = res.get("function_name")
36+
variety = res.get("variety")
37+
index = 0
38+
while not is_valid:
39+
check = checkPromptTemplates(templates, task, additional_inputs)
40+
is_valid = check["valid"]
41+
feedback = check["feedback"]
42+
if not is_valid:
43+
res = TaskChains.promptTemplateRefiner(res, feedback)
44+
else:
45+
break
46+
index += 1
47+
if index == iters:
48+
break
49+
res["function_name"] = function_name
50+
res["variety"] = variety
51+
return finalizer_func(res, task)
52+
2553
def getCodeSnippet(task, code_snippets, iters=10):
2654
task = refineKeyTypeCompatiblity(task)
2755
task_type = task["task_type"]
@@ -30,27 +58,8 @@ def getCodeSnippet(task, code_snippets, iters=10):
3058
code = TaskChains.uiInputText(task=task, code_snippets=code_snippets)
3159
elif task_type == "ui_output_text":
3260
code = TaskChains.uiOutputText(task=task, code_snippets=code_snippets)
33-
elif task_type == "prompt_template":
34-
res = ""
35-
is_valid = False
36-
res = TaskChains.promptTemplate(task=task, code_snippets=code_snippets)
37-
function_name = res.get("function_name")
38-
variety = res.get("variety")
39-
index = 0
40-
while not is_valid:
41-
check = checkPromptTemplates(res, task)
42-
is_valid = check["valid"]
43-
feedback = check["feedback"]
44-
if not is_valid:
45-
res = TaskChains.promptTemplateRefiner(res, feedback)
46-
else:
47-
break
48-
index += 1
49-
if index == iters:
50-
break
51-
res["function_name"] = function_name
52-
res["variety"] = variety
53-
code = getPromptChatTemplateCode(res, task)
61+
elif task_type in ["prompt_template", "chat"]:
62+
code = getGenericPromptTemplateCode(task, iters=iters)
5463
elif task_type == "path_to_content":
5564
code = TaskChains.pathToContent(task=task, code_snippets=code_snippets)
5665
elif task_type == "doc_to_string":
@@ -63,9 +72,6 @@ def getCodeSnippet(task, code_snippets, iters=10):
6372
code = TaskChains.docLoad(task=task, code_snippets=code_snippets)
6473
elif task_type == "doc_summarizer":
6574
code = TaskChains.summarize(task=task, code_snippets=code_snippets)
66-
elif task_type == "chat":
67-
template = TaskChains.chat(task=task)
68-
code = getChatCode(template=template, task=task)
6975
elif task_type == "ui_input_chat":
7076
code = getChatInputCode(TaskChains.uiInputChat(task=task))
7177
elif task_type == "ui_output_chat":

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "demogpt"
7-
version = "1.2.6.3"
7+
version = "1.2.6.4"
88
description = "Auto Gen-AI App Generator with the Power of Llama 2"
99
authors = ["Melih Unsal <melih@demogpt.io>"]
1010
license = "MIT"

0 commit comments

Comments
 (0)