import openai import gradio as gr import json import logging import time from pathlib import Path import tempfile from zipfile import ZipFile import os def instruct(system_prompt : str, message : str) -> str: """ General purpose LLM/AI invocation. Use llama v2 13b chat as an instruct model by wrapping it up in a single turn conversation. """ response = openai.ChatCompletion.create( model="accounts/fireworks/models/llama-v2-13b-chat-w8a16", messages=[{"role":"system", "content": system_prompt}, {"role":"user", "content": message}], temperature=0.7, max_tokens=2048 ) return response.choices[0].message.content sys_prompt1 = """You are a business consultant who helps ordinary people that want to start their own business or SME (Small to Medium Enterprise). You specialize in B2C retail or service shops, or more generally those whose main prescence is via physical store. Your client will present you with the kind of shop they want to open, as well as some contextual information, such as the business owner's personal background or piror experience, the specific situation they have, or additional detail on the business they want to do. You should give a single reply doing this task: Give a list of conrete steps/actions that they should do to boostrap the business up to the opening of the physical shop. Group the actions by *Category* instead of chronologically. For each action give a brief description. """ message1 = """- Shop to open: Coffee shop/cafe in the Bay Area - Additional info: I'm a complete newbie in business. """ sys_prompt2 = """You are a business consultant who helps ordinary people that want to start their own business or SME (Small to Medium Enterprise). You specialize in B2C retail or service shops, or more generally those whose main prescence is via physical store. Your client gave this info about the shop they want to open and some additional info: {initial} ---- You have previously generated an action item list as follows: {base_plan} ---- You should give a single reply doing this task: {task} """ tasks = {} tasks["interior_design"] = """give 3 generic suggested Interior Designs. Explain the main theme of the design and how does it relates to the business, then drill down to details of how the theme may concretely be implemented through specific elements/decor/furnitures etc.""" tasks["product_design"] = """Perform product design appropiate to the context of the shop. For example, for a cafe/restaurant, the "product" to design would be the menu of food items. For retail shops, the "products" would be the type of goods to sell on the shelf. For shop providing service such as hair salon, the "product" would be the service offered such as hair cutting, hair beauty treatment etc.""" tasks["equipments"] = """Give a list of the equipments we will need to buy for the shop at the beginning. Any additional tips when buying?""" tasks["Staffing_HR"] = """Give a list of the minimum amount of staff we need to hire to operate the shop. Can we outsource part of our business to external service provider? If yes list which parts they are. For each staff role, describe their job responsibility, and list what requirements (such as skills, attributes, qualifications, etc) we should have when recruiting.""" tasks["IT_website"] = """We have decided to hire a software agency to help create the website of our shop business for us. Give a business and technical requirement to them, while specifying some details such as website content and layout etc according to the specifics of our business. Due to budget constraint, please reserve some of the more advanced functionality for a planned future phase (and mark/label them in your output as such).""" tasks["Supplier"] = """We would like to make a contract with a supplier so that they will regularly supply us with the materials we need to operate the shop (such as food ingredient for a coffee shop). What are the general steps to make this happen, and what details should we be aware of when arranging this?""" tasks["budgeting"] = """Give a breakdown of the expense, including initial cost, running cost, and operational cost by the type/items that incur the cost. Use a common sense estimate. For items where estimate is difficult because the potential range is too large, mark it as such and we'll handle it later.""" tasks["business_model"] = """What kind of pricing/business model should we adopt? Choose based on its pros and cons among the alternatives and pick one that is appropiate to this business. Then, suggest what level of integration we should have with respect to online shopping/e-commerce. Should our business be offline first or online/offline hybrid. Third, should we choose to join a franchise network or something similar, or are we better off alone? Or are there alternative operating models that you think we should use? Finally, suggest the scale we should operate at (that is, number of shops) and expansion pathway, with respect to time. (Note: scaling up is sometimes but not always the right answer.)""" tasks["business_analysis"] = """Perform a business analysis. What might be our core competencies? Do a SWOT analysis, as well as a value chain analysis. Then suggest a high level, overall business strategy.""" tasks["market_analysis"] = """Perform a market analysis. What should our value proposition and unique selling points be? What is the competitive landscape? And which segment should we target/what are our target audience? Based on these info, formulate a high level marketing strategy.""" #with tempfile.TemporaryDirectory() as tmpdirname: def export_all_docs(docs): tmpdirname = tempfile.mkdtemp() for k, v in docs.items(): fullpath = os.path.join(tmpdirname, k + ".txt") with open(fullpath, "w") as f: f.write(v) export_filename = os.path.join(tmpdirname, "all_docs.zip") with ZipFile(export_filename, "w") as zip: for k in docs: fullpath = os.path.join(tmpdirname, k + ".txt") zip.write(fullpath) return export_filename user_topic_background = """- Shop to open: {topic} - Additional info: {add_info} """ def generate_all_docs(topic : str, add_info : str) -> dict: yield ({}, "Begin generation...") user_message = user_topic_background.format(topic=topic, add_info=add_info) action_items = instruct(sys_prompt1, user_message) responses = {"action_items": action_items} yield (responses, "Generated action_items") for k, v in tasks.items(): result = instruct(sys_prompt2.format(initial=user_message, base_plan=action_items, task=v), "") responses[k] = result yield (responses, "Generated " + k) section = """# {title} {content} """ #def display_docs_combined(docs: dict) -> str: # md = "" # for k, v in docs.items(): # md = md + section.format(title=k, content=v) # return md task_list = [k for k in tasks] task_list.insert(0, "action_items") def display_docs_combined(docs: dict): res = [None] * len(task_list) for k, v in docs.items(): i = task_list.index(k) res[i] = v return res def convert_history_to_openai_format(system_prompt : str, history : list[tuple]): messages = [{ "role": "system", "content": system_prompt }] for (user_msg, assistant_msg) in history: messages.append({ "role": "user", "content": user_msg }) if assistant_msg is not None: messages.append({ "role": "assistant", "content": assistant_msg }) return messages system_prompt3 = """You are a business consultant who helps ordinary people that want to start their own business or SME (Small to Medium Enterprise). You specialize in B2C retail or service shops, or more generally those whose main prescence is via physical store. Your client gave this info about the shop they want to open and some additional info: {initial} Your client would now like to ask you some followup question on the business planning documents you wrote or do general consultation questions. (Optional and could be empty) For your reference and to set context, attached below are the relevant business planning documents you wrote: """ context_template = """## {title} {content} """ def talk_to_ai(message, history, choose_context, docs, init_t): #print(choose_context) sys_p = system_prompt3.format(initial=init_t) for k in choose_context: sys_p += context_template.format(title=k, content=docs[k]) #print(sys_p) data = convert_history_to_openai_format(sys_p, history) data.append({"role": "user", "content": message}) response = openai.ChatCompletion.create( model="accounts/fireworks/models/llama-v2-13b-chat-w8a16", messages=data, temperature=0.7, max_tokens=1024, stream=True ) ans = "" for chunk in response: txt = chunk.choices[0].delta.get("content", "") if txt is not None: ans += txt yield ans with gr.Blocks() as demo: docs = gr.State({}) init_t = gr.State("") gr.Markdown("# Start a Shop (alpha version)") with gr.Tabs() as tabs: with gr.TabItem("Generate Plan", id=0): gr.Markdown("Fill out the info and let AI generate a preliminary plan for starting a physical shop based business. Targetted for small shop owner. Currently takes about 2-3 minutes.") with gr.Row(): with gr.Column(): topic = gr.Textbox(label="Topic (eg Coffee shop in Bay Area)", show_label=True) add_info = gr.TextArea(label="Additional Info", show_label=True) generate_init_plan = gr.Button(value="Generate!") with gr.Column(): status_report = gr.Textbox(label="Status Indicator during generation") prelim_plan = [None] * len(task_list) for i, val in enumerate(task_list): with gr.Accordion(val): prelim_plan[i] = gr.Markdown() #prelim_plan = gr.Markdown() generate_init_plan.click(lambda a, b: user_topic_background.format(topic=a, add_info=b), [topic, add_info], init_t) \ .success(generate_all_docs, [topic, add_info], [docs, status_report]) \ .success(display_docs_combined, docs, prelim_plan) with gr.TabItem("Followup Questions", id=1): gr.Markdown("Here you can ask followup question in the context of the docs generated. Select the document for context to the AI in the dropdown below. Be careful not to choose too many due to LLM context length limitation.") with gr.Row(): #doc_context = gr.State() with gr.Column(): choose_context = gr.Dropdown(choices=task_list, multiselect=True) #set_context_btn = gr.Button(value="Set Context") #set_context_btn.click(lambda x: x, choose_context, doc_context) with gr.Column(): chat = gr.ChatInterface(talk_to_ai, additional_inputs=[choose_context, docs, init_t]) with gr.TabItem("Export", id=2): gr.Markdown("Press the button to create a zip containing backup of all documents.") export_btn = gr.Button(value="Export documents") export_download_area = gr.File() export_btn.click(export_all_docs, docs, export_download_area) demo.queue(concurrency_count=4, max_size=20).launch(debug=False)